1 // Copyright (c) 2007,2009 John Abbott and Anna Bigatti 2 // Author: 2007,2009 Anna Bigatti 3 4 // This file is part of the source of CoCoALib, the CoCoA Library. 5 6 // CoCoALib is free software: you can redistribute it and/or modify 7 // it under the terms of the GNU General Public License as published by 8 // the Free Software Foundation, either version 3 of the License, or 9 // (at your option) any later version. 10 11 // CoCoALib is distributed in the hope that it will be useful, 12 // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 // GNU General Public License for more details. 15 16 // You should have received a copy of the GNU General Public License 17 // along with CoCoALib. If not, see <http://www.gnu.org/licenses/>. 18 19 20 // Source code for abstract class SparsePolyRing and friends 21 22 #include "CoCoA/DenseUPolyRing.H" 23 24 #include "CoCoA/BigIntOps.H" 25 #include "CoCoA/BigRat.H" 26 #include "CoCoA/CpuTimeLimit.H" 27 #include "CoCoA/OpenMath.H" 28 #include "CoCoA/QuotientRing.H" // for IsQuotientRing 29 #include "CoCoA/RingDenseUPolyClean.H" // for NewPolyRing_DUP 30 #include "CoCoA/RingFp.H" // for IsRingFp 31 #include "CoCoA/RingQQ.H" // for IsQQ 32 #include "CoCoA/RingTwinFloat.H" // for IsRingTwinFloat 33 #include "CoCoA/RingZZ.H" // for IsZZ 34 #include "CoCoA/assert.H" 35 #include "CoCoA/degree.H" 36 #include "CoCoA/error.H" 37 #include "CoCoA/symbol.H" 38 #include "CoCoA/utils.H" 39 40 //#include <vector> 41 using std::vector; 42 #include <algorithm> 43 using std::max; 44 using std::sort; 45 46 47 namespace CoCoA 48 { 49 NewPolyRing(const ring & CoeffRing)50 DenseUPolyRing NewPolyRing(const ring& CoeffRing) 51 { 52 return NewPolyRing_DUP(CoeffRing); 53 } 54 NewPolyRing(const ring & CoeffRing,const symbol & IndetSym)55 DenseUPolyRing NewPolyRing(const ring& CoeffRing, const symbol& IndetSym) 56 { 57 return NewPolyRing_DUP(CoeffRing, IndetSym); 58 } 59 IsGoodIndetName(const ring & CoeffRing,const symbol & IndetName)60 bool IsGoodIndetName(const ring& CoeffRing, const symbol& IndetName) 61 { 62 vector<symbol> syms = symbols(CoeffRing); 63 const long NumSyms = len(syms); 64 for (long i=0; i < NumSyms; ++i) 65 { 66 if (syms[i] == IndetName) return false; 67 if (head(syms[i]) == head(IndetName) && 68 NumSubscripts(syms[i]) != NumSubscripts(IndetName)) 69 return false; 70 } 71 return true; 72 } 73 74 mySymbolValue(const symbol & s)75 RingElem DenseUPolyRingBase::mySymbolValue(const symbol& s) const 76 { 77 if (s == myIndetSymbol()) return myIndets()[0]; 78 return myCoeffEmbeddingHomCtor()(myCoeffRing()->mySymbolValue(s)); 79 } 80 81 82 //---- Functions for creating/building polynomials 83 monomial(const DenseUPolyRing & P,ConstRefRingElem c,const MachineInt & exp)84 RingElem monomial(const DenseUPolyRing& P, ConstRefRingElem c, const MachineInt& exp) 85 { 86 if (owner(c) != CoeffRing(P)) CoCoA_THROW_ERROR(ERR::MixedCoeffRings, "monomial(P,c,d)"); 87 if (IsNegative(exp)) 88 CoCoA_THROW_ERROR(ERR::NegExp, "monomial(P,c,d)"); 89 if (!IsSignedLong(exp)) 90 CoCoA_THROW_ERROR(ERR::ExpTooBig, "monomial(P,c,d)"); 91 if (IsZero(c)) return zero(P); 92 return P->myMonomial(raw(c), AsSignedLong(exp)); 93 } 94 95 monomial(const DenseUPolyRing & P,const BigInt & N,const MachineInt & exp)96 RingElem monomial(const DenseUPolyRing& P, const BigInt& N, const MachineInt& exp) 97 { 98 // All arg checking made by the call below... 99 return monomial(P, RingElem(CoeffRing(P), N), exp); 100 } 101 102 monomial(const DenseUPolyRing & P,const BigRat & N,const MachineInt & exp)103 RingElem monomial(const DenseUPolyRing& P, const BigRat& N, const MachineInt& exp) 104 { 105 // All arg checking made by the call below... 106 return monomial(P, RingElem(CoeffRing(P), N), exp); 107 } 108 109 monomial(const DenseUPolyRing & P,const MachineInt & n,const MachineInt & exp)110 RingElem monomial(const DenseUPolyRing& P, const MachineInt& n, const MachineInt& exp) 111 { 112 // All arg checking made by the call below... 113 return monomial(P, RingElem(CoeffRing(P), n), exp); 114 } 115 116 117 /*---------------------------------------------------------------------- 118 Member functions every concrete DenseUPolyRing implementation 119 must have in addition to those of PolyRingBase. 120 ----------------------------------------------------------------------*/ 121 myIsValid(ConstRawPtr rawf)122 bool DenseUPolyRingBase::myIsValid(ConstRawPtr rawf) const 123 { 124 if (myDegPlus1(rawf)>mySize(rawf)) return false; 125 for (long i=myDegPlus1(rawf); i<mySize(rawf); ++i) 126 if (!IsZero(myCoeff(rawf, i))) return false; 127 if (myIsZero(rawf)) return true; 128 if (IsZero(myLC(rawf))) return false; 129 return true; 130 } 131 132 myStdDeg(ConstRawPtr rawf)133 long DenseUPolyRingBase::myStdDeg(ConstRawPtr rawf) const 134 { 135 if (myIsZero(rawf)) CoCoA_THROW_ERROR(ERR::ZeroRingElem, "myStdDeg(rawf)"); 136 return myDegPlus1(rawf) - 1; 137 } 138 139 myDeg(ConstRawPtr rawf,long index)140 long DenseUPolyRingBase::myDeg(ConstRawPtr rawf, long index) const 141 { 142 if (index!=0) CoCoA_THROW_ERROR(ERR::BadIndetIndex, "myDeg(rawf, index)"); 143 return myStdDeg(rawf); 144 } 145 146 myLC(ConstRawPtr rawf)147 RingElemAlias DenseUPolyRingBase::myLC(ConstRawPtr rawf) const 148 { 149 if (myIsZero(rawf)) CoCoA_THROW_ERROR(ERR::ZeroRingElem, "DenseUPolyRingBase::myLC(rawf)"); 150 return myCoeff(rawf, myStdDeg(rawf)); 151 } 152 153 myContent(RawPtr rawcontent,ConstRawPtr rawf)154 void DenseUPolyRingBase::myContent(RawPtr rawcontent, ConstRawPtr rawf) const 155 { 156 const ring& R = myCoeffRing(); 157 CoCoA_ASSERT(IsTrueGCDDomain(R)); 158 // Compute answer in local var to avoid aliasing problems; also exception clean. 159 RingElem ans(R); 160 for (long i=0; i<myDegPlus1(rawf); ++i) 161 { 162 if (IsZero(myCoeff(rawf,i))) continue; 163 R->myGcd(raw(ans), raw(ans), raw(myCoeff(rawf, i))); // ans = GCD(ans, coeff(i)); 164 if (IsOne(ans)) break; 165 } 166 // Finally, swap answer into rawcontent. 167 R->mySwap(rawcontent, raw(ans)); 168 } 169 myContentFrF(RawPtr rawcontent,ConstRawPtr rawf)170 void DenseUPolyRingBase::myContentFrF(RawPtr rawcontent, ConstRawPtr rawf) const 171 { 172 CoCoA_ASSERT(IsFractionFieldOfGCDDomain(myCoeffRing())); 173 const FractionField R = myCoeffRing(); 174 const ring& S = BaseRing(R); 175 RingElem N(S); 176 RingElem D(S,1); 177 for (long i=0; i < myDegPlus1(rawf); ++i) 178 { 179 if (IsZero(myCoeff(rawf,i))) continue; 180 // R->myGcd(raw(ans), raw(ans), raw(num(myCoeff(rawf, i)))); // ans = GCD(ans, num(coeff(i))); 181 N = gcd(N, num(myCoeff(rawf, i))); 182 D = lcm(D, den(myCoeff(rawf, i))); 183 // if (IsOne(ans)) break; 184 } 185 RingHom phi = EmbeddingHom(R); 186 RingElem ans = phi(N)/phi(D); 187 // Finally, swap answer into rawcontent. 188 R->mySwap(rawcontent, raw(ans)); 189 } 190 191 myCommonDenom(RawPtr rawcontent,ConstRawPtr rawf)192 void DenseUPolyRingBase::myCommonDenom(RawPtr rawcontent, ConstRawPtr rawf) const 193 { 194 CoCoA_ASSERT(IsFractionFieldOfGCDDomain(myCoeffRing())); 195 const ring& R = BaseRing(myCoeffRing()); 196 // Compute answer in local var to avoid aliasing problems; also exception clean. 197 RingElem ans = one(R); 198 for (long i=0; i<myDegPlus1(rawf); ++i) 199 { 200 ConstRefRingElem C = myCoeff(rawf, i); 201 if (!IsZero(C)) 202 { 203 const RingElem D = den(C); 204 ans *= D/gcd(D, ans); 205 } 206 } 207 // Finally, swap answer into rawcontent. 208 R->mySwap(rawcontent, raw(ans)); 209 } 210 211 myClearDenom(RawPtr rawg,ConstRawPtr rawf)212 void DenseUPolyRingBase::myClearDenom(RawPtr rawg, ConstRawPtr rawf) const 213 { 214 CoCoA_ASSERT(IsFractionFieldOfGCDDomain(myCoeffRing())); 215 const ring& R = BaseRing(myCoeffRing()); 216 // Compute answer in local var to avoid aliasing problems; also exception clean. 217 RingElem c(R); 218 myCommonDenom(raw(c), rawf); 219 const RingElem coeff = CoeffEmbeddingHom(DenseUPolyRing(this))(EmbeddingHom(myCoeffRing()))(c); 220 myMul(rawg, raw(coeff), rawf); 221 } 222 223 myRemoveBigContent(RawPtr rawf)224 void DenseUPolyRingBase::myRemoveBigContent(RawPtr rawf) const 225 { 226 CoCoA_ASSERT(IsTrueGCDDomain(myCoeffRing())); 227 CoCoA_ASSERT(!myIsZero(rawf)); 228 RingElem cont(myCoeffRing()); 229 myContent(raw(cont), rawf); 230 myDivByCoeff(rawf, raw(cont)); 231 } 232 233 234 /*---------------------------------------------------------------------- 235 Member functions inherited from ring with a single implementation 236 for all DenseUPolyRing implementations 237 ----------------------------------------------------------------------*/ 238 239 namespace 240 { 241 // only if CoeffRing is a field mod(RingElem & a,ConstRefRingElem b)242 void mod(RingElem& a, ConstRefRingElem b) // a = a%b 243 { 244 CoCoA_ASSERT(owner(a) == owner(b)); 245 CoCoA_ASSERT(!IsZero(b)); // this should be an error 246 while (!IsZero(a) && deg(a) >= deg(b)) 247 DenseUPolyRingPtr(owner(a))->myAddMulLM(raw(a), raw(-LC(a)/LC(b)), deg(a)-deg(b), raw(b)); 248 } 249 DivMod(RingElem & q,RingElem & a,ConstRefRingElem b)250 void DivMod(RingElem& q, RingElem& a, ConstRefRingElem b) // q = a/b; a = a%b 251 { 252 // pointers must be different 253 CoCoA_ASSERT(owner(a) == owner(b)); 254 CoCoA_ASSERT(owner(q) == owner(a)); 255 CoCoA_ASSERT(!IsZero(b)); // this should be an error 256 const DenseUPolyRing P = owner(a); 257 q = zero(owner(q)); 258 if (IsZero(a) || (deg(a)<deg(b)) ) return; 259 P->myResize(raw(q), deg(a)-deg(b)+1); 260 while (!IsZero(a) && deg(a) >= deg(b)) 261 { 262 // q += monomial(P, -LC(a)/LC(b), deg(a)-deg(b)); 263 P->myAssignNonZeroCoeff(raw(q), raw(LC(a)/LC(b)), deg(a)-deg(b)); 264 P->myAddMulLM(raw(a), raw(-LC(a)/LC(b)), deg(a)-deg(b), raw(b)); 265 } 266 } 267 ExgcdAux(RingElem & acofac,RingElem & bcofac,RingElem & a,RingElem & b)268 void ExgcdAux(RingElem& acofac, RingElem& bcofac, RingElem& a, RingElem& b) // gcd is acofac*orig_a + bcofac*orig_b; terminates with a=gcd and b=0 269 { 270 // all pointers must be different 271 CoCoA_ASSERT(owner(a) == owner(b)); 272 CoCoA_ASSERT(!IsZero(b)); // this should be an error 273 acofac = 1; 274 bcofac = 0; // i.e. a = acofac*a + bcofac*b 275 RingElem q(owner(b)); 276 RingElem b_acofac(owner(b)); 277 RingElem b_bcofac(one(owner(b))); // i.e. b = b_acofac*a + b_bcofac*b 278 while (!IsZero(b)) 279 { 280 // q = div(a, b); a = a - b*d; 281 DivMod(q, a, b); 282 acofac -= b_acofac*q; 283 bcofac -= b_bcofac*q; 284 swap(a, b); 285 swap(acofac, b_acofac); 286 swap(bcofac, b_bcofac); 287 } 288 } 289 290 291 } // anonymous namespace 292 293 myMul(RawPtr rawlhs,ConstRawPtr rawf,ConstRawPtr rawg)294 void DenseUPolyRingBase::myMul(RawPtr rawlhs, ConstRawPtr rawf, ConstRawPtr rawg) const 295 { 296 ring P(this); 297 RingElemAlias g(P, rawg); 298 299 RingElem ans(P); 300 for (long i=0; i<myDegPlus1(rawf); ++i) 301 myAddMulLM(raw(ans), raw(myCoeff(rawf,i)), i, rawg); 302 mySwap(raw(ans), rawlhs); // really an assignment 303 } 304 305 myIsDivisible(RawPtr rawlhs,ConstRawPtr rawx,ConstRawPtr rawy)306 bool DenseUPolyRingBase::myIsDivisible(RawPtr rawlhs, ConstRawPtr rawx, ConstRawPtr rawy) const 307 { 308 ring P(this); 309 RingElem r = RingElemAlias(P, rawx); 310 RingElem ans(P); 311 DivMod(ans, r, RingElemAlias(P, rawy)); 312 mySwap(raw(ans), rawlhs); // really an assignment 313 return IsZero(r); 314 } 315 316 317 // code for R[x]: compute gcd in FractionField(R)[x] 318 // see also myExgcd myGcd(RawPtr rawlhs,ConstRawPtr rawx,ConstRawPtr rawy)319 void DenseUPolyRingBase::myGcd(RawPtr rawlhs, ConstRawPtr rawx, ConstRawPtr rawy) const 320 { 321 RingElem a = RingElemAlias(ring(this), rawx); 322 if (IsInvertible(a)) a=1; 323 if (myIsZero(rawy)) 324 { 325 mySwap(rawlhs, raw(a)); 326 return; 327 } 328 RingElem b = RingElemAlias(ring(this), rawy); 329 if (IsInvertible(b)) b=1; 330 if (myIsZero(rawx)) 331 { 332 mySwap(rawlhs, raw(b)); 333 return; 334 } 335 if (!IsField(myCoeffRing())) 336 { 337 if (!IsTrueGCDDomain(myCoeffRing())) 338 CoCoA_THROW_ERROR(ERR::NYI, "DenseUPolyRingBase::myGcd"); 339 else 340 { 341 const FractionField K = NewFractionField(myCoeffRing()); 342 const DenseUPolyRing Kx = NewPolyRing(K); 343 const DenseUPolyRing P(this); 344 const RingHom phi = PolyRingHom(P, Kx, CoeffEmbeddingHom(Kx)(EmbeddingHom(K)), indets(Kx)); 345 RingElem z = gcd(phi(a), phi(b)); 346 Kx->myClearDenom(raw(z), raw(z)); 347 RingElem g(P); 348 for (long d=myStdDeg(raw(z)) ; d >= 0 ; --d) 349 g += monomial(P, num(myCoeff(raw(z), d)), d); 350 myDivByCoeff(raw(g), raw(content(g))); 351 myMulByCoeff(raw(g), raw(gcd(content(a), content(b)))); 352 P->mySwap(rawlhs, raw(g)); 353 return; 354 } 355 } 356 // finally Euclid's Algorithm 357 mod(a, b); // a = remainder(a, b) 358 while (!IsZero(a)) 359 { 360 mySwap(raw(a), raw(b)); 361 mod(a, b); // a = remainder(a, b) 362 } 363 if (IsInvertible(b)) b=1; 364 mySwap(rawlhs, raw(b)); 365 } 366 367 368 // See also myGcd myExgcd(RawPtr rawlhs,RawPtr rawxcofac,RawPtr rawycofac,ConstRawPtr rawx,ConstRawPtr rawy)369 void DenseUPolyRingBase::myExgcd(RawPtr rawlhs, RawPtr rawxcofac, RawPtr rawycofac, ConstRawPtr rawx, ConstRawPtr rawy) const 370 { 371 ring P(ring(this)); 372 RingElem ZeroP(P); 373 RingElem OneP(one(P)); 374 RingElem a(RingElemAlias(P, rawx)); 375 if (myIsZero(rawy)) // = raw(b) 376 { 377 mySwap(rawlhs, raw(a)); 378 mySwap(rawxcofac, raw(OneP)); 379 mySwap(rawycofac, raw(ZeroP)); 380 return; 381 } 382 RingElem b(RingElemAlias(P, rawy)); 383 if (myIsZero(rawx)) // = raw(a) 384 { 385 mySwap(rawlhs, raw(b)); 386 mySwap(rawxcofac, raw(ZeroP)); 387 mySwap(rawycofac, raw(OneP)); 388 return; 389 } 390 if (!IsField(myCoeffRing())) 391 CoCoA_THROW_ERROR(ERR::NYI, "DenseUPolyRingBase::myGcd(RawPtr, ConstRawPtr, ConstRawPtr) const"); 392 // finally Euclid's Algorithm 393 RingElem res(P), acofac(P), bcofac(P); 394 ExgcdAux(acofac, bcofac, a, b); 395 mySwap(rawlhs, raw(a)); 396 mySwap(rawxcofac, raw(acofac)); 397 mySwap(rawycofac, raw(bcofac)); 398 } 399 400 mySymbols(std::vector<symbol> & SymList)401 void DenseUPolyRingBase::mySymbols(std::vector<symbol>& SymList) const 402 { 403 myCoeffRing()->mySymbols(SymList); 404 SymList.push_back(myIndetSymbol()); 405 } 406 407 myOutput(std::ostream & out,ConstRawPtr rawf)408 void DenseUPolyRingBase::myOutput(std::ostream& out, ConstRawPtr rawf) const 409 { 410 if (!out) return; // short-cut for bad ostreams 411 412 if (myIsZero(rawf)) { out << "0"; return; } 413 414 const ring& R = myCoeffRing(); 415 bool PrintStar, IsFirstCoeff=true; 416 const bool IsQuotientOfZZ = IsQuotientRing(R) && IsZZ(BaseRing(R)); 417 //bool IsQuotientOfZZ = IsRingFp(R); 418 const bool IsNumberRing = IsZZ(R) || IsQuotientOfZZ || IsQQ(R) || IsRingTwinFloat(R); 419 420 for (long d=myStdDeg(rawf) ; d != 0 ; --d) 421 { 422 PrintStar = true; 423 ConstRefRingElem c = myCoeff(rawf, d); 424 if (IsZero(c)) continue; 425 //---------------------------------------------------------------------- 426 // coefficient 427 //---------------------------------------------------------------------- 428 429 if (!IsNumberRing) 430 { 431 if (!IsFirstCoeff) out << " +"; 432 out << '(' << c << ')'; 433 goto EndCoeffPrint; 434 } 435 // assuming Q is printed with positive denominator 436 if (!IsFirstCoeff) 437 { 438 if (R->myIsPrintedWithMinus(raw(c))) out << " "; 439 else out <<" +"; 440 } 441 if (IsOne(c)) // do not print "1 * " 442 { 443 PrintStar = false; 444 goto EndCoeffPrint; 445 } 446 if ( !IsQuotientOfZZ && IsMinusOne(c) ) // do not print "-1 * " 447 { 448 PrintStar = false; 449 out << "-"; 450 goto EndCoeffPrint; 451 } 452 out << c; 453 454 EndCoeffPrint: 455 456 //---------------------------------------------------------------------- 457 // PP 458 //---------------------------------------------------------------------- 459 if (PrintStar) out << "*"; 460 out << myIndetSymbol(); 461 if (d > 1) out << "^" << d; 462 463 IsFirstCoeff = false; 464 } 465 //---------------------------------------------------------------------- 466 // coefficient 467 //---------------------------------------------------------------------- 468 469 ConstRefRingElem c = myCoeff(rawf, 0); 470 if (IsZero(c)) return; 471 if (!IsNumberRing) 472 { 473 if (!IsFirstCoeff) out << " +"; 474 out << '(' << c << ')'; 475 return; 476 } 477 // assuming Q is printed with positive denominator 478 if (!IsFirstCoeff) 479 { 480 if (R->myIsPrintedWithMinus(raw(c))) out << " "; 481 else out <<" +"; 482 } 483 out << c; 484 } 485 486 myOutputSelf(OpenMathOutput & OMOut)487 void DenseUPolyRingBase::myOutputSelf(OpenMathOutput& OMOut) const 488 { 489 OMOut->mySendApplyStart(); 490 OMOut << OpenMathSymbol("setname1", myImplDetails()); 491 OMOut << myCoeffRing(); 492 OMOut->mySendApplyEnd(); 493 } 494 495 myIsZero(ConstRawPtr rawx)496 bool DenseUPolyRingBase::myIsZero(ConstRawPtr rawx) const 497 { 498 return myDegPlus1(rawx)==0; 499 } 500 501 myIsPrintAtom(ConstRawPtr rawx)502 bool DenseUPolyRingBase::myIsPrintAtom(ConstRawPtr rawx) const 503 { 504 if (!myIsConstant(rawx)) return false; 505 // same as in "output" 506 const ring& R = myCoeffRing(); 507 508 if (IsZZ(R) || IsQQ(R)) return R->myIsPrintAtom(raw(myLC(rawx))); 509 return true; 510 } 511 512 myOutput(OpenMathOutput & OMOut,ConstRawPtr rawx)513 void DenseUPolyRingBase::myOutput(OpenMathOutput& OMOut, ConstRawPtr rawx) const 514 { 515 OMOut->mySendApplyStart(); 516 OMOut << OpenMathSymbol("cocoa", "DUPCoeffs"); 517 // ??? if (IsZero(rawx)) ..... 518 OMOut << myStdDeg(rawx); 519 520 for (long i=0 ; i <= myStdDeg(rawx) ; ++i) 521 OMOut << myCoeff(rawx, i); 522 OMOut->mySendApplyEnd(); 523 } 524 525 myIsOne(ConstRawPtr rawf)526 bool DenseUPolyRingBase::myIsOne(ConstRawPtr rawf) const 527 { 528 if (myDegPlus1(rawf)!=1) return false; 529 return IsOne(myCoeff(rawf, 0)); 530 } 531 532 myIsMinusOne(ConstRawPtr rawf)533 bool DenseUPolyRingBase::myIsMinusOne(ConstRawPtr rawf) const 534 { 535 if (myDegPlus1(rawf)!=1) return false; 536 return IsMinusOne(myCoeff(rawf, 0)); 537 } 538 539 myIsConstant(ConstRawPtr rawf)540 bool DenseUPolyRingBase::myIsConstant(ConstRawPtr rawf) const 541 { 542 if (myDegPlus1(rawf)>1) return false; 543 return true; 544 } 545 546 myIsIndet(long & IndetIndex,ConstRawPtr rawf)547 bool DenseUPolyRingBase::myIsIndet(long& IndetIndex, ConstRawPtr rawf) const 548 { 549 if (myDegPlus1(rawf)!=2) return false; 550 if (!(IsOne(myCoeff(rawf,1)) && IsZero(myCoeff(rawf,0)))) 551 return false; 552 IndetIndex = 0; 553 return true; 554 } 555 556 myIsIndetPosPower(ConstRawPtr rawf)557 bool DenseUPolyRingBase::myIsIndetPosPower(ConstRawPtr rawf) const 558 { 559 long d = -1; 560 for (long i=0; i<myDegPlus1(rawf); ++i) 561 if (!IsZero(myCoeff(rawf, i))) 562 { 563 if (!IsOne(myCoeff(rawf, i))) return false; 564 if (d != -1) return false; else d = i; 565 } 566 return true; 567 } 568 569 myIsEvenPoly(ConstRawPtr rawf)570 bool DenseUPolyRingBase::myIsEvenPoly(ConstRawPtr rawf) const 571 { 572 const long d1 = myDegPlus1(rawf); 573 if (d1 == 0) return true; 574 for (long i=1; i<d1; i+=2) 575 if (!IsZero(myCoeff(rawf, i))) return false; 576 return true; 577 } 578 myIsOddPoly(ConstRawPtr rawf)579 bool DenseUPolyRingBase::myIsOddPoly(ConstRawPtr rawf) const 580 { 581 const long d1 = myDegPlus1(rawf); 582 if (d1 == 0) return true; 583 for (long i=0; i<d1; i+=2) 584 if (!IsZero(myCoeff(rawf, i))) return false; 585 return true; 586 } 587 588 myIsMonomial(ConstRawPtr rawf)589 bool DenseUPolyRingBase::myIsMonomial(ConstRawPtr rawf) const 590 { 591 if (myIsZero(rawf)) return true; 592 for (long i=0; i<myStdDeg(rawf); ++i) 593 if (!myIsZero(raw(myCoeff(rawf,i)))) return false; 594 return true; 595 } 596 597 myIndetPower(RawPtr rawf,long var,long exp)598 void DenseUPolyRingBase::myIndetPower(RawPtr rawf, long var, long exp) const 599 { 600 (void)(var); // to avoid compiler warning about unused parameter 601 CoCoA_ASSERT(var==0); 602 RingElem ans(ring(this)); 603 myResize(raw(ans), exp+1); 604 myAssignNonZeroCoeff(raw(ans), raw(one(myCoeffRing())), exp); 605 mySwap(raw(ans), rawf); // do it this way to be exception clean 606 } 607 608 myNumTerms(ConstRawPtr rawf)609 long DenseUPolyRingBase::myNumTerms(ConstRawPtr rawf) const 610 { 611 long nt = 0; 612 for (long i=0; i<myDegPlus1(rawf); ++i) 613 if (!myCoeffRing()->myIsZero(raw(myCoeff(rawf,i)))) ++nt; 614 return nt; 615 } 616 myMonomial(ConstRawPtr rawc,unsigned long exp)617 RingElem DenseUPolyRingBase::myMonomial(ConstRawPtr rawc, unsigned long exp) const 618 { 619 CoCoA_ASSERT(!myCoeffRing()->myIsZero(rawc)); 620 RingElem ans(ring(this)); 621 myResize(raw(ans), exp+1); 622 myAssignNonZeroCoeff(raw(ans), rawc, exp); 623 return ans; 624 } 625 626 myIsEqual(ConstRawPtr rawx,ConstRawPtr rawy)627 bool DenseUPolyRingBase::myIsEqual(ConstRawPtr rawx, ConstRawPtr rawy) const 628 { 629 if (myIsZero(rawx)) 630 { 631 if (myIsZero(rawy)) return true; 632 else return false; 633 } 634 if (myDegPlus1(rawx) != myDegPlus1(rawy)) return false; 635 for (long i=0; i<myDegPlus1(rawx); ++i) 636 if (myCoeff(rawx,i) != myCoeff(rawy,i)) 637 return false; 638 return true; 639 } 640 641 myIsInteger(BigInt & N,ConstRawPtr rawx)642 bool DenseUPolyRingBase::myIsInteger(BigInt& N, ConstRawPtr rawx) const 643 { 644 if (myIsZero(rawx)) 645 { 646 N = 0; 647 return true; 648 } 649 if (myIsConstant(rawx)) 650 return myCoeffRing()->myIsInteger(N, raw(myCoeff(rawx, 0))); 651 return false; 652 } 653 654 myIsRational(BigRat & Q,ConstRawPtr rawx)655 bool DenseUPolyRingBase::myIsRational(BigRat& Q, ConstRawPtr rawx) const 656 { 657 if (myIsZero(rawx)) { Q = 0; return true; } 658 if (!myIsConstant(rawx)) return false; 659 return IsRational(Q, myCoeff(rawx,0)); 660 } 661 662 663 // bool DenseUPolyRingBase::myIsHomog(ConstRawPtr rawf) const 664 // { 665 // if (myIsConstant(rawf)) { return true; } 666 // CoCoA_THROW_ERROR(ERR::NYI, "DenseUPolyRingBase::myIsHomog(ConstRawPtr)"); 667 // return true; 668 // } 669 670 myIsInvertible(ConstRawPtr rawx)671 bool DenseUPolyRingBase::myIsInvertible(ConstRawPtr rawx) const 672 { 673 return (!myIsZero(rawx)) && myIsConstant(rawx) && IsInvertible(myLC(rawx)); 674 } 675 676 myPowerSmallExp(RawPtr rawlhs,ConstRawPtr rawx,long n)677 void DenseUPolyRingBase::myPowerSmallExp(RawPtr rawlhs, ConstRawPtr rawx, long n) const 678 { 679 // Assert that we have a genuinely non-trivial case. 680 CoCoA_ASSERT(n > 1); 681 CoCoA_ASSERT(!myIsZero(rawx) && !myIsOne(rawx) && !myIsMinusOne(rawx)); 682 long NoUse; 683 if (myIsIndet(NoUse, rawx)) //??? is this the right place for this check?? 684 myIndetPower(rawlhs, 0, n); 685 else 686 myBinaryPower(rawlhs, rawx, n); 687 // mySequentialPower(rawlhs, rawx, n); //??? BUG/SLUG myBinaryPower better if univariate or coeffs are finite field 688 } 689 690 myIndetSymbol(long idx)691 const symbol& DenseUPolyRingBase::myIndetSymbol(long idx) const 692 { 693 if (idx!=0) 694 CoCoA_THROW_ERROR(ERR::BadIndetIndex, "DenseUPolyRingBase::myIndetSymbol(idx)"); 695 return myIndetSymbol(); 696 } 697 698 699 //---- Special functions on RingElem owned by DenseUPolyRing 700 701 702 //-- IdealImpl ---------------------------------------- 703 myIdealCtor(const std::vector<RingElem> & gens)704 ideal DenseUPolyRingBase::myIdealCtor(const std::vector<RingElem>& gens) const 705 { 706 return ideal(new IdealImpl(DenseUPolyRing(this), gens)); //??? ugly ??? 707 } 708 709 IdealImpl(const DenseUPolyRing & P,const std::vector<RingElem> & gens)710 DenseUPolyRingBase::IdealImpl::IdealImpl(const DenseUPolyRing& P, const std::vector<RingElem>& gens): 711 myP(P), 712 myGensValue(gens) 713 { 714 myTidyGensIsValid = false; 715 if (!IsField(CoeffRing(P))) 716 CoCoA_THROW_ERROR("NYI ideal of polynomials with coeffs not in a field", "ideal(DenseUPolyRing, gens)");//??? 717 const long ngens = len(gens); 718 for (long i=0; i < ngens; ++i) 719 if (owner(gens[i]) != myP) CoCoA_THROW_ERROR(ERR::MixedRings, "DenseUPolyRingBase::IdealImpl ctor"); 720 } 721 722 myClone()723 IdealBase* DenseUPolyRingBase::IdealImpl::myClone() const 724 { 725 return new IdealImpl(*this); 726 } 727 728 IamZero()729 bool DenseUPolyRingBase::IdealImpl::IamZero() const 730 { 731 if (myTidyGensIsValid) return myTidyGensValue.empty(); 732 const vector<RingElem>& g = myGensValue; 733 const long ngens = len(g); 734 for (long i=0; i < ngens; ++i) 735 if (!IsZero(g[i])) return false; 736 return true; 737 } 738 739 myTestIsMaximal()740 void DenseUPolyRingBase::IdealImpl::myTestIsMaximal() const 741 { 742 if (!IsField(CoeffRing(myP))) 743 CoCoA_THROW_ERROR(ERR::NYI, "DenseUPolyRingBase::IdealImpl::myTestIsMaximal() non-field CoeffRing"); 744 myTestIsPrime(); 745 } 746 747 myTestIsPrimary()748 void DenseUPolyRingBase::IdealImpl::myTestIsPrimary() const 749 { 750 CoCoA_THROW_ERROR(ERR::NYI, "DenseUPolyRingBase::IdealImpl::myTestIsPrimary()"); 751 } 752 753 myTestIsPrime()754 void DenseUPolyRingBase::IdealImpl::myTestIsPrime() const 755 { 756 if (IamZero()) 757 { myAssignPrimeFlag(IsIntegralDomain(CoeffRing(myRing()))); return; } 758 if (!IsField(CoeffRing(myP))) 759 CoCoA_THROW_ERROR(ERR::NYI, "DenseUPolyRingBase::IdealImpl::myTestIsPrime() non-field CoeffRing"); 760 // The ring is K[x], thus a PID; hence ideal has a single generator. 761 CoCoA_ASSERT(len(myTidyGens(NoCpuTimeLimit()))==1); 762 const RingElem& f = myTidyGens(NoCpuTimeLimit())[0]; 763 myAssignPrimeFlag(!IsConstant(f) && IsIrred(f)); 764 } 765 766 // redefine myAssignMaximalFlag etc, for PID myTestIsRadical()767 void DenseUPolyRingBase::IdealImpl::myTestIsRadical() const 768 { 769 if (!IsField(CoeffRing(myP))) 770 CoCoA_THROW_ERROR(ERR::NYI, "DenseUPolyRingBase::IdealImpl::myTestIsRadical() non-field CoeffRing"); 771 // The ring is K[x], thus a PID; hence ideal has a single generator. 772 CoCoA_ASSERT(len(myTidyGens(NoCpuTimeLimit()))==1); 773 myAssignRadicalFlag(IsSqFree(myTidyGens(NoCpuTimeLimit())[0])); 774 } 775 776 myReduceMod(RingElemRawPtr rawf)777 void DenseUPolyRingBase::IdealImpl::myReduceMod(RingElemRawPtr rawf) const 778 { 779 if (myP->myIsZero(rawf)) return; 780 if (IamZero()) return; 781 RingElem g = RingElemAlias(myP, rawf); 782 mod(g, (myTidyGens(NoCpuTimeLimit()))[0]); 783 myP->mySwap(rawf, raw(g)); 784 } 785 786 IhaveElem(RingElemConstRawPtr rawf)787 bool DenseUPolyRingBase::IdealImpl::IhaveElem(RingElemConstRawPtr rawf) const 788 { 789 RingElem g = RingElemAlias(myP, rawf); 790 myReduceMod(raw(g)); 791 return IsZero(g); 792 } 793 794 GetPtr(const ideal & I)795 inline const DenseUPolyRingBase::IdealImpl* DenseUPolyRingBase::IdealImpl::GetPtr(const ideal& I) 796 { 797 return dynamic_cast<const DenseUPolyRingBase::IdealImpl*>(I.myIdealPtr()); 798 } 799 800 myAdd(const ideal & Jin)801 void DenseUPolyRingBase::IdealImpl::myAdd(const ideal& Jin) 802 { 803 myGensValue.insert(myGensValue.end(), gens(Jin).begin(), gens(Jin).end()); 804 myTidyGensIsValid = false; 805 myTidyGensValue.clear(); 806 } 807 808 myMul(const ideal & Jin)809 void DenseUPolyRingBase::IdealImpl::myMul(const ideal& Jin) 810 { 811 CoCoA_THROW_ERROR(ERR::NYI, "DenseUPolyRingBase::IdealImpl::mul"); 812 } 813 814 myIntersect(const ideal & J)815 void DenseUPolyRingBase::IdealImpl::myIntersect(const ideal& J) 816 { 817 if (IamZero()) return; 818 if (IsZero(J)) 819 { 820 myGensValue.clear(); 821 myTidyGensValue.clear(); 822 myTidyGensIsValid = true; 823 return; 824 } 825 if (!IsField(CoeffRing(myP))) 826 CoCoA_THROW_ERROR(ERR::NYI, "DenseUPolyRingBase::IdealImpl::intersect non-field CoeffRing"); 827 RingElem f = myTidyGens(NoCpuTimeLimit())[0]; 828 RingElem g = TidyGens(J)[0]; 829 // ideal I(myP, (g*f)/gcd(f,g)); 830 RingElem h = (g*f)/gcd(f,g); 831 myGensValue.clear(); 832 myGensValue.push_back(h); 833 myTidyGensValue.clear(); 834 myTidyGensIsValid = false; 835 } 836 837 myColon(const ideal & J)838 void DenseUPolyRingBase::IdealImpl::myColon(const ideal& J) 839 { 840 if (!IsField(CoeffRing(myP))) 841 CoCoA_THROW_ERROR(ERR::NYI, "DenseUPolyRingBase::IdealImpl::colon non-field CoeffRing"); 842 if (IamZero()) return; 843 if (IsZero(J)) 844 { 845 myGensValue.clear(); 846 myGensValue.push_back(one(myP)); 847 myTidyGensValue.clear(); 848 myTidyGensIsValid = false; 849 return; 850 } 851 RingElem f = myTidyGens(NoCpuTimeLimit())[0]; 852 RingElem g = TidyGens(J)[0]; 853 RingElem h = f/gcd(f,g); 854 myGensValue.clear(); 855 myGensValue.push_back(h); 856 myTidyGensValue.clear(); 857 myTidyGensIsValid = false; 858 } 859 860 myDivMod(RingElemRawPtr,RingElemConstRawPtr,RingElemConstRawPtr)861 bool DenseUPolyRingBase::IdealImpl::myDivMod(RingElemRawPtr /*rawlhs*/, RingElemConstRawPtr /*rawnum*/, RingElemConstRawPtr /*rawden*/) const 862 { 863 CoCoA_THROW_ERROR(ERR::NYI, "DenseUPolyRingBase::IdealImpl::myDivMod"); 864 return false; // just to keep compiler quiet!! 865 } 866 867 myTidyGens(const CpuTimeLimit & CheckForTimeOut)868 const std::vector<RingElem>& DenseUPolyRingBase::IdealImpl::myTidyGens(const CpuTimeLimit& CheckForTimeOut) const 869 { 870 if (!IsField(CoeffRing(myP))) 871 CoCoA_THROW_ERROR(ERR::NYI, "DenseUPolyRingBase::IdealImpl::myTidyGens non-field CoeffRing"); 872 if (myTidyGensIsValid) return myTidyGensValue; 873 CoCoA_ASSERT(myTidyGensValue.empty()); 874 RingElem g(myP); 875 const long ngens = len(myGensValue); 876 for (long i=0; i < ngens; ++i) 877 { 878 CheckForTimeOut("DenseUPolyRingBase::IdealImpl::myTidyGens"); // could this ever be useful? 879 myP->myGcd(raw(g), raw(g), raw(myGensValue[i])); 880 if (IsInvertible(g)) break; // gcd is 1 881 } 882 if (!IsZero(g)) myTidyGensValue.push_back(g); 883 myTidyGensIsValid = true; 884 return myTidyGensValue; 885 } 886 887 coeff(ConstRefRingElem f,long d)888 RingElemAlias coeff(ConstRefRingElem f, long d) 889 { 890 if (!IsDenseUPolyRing(owner(f))) 891 CoCoA_THROW_ERROR(ERR::BadRing, "coeff(f,d)"); 892 if (d < 0) 893 CoCoA_THROW_ERROR(ERR::NegExp, "coeff(f,d);"); 894 return DenseUPolyRingPtr(owner(f))->myCoeff(raw(f), AsSignedLong(d)); 895 } 896 897 898 //-- HomImpl ---------------------------------------- 899 HomImpl(const DenseUPolyRing & domain,const ring & codomain,const RingHom & CoeffHom,ConstRefRingElem IndetImage)900 DenseUPolyRingBase::HomImpl::HomImpl(const DenseUPolyRing& domain, const ring& codomain, const RingHom& CoeffHom, ConstRefRingElem IndetImage): 901 RingHomBase(domain, codomain), 902 myCoeffHom(CoeffHom), 903 myIndetImage(IndetImage) 904 { 905 // No need to check anything: checks already made when CoeffHom was built. 906 } 907 908 namespace 909 { 910 // ??? this is essentially the same as ApplyGeneral: it should be improved 911 // assume image==0 ApplyDPRCodomain(RingElem & image,ConstRefRingElem arg,const RingHom CoeffHom,ConstRefRingElem IndetImage)912 void ApplyDPRCodomain(RingElem& image, ConstRefRingElem arg, const RingHom CoeffHom, ConstRefRingElem IndetImage) 913 { 914 const ring DPR = owner(image); 915 RingElem g(DPR); 916 if (!IsZero(arg)) 917 for (long i=0; i<=deg(arg); ++i) 918 { 919 RingElem SummandImage = CoeffHom(coeff(arg,i)); 920 CoCoA_ASSERT(owner(SummandImage) == DPR); 921 if (IsZero(SummandImage)) continue; // efficiency hack???? 922 if (i != 0) 923 SummandImage *= power(IndetImage, i); 924 g += SummandImage; 925 } 926 swap(image, g); 927 } 928 929 ApplyGeneral(RingElem & image,ConstRefRingElem arg,const RingHom CoeffHom,ConstRefRingElem IndetImage)930 void ApplyGeneral(RingElem& image, ConstRefRingElem arg, const RingHom CoeffHom, ConstRefRingElem IndetImage) 931 { 932 ring R = owner(image); 933 RingElem g(R); 934 if (!IsZero(arg)) 935 for (long i=0; i<=deg(arg); ++i) 936 { 937 RingElem SummandImage = CoeffHom(coeff(arg,i)); 938 CoCoA_ASSERT(owner(SummandImage) == R); 939 if (IsZero(SummandImage)) continue; // efficiency hack???? 940 if (i != 0) 941 SummandImage *= power(IndetImage, i); 942 g += SummandImage; 943 } 944 swap(image, g); 945 } 946 } // end of anonymous namespace 947 myApply(RingElemRawPtr rawimage,RingElemConstRawPtr rawarg)948 void DenseUPolyRingBase::HomImpl::myApply(RingElemRawPtr rawimage, RingElemConstRawPtr rawarg) const 949 { 950 RingElem ans(myCodomain); // Putting result into ans is exception safe and avoids aliasing problems. 951 if ( IsDenseUPolyRing(myCodomain) ) 952 ApplyDPRCodomain(ans, RingElemAlias(myDomain, rawarg), myCoeffHom, myIndetImage); 953 else 954 ApplyGeneral(ans, RingElemAlias(myDomain, rawarg), myCoeffHom, myIndetImage); 955 myCodomain->mySwap(rawimage, raw(ans)); 956 } 957 958 myOutputSelfDetails(std::ostream & out)959 void DenseUPolyRingBase::HomImpl::myOutputSelfDetails(std::ostream& out) const 960 { 961 if (!out) return; // short-cut for bad ostreams 962 if (NumIndets(myDomain) == 0) return; 963 out << " sending " 964 << "(" << indet(myDomain, 0) << " |--> " << myIndetImage << ")"; 965 } 966 967 myHomCtor(const ring & codomain,const RingHom & CoeffHom,const std::vector<RingElem> & IndetImages)968 RingHom DenseUPolyRingBase::myHomCtor(const ring& codomain, const RingHom& CoeffHom, const std::vector<RingElem>& IndetImages) const 969 { 970 // Args already sanity checked by PolyRingHom (see PolyRing.C) 971 // DON'T KNOW IF I REALLY WANT TO MAKE THIS CHECK... 972 // // Check to see if we're building an identity homomorphism 973 // if (ring(this) == codomain && IsIdentity(CoeffHom)) 974 // { 975 // bool IndetsFixed = true; 976 // for (long i=0; i < myNumIndetsValue; ++i) 977 // IndetsFixed &= (myIndetVector[i] == IndetImages[i]); 978 // if (IndetsFixed) return IdentityHom(ring(this)); 979 // } 980 // General case 981 return RingHom(new HomImpl(DenseUPolyRing(this), codomain, CoeffHom, IndetImages[0])); 982 } 983 984 myCompose(const RingHom & phi,const RingHom & theta)985 RingHom DenseUPolyRingBase::myCompose(const RingHom& phi, const RingHom& theta) const 986 { 987 vector<RingElem> IndetImages; 988 IndetImages.push_back(phi(theta(myIndets()[0]))); 989 990 return myHomCtor(codomain(phi), phi(theta(myCoeffEmbeddingHomCtor())), IndetImages); 991 } 992 993 994 //-- CoeffEmbeddingHomImpl ---------------------------------------- 995 996 //--------------------------------------------------------------------------- 997 // Functions for the class DenseUPolyRingBase::CoeffEmbeddingHomImpl 998 999 CoeffEmbeddingHomImpl(const DenseUPolyRing & P)1000 DenseUPolyRingBase::CoeffEmbeddingHomImpl::CoeffEmbeddingHomImpl(const DenseUPolyRing& P): 1001 RingHomEmbeddingBase(CoeffRing(P), P) 1002 {} 1003 1004 myApply(RingElemRawPtr rawimage,RingElemConstRawPtr rawarg)1005 void DenseUPolyRingBase::CoeffEmbeddingHomImpl::myApply(RingElemRawPtr rawimage, RingElemConstRawPtr rawarg) const 1006 { 1007 const DenseUPolyRing P = myCodomain; 1008 RingElem ans(P); // don't use image here for aliasing 1009 // ??? ANNA profile this: (probably better to have myMonomial) 1010 if (!myDomain->myIsZero(rawarg)) 1011 ans = monomial(P, RingElemAlias(myDomain, rawarg), 0); 1012 P->mySwap(rawimage, raw(ans)); 1013 } 1014 1015 1016 } // end of namespace CoCoA 1017 1018 // RCS header/log in the next few lines 1019 // $Header: /Volumes/Home_1/cocoa/cvs-repository/CoCoALib-0.99/src/AlgebraicCore/DenseUPolyRing.C,v 1.76 2020/06/17 15:49:22 abbott Exp $ 1020 // $Log: DenseUPolyRing.C,v $ 1021 // Revision 1.76 2020/06/17 15:49:22 abbott 1022 // Summary: Changed CoCoA_ERROR into CoCoA_THROW_ERROR 1023 // 1024 // Revision 1.75 2020/02/12 10:48:59 bigatti 1025 // -- changed calls to myAssignBLAHFlagPID 1026 // 1027 // Revision 1.74 2020/02/12 09:01:47 bigatti 1028 // -- changed myTestIsMaximal etc to return void (and consequences) 1029 // 1030 // Revision 1.73 2020/02/11 16:56:40 abbott 1031 // Summary: Corrected last update (see redmine 969) 1032 // 1033 // Revision 1.72 2020/02/11 16:12:17 abbott 1034 // Summary: Added some checks for bad ostream (even to mem fns myOutput); see redmine 969 1035 // 1036 // Revision 1.71 2019/09/16 17:38:48 abbott 1037 // Summary: Impl myIsEvenPoly, myIsOddPoly 1038 // 1039 // Revision 1.70 2018/05/25 09:24:46 abbott 1040 // Summary: Major redesign of CpuTimeLimit (many consequences) 1041 // 1042 // Revision 1.69 2018/05/18 12:13:36 bigatti 1043 // -- renamed IntOperations --> BigIntOps 1044 // 1045 // Revision 1.68 2018/04/18 14:25:59 abbott 1046 // Summary: Added missing return 1047 // 1048 // Revision 1.67 2018/03/29 09:36:40 bigatti 1049 // -- added member functions myTestIsRadical, myTestIsPrimary and flags 1050 // 1051 // Revision 1.66 2018/03/20 11:45:54 bigatti 1052 // -- changed myPrimeTest --> myTestIsPrime (etc) 1053 // 1054 // Revision 1.65 2017/03/28 12:56:51 bigatti 1055 // -- changed copyright 1056 // 1057 // Revision 1.64 2016/11/08 13:03:31 bigatti 1058 // -- removed useless comment 1059 // 1060 // Revision 1.63 2016/09/08 14:12:32 bigatti 1061 // -- mySetMaximalFlag --> myAssignMaximalFlag 1062 // -- mySetPrimeFlag --> myAssignPrimeFlag 1063 // -- updated the related code 1064 // -- (still "old design", but better aligned) 1065 // 1066 // Revision 1.62 2015/05/04 13:14:10 bigatti 1067 // -- removed and fixed some comments 1068 // 1069 // Revision 1.61 2015/04/24 15:40:59 bigatti 1070 // -- renamed: myAddMul --> myAddMulLM 1071 // -- renamed: myMoveLM --> myMoveLMToFront 1072 // -- new myMoveLMToBack (used in ReductionCog --> bug in test-TmpMorseGraph??) 1073 // 1074 // Revision 1.60 2014/07/31 14:45:17 abbott 1075 // Summary: Merged io.H and UtilsTemplate.H into new header VectorOperations.H 1076 // Author: JAA 1077 // 1078 // Revision 1.59 2014/07/30 14:03:34 abbott 1079 // Summary: Changed myAmbientRing into myRing 1080 // Author: JAA 1081 // 1082 // Revision 1.58 2014/07/28 15:42:26 abbott 1083 // Summary: Changed myCoeffEmbeddingHom into myCoeffEmbeddingHomCtor 1084 // Author: JAA 1085 // 1086 // Revision 1.57 2014/07/14 15:05:58 abbott 1087 // Summary: Added include of utils.H 1088 // Author: JAA 1089 // 1090 // Revision 1.56 2014/07/11 15:35:25 bigatti 1091 // -- default implementation of myOutputSelf(OpenMathOutput& OMOut) 1092 // 1093 // Revision 1.55 2014/07/09 13:01:17 abbott 1094 // Summary: Removed AsDenseUPolyRing 1095 // Author: JAA 1096 // 1097 // Revision 1.54 2014/07/08 15:21:56 abbott 1098 // Summary: Updated comment 1099 // Author: JAA 1100 // 1101 // Revision 1.53 2014/07/08 13:14:40 abbott 1102 // Summary: Removed AsQuotientRing; added new defn of BaseRing 1103 // Author: JAA 1104 // 1105 // Revision 1.52 2014/07/08 08:34:41 abbott 1106 // Summary: Removed AsFractionField 1107 // Author: JAA 1108 // 1109 // Revision 1.51 2014/06/17 10:23:29 abbott 1110 // Summary: Added (void)(var) to avoid compiler warning about unused param in myIndetPower 1111 // Author: JAA 1112 // 1113 // Revision 1.50 2014/05/06 13:20:41 abbott 1114 // Summary: Changed names (my)MaxExponents into (my)Deg 1115 // Author: JAA 1116 // 1117 // Revision 1.49 2014/04/30 16:04:56 abbott 1118 // Summary: Replaced X.size() by len(X) 1119 // Author: JAA 1120 // 1121 // Revision 1.48 2014/04/15 14:24:21 abbott 1122 // Summary: Improved/cleaned IdealImpl:myPrimeTest 1123 // Author: JAA 1124 // 1125 // Revision 1.47 2013/06/28 17:03:51 abbott 1126 // Modified semantics of IdealBase::myDivMod; 1127 // it now returns a boolean. 1128 // Several consequential changes. 1129 // 1130 // Revision 1.46 2013/05/31 09:15:21 abbott 1131 // Changed arg type of fn "coeff" from MachineInt to long becaue it is an index. 1132 // 1133 // Revision 1.45 2012/10/24 12:12:36 abbott 1134 // Changed return type of coeff and myLC. 1135 // Replaced several ctor calls so that they build RingElemAlias. 1136 // 1137 // Revision 1.44 2012/10/17 12:03:19 abbott 1138 // Replaced RefRingElem by RingElem& 1139 // 1140 // Revision 1.43 2012/05/30 16:04:55 bigatti 1141 // -- applied "3" convention on bool3 functions and member fields 1142 // 1143 // Revision 1.42 2012/05/29 07:45:23 abbott 1144 // Implemented simplification change to bool3: 1145 // changed names of the constants, 1146 // changed names of the testing fns. 1147 // 1148 // Revision 1.41 2012/05/28 09:18:21 abbott 1149 // Created IntOperations which gathers together all operations on 1150 // integers (both big and small). Many consequential changes. 1151 // 1152 // Revision 1.40 2012/05/24 14:53:35 bigatti 1153 // -- changed symbol "index" into "subscripts" 1154 // 1155 // Revision 1.39 2012/05/22 10:02:37 abbott 1156 // Removed IsGCDDomain; substituted by IsTrueGCDDomain. 1157 // Added IsFractionFieldOfGCDDomain. 1158 // 1159 // Revision 1.38 2012/04/27 15:08:58 abbott 1160 // Corrected myContentFrF 1161 // 1162 // Revision 1.37 2012/02/10 10:26:40 bigatti 1163 // -- changed RingZ.H, RingQ.H --> RingZZ.H, RingQQ.H 1164 // 1165 // Revision 1.36 2012/02/08 17:12:37 bigatti 1166 // -- changed: Z,Q -> ZZ,QQ 1167 // 1168 // Revision 1.35 2012/01/26 16:47:00 bigatti 1169 // -- changed back_inserter into insert 1170 // 1171 // Revision 1.34 2011/11/09 14:03:40 bigatti 1172 // -- renamed MachineInteger --> MachineInt 1173 // 1174 // Revision 1.33 2011/08/24 10:24:17 bigatti 1175 // -- renamed QQ --> BigRat 1176 // -- sorted #include 1177 // 1178 // Revision 1.32 2011/08/14 15:52:17 abbott 1179 // Changed ZZ into BigInt (phase 1: just the library sources). 1180 // 1181 // Revision 1.31 2011/06/23 16:04:47 abbott 1182 // Added IamExact mem fn for rings. 1183 // Added myRecvTwinFloat mem fn for rings. 1184 // Added first imple of RingHom from RingTwinFloat to other rings. 1185 // 1186 // Revision 1.30 2011/04/27 08:21:48 bigatti 1187 // -- added gcd with coefficients in GCDDomain 1188 // 1189 // Revision 1.29 2011/03/16 15:38:31 bigatti 1190 // -- added myIsIndetPosPower(f) 1191 // 1192 // Revision 1.28 2011/03/10 16:39:34 abbott 1193 // Replaced (very many) size_t by long in function interfaces (for rings, 1194 // PPMonoids and modules). Also replaced most size_t inside fn defns. 1195 // 1196 // Revision 1.27 2011/03/01 14:10:47 bigatti 1197 // -- added ClearDenom/myClearDenom 1198 // 1199 // Revision 1.26 2011/02/23 16:04:50 bigatti 1200 // -- more fixes to get gcd==1 when coprime 1201 // 1202 // Revision 1.25 2011/01/18 14:38:43 bigatti 1203 // -- moved **_forC5 functions into CoCoA-5/CoCoALibSupplement: 1204 // myMonomials_forC5, mySupport_forC5, monomials_forC5, support_forC5, 1205 // LPP_forC5, LT_forC5, LM_forC5 1206 // 1207 // Revision 1.24 2010/11/30 11:30:49 bigatti 1208 // -- moved IndetsCalled into unique implementation in PolyRing 1209 // -- renamed IndetName --> IndetSymbol 1210 // -- added myIndetSymbol 1211 // 1212 // Revision 1.23 2010/11/25 12:31:22 bigatti 1213 // -- added myIndetsCalled 1214 // 1215 // Revision 1.22 2010/11/05 15:59:49 bigatti 1216 // -- added myMonomials_forC5, mySupport_forC5 1217 // 1218 // Revision 1.21 2010/10/01 15:45:17 bigatti 1219 // -- added mySymbolValue 1220 // 1221 // Revision 1.20 2010/06/10 08:00:02 bigatti 1222 // -- fixed naming conventions 1223 // 1224 // Revision 1.19 2010/02/04 10:12:04 bigatti 1225 // -- added "mul" for ideal (implemented only for SparsePolyRing) 1226 // 1227 // Revision 1.18 2009/10/02 13:27:26 bigatti 1228 // -- unique implementation of myDiv in PolyRing.C 1229 // 1230 // Revision 1.17 2009/09/24 16:24:19 abbott 1231 // Added include directive (after removing it from RingFp.H). 1232 // 1233 // Revision 1.16 2009/07/24 12:26:43 abbott 1234 // Added CommonDenom function for polynomials. 1235 // 1236 // Revision 1.15 2009/07/02 16:32:11 abbott 1237 // Consequential changes stemming from new class QQ, and modified interface to the member 1238 // function RingBase::myIsRational. Also some new conversion functions. 1239 // 1240 // Revision 1.14 2009/05/22 10:24:12 bigatti 1241 // -- updated def of IsQuotientOfZ in myOutput 1242 // 1243 // Revision 1.13 2008/12/17 12:11:52 abbott 1244 // Changed type from long to MachineInt in operations which use a machine integer 1245 // in place of a RingElem. The change is "superficial" but affects many files. 1246 // 1247 // Revision 1.12 2008/12/12 15:00:53 bigatti 1248 // -- added { } to disambiguate "if" 1249 // 1250 // Revision 1.11 2008/04/21 12:55:39 abbott 1251 // Fixed some minor bugs, and improved code layout slightly. 1252 // 1253 // Revision 1.10 2008/03/12 16:47:14 bigatti 1254 // -- added: myExgcd, myPrimeTest, myMaximalTest 1255 // 1256 // Revision 1.9 2007/12/21 12:29:08 bigatti 1257 // -- abstract implementation in DenseUPolyRing of myDiv, myIsDivisible, myIsInvertible, myGcd 1258 // -- abstract implementation in DenseUPolyRing of ideal operations 1259 // -- some cleaning 1260 // 1261 // Revision 1.8 2007/12/07 15:27:01 bigatti 1262 // -- default implementation of "IamOne" in ideal.C 1263 // 1264 // Revision 1.7 2007/12/05 11:06:24 bigatti 1265 // -- changed "size_t StdDeg/myStdDeg(f)" into "long" (and related functions) 1266 // -- changed "log/myLog(f, i)" into "MaxExponent/myMaxExponent(f, i)" 1267 // -- fixed bug in "IsOne(ideal)" in SparsePolyRing.C 1268 // 1269 // Revision 1.6 2007/12/04 14:13:23 bigatti 1270 // -- added forgotten declaration.... sorry 1271 // 1272 // Revision 1.5 2007/12/04 13:44:50 bigatti 1273 // -- fixed problem with myMinCapacity in constructor 1274 // -- commented out myPowerSmallExp in RingDenseUPolyCleanImpl 1275 // -- refined myPowerSmallExp in DenseUPolyRing 1276 // 1277 // Revision 1.4 2007/10/30 17:14:08 abbott 1278 // Changed licence from GPL-2 only to GPL-3 or later. 1279 // New version for such an important change. 1280 // 1281 // Revision 1.3 2007/10/15 12:40:31 bigatti 1282 // -- new implementation for myAddMul 1283 // -- new: coeffs between deg+1 and size are now guaranteed to be 0 1284 // 1285 // Revision 1.2 2007/10/10 14:02:37 bigatti 1286 // -- added myMulBy1MinusXExp 1287 // -- fixed a few little bugs 1288 // 1289 // Revision 1.1 2007/10/05 15:28:56 bigatti 1290 // -- added abstract class DenseUPolyRing for representing dense 1291 // univariate polynomials 1292 // -- added concrete class RingDenseUPolyClean, the cleanest 1293 // implementation 1294 // -- just for testing, still horribly inefficient and incomplete 1295 // 1296