1 // Copyright (c) 2018 John Abbott and Anna M. Bigatti 2 // Authors: 2018 John Abbott and Anna M. Bigatti 3 // 2017 Alice Moallemy (translation CoCoA5-->CoCoALib) 4 5 // This file is part of the source of CoCoALib, the CoCoA Library. 6 7 // CoCoALib is free software: you can redistribute it and/or modify 8 // it under the terms of the GNU General Public License as published by 9 // the Free Software Foundation, either version 3 of the License, or 10 // (at your option) any later version. 11 12 // CoCoALib is distributed in the hope that it will be useful, 13 // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 // GNU General Public License for more details. 16 17 // You should have received a copy of the GNU General Public License 18 // along with CoCoALib. If not, see <http://www.gnu.org/licenses/>. 19 20 21 // Source code for ideals in SparsePolyRing (functions and member functions) 22 23 #include "CoCoA/SparsePolyOps-ideal.H" 24 25 #include "CoCoA/BigIntOps.H" 26 #include "CoCoA/BigRat.H" 27 #include "CoCoA/CpuTimeLimit.H" 28 #include "CoCoA/DUPFp.H" 29 #include "CoCoA/DenseMatrix.H" // for MultiplicationMat/myDiv 30 #include "CoCoA/MatrixOps.H" // for LinSolve 31 #include "CoCoA/MatrixView.H" // for ZeroMat 32 #include "CoCoA/PPMonoidHom.H" 33 #include "CoCoA/PolyRing.H" 34 #include "CoCoA/QuotientRing.H" // for IsQuotientRing 35 #include "CoCoA/RingFp.H" // for IsRingFp 36 #include "CoCoA/RingHom.H" 37 #include "CoCoA/RingQQ.H" // for IsQQ 38 #include "CoCoA/RingZZ.H" // for IsZZ 39 #include "CoCoA/SmallFpImpl.H" 40 #include "CoCoA/SparsePolyIter.H" 41 #include "CoCoA/SparsePolyOps-MinPoly.H" // for MinPolyDef 42 #include "CoCoA/SparsePolyOps-ideal-monomial.H" 43 #include "CoCoA/SparsePolyRing.H" 44 #include "CoCoA/TmpGOperations.H" // for myIntersect, my Elim.. 45 #include "CoCoA/TmpPPVector.H" // for interreducing in GBasisByHomog 46 #include "CoCoA/TmpUniversalInvolutiveBasisContainer.H" // for ideal ctor 47 #include "CoCoA/apply.H" 48 #include "CoCoA/assert.H" 49 #include "CoCoA/error.H" 50 #include "CoCoA/factor.H" // for myGcd 51 #include "CoCoA/random.H" // for RandomLongStream 52 #include "CoCoA/time.H" 53 #include "CoCoA/verbose.H" 54 //#include "CoCoA/ideal.H" // for myGcd 55 //#include "CoCoA/matrix.H" // for OrdMat, myDivMod 56 57 #include <algorithm> 58 //using std::max; // for MaxExponent, StdDeg 59 using std::remove; // for myColon 60 using std::sort; // for AreGoodIndetNames, QuotientBasisSorted 61 //#include <functional> 62 //using std::not1; // for AreLPPSqFree 63 //using std::ptr_fun; // for AreLPPSqFree 64 #include <iostream> 65 // using std::ostream in SparsePolyRingBase::myOutput 66 //#include <iterator> 67 //using std::back_inserter; 68 #include <list> 69 //#include <vector> 70 using std::vector; 71 72 namespace CoCoA 73 { 74 75 myGens()76 const std::vector<RingElem>& SparsePolyRingBase::IdealImpl::myGens() const 77 { return myGensValue; } 78 79 myTidyGens(const CpuTimeLimit & CheckForTimeOut)80 const std::vector<RingElem>& SparsePolyRingBase::IdealImpl::myTidyGens(const CpuTimeLimit& CheckForTimeOut) const 81 { return myGBasis(CheckForTimeOut); } 82 83 GBasis(const ideal & I,const CpuTimeLimit & timeout)84 const std::vector<RingElem>& GBasis(const ideal& I, 85 const CpuTimeLimit& timeout) 86 { 87 if (!IsSparsePolyRing(RingOf(I))) 88 CoCoA_ERROR(ERR::NotSparsePolyRing, "GBasis(I)"); 89 return TidyGens(I, timeout); 90 } 91 92 GBasisByHomog(const ideal & I,const CpuTimeLimit & timeout)93 const std::vector<RingElem>& GBasisByHomog(const ideal& I, 94 const CpuTimeLimit& timeout) 95 { 96 if (!IsSparsePolyRing(RingOf(I))) 97 CoCoA_ERROR(ERR::NotSparsePolyRing, "GBasisByHomog(I, timeout)"); 98 const SparsePolyRingBase::IdealImpl* const ptrI = 99 SparsePolyRingBase::IdealImpl::ourGetPtr(I); 100 return ptrI->myGBasisByHomog(timeout); 101 } 102 103 GBasisSelfSatCore(const ideal & I)104 std::vector<RingElem> GBasisSelfSatCore(const ideal& I) 105 { 106 if (!IsSparsePolyRing(RingOf(I))) 107 CoCoA_ERROR(ERR::NotSparsePolyRing, "GBasisSelfSatCore(I)"); 108 const SparsePolyRingBase::IdealImpl* const ptrI = 109 SparsePolyRingBase::IdealImpl::ourGetPtr(I); 110 return ptrI->myGBasisSelfSatCore(); 111 } 112 113 GBasisRealSolve(const ideal & I)114 std::vector<RingElem> GBasisRealSolve(const ideal& I) 115 { 116 if (!IsSparsePolyRing(RingOf(I))) 117 CoCoA_ERROR(ERR::NotSparsePolyRing, "GBasisRealSolve(I)"); 118 const SparsePolyRingBase::IdealImpl* const ptrI = 119 SparsePolyRingBase::IdealImpl::ourGetPtr(I); 120 return ptrI->myGBasisRealSolve(); 121 } 122 123 ReducedGBasis(const ideal & I)124 const std::vector<RingElem>& ReducedGBasis(const ideal& I) 125 { 126 if (IsCommutative(RingOf(I))) return GBasis(I); // the same (2017) 127 CoCoA_ERROR(ERR::NYI, "ReducedGBasis non-commutative"); 128 return GBasis(I); // just to keep the compiler quiet 129 } 130 131 MinGens(const ideal & I)132 const std::vector<RingElem>& MinGens(const ideal& I) 133 { 134 if (!IsSparsePolyRing(RingOf(I))) 135 CoCoA_ERROR(ERR::NotSparsePolyRing, "MinGens(I)"); 136 const SparsePolyRingBase::IdealImpl* const ptrI = 137 SparsePolyRingBase::IdealImpl::ourGetPtr(I); 138 return ptrI->myMinGens(); 139 } 140 141 myPrimaryDecomposition()142 std::vector<ideal> SparsePolyRingBase::IdealImpl::myPrimaryDecomposition() const 143 { 144 //if (IhaveMonomialGens()) return myPrimaryDecomposition_MonId(); 145 if (IhaveSqFreeMonomialGens()) return myPrimaryDecomposition_MonId(); 146 if (IamZeroDim()) return myPrimaryDecomposition_0dim(); 147 CoCoA_ERROR(ERR::NYI, "myPrimaryDecomposition() -- general ideal"); 148 return vector<ideal>(); // just to keep compiler quiet 149 } 150 151 LT(const ideal & I)152 ideal LT(const ideal& I) 153 { 154 if (!IsSparsePolyRing(RingOf(I))) 155 CoCoA_ERROR(ERR::NotSparsePolyRing, "LT(I)"); 156 std::vector<RingElem> GB = TidyGens(I); 157 std::vector<RingElem> v; 158 const SparsePolyRing P = RingOf(I); 159 for (long i=0; i<len(GB); ++i) 160 v.push_back(monomial(P, LPP(GB[i]))); 161 return ideal(P, v); 162 } 163 164 LF(const ideal & I)165 ideal LF(const ideal& I) 166 { 167 if (!IsSparsePolyRing(RingOf(I))) 168 CoCoA_ERROR(ERR::NotSparsePolyRing, "LF(I)"); 169 const SparsePolyRing P = RingOf(I); 170 if ( GradingDim(P)==0 ) CoCoA_ERROR("GradingDim must be non-0", "LF(I)"); 171 std::vector<RingElem> GB = TidyGens(I); 172 std::vector<RingElem> v; 173 for (long i=0; i<len(GB); ++i) v.push_back(LF(GB[i])); 174 return ideal(P, v); 175 } 176 177 homog(const ideal & I,ConstRefRingElem x)178 ideal homog(const ideal& I, ConstRefRingElem x) 179 { 180 if (!IsSparsePolyRing(RingOf(I))) 181 CoCoA_ERROR(ERR::NotSparsePolyRing, "homog(I, x)"); 182 if (AreGensMonomial(I)) return I; 183 if (IsZero(I)) return I; 184 std::vector<RingElem> HomogIdealGens; 185 std::vector<RingElem> v(1,x); 186 ComputeHomogenization(HomogIdealGens, gens(I), v); 187 return ideal(HomogIdealGens); 188 } 189 190 IdealOfGBasis(const ideal & I)191 ideal IdealOfGBasis(const ideal& I) 192 { 193 ideal J(RingOf(I), GBasis(I)); 194 SetGBasisAsGens(J); 195 // if (!uncertain3(IamPrime3Flag)) ... 196 // if (!uncertain3(IamMaximal3Flag 197 return J; 198 } 199 200 IdealOfMinGens(const ideal & I)201 ideal IdealOfMinGens(const ideal& I) 202 { 203 ideal J = I; 204 MinGens(J); // so GBasis and such are stored in original ideal 205 MakeUnique(J)->myMinimalize(); 206 return J; 207 } 208 209 210 // Anna: must be friend for ourGetPtr HasGBasis(const ideal & I)211 bool HasGBasis(const ideal& I) 212 { 213 if (!IsSparsePolyRing(RingOf(I))) 214 CoCoA_ERROR(ERR::NotSparsePolyRing, "HasGBasis(I)"); 215 const SparsePolyRingBase::IdealImpl* const ptrI = 216 SparsePolyRingBase::IdealImpl::ourGetPtr(I); 217 return ptrI->IhaveGBasis(); 218 } 219 220 221 // Anna: must be friend for ourGetPtr AreGensMonomial(const ideal & I)222 bool AreGensMonomial(const ideal& I) 223 { 224 if (!IsSparsePolyRing(RingOf(I))) 225 CoCoA_ERROR(ERR::NotSparsePolyRing, "AreGensMonomial(I)"); 226 const SparsePolyRingBase::IdealImpl* const ptrI = 227 SparsePolyRingBase::IdealImpl::ourGetPtr(I); 228 return ptrI->IhaveMonomialGens(); 229 } 230 231 232 // Anna: must be friend for ourGetPtr AreGensSqFreeMonomial(const ideal & I)233 bool AreGensSqFreeMonomial(const ideal& I) 234 { 235 if (!IsSparsePolyRing(RingOf(I))) 236 CoCoA_ERROR(ERR::NotSparsePolyRing, "AreGensSqFreeMonomial(I)"); 237 const SparsePolyRingBase::IdealImpl* const ptrI = 238 SparsePolyRingBase::IdealImpl::ourGetPtr(I); 239 return ptrI->IhaveSqFreeMonomialGens(); 240 } 241 242 243 // Anna: must be friend for ourGetPtr SetGBasisAsGens(const ideal & I)244 void SetGBasisAsGens(const ideal& I) 245 { 246 if (!IsSparsePolyRing(RingOf(I))) 247 CoCoA_ERROR(ERR::NotSparsePolyRing, "GBasisAsGens(I)"); 248 const SparsePolyRingBase::IdealImpl* const ptrI = 249 SparsePolyRingBase::IdealImpl::ourGetPtr(I); 250 ptrI->mySetGBasisAsGens(); 251 } 252 253 254 // namespace //anonymous for QuotientBasis 255 // { 256 257 // bool IsDivisible(ConstRefPPMonoidElem pp, const std::list<PPMonoidElem>& ByL) 258 // { 259 // for (std::list<PPMonoidElem>::const_iterator i=ByL.begin(); i != ByL.end(); ++i) 260 // if (IsDivisible(pp, *i)) return true; 261 // return false; 262 // } 263 264 265 // // // ??? copied from ex-QuotientBasis.C 266 // // bool IsDivisible(ConstRefPPMonoidElem pp, const std::vector<PPMonoidElem>& ByL) 267 // // { 268 // // const long n = len(ByL); 269 // // for (long i=0; i < n; ++i) 270 // // if ( IsDivisible(pp, ByL[i]) ) return true; 271 // // return false; 272 // // } 273 274 275 // // Apparently STL bind2nd cannot have (const?) reference arguments. 276 // // Apparently BOOST bind would work: what about C++-11? 277 // // This is a hack for STL 278 // class IsDivHack 279 // { 280 // public: 281 // IsDivHack (const std::list<PPMonoidElem>& L): myL(L) {} 282 // bool operator () (ConstRefPPMonoidElem pp) {return IsDivisible(pp, myL);} 283 284 // private: 285 // const std::list<PPMonoidElem> & myL; 286 // }; 287 288 289 // void QuotientBasisRec(std::vector<PPMonoidElem>& ans, 290 // const std::list<PPMonoidElem>& L, 291 // ConstRefPPMonoidElem prefix, 292 // long idx) 293 // { 294 // PPMonoid PPM = owner((L.front())); 295 // const PPMonoidElem& X = indets(PPM)[idx]; 296 // PPMonoidElem prefixXd(prefix); // prefix * x[idx]^d 297 // int MaxDeg = 0; 298 // if (idx == NumIndets(PPM)-1) 299 // { 300 // MaxDeg = exponent((L.front()), idx); 301 // for (int d=0; d < MaxDeg; ++d, prefixXd *= X) ans.push_back(prefixXd); 302 // return; 303 // } 304 // for (std::list<PPMonoidElem>::const_iterator it=L.begin(); it != L.end() ; ++it) 305 // if (exponent((*it),idx) > MaxDeg) MaxDeg = exponent((*it),idx); 306 // std::list<PPMonoidElem> CutOff, tmp; 307 // PPMonoidElem Xd(PPM); // x[idx]^d 308 // for (int d=0; d < MaxDeg; ++d, prefixXd *= X, Xd *= X) 309 // { 310 // for (std::list<PPMonoidElem>::const_iterator it=L.begin(); it != L.end(); ++it) 311 // if (exponent(*it,idx) == d) tmp.push_back(((*it)/Xd)); 312 // CutOff.remove_if(IsDivHack(tmp)); 313 // CutOff.splice(CutOff.end(), tmp); 314 // QuotientBasisRec(ans, CutOff, prefixXd, idx+1); 315 // } 316 // } 317 // } // anonymous namespace 318 319 320 // std::vector<PPMonoidElem> QuotientBasis(const ideal& I) 321 // { 322 // const char* const fn = "QuotientBasis"; 323 // if (!IsSparsePolyRing(RingOf(I))) CoCoA_ERROR(ERR::NotSparsePolyRing, fn); 324 // if (!IsZeroDim(I)) CoCoA_ERROR("ideal must be 0-dimensional", fn); 325 // vector<RingElem> GB = GBasis(I); 326 // std::list<PPMonoidElem> LeadingPPs; 327 // vector<PPMonoidElem> ans; 328 // for (long i=0; i < len(GB); ++i) LeadingPPs.push_back(LPP(GB[i])); 329 // QuotientBasisRec(ans, LeadingPPs, PPMonoidElem(PPM(RingOf(I))), 0); 330 // return ans; 331 // } 332 333 334 // std::vector<PPMonoidElem> QuotientBasisSorted(const ideal& I) 335 // { 336 // const char* const fn = "QuotientBasis"; 337 // if (!IsSparsePolyRing(RingOf(I))) CoCoA_ERROR(ERR::NotSparsePolyRing, fn); 338 // if (!IsZeroDim(I)) CoCoA_ERROR("ideal must be 0-dimensional", fn); 339 // vector<PPMonoidElem> QB = QuotientBasis(I); 340 // std::sort(QB.begin(), QB.end()); 341 // return QB; 342 // } 343 344 345 346 347 348 //-- IdealImpl ---------------------------------------- 349 myIdealCtor(const std::vector<RingElem> & gens)350 ideal SparsePolyRingBase::myIdealCtor(const std::vector<RingElem>& gens) const 351 { 352 return ideal(new IdealImpl(SparsePolyRing(this), gens)); //??? ugly ??? 353 } 354 355 IdealImpl(const SparsePolyRing & P,const std::vector<RingElem> & gens)356 SparsePolyRingBase::IdealImpl::IdealImpl(const SparsePolyRing& P, const std::vector<RingElem>& gens): 357 myP(P), 358 myGensValue(gens), 359 myInvBasisContainerPtr(new Involutive::UniversalInvolutiveBasisContainer(gens)), 360 IhaveGBasisValue(false) 361 { 362 // IhaveMonomialGens3Value = uncertain3; // default for bool3 363 // IhaveSqFreeMonomial3Gens = uncertain3; // default for bool3 364 if (!IsField(CoeffRing(P))) 365 CoCoA_ERROR("ERR:NYI ideal of polynomials with coeffs not in a field", "ideal(SparsePolyRing, gens)");//??? 366 } 367 368 myClone()369 IdealBase* SparsePolyRingBase::IdealImpl::myClone() const 370 { 371 return new IdealImpl(*this); 372 } 373 374 myRing()375 const SparsePolyRing& SparsePolyRingBase::IdealImpl::myRing() const 376 { 377 return myP; 378 } 379 380 IamZero()381 bool SparsePolyRingBase::IdealImpl::IamZero() const 382 { 383 for (long i=0; i<len(myGens()); ++i) 384 if (!IsZero(myGens()[i])) return false; 385 return true; 386 } 387 388 389 390 namespace // anonymous -------------------------------- 391 { AreLPPSqFree(const std::vector<RingElem> & v)392 bool AreLPPSqFree(const std::vector<RingElem>& v) 393 { 394 const long n = len(v); 395 for (long i=0; i < n; ++i) 396 if (!IsSqFree(LPP(v[i]))) return false; 397 return true; 398 // We *DO NOT USE* STL algorithm because std::ptr_fun does not work if the fn has formal params which are of reference type 399 // return find_if(v.begin(), v.end(), 400 // not1(ptr_fun(CoCoA::IsSqFreeLPP))) 401 // // not1(ptr_fun(static_cast<bool(*)(ConstRefRingElem)>(CoCoA::IsRadLPP)))) 402 // == v.end(); 403 } 404 405 } // anonymous end ---------------------------------- 406 407 IhaveGBasis()408 bool SparsePolyRingBase::IdealImpl::IhaveGBasis() const 409 { return IhaveGBasisValue; } 410 411 IhaveMonomialGens()412 bool SparsePolyRingBase::IdealImpl::IhaveMonomialGens() const 413 { 414 if (IsUncertain3(IhaveMonomialGens3Value)) 415 IhaveMonomialGens3Value = AreMonomials(myGensValue); 416 return IsTrue3(IhaveMonomialGens3Value); 417 } 418 419 IhaveSqFreeMonomialGens()420 bool SparsePolyRingBase::IdealImpl::IhaveSqFreeMonomialGens() const 421 { 422 if (IsUncertain3(IhaveSqFreeMonomialGens3Value)) 423 { 424 if (!IhaveMonomialGens()) IhaveSqFreeMonomialGens3Value = false3; 425 else IhaveSqFreeMonomialGens3Value = AreLPPSqFree(myGensValue); 426 } 427 return IsTrue3(IhaveSqFreeMonomialGens3Value); 428 } 429 430 mySetGBasisAsGens()431 void SparsePolyRingBase::IdealImpl::mySetGBasisAsGens() const 432 { 433 myGBasisValue = myGensValue; 434 IhaveGBasisValue = true; 435 } 436 437 myReset()438 void SparsePolyRingBase::IdealImpl::myReset() const 439 { 440 IamMaximal3Flag = uncertain3; 441 IamPrimary3Flag = uncertain3; 442 IamPrime3Flag = uncertain3; 443 IamRadical3Flag = uncertain3; 444 IhaveSqFreeMonomialGens3Value = uncertain3; 445 IhaveMonomialGens3Value = uncertain3; 446 IhaveGBasisValue = false; 447 myGBasisValue.clear(); 448 myMinGensValue.clear(); 449 } 450 451 myTestIsMaximal()452 void SparsePolyRingBase::IdealImpl::myTestIsMaximal() const 453 { 454 if (IamZero()) { myAssignMaximalFlag(false); return; }// <0> in K[X] 455 if (!IsField(CoeffRing(myP))) 456 CoCoA_ERROR(ERR::ExpectedCoeffsInField, "myTestIsMaximal()");//??? 457 if (NumIndets(myP) == 1) // univariate poly ring 458 { myAssignMaximalFlag(IsIrred(myGBasis(NoCpuTimeLimit())[0])); return; } 459 if (IamZeroDim()) 460 myTestIsMaximal_0dim(); // assigns flags 461 else 462 myAssignMaximalFlag(false); 463 } 464 465 myTestIsPrimary()466 void SparsePolyRingBase::IdealImpl::myTestIsPrimary() const 467 { 468 // std::cout << "gens" << myGensValue << std::endl; 469 if (!IsField(CoeffRing(myP))) 470 CoCoA_ERROR(ERR::ExpectedCoeffsInField, "myTestIsPrimary()");//??? 471 if (NumIndets(myP) == 1) // univariate poly ring 472 { 473 const factorization<RingElem> F = factor(myGBasis(NoCpuTimeLimit())[0]); // PID 474 myAssignPrimaryFlag(len(F.myFactors()) == 1); 475 if (IamPrimary()) 476 myAssignMaximalFlag(F.myMultiplicities()[0] == 1); // since we have the info 477 return; 478 } 479 if (!IamZeroDim()) 480 CoCoA_ERROR("Not Yet Implemented for general ideals", "myTestIsPrimary"); 481 myTestIsPrimary_0dim(); 482 } 483 484 myTestIsPrime()485 void SparsePolyRingBase::IdealImpl::myTestIsPrime() const 486 { 487 if (NumIndets(myP) == 1 && IsField(CoeffRing(myP))) 488 { myTestIsMaximal(); return; } 489 CoCoA_ERROR(ERR::NYI, "SparsePolyRingBase::IdealImpl::myTestIsPrime()");//??? 490 } 491 492 myTestIsRadical()493 void SparsePolyRingBase::IdealImpl::myTestIsRadical() const 494 { 495 if (!IsField(CoeffRing(myP))) 496 CoCoA_ERROR(ERR::ExpectedCoeffsInField, "myTestIsRadical()");//??? 497 if (IhaveMonomialGens()) { myTestIsRadical_MonId(); return; } 498 if (NumIndets(myP) == 1) // univariate poly ring 499 { 500 const factorization<RingElem> F = factor(myGBasis(NoCpuTimeLimit())[0]); // PID 501 if (len(F.myFactors()) != 1) myAssignPrimeFlag(false); 502 if (F.myMultiplicities()[0] == 1) myAssignMaximalFlag(true); 503 return; 504 } 505 if (!IamZeroDim()) 506 CoCoA_ERROR("Not Yet Implemented for general ideals", "myTestIsRadical"); 507 myTestIsRadical_0dim(); 508 } 509 510 myReduceMod(RingElemRawPtr rawf)511 void SparsePolyRingBase::IdealImpl::myReduceMod(RingElemRawPtr rawf) const 512 { 513 //??? very basic default implementation 514 RingElem tmp = NR(RingElemAlias(myP, rawf), myGBasis(NoCpuTimeLimit())); 515 myP->mySwap(rawf, raw(tmp)); 516 } 517 518 IhaveElem(RingElemConstRawPtr rawf)519 bool SparsePolyRingBase::IdealImpl::IhaveElem(RingElemConstRawPtr rawf) const 520 { 521 RingElem g = RingElemAlias(myP, rawf); 522 myReduceMod(raw(g)); 523 return IsZero(g); 524 } 525 526 IamZeroDim()527 bool SparsePolyRingBase::IdealImpl::IamZeroDim() const 528 { 529 const vector<RingElem>& GB = myTidyGens(NoCpuTimeLimit()); 530 const long GBlen = len(GB); 531 const int nvars = NumIndets(myRing()); 532 vector<bool> AlreadySeen(nvars); 533 int NumIndetPowers = 0; 534 long index; BigInt IgnoreExp; // for rtn vals from IsIndetPosPower 535 for (long i=0; i < GBlen; ++i) 536 { 537 if (IsIndetPosPower(index, IgnoreExp, LPP(GB[i])) && !AlreadySeen[index]) 538 { 539 AlreadySeen[index] = true; 540 if (++NumIndetPowers == nvars) return true; 541 } 542 } 543 return false; 544 } 545 546 ourGetPtr(const ideal & I)547 const SparsePolyRingBase::IdealImpl* SparsePolyRingBase::IdealImpl::ourGetPtr(const ideal& I) 548 { 549 return dynamic_cast<const SparsePolyRingBase::IdealImpl*>(I.myIdealPtr()); 550 } 551 552 myAdd(const ideal & Jin)553 void SparsePolyRingBase::IdealImpl::myAdd(const ideal& Jin) 554 { 555 const IdealImpl* const J = ourGetPtr(Jin); 556 if (IsZero(Jin)) return; 557 myGensValue.insert(myGensValue.end(), gens(Jin).begin(), gens(Jin).end()); 558 bool3 IhaveMG_old = IhaveMonomialGens3Value; 559 bool3 IhaveSFMG_old = IhaveSqFreeMonomialGens3Value; 560 myReset(); 561 // we can recover some info about monomial gens: 562 IhaveMonomialGens3Value = IhaveMG_old; 563 IhaveSqFreeMonomialGens3Value = IhaveSFMG_old; 564 if (IsTrue3(IhaveMonomialGens3Value)) 565 IhaveMonomialGens3Value = J->IhaveMonomialGens3Value; 566 if (IsTrue3(IhaveSqFreeMonomialGens3Value)) 567 IhaveSqFreeMonomialGens3Value = J->IhaveSqFreeMonomialGens3Value; 568 } 569 570 myMul(const ideal & Jin)571 void SparsePolyRingBase::IdealImpl::myMul(const ideal& Jin) 572 { 573 if (IhaveMonomialGens() && AreGensMonomial(Jin)) 574 { 575 myMul_MonId(Jin); 576 return; 577 } 578 vector<RingElem> tmpV; 579 const SparsePolyRingBase::IdealImpl* const J = ourGetPtr(Jin); 580 for (const auto& gI: myGensValue) 581 for (const auto& gJ: J->myGensValue) tmpV.push_back(gI*gJ); 582 swap(tmpV, myGensValue); // ANNA does this make copies??? 2010-02-03 583 myReset(); // can we recover some info? 584 } 585 586 myIntersect(const ideal & J)587 void SparsePolyRingBase::IdealImpl::myIntersect(const ideal& J) 588 { 589 if (IamZero()) return; 590 CoCoA_ASSERT(!IsZero(J)); 591 if (IhaveMonomialGens() && AreGensMonomial(J)) 592 { 593 myIntersect_MonId(J); 594 return; 595 } 596 ComputeIntersection(myGensValue, myGensValue, gens(J)); 597 myReset(); // can we recover some info? 598 } 599 600 myColon(const ideal & J)601 void SparsePolyRingBase::IdealImpl::myColon(const ideal& J) 602 { 603 if (IsZero(J)) 604 myGensValue = vector<RingElem>(1, one(myRing())); 605 else 606 { 607 if (IhaveMonomialGens() && AreGensMonomial(J)) 608 { 609 myColon_MonId(J); 610 return; 611 } 612 const RingElem Z(zero(myRing())); 613 myGensValue.erase(remove(myGensValue.begin(), myGensValue.end(),Z), 614 myGensValue.end()); 615 ComputeColon(myGensValue, myGensValue, gens(J)); 616 } 617 myReset(); // can we recover some info? 618 } 619 620 mySaturate(const ideal & J)621 void SparsePolyRingBase::IdealImpl::mySaturate(const ideal& J) 622 { 623 ComputeSaturation(myGensValue, myGensValue, gens(J)); 624 myReset(); 625 } 626 627 myMinimalize()628 void SparsePolyRingBase::IdealImpl::myMinimalize() 629 { 630 if (GradingDim(myRing())==0 || !IsHomog(myGensValue)) 631 CoCoA_ERROR("Input is not homogeneous", "myMinimalize"); 632 myGBasis(NoCpuTimeLimit()); // this sets GBasis and MinGens 633 myGensValue = myMinGens(); // if monomial ideal min gens are in GBasis 634 if (IsFalse3(IhaveMonomialGens3Value)) 635 IhaveMonomialGens3Value = uncertain3; 636 if (IsFalse3(IhaveSqFreeMonomialGens3Value)) 637 IhaveSqFreeMonomialGens3Value = uncertain3; 638 } 639 640 myElim(const std::vector<RingElem> & ElimIndets)641 void SparsePolyRingBase::IdealImpl::myElim(const std::vector<RingElem>& ElimIndets) 642 { 643 // if (IhaveGBasisValue) and elim ordering ... 644 if (IhaveMonomialGens()) 645 { 646 myElim_MonId(ElimIndets); 647 return; 648 } 649 const RingElem Z(zero(myRing())); 650 myGensValue.erase(remove(myGensValue.begin(), myGensValue.end(),Z), 651 myGensValue.end()); 652 PPMonoidElem ElimIndetsProd(myRing()->myPPM()); 653 const long n = len(ElimIndets); 654 for (long i=0 ; i<n ; ++i) 655 { 656 if (!IsIndet(ElimIndets[i])) 657 CoCoA_ERROR(ERR::NotIndet, "myElim"); 658 ElimIndetsProd *= LPP(ElimIndets[i]); 659 } 660 ComputeElim(myGensValue, myGensValue, ElimIndetsProd); 661 myReset(); // can we recover some info? 662 } 663 664 665 namespace { // anonymous ------------------------------ CoeffOfTermSparse(ConstRefRingElem f,ConstRefPPMonoidElem pp)666 RingElem CoeffOfTermSparse(ConstRefRingElem f, ConstRefPPMonoidElem pp) 667 { 668 for (SparsePolyIter itf=BeginIter(f); !IsEnded(itf); ++itf) 669 if (PP(itf) == pp) return coeff(itf); 670 return zero(CoeffRing(owner(f))); 671 } 672 MultiplicationMat(ConstRefRingElem f,const ideal & I)673 matrix MultiplicationMat(ConstRefRingElem f, const ideal& I) 674 { 675 std::vector<PPMonoidElem> QB = QuotientBasis(I); 676 SparsePolyRing P = owner(f); 677 matrix Mf = NewDenseMat(CoeffRing(P), len(QB), len(QB)); 678 for (long j=0; j<len(QB); ++j) 679 { 680 RingElem tmpf = f; 681 P->myMulByPP(raw(tmpf), raw(QB[j])); 682 tmpf = NF(tmpf, I); 683 for (long i=0; i<len(QB); ++i) 684 SetEntry(Mf,i,j, CoeffOfTermSparse(tmpf,QB[i])); 685 } 686 return Mf; 687 } 688 689 } // anonymous end ------------------------------------------- 690 691 myDivMod(RingElemRawPtr rawlhs,RingElemConstRawPtr rawnum,RingElemConstRawPtr rawden)692 bool SparsePolyRingBase::IdealImpl::myDivMod(RingElemRawPtr rawlhs, RingElemConstRawPtr rawnum, RingElemConstRawPtr rawden) const 693 { 694 // check for IsZeroDivisor(den) is done by operator/ 695 const SparsePolyRing P = myRing(); 696 // if (IsField(CoeffRing(P)) && P->myIsConstant(rawden)) 697 if (P->myIsConstant(rawden)) 698 { 699 RingElem GDivF = RingElemAlias(P, rawnum); 700 P->myDivByCoeff(raw(GDivF), raw(P->myLC(rawden))); // exc safe? 701 P->mySwap(rawlhs, raw(GDivF)); 702 return true; 703 } 704 if (IamZeroDim()) 705 { 706 ideal I = ideal(const_cast<IdealImpl*>(this)); // Tappullus Horribilis 707 std::vector<PPMonoidElem> QB = QuotientBasis(I); 708 long LenQB = len(QB); 709 RingElem G = RingElemAlias(P,rawnum); 710 RingElem F = RingElemAlias(P,rawden); 711 matrix coeffsG = NewDenseMat(ZeroMat(CoeffRing(P), len(QB), 1)); 712 for (long i=0; i<LenQB; ++i) 713 SetEntry(coeffsG,i,0, CoeffOfTermSparse(G, QB[i])); 714 matrix coeffsGDivF = LinSolve(MultiplicationMat(F,I), coeffsG); 715 RingElem GDivF(P); 716 for (long i=0; i<LenQB; ++i) 717 GDivF += monomial(P, coeffsGDivF(i,0), QB[i]); 718 P->mySwap(rawlhs, raw(GDivF)); 719 return true; 720 } 721 722 // The following should be a general solution... 723 /// auto tmp = GenRepr(rawnum, ideal(rawden)+this); 724 /// return tmp[0]; 725 726 CoCoA_ERROR(ERR::NYI, "SparsePolyRingBase::IdealImpl::myDivMod"); 727 return false; // just to keep the compiler quiet!! 728 } 729 730 731 732 myGBasis(const CpuTimeLimit & CheckForTimeOut)733 const std::vector<RingElem>& SparsePolyRingBase::IdealImpl::myGBasis(const CpuTimeLimit& CheckForTimeOut) const 734 { 735 if (IhaveGBasis()) return myGBasisValue; 736 if (IhaveMonomialGens()) return myGBasis_MonId(); 737 //CoCoA_ASSERT(myGBasisValue.empty()); // false for MinGens of points 738 if (IamZero()) 739 { 740 CoCoA_ASSERT(myGBasisValue.empty()); 741 CoCoA_ASSERT(myMinGensValue.empty()); 742 } 743 else 744 { 745 if (len(myGensValue)==1) 746 { 747 myMinGensValue = myGensValue; 748 CoCoA_ASSERT(myGBasisValue.empty()); 749 myGBasisValue.push_back(monic(myGensValue[0])); 750 } 751 else 752 { 753 vector<RingElem> MinGens; 754 ComputeGBasis(myGBasisValue, MinGens, myGensValue, CheckForTimeOut); 755 if (!MinGens.empty()) // MinGens is non-empty only if ideal is homog 756 myMinGensValue = MinGens; 757 } 758 } 759 IhaveGBasisValue = true; 760 return myGBasisValue; 761 } 762 763 764 namespace { // anonymous 765 NewPolyRingForHomog(SparsePolyRing P)766 SparsePolyRing NewPolyRingForHomog(SparsePolyRing P) 767 { 768 long n = NumIndets(P); 769 if (IsStdDegRevLex(ordering(PPM(P)))) 770 return NewPolyRing(CoeffRing(P), NewSymbols(n+1)); 771 if (IsLex(ordering(PPM(P)))) 772 return NewPolyRing(CoeffRing(P), NewSymbols(n+1), StdDegLex); 773 if (IsStdDegLex(ordering(PPM(P)))) 774 { 775 RingElem I = one(RingZZ()); 776 RingElem Z = zero(RingZZ()); 777 PPOrdering O = 778 NewMatrixOrdering(MakeTermOrd(BlockMat2x2( 779 RowMat(vector<RingElem>(n,I)), 780 RowMat(vector<RingElem>(1,I)), 781 StdDegLexMat(n), 782 ColMat(vector<RingElem>(n,Z)))), 783 1); 784 return NewPolyRing(CoeffRing(P), NewSymbols(n+1), O); 785 } 786 787 // per DegLex bisogna anche ritornare la h (messa al posto opportuno) e gli omomorfismi 788 // if (IsStdDegLex(ordering(PPM(P)))) /// NONONO: h must be first. 789 // return NewPolyRing(CoeffRing(P), NewSymbols(n+1), StdDegLex); 790 CoCoA_ERROR(ERR::NYI, "GBasisByHomog: only for DegRevLex, lex"); 791 return P; // senseless, JUST TO KEEP COMPILER QUIET 792 } 793 794 } 795 796 797 namespace { // anonymous 798 LPPLessThan(const RingElem & f,const RingElem & g)799 bool LPPLessThan(const RingElem& f, const RingElem& g) 800 { return LPP(f) < LPP(g); } 801 802 } // anonymous namespace 803 myGBasisByHomog(const CpuTimeLimit & CheckForTimeOut)804 const std::vector<RingElem>& SparsePolyRingBase::IdealImpl::myGBasisByHomog(const CpuTimeLimit& CheckForTimeOut) const 805 { 806 if (IhaveMonomialGens()) return myGBasis_MonId(); 807 if (IhaveGBasis()) return myGBasisValue; 808 CoCoA_ASSERT(myGBasisValue.empty()); 809 if (IamZero()) return myGBasisValue; 810 // check GradingDim 811 // make correct ordering 812 const SparsePolyRing& P = myRing(); 813 SparsePolyRing Ph = NewPolyRingForHomog(P); 814 const long n = NumIndets(P); 815 const RingElem& h = indet(Ph, n); 816 const std::vector<RingElem>& X = indets(Ph); 817 const RingHom phi =PolyAlgebraHom(P,Ph,vector<RingElem>(X.begin(),X.begin()+n)); 818 std::vector<RingElem> v = indets(P); v.push_back(one(P)); 819 const RingHom dehom = PolyAlgebraHom(Ph,P,v); 820 const std::vector<RingElem>& g = myGens(); 821 std::vector<RingElem> gh; // use transform here??? 822 for (long i=0; i<len(g); ++i) gh.push_back(homog(phi(g[i]), h)); 823 std::vector<RingElem> GB = apply(dehom, GBasis(ideal(gh),CheckForTimeOut)); 824 gh.clear(); 825 // interreduce GB 826 std::vector<RingElem> GBaux; 827 sort(GB.begin(), GB.end(), LPPLessThan); 828 // PPVector LT_GB(PPM(P), NewDivMaskEvenPowers()); 829 PPWithMask LT_GBi(one(PPM(P)), NewDivMaskEvenPowers()); 830 PPVector LT_GB_min(PPM(P), NewDivMaskEvenPowers()); 831 for (long i=0; i<len(GB); ++i) 832 { 833 // PushBack(LT_GB, LPP(GB[i])); 834 LT_GBi = LPP(GB[i]); 835 if (!IsDivisible(LT_GBi, LT_GB_min)) 836 { 837 PushBack(LT_GB_min, LT_GBi); 838 GBaux.push_back(monic(NR(GB[i], GBaux))); 839 } 840 } 841 swap(myGBasisValue, GBaux); 842 IhaveGBasisValue = true; 843 return myGBasisValue; 844 } 845 846 myGBasisSelfSatCore()847 std::vector<RingElem> SparsePolyRingBase::IdealImpl::myGBasisSelfSatCore() const 848 { 849 if (IhaveMonomialGens()) return myGBasis_MonId(); 850 if (IhaveGBasis()) return myGBasisValue; 851 CoCoA_ASSERT(myGBasisValue.empty()); 852 if (IamZero()) return myGBasisValue; 853 vector<RingElem> GBSelfSat; 854 ComputeGBasisSelfSatCore(GBSelfSat, myGensValue); 855 return GBSelfSat; 856 } 857 858 myGBasisRealSolve()859 std::vector<RingElem> SparsePolyRingBase::IdealImpl::myGBasisRealSolve() const 860 { 861 if (IamZero()) return myGBasisValue; 862 vector<RingElem> GBRealSolve; 863 ComputeGBasisRealSolve(GBRealSolve, myGensValue); 864 return GBRealSolve; 865 } 866 867 myMinGens()868 const std::vector<RingElem>& SparsePolyRingBase::IdealImpl::myMinGens() const 869 { 870 if (!myMinGensValue.empty()) return myMinGensValue; 871 if (IhaveMonomialGens()) return myGBasis_MonId(); // interreduced 872 if (GradingDim(myRing())==0 || !IsHomog(myGensValue)) 873 CoCoA_ERROR("Input is not homogeneous", "myMinGens"); 874 IhaveGBasisValue = false; // force Buchberger algorithm for getting MinGens 875 myGBasis(NoCpuTimeLimit()); 876 return myMinGensValue; 877 } 878 879 IsZeroDim(const ideal & I)880 bool IsZeroDim(const ideal& I) 881 { 882 if (!IsSparsePolyRing(RingOf(I))) 883 CoCoA_ERROR(ERR::NotSparsePolyRing, "IsZeroDim(I)"); 884 if (IsZero(I) || IsOne(I)) return false; 885 // Now we know I is non-trivial. 886 // const SparsePolyRing P = RingOf(I); 887 // const vector<RingElem>& GB = TidyGens(I); 888 // const long GBlen = len(GB); // MUST BE A REDUCED GBASIS !!! 889 // long NumIndetPowers = 0; 890 // for (long i=0; i < GBlen; ++i) 891 // if (IsIndetPosPower(LPP(GB[i]))) 892 // ++NumIndetPowers; 893 // return (NumIndetPowers == NumIndets(P)); 894 return SparsePolyRingBase::IdealImpl::ourGetPtr(I)->IamZeroDim(); 895 } 896 897 IsHomog(const ideal & I)898 bool IsHomog(const ideal& I) 899 { 900 if (!IsSparsePolyRing(RingOf(I))) 901 CoCoA_ERROR(ERR::NotSparsePolyRing, "IsHomog(ideal)"); 902 if (GradingDim(RingOf(I))==0) 903 CoCoA_ERROR(ERR::ZeroGradingDim, "IsHomog(ideal)"); 904 if (IsZero(I) || IsOne(I)) return true; 905 // Now we know I is non-trivial. 906 const SparsePolyRing P = RingOf(I); 907 const vector<RingElem>& GB = TidyGens(I); 908 const long GBlen = len(GB); // MUST BE A REDUCED GBASIS !!! 909 for (long i=0; i < GBlen; ++i) 910 if (!IsHomog(GB[i])) return false; 911 return true; 912 } 913 914 DenSigma(const ideal & I)915 RingElem DenSigma(const ideal& I) 916 { 917 if (!IsSparsePolyRing(RingOf(I))) 918 CoCoA_ERROR(ERR::NotSparsePolyRing, "DenSigma(I)"); 919 if (!IsFractionField(CoeffRing(RingOf(I)))) 920 CoCoA_ERROR("Coeff ring must be a fraction field of a GCDDomain", "DenSigma(I)"); 921 return CommonDenom(ReducedGBasis(I)); 922 } 923 924 // template??? IsSigmaGoodPrime(const BigInt & p,const ideal & I)925 bool IsSigmaGoodPrime(const BigInt& p, const ideal& I) 926 { 927 if (!IsSparsePolyRing(RingOf(I))) 928 CoCoA_ERROR(ERR::NotSparsePolyRing, "IsSigmaGoodPrime(p,I)"); 929 if (!IsQQ(CoeffRing(RingOf(I)))) 930 CoCoA_ERROR("Coeff ring must be RingQQ", "IsSigmaGoodPrime(p,I)"); 931 if (!IsPrime(p)) 932 CoCoA_ERROR("First argument must be a prime number", "IsSigmaGoodPrime(p,I)"); 933 return !IsDivisible(CommonDenom(ReducedGBasis(I)), p); 934 } 935 936 // template??? IsSigmaGoodPrime(const long p,const ideal & I)937 bool IsSigmaGoodPrime(const long p, const ideal& I) 938 { 939 if (!IsSparsePolyRing(RingOf(I))) 940 CoCoA_ERROR(ERR::NotSparsePolyRing, "IsSigmaGoodPrime(p,I)"); 941 if (!IsQQ(CoeffRing(RingOf(I)))) 942 CoCoA_ERROR("Coeff ring must be RingQQ", "IsSigmaGoodPrime(p,I)"); 943 if (!IsPrime(p)) 944 CoCoA_ERROR("First argument must be a prime number", "IsSigmaGoodPrime(p,I)"); 945 return !IsDivisible(CommonDenom(ReducedGBasis(I)), p); 946 } 947 948 949 // namespace { // anonymous radical_0dimDRL(const ideal & I)950 ideal radical_0dimDRL(const ideal& I) 951 { 952 const SparsePolyRingBase::IdealImpl* const ptrI = 953 SparsePolyRingBase::IdealImpl::ourGetPtr(I); 954 return ptrI->myRadical_0dimDRL(); // behaves differently from other memb fns 955 } 956 // } 957 958 959 //namespace { // anonymous ??? vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv radical_0dim(const ideal & I)960 ideal radical_0dim(const ideal& I) 961 { 962 PolyRing P = RingOf(I); 963 // if (HasStdDegRevLex(P)) return radical_0dimDRL(I); 964 if (HasGBasis(I)) return radical_0dimDRL(I); 965 PolyRing P_drl = NewPolyRing(CoeffRing(P), NewSymbols(NumIndets(P))); 966 RingHom phi = PolyAlgebraHom(P, P_drl, indets(P_drl)); 967 RingHom psi = PolyAlgebraHom(P_drl, P, indets(P)); 968 ideal RadI = radical_0dimDRL(ideal(apply(phi, gens(I)))); 969 return ideal(apply(psi, gens(RadI))); 970 } // radical_0dim(I) 971 972 radical_MonId(const ideal & I)973 ideal radical_MonId(const ideal& I) 974 { 975 VerboseLog VERBOSE("radical_MonId"); 976 VERBOSE(1000) << " starting " << std::endl; 977 const SparsePolyRingBase::IdealImpl* const ptrI = 978 SparsePolyRingBase::IdealImpl::ourGetPtr(I); 979 return ptrI->myRadical_MonId(); // behaves differently from other memb fns 980 } 981 982 //} // ^^^^^ anonymous namespace ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 983 984 985 // will be radical(I) radical_tmp(const ideal & I)986 ideal radical_tmp(const ideal& I) 987 { 988 VerboseLog VERBOSE("radical_tmp"); 989 VERBOSE(1000) << " starting " << std::endl; 990 if (IsTrue3(IsRadical3(I))) return I; 991 if (AreGensMonomial(I)) return radical_MonId(I); // monomial ideal 992 if (IsZeroDim(I)) return radical_0dim(I); // 0-dim ideal 993 CoCoA_ERROR(ERR::NYI, "radical_tmp for general poly ideals"); 994 return I; // just to keep compiler quiet 995 } // radical_0dim(I) 996 997 998 999 } // end of namespace CoCoA 1000 1001 // RCS header/log in the next few lines 1002 // $Header: /Volumes/Home_1/cocoa/cvs-repository/CoCoALib-0.99/src/AlgebraicCore/SparsePolyOps-ideal.C,v 1.44 2020/03/06 18:40:07 abbott Exp $ 1003 // $Log: SparsePolyOps-ideal.C,v $ 1004 // Revision 1.44 2020/03/06 18:40:07 abbott 1005 // Summary: Added some const 1006 // 1007 // Revision 1.43 2020/03/06 16:38:48 bigatti 1008 // -- added GBasisByHomog with DegLex 1009 // 1010 // Revision 1.42 2020/02/26 15:29:15 bigatti 1011 // -- commented out ASSERT for GBasis (called by MinGens redmine#1420) 1012 // 1013 // Revision 1.41 2020/02/14 09:01:10 bigatti 1014 // -- removed typo 1015 // 1016 // Revision 1.40 2020/02/14 08:58:52 bigatti 1017 // -- mingens: for gbasis computation with Buchberger, 1018 // if myMinGensValue not set (IdealOfProjectivePoints) 1019 // 1020 // Revision 1.39 2020/02/13 14:01:23 bigatti 1021 // -- now using auto in for loops 1022 // 1023 // Revision 1.38 2020/02/12 10:27:38 bigatti 1024 // -- improved myAssignBLAHFlag 1025 // 1026 // Revision 1.37 2020/02/12 09:42:17 abbott 1027 // Summary: Corrected defn of myTestIsPrimary 1028 // 1029 // Revision 1.36 2020/02/12 09:01:47 bigatti 1030 // -- changed myTestIsMaximal etc to return void (and consequences) 1031 // 1032 // Revision 1.35 2020/01/26 14:37:24 abbott 1033 // Summary: Removed useless include (of NumTheory) 1034 // 1035 // Revision 1.34 2020/01/13 17:42:38 bigatti 1036 // -- minor change in GBasisByHomog 1037 // 1038 // Revision 1.33 2019/12/28 17:54:50 abbott 1039 // Summary: New defn of IamZeroDim now works with any GB (previous reqd minGB) 1040 // 1041 // Revision 1.32 2019/12/27 17:42:31 bigatti 1042 // -- fixed interreduction in GBasisByHomog 1043 // -- IsZeroDim --> IamZeroDim in member functions 1044 // 1045 // Revision 1.31 2019/10/21 16:40:46 bigatti 1046 // -- added VERBOSE(1000) for some functions (to see if they are called) 1047 // 1048 // Revision 1.30 2019/10/15 12:57:55 bigatti 1049 // -- renamed files for ideals 1050 // 1051 // Revision 1.29 2019/10/03 14:54:37 bigatti 1052 // -- added radical_MonId 1053 // 1054 // Revision 1.28 2019/10/02 10:40:47 bigatti 1055 // -- minor change in view of adding optimized radical for MonomialIdeals 1056 // 1057 // Revision 1.27 2019/09/27 14:56:55 abbott 1058 // Summary: Fixed redmine 1322; some cleaning 1059 // 1060 // Revision 1.26 2019/09/27 14:44:06 abbott 1061 // Summary: Corrected use of empty inside CoCoA_ASSERT 1062 // 1063 // Revision 1.25 2019/09/25 16:04:19 bigatti 1064 // -- gbasis for principal ideals now just computes monic(f) 1065 // -- added radical_tmp, checking the implemented cases (will become radical) 1066 // 1067 // Revision 1.24 2019/03/04 11:14:04 abbott 1068 // Summary: Added "just to keep compiler quiet" 1069 // 1070 // Revision 1.23 2018/12/17 15:21:41 bigatti 1071 // -- timeout in GBasisByHomog 1072 // 1073 // Revision 1.22 2018/09/28 15:54:04 abbott 1074 // Summary: Removed pseudo-ctors NewPolyRing which took just num of indets; now must specify their names 1075 // 1076 // Revision 1.21 2018/08/06 09:38:29 bigatti 1077 // -- renamed GBasisViaHomog --> GBasisByHomog 1078 // 1079 // Revision 1.20 2018/08/06 08:57:48 bigatti 1080 // -- added timeout for GBasisByHomog 1081 // -- now using GBasisByHomog in IsPrimary and radical 1082 // 1083 // Revision 1.19 2018/08/05 16:31:25 bigatti 1084 // -- added GBasisByHomog 1085 // 1086 // Revision 1.18 2018/06/27 12:15:19 abbott 1087 // Summary: Renamed RealSolveCore to RealSolve 1088 // 1089 // Revision 1.17 2018/06/27 08:50:39 abbott 1090 // Summary: Revised to work with new CpuTimeLimit 1091 // 1092 // Revision 1.16 2018/05/25 09:24:46 abbott 1093 // Summary: Major redesign of CpuTimeLimit (many consequences) 1094 // 1095 // Revision 1.15 2018/05/18 12:23:50 bigatti 1096 // -- renamed IntOperations --> BigIntOps 1097 // 1098 // Revision 1.14 2018/05/17 15:49:00 bigatti 1099 // -- sorted #includes 1100 // -- renamed MatrixOperations --> MatrixOps 1101 // 1102 // Revision 1.13 2018/04/18 15:39:34 abbott 1103 // Summary: Added missing return in NYI fn. 1104 // 1105 // Revision 1.12 2018/04/16 21:49:26 bigatti 1106 // -- added IamZeroDim 1107 // -- added myPrimaryDecomposition_0dim 1108 // 1109 // Revision 1.11 2018/04/10 14:59:32 bigatti 1110 // -- now member function for PrimaryDecomposition 1111 // 1112 // Revision 1.10 2018/04/10 14:51:43 bigatti 1113 // -- added virtual myPrimaryDecomposition (with default implementation) 1114 // 1115 // Revision 1.9 2018/04/10 14:20:47 bigatti 1116 // -- fixed includes 1117 // 1118 // Revision 1.8 2018/04/09 16:25:53 bigatti 1119 // -- functions for zer-dim ideals moved into SparsePolyOps-IdealZeroDim 1120 // 1121 // Revision 1.7 2018/04/06 17:28:22 bigatti 1122 // -- fixed includes 1123 // 1124 // Revision 1.6 2018/04/04 12:36:51 bigatti 1125 // -- radical: returning I itself, in IsRadical3 = true 1126 // 1127 // Revision 1.5 2018/03/29 13:09:04 bigatti 1128 // -- improved isprimary (with gbasis timeout) 1129 // 1130 // Revision 1.4 2018/03/29 09:36:40 bigatti 1131 // -- added member functions myTestIsRadical, myTestIsPrimary and flags 1132 // 1133 // Revision 1.3 2018/03/20 11:48:12 bigatti 1134 // -- new code for 0dim ideals (radical, primary...) 1135 // 1136 // Revision 1.2 2018/03/15 14:18:06 bigatti 1137 // -- added files SparsePolyOps-ideal.H and SparsePolyOps-involutive.H 1138 // 1139 // Revision 1.1 2018/03/12 14:38:41 bigatti 1140 // -- renamed SparsePoly-ideal/involutive into SparsePolyOps-ideal/involutive 1141 // 1142 // Revision 1.3 2018/03/09 14:54:01 bigatti 1143 // -- removed useless includes 1144 // 1145 // Revision 1.2 2018/02/27 17:26:07 bigatti 1146 // -- split off involutive part 1147 // 1148 // Revision 1.1 2018/02/27 17:12:37 bigatti 1149 // -- Renamed SparsePolyRing_ideal.C --> SparsePoly-ideal.C 1150 // 1151