Пример #1
0
 polynomial operator+(const polynomial<T>& o) const
 {
   int len;
   const polynomial<T> *p;
   size() >= o.size() ? (p=this, len=size()) : (p=&o, len=o.size());
   polynomial<T> out(len);
   std::transform(vals->data(),vals->data()+std::min(size(),o.size()),o.vals->data(),out.vals->data(),[](T a, T b){return a+b;});
   if (size() != o.size()) std::copy_n(&p->element(std::min(size(),o.size())),abs(size()-o.size()),&out(std::min(size(),o.size())));
   return out;
 }
Пример #2
0
 polynomial operator*(const polynomial<T>& o) const
 {
   int len = size()+o.size()-1;
   polynomial<T> out(len);
   for (int ii = 0; ii<size(); ii++)
   {
     for (int jj = 0; jj<o.size(); jj++)
       out(ii+jj) += (element(ii)*o(jj));
   }
   return out;
 }
Пример #3
0
 friend polynomial derivative(polynomial const& p) {
  int s = p.size();
  if(s == 0) return {};

  polynomial res;
  res.coeffs.resize(s-1);
  for(int n = 0; n < s-1; ++n)
   res.coeffs(n) = p.coeffs(n+1) * CoeffType(n+1);
  return res;
 }
Пример #4
0
 friend polynomial antiderivative(polynomial const& p) {
  int s = p.size();
  if(s == 0) return {};

  polynomial res;
  res.coeffs.resize(s+1);
  res.coeffs(0) = CoeffType{};
  for(int n = 1; n < s+1; ++n)
   res.coeffs(n) = p.coeffs(n-1) / CoeffType(n);
  return res;
 }
Пример #5
0
 void divide(const polynomial &b)
 {
     int m=b.size(),res[1110];
     for (int i=n;i>=m;i--)
     {
         int t=a[i]/b[m];
         for (int j=i;j>=i-m;j--)
             a[j]-=b[j-i+m]*t;
         res[i-m]=t;
     }
     n-=m;
     for (int i=0;i<=n;i++)
         a[i]=res[i];
 }
Пример #6
0
void fr_kernels(int i, const polynomial& P, const monomial& d, monomial& bk, polynomial& bcok, int& bv)
{
    for (int j = i; j < literal_size(); ++j)
    {
        int times = 0;
        for (int k = 0; k < P.size(); ++k)
        {
            if (P[k].getpow(j) != 0)
            {
                ++times;
            }
        }
        if (times > 1)
        {
            monomial Lj(j);
            polynomial Ft = P / Lj;
            monomial C = Ft.gcd();
            bool cflag = true;
            for (int k = 0; k < C.size(); ++k)
            {
                if (C.lit(k) < j)
                {
                    cflag = false;
                    break;
                }
            }
            if (cflag)
            {
                polynomial FI = Ft / C;//kernel
                monomial DI = d * C * Lj;//co-kernel
                int v = fr_value(DI, FI);
                if (v > bv)
                {
                    bv = v;
                    bk = DI;
                    bcok = FI;
                }
                fr_kernels(j, FI, DI, bk, bcok, bv);
            }
        }
    }
}
Пример #7
0
 polynomial operator-(const polynomial<T>& o) const
 {
   int len, sign;
   int min = std::min(size(),o.size());
   const polynomial<T> *p;
   size() >= o.size() ? (p=this, len=size(), sign=1) : (p=&o, len=o.size(), sign=-1);
   polynomial<T> out(len);
   std::transform(vals->data(),vals->data()+min,o.vals->data(),out.vals->data(),[](T a, T b){return a-b;});
   if (size() != o.size())
   {
     std::copy_n(&p->element(min),abs(size()-o.size()),&out(min));
     if (sign == -1) std::transform(&out(min),&out(min)+abs(size()-o.size()),&out(min),[](T a){return -1.0*a;});
   }
   return out;
 }
Пример #8
0
//The fr_kernels part are part of initial fastrun stategy
//Now they are deprecated, but we still keep these code in case.
int fr_value(const monomial& bk, const polynomial& bcok)
{
    return (bcok.size() - 1) * bk.multiplication_number();
}
Пример #9
0
void kernels(int i, const polynomial& P, const monomial& d, vector<pair<monomial, polynomial>>& kernelmap)
{
    //we use bitset for sj1 as we need fast lookup
    //while for sj2 we need iteration therefore we use set
    std::set<int> sj2;
    //brackets here for early release sj1, to reduce memory cost, as in recursive calling we may waste lots of memory
    {
        boost::dynamic_bitset<uint64_t> sj1(literal_size());//default value should be 0, i.e. false
        for (int mi = 0; mi < P.size(); ++mi)
        {
            for (int ti = 0; ti < P[mi].size(); ++ti)
            {
                int tmp = P[mi].lit(ti);
                if (tmp < i) { continue; }
                if (sj1[tmp] == 0)
                {
                    sj1[tmp] = 1;
                }
                else
                {
                    sj2.insert(tmp);
                }
            }
        }
    }
    for (auto j : sj2)
    {
        monomial Lj(j);
        polynomial Ft = P / Lj;
        monomial C = Ft.gcd();
        //optimization for this common case
        if (C == monomial())
        {
            monomial DI = d * Lj;//co-kernel
            kernelmap.push_back(make_pair(DI, Ft));
            kernels(j, Ft, DI, kernelmap);
            continue;
        }
        bool cflag = true;
        for (int k = 0; k < C.size(); ++k)
        {
            if (C.lit(k) < j)
            {
                cflag = false;
                break;
            }
        }
        if (cflag)
        {
            polynomial FI = Ft / C;//kernel
            monomial DI = d * C * Lj;//co-kernel
            //special for if FI=1+...
            /*
            if (FI.contain(monomial()))
            {
                for (int l = 0; l < C.size(); ++l)
                {
                    polynomial NFI = FI * monomial(C.lit(l));
                    monomial NDI = DI;
                    NDI /= monomial(C.lit(l));
                    std::cout<<NDI<<" "<<NFI<<std::endl;
                    kernelmap.push_back(make_pair(NDI, NFI));
                    kernels(j, NFI, NDI, kernelmap);
                }
            }
            */
            kernelmap.push_back(make_pair(DI, FI));
            kernels(j, FI, DI, kernelmap);
        }
    }
}
Пример #10
0
 polynomial(const polynomial& o) : vals(std::make_shared<std::vector<T>>(o.size()))
 {
   std::copy_n(o.vals->data(), size(), vals->data());
 }