1 #ifndef _UPOLYNOMIAL_H_     2 #define _UPOLYNOMIAL_H_     5 #include "../Polynomial/BPASUnivarPolynomial.hpp"     6 #include "../IntegerPolynomial/uzpolynomial.h"     7 #include "../RationalNumberPolynomial/urpolynomial.h"     8 #include "../Utils/TemplateHelpers.hpp"     9 #include "../Utils/RandomHelpers.hpp"    19 template <
class Ring, 
class Derived>
    28     std::vector< UnivariateTerm<Ring> > terms;
    30     inline bool isEqual(
const Derived& b)
 const {
    31         if (
degree() > 0 && b.degree() > 0 && (name != b.name))
    34         int m = b.terms.size();
    37         for (
int i = 0; i < n; ++i) {
    38             UnivariateTerm<Ring> t = b.terms[i];
    39             if (terms[i].coef != t.coef || terms[i].exp != t.exp)
    51         n = terms.size(), m++;
    53         for (
int i = 0; i < m; ++i) {
    54             if (k < n && terms[k].exp == i) {
    71         n = terms.size(), m++;
    73         for (
int i = 0; i < m; ++i) {
    74             if (k < n && terms[k].exp == i) {
    86     inline void pomopo(UnivariateTerm<Ring> t, 
const Derived& b) {
    87         int ai = 0, m = b.terms.size();
   147         const UnivariateTerm<Ring>* bterms = b.terms.data();
   148         Ring prodCoef, tcoef = t.coef;
   149         int prodExp, tExp = t.exp, aExp;
   150         for (
int i = 0; i < m; ++i) {
   151             prodCoef = tcoef * bterms[i].coef;
   152             prodExp = tExp + bterms[i].exp;
   154             if (ai >= terms.size()) {
   155                 terms.emplace_back(prodCoef, prodExp);
   158                 aExp = terms[ai].exp;
   159                 while (aExp < prodExp) {
   161                     if (ai < terms.size())
   162                         aExp = terms[ai].exp;
   164                         terms.emplace_back(prodCoef, prodExp);
   169                 if (aExp == prodExp) {
   170                     terms[ai].coef += prodCoef;
   171                     if (!terms[ai].coef.isZero()) {
   174                         terms.erase(terms.begin()+ai);
   177                 else if (aExp > prodExp) {
   178                     terms.emplace(terms.begin()+ai, prodCoef, prodExp);
   186     inline void pomopo(Ring c, UnivariateTerm<Ring> t, 
const Derived& b) {
   187         int ai = 0, m = b.terms.size();
   189         for (
int i = 0; i < m; ++i) {
   190             UnivariateTerm<Ring> product;
   191             product.coef = t.coef * b.terms[i].coef;
   192             product.exp = t.exp + b.terms[i].exp;
   194             if (ai >= terms.size()) {
   195                 terms.push_back(product);
   199                 int e1 = terms[ai].exp, e2 = product.exp;
   203                     if (ai < terms.size())
   206                         terms.push_back(product);
   213                     terms[ai].coef += product.coef;
   214                     if (terms[ai].coef.isZero())
   215                         terms.erase(terms.begin()+ai);
   219                     terms.insert(terms.begin()+ai, product);
   224         for (
int i = ai; i < terms.size(); ++i)
   230     inline Derived LazardSe(Derived& sd, Derived& sdm, Ring& y)
 const {
   231         int n = (sd.degree() - sdm.degree()).get_si() - 1;
   232         if (!n) { 
return sdm; }
   233         Ring x = sdm.leadingCoefficient();
   235         int a = (int) pow(2, floor(log2(n)));
   258     inline Derived DucosSem(Derived& a, Derived& sdm, Derived& se, Ring sd)
 const {
   261         int e = sdm.degree().get_si();
   264         Ring ec = se.leadingCoefficient();
   274             Ring dc = a.leadingCoefficient();
   281             rTemp = a.coefficient(e);
   288             rTemp = se.coefficient(e-1);
   290             supTemp.setCoefficient(0,rTemp);
   292             supTemp.setCoefficient(1,rTemp);
   301             Ring mc = sdm.leadingCoefficient();
   302             Derived* P = 
new Derived[d.get_si()];
   303             for (
int i = 0; i < e; ++i) {
   304                 P[i].setVariableName(name);
   305                 P[i].setCoefficient(i, ec);
   307             for (
int i = e+1; d > i; ++i)
   309             P[e].setVariableName(name);
   310             P[e].setCoefficient(e, ec);
   313             res.setCoefficient(1, ec);
   314             UnivariateTerm<Ring> t (ec, 1);
   315             for(
int i = e+1; i < d; ++i) {
   317                     ec = -P[i-1].coefficient(e-1);
   326                 P[i].pomopo(t, P[i-1]);
   328             res *= P[d.get_si()-1];
   331             for (
int i = 0; i < d; ++i) {
   332                 P[i] *= a.coefficient(i);
   335             D /= a.leadingCoefficient();
   338             ec = -res.coefficient(e);
   343             res.pomopo(mc, t, D);
   348             if ((d - e + 1) % 2 == 1) {
   355     inline UnivariateTerm<Ring> leadingTerm()
 const {
   356         int n = terms.size();
   357         if (n) { 
return terms[n-1]; }
   358         else { 
return UnivariateTerm<Ring>(); }
   362         mpz_class characteristic;
   373         characteristic = e.getCharacteristic();
   383         characteristic = e.getCharacteristic();
   387         UnivariateTerm<Ring> t;
   393         UnivariateTerm<Ring> t;
   399         UnivariateTerm<Ring> t;
   406         UnivariateTerm<Ring> t;
   413         for (
int i = 0; i <= b.degree().get_si(); ++i) {
   414             Ring e (
Integer(b.coefficient(i)));
   416                 UnivariateTerm<Ring> t;
   426         for (
int i = 0; i <= b.degree().get_si(); ++i) {
   429                 UnivariateTerm<Ring> t;
   466         int n = terms.size();
   467         if (n) { 
return terms[n-1].exp; }
   477         int n = terms.size();
   478         if (n) { 
return terms[n-1].coef; }
   479         else { 
return Ring(); }
   482     inline Ring trailingCoefficient()
 const {
   483         int n = terms.size();
   485             return terms[0].coef;
   497         int n = terms.size();
   498         for (
int i = 0; i < n; ++i) {
   499             if (k == terms[i].exp)
   500                 return terms[i].coef;
   501             else if (k < terms[i].exp)
   514         UnivariateTerm<Ring> b;
   519         int k = terms.size() - 1;
   520         if ((k < 0 || b.exp > terms[k].exp) && !c.isZero())
   523             for (
int i = 0; i <= k; ++i) {
   524                 int e1 = terms[i].exp, e2 = b.exp;
   526                     terms[i].coef = b.coef;
   527                     if (terms[i].coef.isZero())
   528                         terms.erase(terms.begin()+i);
   533                         terms.insert(terms.begin()+i, b);
   558     inline Derived unitCanonical(Derived* u = NULL, Derived* v = NULL)
 const {
   561         Ring canon = lead.unitCanonical(&ru, &rv);
   562         Derived ret = *
this * ru;
   584             characteristic = e.getCharacteristic();
   586         return dynamic_cast<Derived&
>(*this);
   596         UnivariateTerm<Ring> t;
   599         return dynamic_cast<Derived&
>(*this);
   609         return !(isEqual(b));
   635         return !(terms.size());
   653         if (terms.size() == 1 && !terms[0].exp)
   654             return terms[0].coef.isOne();
   665         UnivariateTerm<Ring> t;
   677         if (terms.size() == 1 && !terms[0].exp)
   678             return terms[0].coef.isNegativeOne();
   689         UnivariateTerm<Ring> t;
   690         t.coef.negativeOne();
   701         if (terms.size() == 1 && !terms[0].exp)
   702             return terms[0].coef.isConstant();
   712         if (terms.size() && !terms[0].exp)
   713             return terms[0].coef;
   728         int n = terms.size();
   731             for (
int i = 1; i < n; ++i) {
   732                 c = c.gcd(terms[i].coef);
   741     inline Derived primitivePart()
 const {
   743         std::cerr << 
"BPAS ERROR: SUP<Ring>::primitivePart NOT YET IMPLEMENTED" << std::endl;
   771                 if (e % 2) { res *= x; }
   792         return dynamic_cast<Derived&
>(*this);
   813         for (
int i = 0; i < terms.size(); ++i)
   814             terms[i].exp += (
unsigned long int) k;
   815         return dynamic_cast<Derived&
>(*this);
   839         unsigned long int e = (
unsigned long int) k;
   840         while (i < terms.size()) {
   841             if (terms[i].exp >= e) {
   845             else { terms.erase(terms.begin()); }
   847         return dynamic_cast<Derived&
>(*this);
   866         if (!terms.size()) { 
return (*
this = b); }
   867         if (!b.terms.size()) { 
return dynamic_cast<Derived&
>(*this); }
   868         if (
isConstant()) { 
return (*
this = b + terms[0].coef); }
   869         if (b.isConstant()) { 
return (*
this += b.terms[0].coef); }
   870         if (name != b.name) {
   871             std::cout << 
"BPAS: error, trying to add between Ring[" << name << 
"] and Ring[" << b.name << 
"]." << std::endl;
   876         for (
int i = 0; i < b.terms.size(); ++i) {
   877             UnivariateTerm<Ring> bt = b.terms[i];
   878             if (ai >= terms.size()) {
   883                 int e1 = terms[ai].exp, e2 = bt.exp;
   886                     if (ai < terms.size())
   895                     terms[ai].coef += bt.coef;
   896                     if (terms[ai].coef.isZero())
   897                         terms.erase(terms.begin()+ai);
   901                     terms.insert(terms.begin()+ai, bt);
   904         return dynamic_cast<Derived&
>(*this);
   925                 UnivariateTerm<Ring> a = terms[0];
   929                     terms.insert(terms.begin(), a);
   933                     if (terms[0].coef.isZero())
   934                         terms.erase(terms.begin());
   938                 UnivariateTerm<Ring> a;
   944         return dynamic_cast<Derived&
>(*this);
   947     inline friend Derived 
operator+ (
const Ring& c, 
const Derived& p) {
   959         for (
int i = 0; i < terms.size(); ++i) {
   960             UnivariateTerm<Ring> t;
   961             t.coef = -terms[i].coef;
   962             t.exp = terms[i].exp;
   963             res.terms.push_back(t);
   984         if (!terms.size()) { 
return (*
this = -b); }
   985         if (!b.terms.size()) { 
return dynamic_cast<Derived&
>(*this); }
   986         if (
isConstant()) { 
return (*
this = -b + terms[0].coef); }
   987         if (b.isConstant()) { 
return (*
this -= b.terms[0].coef); }
   988         if (name != b.name) {
   989             std::cout << 
"BPAS: error, trying to subtract between Ring[" << name << 
"] and Ring[" << b.name << 
"]." << std::endl;
   994         for (
int i = 0; i < b.terms.size(); ++i) {
   995             UnivariateTerm<Ring> t = b.terms[i];
   998             if (ai >= terms.size()) {
  1003                 int e1 = terms[ai].exp, e2 = t.exp;
  1006                     if (ai < terms.size())
  1015                     terms[ai].coef += t.coef;
  1016                     if (terms[ai].coef.isZero())
  1017                         terms.erase(terms.begin()+ai);
  1021                     terms.insert(terms.begin()+ai, t);
  1024         return dynamic_cast<Derived&
>(*this);
  1045                 UnivariateTerm<Ring> t = terms[0];
  1049                     terms.insert(terms.begin(), t);
  1053                     if (terms[0].coef.isZero())
  1054                         terms.erase(terms.begin());
  1058                 UnivariateTerm<Ring> t;
  1064         return dynamic_cast<Derived&
>(*this);
  1067     inline friend Derived 
operator- (
const Ring& c, 
const Derived& p) {
  1077         int n = terms.size(), m = b.terms.size();
  1085             for (
int i = 0; i < m; ++i) {
  1086                 UnivariateTerm<Ring> bt = b.terms[i];
  1087                 UnivariateTerm<Ring> t;
  1088                 t.coef = terms[0].coef * bt.coef;
  1090                 res.terms.push_back(t);
  1096         if (b.degree() == 0) {
  1097             UnivariateTerm<Ring> bt = b.terms[0];
  1098             for (
int i = 0; i < n; ++i) {
  1099                 UnivariateTerm<Ring> t;
  1100                 t.coef = terms[i].coef * bt.coef;
  1101                 t.exp = terms[i].exp;
  1102                 res.terms.push_back(t);
  1107         if (name != b.name) {
  1108             std::cout << 
"BPAS: error, trying to multiply between Ring[" << name << 
"] and Ring[" << b.name << 
"]." << std::endl;
  1114                 for (
int i = 0; i < n; ++i)
  1115                     res.pomopo(terms[i], b);
  1118                 for (
int i = 0; i < m; ++i)
  1119                     res.pomopo(b.terms[i], *
this);
  1123             int s = (m > n) ? m : n;
  1126             f0.name = f1.name = name;
  1127             for (
int i = 0; i < n; ++i) {
  1128                 if (terms[i].exp < s)
  1129                     f0.terms.push_back(terms[i]);
  1131                     UnivariateTerm<Ring> t (terms[i].coef, terms[i].exp-s);
  1132                     f1.terms.push_back(t);
  1136             g0.name = g1.name = name;
  1137             for (
int i = 0; i < m; ++i) {
  1138                 if (b.terms[i].exp < s)
  1139                     g0.terms.push_back(b.terms[i]);
  1141                     UnivariateTerm<Ring> t (b.terms[i].coef, b.terms[i].exp-s);
  1142                     g1.terms.push_back(t);
  1146             t0.name = t1.name = name;
  1147             n = f0.terms.size(), m = g0.terms.size();
  1149                 for (
int i = 0; i < n; ++i)
  1150                     res.pomopo(f0.terms[i], g0);
  1153                 for (
int i = 0; i < m; ++i)
  1154                     res.pomopo(g0.terms[i], f0);
  1156             n = f1.terms.size(), m = g1.terms.size();
  1158                 for (
int i = 0; i < n; ++i)
  1159                     t0.pomopo(f1.terms[i], g1);
  1162                 for (
int i = 0; i < m; ++i)
  1163                     t0.pomopo(g1.terms[i], f1);
  1166             n = f0.terms.size(), m = g0.terms.size();
  1168                 for (
int i = 0; i < n; ++i)
  1169                     t1.pomopo(f0.terms[i], g0);
  1172                 for (
int i = 0; i < m; ++i)
  1173                     t1.pomopo(g0.terms[i], f0);
  1176             for (
int i = 0; i < t1.terms.size(); ++i)
  1177                 t1.terms[i].exp += s;
  1179             for (
int i = 0; i < t0.terms.size(); ++i)
  1180                 t0.terms[i].exp += s;
  1193         return dynamic_cast<Derived&
>(*this);
  1206     inline Derived 
operator* (
const sfixn& e)
 const {
  1218             if (!c.isZero() && !c.isOne()) {
  1219                 for (
int i = 0; i < terms.size(); ++i)
  1222             else if (c.isZero())
  1225         return dynamic_cast<Derived&
>(*this);
  1228     inline Derived& 
operator*= (
const sfixn& e) {
  1229         if (e != 0 && e != 1) {
  1230             for (
int i = 0; i < terms.size(); ++i)
  1233         else if (e == 0) { 
zero(); }
  1234         return dynamic_cast<Derived&
>(*this);
  1237     inline friend Derived 
operator* (
const Ring& e, 
const Derived& p) {
  1241     inline friend Derived 
operator* (
const sfixn& e, 
const Derived& p) {
  1265             std::cout << 
"BPAS: error, dividend is zero from Derived." << std::endl;
  1268         if (b.isConstant()) { 
return (*
this /= b.terms[0].coef); }
  1271             return dynamic_cast<Derived&
>(*this);
  1273         if (name != b.name) {
  1274             std::cout << 
"BPAS: error, trying to exact divide between Ring[" << name << 
"] and Ring[" << b.name << 
"]." << std::endl;
  1282         UnivariateTerm<Ring> bt = b.leadingTerm();
  1284         if (db == 1 && bt.coef.
isOne()) {
  1285             if (b.terms.size() > 1) {
  1288                 UnivariateTerm<Ring> t, at = leadingTerm();
  1289                 if (!terms[0].exp) {
  1290                     prev = t.coef = terms[0].coef / b.terms[0].coef;
  1292                     q.terms.push_back(t);
  1295                 else { prev.zero(); }
  1296                 for (
int i = 1; i < at.exp; ++i) {
  1297                     if (k < terms.size() && terms[k].exp == i) {
  1302                     t.coef = (e - prev) / b.terms[0].coef;
  1303                     if (!t.coef.isZero()) {
  1305                         q.terms.push_back(t);
  1309                 if (prev == at.coef)
  1312                     std::cout << 
"BPAS: error, not exact division in Derived." << std::endl;
  1317                 if (!terms[0].exp) {
  1318                     std::cout << 
"BPAS: error, not exact division in Derived." << std::endl;
  1322                     for (
int i = 0; i < terms.size(); ++i)
  1324                     return dynamic_cast<Derived&
>(*this);
  1330             UnivariateTerm<Ring> at = leadingTerm();
  1331             UnivariateTerm<Ring> lc, nlc;
  1332             lc.coef = at.coef / bt.coef;
  1333             lc.exp = at.exp - bt.exp;
  1334             nlc.coef = -lc.coef;
  1337             q.terms.insert(q.terms.begin(), lc);
  1340             std::cout << 
"BPAS: error, not exact division in Derived." << std::endl;
  1364             std::cout << 
"BPAS: error, dividend is zero from Derived." << std::endl;
  1367         else if (!e.isOne()) {
  1369             while (i < terms.size()) {
  1371                 if (terms[i].coef.isZero())
  1372                     terms.erase(terms.begin()+i);
  1376         return dynamic_cast<Derived&
>(*this);
  1379     inline friend Derived 
operator/ (
const Ring& e, 
const Derived& p) {
  1381             std::cout << 
"BPAS: error, dividend is zero from Derived." << std::endl;
  1387         if (p.isConstant()) {
  1389             return (q /= p.terms[0].coef);
  1400         for (
int i = 0; i < terms.size(); ++i)
  1401             terms[i].coef = -terms[i].coef;
  1413             std::cout << 
"BPAS: error, dividend is zero from Derived." << std::endl;
  1416         else if (!b.leadingCoefficient().isOne()) {
  1417             std::cout << 
"BPAS: error, leading coefficient is not one in monicDivide() from Derived." << std::endl;
  1421         if (b.isConstant()) {
  1431         if (name != b.name) {
  1432             std::cout << 
"BPAS: error, trying to monic divide between Ring[" << name << 
"] and Ring[" << b.name << 
"]." << std::endl;
  1438         UnivariateTerm<Ring> bt = b.leadingTerm();
  1439         while (
degree() >= b.degree()) {
  1440             UnivariateTerm<Ring> at = leadingTerm();
  1441             UnivariateTerm<Ring> nlc;
  1442             nlc.coef = -at.coef;
  1443             nlc.exp = at.exp - bt.exp;
  1446             quo.terms.insert(quo.terms.begin(), at);
  1460         std::cout << 
"*this " <<  *
this << std::endl;
  1461         *rem = *
this; std::cout<< 
"salam"<<std::endl;
  1462         return rem->monicDivide(b);
  1478         if (b.isZero() || db == 0) {
  1479             std::cout << 
"BPAS: error, dividend is zero or constant from Derived." << std::endl;
  1488         if (name != b.name) {
  1489             std::cout << 
"BPAS: error, trying to pseudo divide between Ring[" << name << 
"] and Ring[" << b.name << 
"]." << std::endl;
  1501         Ring blc = b.leadingTerm().coef;
  1506             UnivariateTerm<Ring> at = leadingTerm();
  1507             UnivariateTerm<Ring> nlc;
  1508             nlc.coef = -at.coef;
  1509             nlc.exp = at.exp - db.get_si();
  1513             pomopo(blc, nlc, b);
  1515             quo.terms.insert(quo.terms.begin(), at);
  1517         for (
int i = e; diff >= i; ++i)
  1534         return rem->lazyPseudoDivide(b, c, d);
  1565     inline Derived 
pseudoDivide (
const Derived& b, Derived* rem, Ring* d)
 const {
  1580         if (k <= 0) { 
return; }
  1582         while (i < terms.size()) {
  1583             if (terms[i].exp >= k) {
  1584                 for (
int j = 0; j < k; ++j)
  1585                     terms[i].coef *= Ring(terms[i].exp - j);
  1590                 terms.erase(terms.begin());
  1627         int i = terms.size()-1;
  1629             terms[i].coef /= (terms[i].exp + 1);
  1653         int n = terms.size();
  1654         if (n && terms[0].exp == 0 && terms[0].coef == Ring(0))
  1665         int d = terms.size() - 1;
  1666         if (d < 0) { 
return Ring(); }
  1667         int e = terms[d].exp - 1;
  1668         Ring px = terms[d].coef;
  1670         for (
int i = e; i > -1; --i) {
  1672             if (i == terms[d].exp && d > -1) {
  1673                 px += terms[d].coef;
  1685     template <
class LargerRing>
  1686     inline LargerRing 
evaluate(
const LargerRing& x)
 const {
  1688         int d = terms.size() - 1;
  1689         if (d < 0) { 
return LargerRing(); }
  1690         int e = terms[d].exp - 1;
  1691         LargerRing px = (LargerRing)terms[d].coef;
  1694         for (
int i = e; i > -1; --i) {
  1696             if (i == terms[d].exp && d > -1) {
  1697                 a = (LargerRing)terms[d].coef;
  1705     inline void fillChain (std::vector<Derived>& chain)
 const {
  1708         int fullSize(chain[chain.size()-2].degree().get_ui()+2);
  1712         if (chain.size() < fullSize) {
  1713             chain.reserve(fullSize);
  1714             for (
int i=chain.size()-2; i>0; --i) {
  1715                 if (chain[i].
degree() != chain[i-1].degree()+1) {
  1716                     delta = chain[i].degree().get_ui() - chain[i-1].degree().get_ui();
  1719                         for (
int j=0; j<delta-2; ++j)
  1720                             chain.insert(chain.begin()+i,
zero);
  1723                         for (
int j=0; j<delta-1; ++j)
  1724                             chain.insert(chain.begin()+i,
zero);
  1728             if (chain[0].
degree() != 0) {
  1729                     for (
int j=0; j<chain[0].degree(); ++j)
  1730                         chain.insert(chain.begin(),
zero);
  1743         if (name != q.name) {
  1744             std::cout << 
"BPAS: error, trying to compute subresultant chains between Ring[" << name << 
"] and Ring[" << q.name << 
"]." << std::endl;
  1748         if (
degree() == 0 || q.degree() == 0){
  1749             std::cout << 
"BPAS: error, Input polynomials to subresultantChain must have positive degree." << std::endl;
  1753         std::vector< Derived > S;
  1755         if (q.degree() > 
degree()) {
  1764         int k = (a.degree() - b.degree()).get_si();
  1767         Derived A = b, B = a, C = -b;
  1769             b *= b.leadingCoefficient()^(k-1); 
  1778             S.insert(S.begin(), B);
  1779             delta = A.degree() - B.degree();
  1781                 C = LazardSe(S[1], S[0], s);
  1782                 S.insert(S.begin(), C);
  1785             if (B.degree() == 0)
  1787             B = DucosSem(A, B, C, s);
  1789             s = A.leadingCoefficient();
  1792         if (S.at(0).degree() > 0) {
  1793             S.insert(S.begin(), B);
  1796             std::cerr << 
"filling chain..." << std::endl;
  1811         for (
int i=s.size()-2; i>0; --i) {
  1812             delta = s.at(i).degree() - s.at(i-1).degree();
  1814                 if (i == 1 && s.at(i-1).isZero())
  1818                 for (
int j=0; j<n; j++)
  1819                     s.insert(s.begin()+i-1,sup);
  1906     inline Derived 
gcd (
const Derived& q)
 const {
  1907         if (
isZero()) { 
return q; }
  1908         if (q.isZero()) { 
return *
this; }
  1909         if (name != q.name) {
  1910             std::cout << 
"BPAS: error, trying to compute GCD between Ring[" << name << 
"] and Ring[" << q.name << 
"]." << std::endl;
  1914         Derived a(*
this), b(q);
  1915         if (a.degree() == 0 || b.degree() == 0) {
  1938             std::vector< Derived > R = a.subresultantChain(b);
  1940             r.setCoefficient(0, ca.gcd(cb));
  1946                 for (
int i = 0; i < n; ++i) {
  1948                         cr = R[i].content();
  1957                 if (a.degree() <= b.degree()) { r *= a; }
  1970         std::vector< Derived > sf;
  1971         int d = terms.size()-1;
  1973             sf.push_back(*
this);
  1974         else if (terms[d].exp == 1) {
  1979             t = *
this / terms[d].coef;
  1983             Derived a (*
this), b(*
this);
  1985             Derived g = a.gcd(b);
  1993             while (!z.isZero()) {
  2007             for (
int i = 0; i < sf.size(); ++i) {
  2008                 e *= sf[i].leadingCoefficient();
  2009                 sf[i] /= sf[i].leadingCoefficient();
  2014             sf.insert(sf.begin(), t);
  2018         f.setRingElement(sf[0]);
  2019         for (
int i = 1; i < sf.size(); ++i) {
  2020             f.addFactor(sf[i], i);
  2032     inline void print (std::ostream &out)
 const {
  2033         int n = terms.size();
  2034         if (!n) { out << 
"0"; }
  2035         for (
int i = 0; i < n; ++i) {
  2036             if (this->terms[i].exp) {
  2037                 if (this->terms[i].coef.isNegativeOne())
  2039                 else if (i && this->terms[i].coef.isConstant() >= 0)
  2041                 if (!this->terms[i].coef.isConstant())
  2042                     out << 
"(" << this->terms[i].coef << 
")*";
  2043                 else if (!this->terms[i].coef.isOne() && !this->terms[i].coef.isNegativeOne())
  2044                     out << this->terms[i].coef << 
"*";
  2046                 if (this->terms[i].exp > 1)
  2047                     out << 
"^" << this->terms[i].exp;
  2050                 if (this->terms[i].coef.isConstant()) { out << this->terms[i].coef; }
  2051                 else { out << 
"(" << this->terms[i].coef << 
")"; }
  2058         std::cerr << 
"BPAS ERROR: SMP<Ring>::convertToExpressionTree NOT YET IMPLEMENTED" << std::endl;
  2064         int k = 0, n = terms.size(), d = 0;
  2065         if (n) { d = terms[n-1].exp; }
  2068         for (
int i = 0; i <= d; ++i) {
  2070                 if (!terms[k].coef.isConstant()) {
  2074                 else if (terms[k].exp == i) {
  2080         if (!isDense) { res.
zero(); }
  2086         int k = 0, n = terms.size(), d = 0;
  2087         if (n) { d = terms[n-1].exp; }
  2090         for (
int i = 0; i <= d; ++i) {
  2092                 if (!terms[k].coef.isConstant()) {
  2096                 else if (terms[k].exp == i) {
  2102         if (!isDense) { res.
zero(); }
  2122 template <
class Field, 
class Derived>
  2125     Integer euclideanSize()
 const {
  2129     Derived euclideanDivision(
  2131         Derived* q = NULL)
 const  2133         Field lc = b.leadingCoefficient();
  2134         Derived monicb = b * lc.inverse();
  2141             Derived rem = *
this;
  2142             return rem.monicDivide(b);
  2147     Derived extendedEuclidean(
  2158     Derived quotient(
const Derived& b)
 const {
  2160         this->euclideanDivision(b, &q);
  2164     Derived remainder(
const Derived& b)
 const {
  2165         return this->euclideanDivision(b);
  2168     Derived operator%(
const Derived& b)
 const {
  2169         Derived ret = *
this;
  2174     Derived& operator%=(
const Derived& b) {
  2175         *
this = this->remainder(b);
  2176         return dynamic_cast<Derived&
>(*this);
  2192 template <
class Ring>
  2193 class SparseUnivariatePolynomial : 
public std::conditional<std::is_base_of<BPASField<Ring>, Ring>::value, SparseUnivariateTempFieldPoly<Ring, SparseUnivariatePolynomial<Ring>>, SparseUnivariateTempPoly<Ring, SparseUnivariatePolynomial<Ring>> >::type {
  2201         Base::operator=(other);
  2206         Base::operator=(other);
  2260     rand_mpq_t(coefBound,1,randVal);
  2261     mpq_class coef(randVal);
  2263     P.setCoefficient(n, coef);
  2264     int nTerms = ceil(sparsity*n);
  2266     for(
int i = 0; i < nTerms; i++) {
  2269         rand_mpq_t(coefBound,1,randVal);
  2270         coef = mpq_class(randVal);
  2271         P.setCoefficient(index, coef);
 Derived & operator<<=(int k)
Overload operator <<= replace by muplitying x^k. 
Definition: upolynomial.h:812
Derived & operator*=(const Derived &b)
Overload operator *=. 
Definition: upolynomial.h:1191
Factors< Derived > squareFree() const
Square free. 
Definition: upolynomial.h:1969
Derived operator/(const Derived &b) const
Overload operator / EdeDivision. 
Definition: upolynomial.h:1251
A sparsely represented univariate polynomial over an arbitrary ring. 
Definition: BigPrimeField.hpp:21
Derived operator^(long long int e) const
Overload operator ^ replace xor operation by exponentiation. 
Definition: upolynomial.h:753
Derived pseudoDivide(const Derived &b, Derived *rem, Ring *d) const
Pseudo dividsion Return the quotient. 
Definition: upolynomial.h:1565
Ring content() const override
Content of the polynomial. 
Definition: upolynomial.h:726
Derived lazyPseudoDivide(const Derived &b, Derived *rem, Ring *c, Ring *d) const
Lazy pseudo dividsion Return the quotient e is the exact number of division steps. 
Definition: upolynomial.h:1532
std::vector< Derived > monomialBasisSubresultantChain(const Derived &q)
monomialBasisSubResultantChain 
Definition: upolynomial.h:1807
void zero()
Zero polynomial. 
Definition: urpolynomial.h:313
void negativeOne()
Set polynomial to -1. 
Definition: upolynomial.h:687
Derived operator*(const Derived &b) const
Multiply another polynomial. 
Definition: upolynomial.h:1076
std::vector< Derived > subresultantChain(const Derived &q, int filled=0) const
Subresultant Chain Return the list of subresultants. 
Definition: upolynomial.h:1742
void setVariableName(const Symbol &x)
Set variable's name. 
Definition: urpolynomial.h:240
Derived lazyPseudoDivide(const Derived &b, Ring *c, Ring *d=NULL)
Lazy pseudo dividsion Return the quotient and itself becomes remainder e is the exact number of divis...
Definition: upolynomial.h:1474
An arbitrary-precision complex rational number. 
Definition: ComplexRationalNumber.hpp:23
Derived operator-() const
Overload operator -, negate. 
Definition: upolynomial.h:956
Symbol variable() const
Get the variable name. 
Definition: upolynomial.h:545
RationalNumber coefficient(int k) const
Get a coefficient of the polynomial. 
Definition: urpolynomial.h:199
void integrate()
Compute integral with constant of integration set to 0. 
Definition: upolynomial.h:1626
An ExpressionTree encompasses various forms of data that can be expressed generically as a binary tre...
Definition: ExpressionTree.hpp:17
Integer numberOfTerms() const
Get the number of terms. 
Definition: upolynomial.h:456
Derived & operator>>=(int k)
Overload operator >>= replace by dividing x^k, and return the quotient. 
Definition: upolynomial.h:837
bool isNegativeOne() const
Is polynomial a constant -1. 
Definition: upolynomial.h:676
Derived monicDivide(const Derived &b)
Monic division Assuming the leading coefficient of dividend is 1 Return quotient and itself becomes r...
Definition: upolynomial.h:1411
A univariate polynomial with Integer coefficients using a dense representation. 
Definition: uzpolynomial.h:14
Integer degree() const
Get degree of the polynomial. 
Definition: urpolynomial.h:149
Symbol variable() const
Get variable's name. 
Definition: uzpolynomial.h:196
bool isZero() const
Is zero polynomial. 
Definition: upolynomial.h:634
int isConstant() const
Is a constant. 
Definition: upolynomial.h:700
Ring evaluate(const Ring &x) const
Evaluate f(x) 
Definition: upolynomial.h:1664
LargerRing evaluate(const LargerRing &x) const
Evaluate f(x) 
Definition: upolynomial.h:1686
A univariate polynomial over an arbitrary BPASRing represented sparsely. 
Definition: upolynomial.h:20
Derived monicDivide(const Derived &b, Derived *rem) const
Monic division Assuming the leading coefficient of dividend is 1 Return quotient. ...
Definition: upolynomial.h:1459
void setCoefficient(int k, const mpz_class value)
Set a coefficient of the polynomial. 
Definition: uzpolynomial.h:165
void setCoefficient(int e, const Ring &c)
Set a coeffcient with its exponent. 
Definition: upolynomial.h:513
Ring coefficient(int k) const
Get a coefficient. 
Definition: upolynomial.h:496
Integer leadingCoefficient() const
Get the leading coefficient. 
Definition: uzpolynomial.h:114
bool isOne() const
Is polynomial a constant 1. 
Definition: upolynomial.h:652
Derived operator>>(int k) const
Overload operator >> replace by dividing x^k, and return the quotient. 
Definition: upolynomial.h:825
A univariate polynomial with RationalNumber coefficients represented densely. 
Definition: urpolynomial.h:16
void negate()
Negate the polynomial. 
Definition: upolynomial.h:1399
Derived & operator/=(const Derived &b)
Overload operator /= ExactDivision. 
Definition: upolynomial.h:1263
bool operator==(const Derived &b) const
Overload operator ==. 
Definition: upolynomial.h:617
Integer coefficient(int k) const
Get a coefficient of the polynomial. 
Definition: uzpolynomial.h:152
A simple data structure for encapsulating a collection of Factor elements. 
Definition: Factors.hpp:95
void zero()
Zero polynomial. 
Definition: uzpolynomial.h:263
Derived gcd(const Derived &q) const
GCD(p, q) 
Definition: upolynomial.h:1906
bool operator!=(const Derived &b) const
Overload operator !=. 
Definition: upolynomial.h:608
Derived operator<<(int k) const
Overload operator << replace by muplitying x^k. 
Definition: upolynomial.h:801
An arbitrary-precision Integer. 
Definition: Integer.hpp:22
An abstract class defining the interface of a univariate polynomial over an arbitrary BPASRing...
Definition: BPASUnivarPolynomial.hpp:22
void setVariableName(const Symbol &c)
Set the variable name. 
Definition: upolynomial.h:554
Derived derivative(int k) const
Return k-th derivative. 
Definition: upolynomial.h:1607
Derived operator+(const Derived &b) const
Overload operator +. 
Definition: upolynomial.h:855
void one()
Set polynomial to 1. 
Definition: upolynomial.h:663
Derived & operator+=(const Derived &b)
Overload operator+=. 
Definition: upolynomial.h:865
Derived integral() const
Compute integral with constant of integration 0. 
Definition: upolynomial.h:1639
Derived & operator=(const Derived &b)
Overload operator =. 
Definition: upolynomial.h:578
Ring leadingCoefficient() const
Get the leading coefficient. 
Definition: upolynomial.h:476
Derived & operator^=(long long int e)
Overload operator ^= replace xor operation by exponentiation. 
Definition: upolynomial.h:790
void differentiate()
Convert current object to its derivative. 
Definition: upolynomial.h:1598
void print(std::ostream &out) const
Overload stream operator <<. 
Definition: upolynomial.h:2032
void setCoefficient(int k, const RationalNumber &value)
Set a coefficient of the polynomial. 
Definition: urpolynomial.h:211
void differentiate(int k)
Compute k-th derivative. 
Definition: upolynomial.h:1579
An encapsulation of a mathematical symbol. 
Definition: Symbol.hpp:23
An arbitrary-precision rational number. 
Definition: RationalNumber.hpp:24
Derived & operator-=(const Derived &b)
Overload operator -=. 
Definition: upolynomial.h:983
Ring convertToConstant()
Convert to a constant. 
Definition: upolynomial.h:711
bool isConstantTermZero() const
Is trailing coefficient zero. 
Definition: upolynomial.h:1650
void zero()
Zero polynomial. 
Definition: upolynomial.h:643
Symbol variable() const
Get variable's name. 
Definition: urpolynomial.h:231
bool isOne() const
Is a 1. 
Definition: Integer.hpp:179
Derived pseudoDivide(const Derived &b, Ring *d=NULL)
Pseudo dividsion Return the quotient and itself becomes remainder. 
Definition: upolynomial.h:1545
A univariate polynomial over an arbitrary BPASField represented sparsely. 
Definition: upolynomial.h:2123
Integer degree() const
Get the degree of the polynomial. 
Definition: upolynomial.h:465
Integer degree() const
Get degree of the polynomial. 
Definition: uzpolynomial.h:105
void setVariableName(const Symbol &x)
Set variable's name. 
Definition: uzpolynomial.h:204
Derived resultant(const Derived &q)
Resultant. 
Definition: upolynomial.h:1896
Derived derivative() const
Compute derivative. 
Definition: upolynomial.h:1617