1 // Copyright (c) 2018 John Abbott, Anna Bigatti 2 3 // This file is part of the source of CoCoALib, the CoCoA Library. 4 5 // CoCoALib is free software: you can redistribute it and/or modify 6 // it under the terms of the GNU General Public License as published by 7 // the Free Software Foundation, either version 3 of the License, or 8 // (at your option) any later version. 9 10 // CoCoALib is distributed in the hope that it will be useful, 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 // GNU General Public License for more details. 14 15 // You should have received a copy of the GNU General Public License 16 // along with CoCoALib. If not, see <http://www.gnu.org/licenses/>. 17 18 19 // Source code for RingWeylImpl 20 21 #include "CoCoA/DistrMPolyClean.H" 22 23 #include "CoCoA/BigIntOps.H" 24 #include "CoCoA/MatrixForOrdering.H" 25 #include "CoCoA/MatrixOps.H" 26 #include "CoCoA/OpenMath.H" 27 #include "CoCoA/PPMonoid.H" 28 #include "CoCoA/PPMonoidEv.H" 29 #include "CoCoA/PPOrdering.H" 30 #include "CoCoA/RingDistrMPolyClean.H" 31 #include "CoCoA/RingHom.H" 32 #include "CoCoA/RingWeyl.H" 33 #include "CoCoA/TmpGReductor.H" 34 #include "CoCoA/TmpUniversalInvolutiveBasisContainer.H" 35 #include "CoCoA/assert.H" 36 #include "CoCoA/convert.H" 37 #include "CoCoA/ideal.H" 38 #include "CoCoA/matrix.H" 39 #include "CoCoA/symbol.H" 40 #include "CoCoA/utils.H" 41 42 #include <memory> 43 using std::unique_ptr; 44 #include <iostream> 45 using std::ostream; 46 using std::endl; // just for debugging 47 //#include <vector> 48 using std::vector; 49 50 51 52 namespace CoCoA 53 { 54 55 class RingExtAlgImpl: public SparsePolyRingBase //???? should be NCRingBase non-commutative!!! 56 { 57 58 public: 59 // RingWeylImpl(const ring& CoeffRing, long NumIndets, const std::vector<long>& ElimIndets); 60 RingExtAlgImpl(const ring& CoeffRing, const std::vector<symbol>& names); 61 ~RingExtAlgImpl(); 62 63 private: // data members of RingWeyl 64 const SparsePolyRing myReprRing; 65 // long myNumTrueIndetsValue; 66 std::unique_ptr<RingElem> myZeroPtr; ///< Every ring stores its own zero. 67 std::unique_ptr<RingElem> myOnePtr; ///< Every ring stores its own one. 68 std::vector<RingElem> myIndetVector; 69 // std::vector<RingElem> myDerivationVector; 70 71 private: 72 int myCoeffProdPP(PPMonoidElemConstRawPtr rawpp1, PPMonoidElemConstRawPtr rawpp2) const; 73 74 public: 75 //---------------------------------------------------------------------- 76 // Functions which every ring must implement: 77 //---------------------------------------------------------------------- 78 virtual bool IamCommutative() const; 79 virtual bool3 IamIntegralDomain3(bool) const; 80 virtual bool IamTrueGCDDomain() const; 81 virtual ConstRefRingElem myZero() const; 82 virtual ConstRefRingElem myOne() const; 83 using RingBase::myNew; // disable warnings of overloading 84 using RingBase::myAssign; // disable warnings of overloading 85 using PolyRingBase::myIndets; // disable warnings of overloading 86 virtual RingElemRawPtr myNew() const; 87 virtual RingElemRawPtr myNew(const MachineInt& n) const; 88 virtual RingElemRawPtr myNew(const BigInt& N) const; 89 virtual RingElemRawPtr myNew(ConstRawPtr rawcopy) const; 90 virtual void myDelete(RawPtr rawx) const; // destroys x (incl all resources) 91 virtual void mySwap(RawPtr rawx, RawPtr rawy) const; // swap(x, y) 92 virtual void myAssign(RawPtr rawlhs, ConstRawPtr rawx) const; // lhs = x 93 virtual void myAssign(RawPtr rawlhs, const MachineInt& n) const; // lhs = n 94 virtual void myAssign(RawPtr rawlhs, const BigInt& N) const; // lhs = N 95 virtual void myAssignZero(RawPtr rawlhs) const; // lhs = 0 96 virtual void myRecvTwinFloat(RawPtr rawlhs, ConstRawPtr rawx) const; 97 virtual void myNegate(RawPtr rawlhs, ConstRawPtr rawx) const; // lhs = -x 98 virtual void myAdd(RawPtr rawlhs, ConstRawPtr rawx, ConstRawPtr rawy) const; // lhs = x+y 99 virtual void mySub(RawPtr rawlhs, ConstRawPtr rawx, ConstRawPtr rawy) const; // lhs = x-y 100 // virtual void myMul(RawPtr rawlhs, ConstRawPtr rawx, ConstRawPtr rawy) const; // lhs = x*y 101 // virtual void myDiv(RawPtr rawlhs, ConstRawPtr rawx, ConstRawPtr rawy) const; // lhs = x/y 102 virtual bool myIsDivisible(RawPtr rawlhs, ConstRawPtr rawx, ConstRawPtr rawy) const;// lhs = x/y, if divisible 103 virtual bool myIsInvertible(ConstRawPtr rawx) const; // true iff x is invertible 104 // virtual bool myIsPrintAtom(ConstRawPtr rawx) const; 105 virtual void myGcd(RawPtr rawlhs, ConstRawPtr rawx, ConstRawPtr rawy) const; // not a TrueGCDDomain 106 virtual void myPowerSmallExp(RawPtr rawlhs, ConstRawPtr rawx, long n) const;// lhs = x^n, n>1, x not -1,0,1 107 virtual void mySymbols(std::vector<symbol>& SymList) const; // appends ring's symbols to SymList 108 virtual void myOutput(std::ostream& out, ConstRawPtr rawx) const; // out << x 109 using PolyRingBase::myOutputSelf; // disable warnings of overloading 110 // virtual void myOutputSelf(OpenMathOutput& OMOut) const; // OMOut << R myImplDetails()111 virtual std::string myImplDetails() const {return "RingWeyl";} 112 virtual void myOutput(OpenMathOutput& OMOut, ConstRawPtr rawx) const; // OMOut << x 113 virtual bool myIsZero(ConstRawPtr rawx) const; // x == 0 114 virtual bool myIsOne(ConstRawPtr rawx) const; // x == 1 115 virtual bool myIsMinusOne(ConstRawPtr rawx) const; // x == -1 116 // virtual bool myIsZeroAddMul: use default definition 117 virtual bool myIsEqual(ConstRawPtr rawx, ConstRawPtr rawy) const; // x == y 118 119 virtual ideal myIdealCtor(const std::vector<RingElem>& gens) const; 120 121 virtual RingHom myCompose(const RingHom& phi, const RingHom& theta) const; // phi(theta(...)) 122 123 124 /*---------------------------------------------------------------------- 125 Member functions every PolyRing must have 126 in addition to those of RingBase. 127 ----------------------------------------------------------------------*/ 128 virtual long myNumIndets() const; 129 virtual const ring& myCoeffRing() const; 130 virtual const std::vector<RingElem>& myIndets() const; 131 virtual void myIndetPower(RawPtr rawf, long var, long exp) const; 132 133 ///@name Simple functions on polynomials 134 //@{ 135 virtual long myNumTerms(ConstRawPtr rawf) const; 136 virtual bool myIsConstant(ConstRawPtr rawf) const; 137 virtual bool myIsIndet(long& index, ConstRawPtr rawf) const; 138 virtual bool myIsMonomial(ConstRawPtr rawf) const; 139 virtual long myStdDeg(ConstRawPtr rawf) const; 140 virtual long myDeg(ConstRawPtr rawf, long var) const; 141 virtual RingElemAlias myLC(ConstRawPtr rawf) const; 142 virtual void myContent(RawPtr rawcontent, ConstRawPtr rawf) const; 143 virtual void myRemoveBigContent(RawPtr rawf) const; 144 virtual void myMulByCoeff(RawPtr rawf, ConstRawPtr rawc) const; ///< WEAK EXCEPTION GUARANTEE 145 virtual bool myDivByCoeff(RawPtr rawf, ConstRawPtr rawc) const; ///< WEAK EXCEPTION GUARANTEE 146 virtual void myDeriv(RawPtr rawlhs, ConstRawPtr rawf, ConstRawPtr rawx) const; ///< lhs = deriv(f, x) 147 //@} 148 149 // friend const RingElem& indet(const RingWeyl& RW, long var); 150 // friend const RingElem& derivation(const RingWeyl& RW, long var); 151 152 virtual RingHom myHomCtor(const ring& codomain, const RingHom& CoeffHom, const std::vector<RingElem>& IndetImages) const; 153 154 //---------------------------------------------------------------------- 155 // Functions which every SparsePolyRing must implement: 156 //---------------------------------------------------------------------- 157 158 virtual const PPMonoid& myPPM() const; 159 160 ///@name Functions for creating/building polynomials 161 //@{ 162 virtual RingElem myMonomial(ConstRawPtr rawc, PPMonoidElemConstRawPtr rawpp) const; 163 virtual SparsePolyIter myBeginIter(ConstRawPtr rawf) const; 164 virtual SparsePolyIter myEndIter(ConstRawPtr rawf) const; 165 166 virtual void myPushFront(RawPtr rawf, ConstRawPtr rawc, const std::vector<long>& expv) const; 167 virtual void myPushBack(RawPtr rawf, ConstRawPtr rawc, const std::vector<long>& expv) const; 168 virtual void myPushFront(RawPtr rawf, ConstRawPtr rawc, PPMonoidElemConstRawPtr rawpp) const; 169 virtual void myPushBack(RawPtr rawf, ConstRawPtr rawc, PPMonoidElemConstRawPtr rawpp) const; 170 //@} 171 172 ///@name Special functions on polynomials needed for implementing Buchberger's Algorithm 173 //@{ 174 // virtual void myWDeg(degree& d, ConstRawPtr rawf) const; 175 // virtual int myCmpWDeg(ConstRawPtr rawf, ConstRawPtr rawg) const; 176 virtual ConstRefPPMonoidElem myLPP(ConstRawPtr rawf) const; 177 virtual void myMulByPP(RawPtr rawf, PPMonoidElemConstRawPtr rawpp) const; 178 virtual bool myIsZeroAddLCs(RawPtr rawf, RawPtr rawg) const; ///< f+=LM(g); g-=LM(g); assumes LPP(f)==LPP(g); returns LC(f)+LC(g)==0 179 virtual void myMoveLMToFront(RawPtr rawf, RawPtr rawg) const; 180 virtual void myMoveLMToBack(RawPtr rawf, RawPtr rawg) const; 181 virtual void myDeleteLM(RawPtr rawf) const; // ????? right interface 182 virtual void myDivLM(RawPtr rawlhs, ConstRawPtr rawf, ConstRawPtr rawg) const; ///< lhs=div(LM(f),LM(g)); assumes f!=0,g!=0 183 virtual int myCmpLPP(ConstRawPtr rawf, ConstRawPtr rawg) const; ///< cmp(LPP(f),LPP(g)); assumes f!=0,g!=0 184 virtual void myAddClear(RawPtr rawf, RawPtr rawg) const; ///< f+=g; g=0; 185 virtual void myAppendClear(RawPtr rawf, RawPtr rawg) const; ///< f+=g; g=0; appends g to f with no checks 186 187 virtual void myAddMulLM(RawPtr rawf, ConstRawPtr rawh, ConstRawPtr rawg) const; ///< f += LM(h)*g 188 virtual void myAddMulLM(RawPtr rawf, ConstRawPtr rawh, ConstRawPtr rawg, SkipLMFlag) const; ///< f += LM(h)*g 189 virtual void myReductionStep(RawPtr rawf, ConstRawPtr rawg) const; 190 // ??? aggiungere coefficiente 191 virtual void myReductionStepGCD(RawPtr rawf, ConstRawPtr rawg, RingElem& FScale) const; 192 // should it all be in ReductionStep ??? ANNA 193 //@} 194 195 196 ///////////////////// 197 // >>> WARNING <<< // 198 ///////////////////// 199 // DO NOT USE THE HOM CLASS -- I have not checked it 200 private: // HomImpl class: overwrite some implementations of SparsePolyRing functions 201 class HomImpl: public SparsePolyRingBase::HomImpl 202 { 203 public: 204 HomImpl(const SparsePolyRing& domain, const ring& codomain, const RingHom& CoeffHom, const std::vector<RingElem>& IndetImages); 205 }; 206 207 private: // Ideal class: overwrite some implementations of SparsePolyRing functions 208 class IdealImpl: public SparsePolyRingBase::IdealImpl 209 { 210 public: 211 IdealImpl(const SparsePolyRing& P, const std::vector<RingElem>& gens); 212 // default copy ctor is OK 213 virtual void myReduceMod(RingElemRawPtr rawr) const; // r elem of R, where I is ideal in R 214 virtual bool IhaveElem(RingElemConstRawPtr rawr) const; 215 virtual void myIntersect(const ideal&); 216 virtual void myColon(const ideal&); 217 virtual bool myDivMod(RingElemRawPtr rawlhs, RingElemConstRawPtr rawnum, RingElemConstRawPtr rawden) const; // result is true iff quot exists & is unique; if true set lhs = num/den modulo I 218 219 virtual void myTestIsMaximal() const; 220 virtual void myTestIsPrimary() const; 221 virtual void myTestIsPrime() const; 222 virtual void myTestIsRadical() const; 223 virtual const std::vector<RingElem>& myGBasis(const CpuTimeLimit& CheckForTimeOut) const; 224 }; 225 }; 226 227 //---------------------------------------------------------------------- 228 229 // std::vector<symbol> WANAMES(long NumIndets) 230 // { 231 // vector<symbol> ans = SymbolRange("x", 0, NumIndets-1); 232 // vector<symbol> d = SymbolRange("d", 0, NumIndets-1); 233 // ans.insert(ans.end(), d.begin(), d.end()); 234 // return ans; 235 // } 236 237 // std::vector<symbol> WANAMES(const std::vector<symbol>& names) 238 // { 239 // vector<symbol> ans=names; 240 // const long NumNames = len(names); 241 // ans.reserve(2*NumNames); 242 // for ( long i=0 ; i < NumNames ; ++i ) 243 // { 244 // if ( NumSubscripts(names[i])!=0 ) 245 // CoCoA_THROW_ERROR("names must have no subscripts", 246 // "WANAMES(const vector<symbol>& names)"); 247 // ans.push_back(symbol("d"+head(names[i]))); 248 // } 249 // return ans; 250 // } 251 252 RingExtAlgImpl(const ring & CoeffRing,const std::vector<symbol> & VarNames)253 RingExtAlgImpl::RingExtAlgImpl(const ring& CoeffRing, const std::vector<symbol>& VarNames): 254 myReprRing(NewPolyRing(CoeffRing, VarNames)) 255 // myNumTrueIndetsValue(len(WANames)/2) 256 { 257 // const long NumTrueIndets=len(WANames)/2; 258 CoCoA_ASSERT(IsCommutative(CoeffRing)); 259 myRefCountInc(); // this is needed for exception cleanliness, in case one of the lines below throws 260 myZeroPtr.reset(new RingElem(ring(this))); 261 myOnePtr.reset(new RingElem(ring(this), 1)); 262 myIndetVector.resize(NumIndets(myReprRing), *myZeroPtr); 263 // myDerivationVector.resize(myNumIndetsValue, *myZeroPtr); 264 // for (long i=0; i < myNumIndetsValue; ++i) 265 // myIndetVector.resize(NumIndets(myReprRing), *myZeroPtr); 266 vector<long> expv(NumIndets(myReprRing)); 267 268 for (long i=0; i < NumIndets(myReprRing); ++i) 269 { 270 expv[i] = 1; 271 myPushFront(raw(myIndetVector[i]), raw(one(CoeffRing)), expv); 272 expv[i] = 0; 273 } 274 myRefCountZero(); // otherwise it is 2 + NumIndets and won't be destroyed 275 } 276 277 ~RingExtAlgImpl()278 RingExtAlgImpl::~RingExtAlgImpl() 279 {} 280 281 282 // inline const RingExtAlgImpl* RingWeyl::operator->() const 283 // { 284 // return static_cast<const RingExtAlgImpl*>(myRingPtr()); 285 // } 286 287 288 // inline WeylPoly& ring_weyl::AsWeylPoly(RawPtr rawx) const 289 // { 290 // return *x.WeylPolyPtr; 291 // // return *static_cast<ring_weyl::WeylPoly*>(x.WeylPolyPtr); 292 // } 293 294 295 // inline const WeylPoly& ring_weyl::AsWeylPoly(ConstRawPtr rawx) const 296 // { 297 // return *x.WeylPolyPtr; 298 // // return *static_cast<ring_weyl::WeylPoly*>(x.WeylPolyPtr); 299 // } 300 301 302 // RingWeyl::RingWeyl(const RingExtAlgImpl* RingPtr): 303 // SparsePolyRing(RingPtr) 304 // {} 305 306 307 //---------------------------------------------------------------------- 308 // Functions which every ring must implement: 309 //---------------------------------------------------------------------- 310 IamCommutative()311 bool RingExtAlgImpl::IamCommutative() const 312 { 313 return myNumIndets() == 0; // we are assuming the coeff ring is commutative 314 } 315 316 IamIntegralDomain3(bool QuickMode)317 bool3 RingExtAlgImpl::IamIntegralDomain3(bool QuickMode) const 318 { 319 if (myNumIndets() > 0) return false3; 320 return myReprRing->IamIntegralDomain3(QuickMode); //??? I think this is right 321 } 322 323 IamTrueGCDDomain()324 bool RingExtAlgImpl::IamTrueGCDDomain() const 325 { 326 return false; // I have no clue how to compute GCDs even if they do exist 327 } 328 329 myZero()330 ConstRefRingElem RingExtAlgImpl::myZero() const 331 { 332 return *myZeroPtr; 333 } 334 335 myOne()336 ConstRefRingElem RingExtAlgImpl::myOne() const 337 { 338 return *myOnePtr; 339 } 340 341 myNew()342 RingElemRawPtr RingExtAlgImpl::myNew() const 343 { 344 return myReprRing->myNew(); 345 } 346 347 myNew(const MachineInt & n)348 RingElemRawPtr RingExtAlgImpl::myNew(const MachineInt& n) const 349 { 350 return myReprRing->myNew(n); 351 } 352 353 myNew(const BigInt & N)354 RingElemRawPtr RingExtAlgImpl::myNew(const BigInt& N) const 355 { 356 return myReprRing->myNew(N); 357 } 358 359 myNew(ConstRawPtr rawcopy)360 RingElemRawPtr RingExtAlgImpl::myNew(ConstRawPtr rawcopy) const 361 { 362 return myReprRing->myNew(rawcopy); 363 } 364 365 myDelete(RawPtr rawx)366 void RingExtAlgImpl::myDelete(RawPtr rawx) const 367 { 368 myReprRing->myDelete(rawx); 369 } 370 371 mySwap(RawPtr rawx,RawPtr rawy)372 void RingExtAlgImpl::mySwap(RawPtr rawx, RawPtr rawy) const 373 { 374 myReprRing->mySwap(rawx, rawy); 375 } 376 377 myAssign(RawPtr rawlhs,ConstRawPtr rawx)378 void RingExtAlgImpl::myAssign(RawPtr rawlhs, ConstRawPtr rawx) const 379 { 380 myReprRing->myAssign(rawlhs, rawx); 381 } 382 383 myAssign(RawPtr rawlhs,const MachineInt & n)384 void RingExtAlgImpl::myAssign(RawPtr rawlhs, const MachineInt& n) const 385 { 386 myReprRing->myAssign(rawlhs, n); 387 } 388 389 myAssign(RawPtr rawlhs,const BigInt & N)390 void RingExtAlgImpl::myAssign(RawPtr rawlhs, const BigInt& N) const 391 { 392 myReprRing->myAssign(rawlhs, N); 393 } 394 395 myAssignZero(RawPtr rawlhs)396 void RingExtAlgImpl::myAssignZero(RawPtr rawlhs) const 397 { 398 myReprRing->myAssignZero(rawlhs); 399 } 400 401 myRecvTwinFloat(RawPtr rawlhs,ConstRawPtr rawx)402 void RingExtAlgImpl::myRecvTwinFloat(RawPtr rawlhs, ConstRawPtr rawx) const 403 { 404 CoCoA_ASSERT(!IsExact(myReprRing)); 405 myReprRing->myRecvTwinFloat(rawlhs, rawx); 406 } 407 myNegate(RawPtr rawlhs,ConstRawPtr rawx)408 void RingExtAlgImpl::myNegate(RawPtr rawlhs, ConstRawPtr rawx) const 409 { 410 myReprRing->myNegate(rawlhs, rawx); 411 } 412 413 myAdd(RawPtr rawlhs,ConstRawPtr rawx,ConstRawPtr rawy)414 void RingExtAlgImpl::myAdd(RawPtr rawlhs, ConstRawPtr rawx, ConstRawPtr rawy) const 415 { 416 myReprRing->myAdd(rawlhs, rawx, rawy); 417 } 418 419 mySub(RawPtr rawlhs,ConstRawPtr rawx,ConstRawPtr rawy)420 void RingExtAlgImpl::mySub(RawPtr rawlhs, ConstRawPtr rawx, ConstRawPtr rawy) const 421 { 422 myReprRing->mySub(rawlhs, rawx, rawy); 423 } 424 425 426 //??? ANNA: I believe the general implementation in SparsePolyRing works for RingWeyl 427 // void RingExtAlgImpl::myMul(RawPtr rawlhs, ConstRawPtr rawx, ConstRawPtr rawy) const 428 // { 429 // if (myReprRing->myIsZero(x) || myReprRing->myIsZero(y)) { myReprRing->myAssignZero(rawlhs); return; } 430 // RingElem f(myReprRing); 431 // myReprRing->myAssign(raw(f), rawx); 432 // ConstRefRingElem g(myReprRing, rawy); 433 // // std::clog<<"f="<<f<<std::endl; 434 // // std::clog<<"g="<<g<<std::endl; 435 // RingElem ans(myReprRing); // compute answer in a temporary for exception safety 436 // while (!CoCoA::IsZero(f)) 437 // { 438 // RingElem LMf(myReprRing); 439 // myMoveLMToFront(raw(LMf), raw(f)); 440 // PPMonoidElem LPPf = LPP(LMf); 441 // RingElem LMfg(g); 442 // myMulByPP(raw(LMfg), raw(LPPf)); 443 // // std::clog<<"LMf="<<LMf<<std::endl; 444 // // std::clog<<"LMfg="<<LMfg<<std::endl; 445 // myReprRing->myMulByCoeff(raw(LMfg), raw(LC(LMf))); //????UGLY!!!! 446 // ans += LMfg; 447 // } 448 // mySwap(rawlhs, raw(ans));// really an assignment -- is this safe???? 449 // } 450 451 452 // void RingExtAlgImpl::myDiv(RawPtr /*rawlhs*/, ConstRawPtr /*rawx*/, ConstRawPtr /*rawy*/) const 453 // { 454 // CoCoA_THROW_ERROR(ERR::NYI, "RingExtAlgImpl::myDiv"); 455 // return;//??? 456 // // bool OK; // Two lines o/w compiler complains that 457 // // OK = CoCoA::WeylDiv(AsDMPI(rawlhs), AsDMPI(x), AsDMPI(y)); // OK is unused when debugging is off. 458 // // CoCoA_ASSERT(OK); 459 // } 460 461 myIsDivisible(RawPtr,ConstRawPtr,ConstRawPtr)462 bool RingExtAlgImpl::myIsDivisible(RawPtr /*rawlhs*/, ConstRawPtr /*rawx*/, ConstRawPtr /*rawy*/) const 463 { 464 CoCoA_THROW_ERROR(ERR::NYI, "RingExtAlgImpl::myIsDivisible"); 465 return false; 466 // return CoCoA::WeylDiv(AsDMPI(rawlhs), AsDMPI(x), AsDMPI(y)); 467 } 468 469 myIsInvertible(ConstRawPtr)470 bool RingExtAlgImpl::myIsInvertible(ConstRawPtr /*rawx*/) const 471 { 472 CoCoA_THROW_ERROR(ERR::NYI, "RingExtAlgImpl::myIsInvertible"); //??? d[1]*x[1] = 1 473 return false;//??? 474 } 475 476 477 // bool RingExtAlgImpl::myIsPrintAtom(ConstRawPtr rawx) const 478 // { 479 // return myReprRing->myIsPrintAtom(rawx); //??? default always false 480 // } 481 482 myGcd(RawPtr,ConstRawPtr,ConstRawPtr)483 void RingExtAlgImpl::myGcd(RawPtr /*rawlhs*/, ConstRawPtr /*rawx*/, ConstRawPtr /*rawy*/) const 484 { 485 CoCoA_THROW_ERROR(ERR::NYI, "RingExtAlgImpl::myGcd"); 486 } 487 488 myPowerSmallExp(RawPtr rawlhs,ConstRawPtr rawx,long n)489 void RingExtAlgImpl::myPowerSmallExp(RawPtr rawlhs, ConstRawPtr rawx, long n) const 490 { 491 // Assert that we have a genuinely non-trivial case. 492 CoCoA_ASSERT(n > 1); 493 CoCoA_ASSERT(!myIsZero(rawx) && !myIsOne(rawx) && !myIsMinusOne(rawx)); 494 495 mySequentialPower(rawlhs, rawx, n); // probably better than myBinaryPower, I guess. 496 } 497 498 mySymbols(std::vector<symbol> & SymList)499 void RingExtAlgImpl::mySymbols(std::vector<symbol>& SymList) const 500 { //??? ANNA: which symbols are in a RingExtAlgImpl?? 501 myReprRing->mySymbols(SymList); 502 } 503 504 myOutput(std::ostream & out,ConstRawPtr rawx)505 void RingExtAlgImpl::myOutput(std::ostream& out, ConstRawPtr rawx) const 506 { 507 if (!out) return; // short-cut for bad ostreams 508 myReprRing->myOutput(out, rawx); 509 } 510 511 512 // void RingExtAlgImpl::myOutputSelf(std::ostream& out) const 513 // { 514 // out << "RingExtAlgImpl(" << CoeffRing(myReprRing) << ", " << NumIndets(myReprRing) << ")"; 515 // //????????? WHAT ABOUT THE ORDERING AND GRADING???? 516 // } 517 518 519 // void RingExtAlgImpl::myOutputSelf(OpenMathOutput& OMOut) const 520 // { 521 // OMOut->mySendApplyStart(); 522 // OMOut << OpenMathSymbol("polyd", "poly_ring_d"); //??? weyl? 523 // OMOut << CoeffRing(myReprRing); 524 // OMOut << NumIndets(myReprRing); //???? losing the ordering and grading info here!!! 525 // OMOut->mySendApplyEnd(); 526 // } 527 528 myOutput(OpenMathOutput & OMOut,ConstRawPtr rawx)529 void RingExtAlgImpl::myOutput(OpenMathOutput& OMOut, ConstRawPtr rawx) const 530 { 531 myReprRing->myOutput(OMOut, rawx); 532 } 533 534 myIsZero(ConstRawPtr rawx)535 bool RingExtAlgImpl::myIsZero(ConstRawPtr rawx) const 536 { 537 return myReprRing->myIsZero(rawx); 538 } 539 540 myIsOne(ConstRawPtr rawx)541 bool RingExtAlgImpl::myIsOne(ConstRawPtr rawx) const 542 { 543 return myReprRing->myIsOne(rawx); 544 } 545 546 myIsMinusOne(ConstRawPtr rawx)547 bool RingExtAlgImpl::myIsMinusOne(ConstRawPtr rawx) const 548 { 549 return myReprRing->myIsMinusOne(rawx); 550 } 551 552 553 // bool RingExtAlgImpl::myIsZeroAddMul(RawPtr rawlhs, ConstRawPtr rawy, ConstRawPtr rawz) const; // use default definition 554 555 myIsEqual(ConstRawPtr rawx,ConstRawPtr rawy)556 bool RingExtAlgImpl::myIsEqual(ConstRawPtr rawx, ConstRawPtr rawy) const 557 { 558 return myReprRing->myIsEqual(rawx, rawy); 559 } 560 561 myCompose(const RingHom &,const RingHom & theta)562 RingHom RingExtAlgImpl::myCompose(const RingHom& /*phi*/, const RingHom& theta) const 563 { 564 CoCoA_THROW_ERROR(ERR::NYI, "RingExtAlgImpl::compose"); 565 return theta; // just to keep compiler quiet 566 } 567 568 //---------------------------------------------------------------------- 569 570 // long NumIndets(const RingWeyl& RW) 571 // { 572 // return RW->myNumIndets(); 573 // } 574 575 //---------------------------------------------------------------------- 576 // Functions which every PolyRing must implement 577 //---------------------------------------------------------------------- 578 myNumIndets()579 long RingExtAlgImpl::myNumIndets() const 580 { 581 return myReprRing->myNumIndets(); 582 } 583 584 myCoeffRing()585 const ring& RingExtAlgImpl::myCoeffRing() const 586 { 587 return myReprRing->myCoeffRing(); 588 } 589 590 myIndets()591 const std::vector<RingElem>& RingExtAlgImpl::myIndets() const 592 { 593 return myIndetVector; 594 } 595 596 myIndetPower(RawPtr rawf,long var,long exp)597 void RingExtAlgImpl::myIndetPower(RawPtr rawf, long var, long exp) const 598 { 599 myReprRing->myIndetPower(rawf, var, exp); 600 } 601 602 myNumTerms(ConstRawPtr rawx)603 long RingExtAlgImpl::myNumTerms(ConstRawPtr rawx) const 604 { 605 return myReprRing->myNumTerms(rawx); 606 } 607 608 myIsConstant(ConstRawPtr rawf)609 bool RingExtAlgImpl::myIsConstant(ConstRawPtr rawf) const 610 { 611 return myReprRing->myIsConstant(rawf); 612 } 613 614 myIsIndet(long & index,ConstRawPtr rawf)615 bool RingExtAlgImpl::myIsIndet(long& index, ConstRawPtr rawf) const 616 { 617 return myReprRing->myIsIndet(index, rawf); 618 } 619 620 myIsMonomial(ConstRawPtr rawf)621 bool RingExtAlgImpl::myIsMonomial(ConstRawPtr rawf) const 622 { 623 return myReprRing->myIsMonomial(rawf); 624 } 625 626 myStdDeg(ConstRawPtr rawf)627 long RingExtAlgImpl::myStdDeg(ConstRawPtr rawf) const 628 { 629 return myReprRing->myStdDeg(rawf); 630 } 631 632 myDeg(ConstRawPtr rawf,long var)633 long RingExtAlgImpl::myDeg(ConstRawPtr rawf, long var) const 634 { 635 CoCoA_ASSERT(!myIsZero(rawf)); 636 return myReprRing->myDeg(rawf, var);//???????? 637 } 638 639 myLC(ConstRawPtr rawf)640 RingElemAlias RingExtAlgImpl::myLC(ConstRawPtr rawf) const 641 { 642 CoCoA_ASSERT(!myIsZero(rawf)); 643 return myReprRing->myLC(rawf);//??????????? 644 } 645 646 myContent(RawPtr rawdest,ConstRawPtr rawf)647 void RingExtAlgImpl::myContent(RawPtr rawdest, ConstRawPtr rawf) const 648 { 649 myReprRing->myContent(rawdest, rawf); 650 } 651 652 myRemoveBigContent(RawPtr rawf)653 void RingExtAlgImpl::myRemoveBigContent(RawPtr rawf) const 654 { 655 myReprRing->myRemoveBigContent(rawf); 656 } 657 658 myMulByCoeff(RawPtr rawf,ConstRawPtr rawc)659 void RingExtAlgImpl::myMulByCoeff(RawPtr rawf, ConstRawPtr rawc) const // WEAK EXCEPTION GUARANTEE 660 { 661 myReprRing->myMulByCoeff(rawf, rawc); 662 } 663 664 myDivByCoeff(RawPtr rawf,ConstRawPtr rawc)665 bool RingExtAlgImpl::myDivByCoeff(RawPtr rawf, ConstRawPtr rawc) const // WEAK EXCEPTION GUARANTEE 666 { 667 return myReprRing->myDivByCoeff(rawf, rawc); 668 } 669 670 myDeriv(RawPtr,ConstRawPtr,ConstRawPtr)671 void RingExtAlgImpl::myDeriv(RawPtr /*rawlhs*/, ConstRawPtr /*rawf*/, ConstRawPtr /*rawx*/) const 672 { 673 CoCoA_THROW_ERROR(ERR::NYI, "RingExtAlgImpl::myDeriv"); 674 } 675 676 myHomCtor(const ring &,const RingHom &,const std::vector<RingElem> &)677 RingHom RingExtAlgImpl::myHomCtor(const ring& /*codomain*/, const RingHom& /*CoeffHom*/, const std::vector<RingElem>& /*IndetImages*/) const 678 { 679 CoCoA_THROW_ERROR("DOES NOT EXIST", "RingExtAlgImpl::myHomCtor"); 680 return IdentityHom(myReprRing); // just to keep compiler quiet 681 } 682 683 684 685 //---------------------------------------------------------------------- 686 // Functions which every SparsePolyRing must implement: 687 //---------------------------------------------------------------------- 688 myPPM()689 const PPMonoid& RingExtAlgImpl::myPPM() const 690 { 691 return myReprRing->myPPM(); 692 } 693 694 myMonomial(ConstRawPtr rawc,PPMonoidElemConstRawPtr rawpp)695 RingElem RingExtAlgImpl::myMonomial(ConstRawPtr rawc, PPMonoidElemConstRawPtr rawpp) const 696 { 697 RingElem ans(ring(this)); 698 RingElem m = myReprRing->myMonomial(rawc, rawpp); 699 mySwap(raw(ans), raw(m)); 700 return ans; 701 } 702 703 myBeginIter(ConstRawPtr rawf)704 SparsePolyIter RingExtAlgImpl::myBeginIter(ConstRawPtr rawf) const 705 { 706 return myReprRing->myBeginIter(rawf); 707 } 708 709 myEndIter(ConstRawPtr rawf)710 SparsePolyIter RingExtAlgImpl::myEndIter(ConstRawPtr rawf) const 711 { 712 return myReprRing->myEndIter(rawf); 713 } 714 715 myPushFront(RawPtr rawf,ConstRawPtr rawc,const std::vector<long> & expv)716 void RingExtAlgImpl::myPushFront(RawPtr rawf, ConstRawPtr rawc, const std::vector<long>& expv) const 717 { 718 myReprRing->myPushFront(rawf, rawc, expv);//??? how many elements does expv have??? 719 } 720 721 myPushBack(RawPtr rawf,ConstRawPtr rawc,const std::vector<long> & expv)722 void RingExtAlgImpl::myPushBack(RawPtr rawf, ConstRawPtr rawc, const std::vector<long>& expv) const 723 { 724 myReprRing->myPushBack(rawf, rawc, expv);//??? how many elements does expv have??? 725 } 726 727 myPushFront(RawPtr rawf,ConstRawPtr rawc,PPMonoidElemConstRawPtr rawpp)728 void RingExtAlgImpl::myPushFront(RawPtr rawf, ConstRawPtr rawc, PPMonoidElemConstRawPtr rawpp) const 729 { 730 myReprRing->myPushFront(rawf, rawc, rawpp); 731 } 732 733 myPushBack(RawPtr rawf,ConstRawPtr rawc,PPMonoidElemConstRawPtr rawpp)734 void RingExtAlgImpl::myPushBack(RawPtr rawf, ConstRawPtr rawc, PPMonoidElemConstRawPtr rawpp) const 735 { 736 myReprRing->myPushBack(rawf, rawc, rawpp); 737 } 738 739 myLPP(ConstRawPtr rawf)740 ConstRefPPMonoidElem RingExtAlgImpl::myLPP(ConstRawPtr rawf) const 741 { 742 CoCoA_ASSERT(!myIsZero(rawf)); 743 return myReprRing->myLPP(rawf); 744 } 745 746 myCoeffProdPP(PPMonoidElemConstRawPtr rawpp1,PPMonoidElemConstRawPtr rawpp2)747 int RingExtAlgImpl::myCoeffProdPP(PPMonoidElemConstRawPtr rawpp1, PPMonoidElemConstRawPtr rawpp2) const 748 { 749 const PPMonoid& PParith = PPM(myReprRing); 750 if (!PParith->myIsCoprime(rawpp1, rawpp2)) return 0; 751 const int n = NumIndets(PParith); 752 vector<long> expv(n); 753 PParith->myExponents(expv, rawpp1); 754 vector<long> Rcount(n); 755 for (int i=0; i < n; ++i) 756 { 757 if (expv[i] == 0) continue; 758 for (int j=0; j <= i; ++j) 759 ++Rcount[j]; 760 } 761 PParith->myExponents(expv, rawpp2); 762 int count = 0; 763 for (int i=0; i < n; ++i) 764 if (expv[i] > 0) 765 count += Rcount[i]; 766 if ((count&1) == 1) return -1; 767 return 1; 768 } 769 770 // f = pp*f NOTE: pp is on the LEFT and f is on the RIGHT myMulByPP(RawPtr rawf,PPMonoidElemConstRawPtr rawpp)771 void RingExtAlgImpl::myMulByPP(RawPtr rawf, PPMonoidElemConstRawPtr rawpp) const 772 { 773 if (myReprRing->myIsZero(rawf)) return; 774 775 RingElem g(myReprRing); 776 // myReprRing->myAssign(raw(g), rawf); 777 //??? std::clog<<"Alias(f)="<<g<<std::endl; 778 // const long nvars = myNumIndets(); 779 const PPMonoid& PParith = PPM(myReprRing); 780 PPMonoidElem ProdPP(PParith); 781 for (SparsePolyIter it = myReprRing->myBeginIter(rawf); !IsEnded(it); ++it) 782 { 783 const int PPcoeff = myCoeffProdPP(rawpp, raw(PP(it))); 784 if (PPcoeff == 0) continue; 785 const RingElem c = PPcoeff*coeff(it); 786 PParith->myMul(raw(ProdPP), rawpp, raw(PP(it))); 787 PushBack(g, c, ProdPP); 788 } 789 790 mySwap(rawf, raw(g));// really an assignment -- is this safe???? 791 } 792 793 myIsZeroAddLCs(RawPtr rawf,RawPtr rawg)794 bool RingExtAlgImpl::myIsZeroAddLCs(RawPtr rawf, RawPtr rawg) const 795 { 796 return myReprRing->myIsZeroAddLCs(rawf, rawg); 797 } 798 799 myMoveLMToFront(RawPtr rawf,RawPtr rawg)800 void RingExtAlgImpl::myMoveLMToFront(RawPtr rawf, RawPtr rawg) const 801 { 802 CoCoA_ASSERT(!myIsZero(rawg)); 803 myReprRing->myMoveLMToFront(rawf, rawg); 804 } 805 806 myMoveLMToBack(RawPtr rawf,RawPtr rawg)807 void RingExtAlgImpl::myMoveLMToBack(RawPtr rawf, RawPtr rawg) const 808 { 809 CoCoA_ASSERT(!myIsZero(rawg)); 810 myReprRing->myMoveLMToBack(rawf, rawg); 811 } 812 813 myDeleteLM(RawPtr rawf)814 void RingExtAlgImpl::myDeleteLM(RawPtr rawf) const 815 { 816 CoCoA_ASSERT(!myIsZero(rawf)); 817 myReprRing->myDeleteLM(rawf); 818 } 819 820 myDivLM(RawPtr rawlhs,ConstRawPtr rawf,ConstRawPtr rawg)821 void RingExtAlgImpl::myDivLM(RawPtr rawlhs, ConstRawPtr rawf, ConstRawPtr rawg) const 822 { 823 CoCoA_ASSERT(!myIsZero(rawf) && !myIsZero(rawg)); 824 myReprRing->myDivLM(rawlhs, rawf, rawg); 825 } 826 827 myCmpLPP(ConstRawPtr rawf,ConstRawPtr rawg)828 int RingExtAlgImpl::myCmpLPP(ConstRawPtr rawf, ConstRawPtr rawg) const 829 { 830 CoCoA_ASSERT(!myIsZero(rawf) && !myIsZero(rawg)); 831 return myReprRing->myCmpLPP(rawf, rawg); 832 } 833 834 myAddClear(RawPtr rawf,RawPtr rawg)835 void RingExtAlgImpl::myAddClear(RawPtr rawf, RawPtr rawg) const 836 { 837 myReprRing->myAddClear(rawf, rawg); 838 } 839 840 myAppendClear(RawPtr rawf,RawPtr rawg)841 void RingExtAlgImpl::myAppendClear(RawPtr rawf, RawPtr rawg) const 842 { 843 myReprRing->myAppendClear(rawf, rawg); 844 } 845 846 myAddMulLM(RawPtr rawf,ConstRawPtr rawh,ConstRawPtr rawg)847 void RingExtAlgImpl::myAddMulLM(RawPtr rawf, ConstRawPtr rawh, ConstRawPtr rawg) const //???? delete me??? 848 { 849 myAddMulLM(rawf, rawh, rawg, DontSkipLMg); 850 } 851 852 myAddMulLM(RawPtr rawf,ConstRawPtr rawh,ConstRawPtr rawg,SkipLMFlag skip)853 void RingExtAlgImpl::myAddMulLM(RawPtr rawf, ConstRawPtr rawh, ConstRawPtr rawg, SkipLMFlag skip) const 854 { 855 CoCoA_ASSERT(myNumTerms(rawh)==1); 856 RingElem prod(ring(this), myNew(rawg)); 857 myMulByCoeff(raw(prod), raw(myLC(rawh))); 858 myMulByPP(raw(prod), raw(myLPP(rawh))); 859 myReprRing->myAddMulLM(rawf, raw(myOne()), raw(prod), skip); 860 } 861 862 myReductionStep(RawPtr rawf,ConstRawPtr rawg)863 void RingExtAlgImpl::myReductionStep(RawPtr rawf, ConstRawPtr rawg) const 864 { 865 PPMonoidElem q = myLPP(rawf)/myLPP(rawg); 866 RingElem c = -myLC(rawf)/myLC(rawg); // RingElem c = -LC(repf)/LC(repg); 867 RingElem qg(myReprRing); myReprRing->myAssign(raw(qg), rawg); // qg is copy of rawg 868 myMulByPP(raw(qg), raw(q)); // qg = q * g //??? should we use myAddMul 869 myMulByCoeff(raw(qg), raw(c)); 870 myAdd(rawf, rawf, raw(qg)); // repf += qg; 871 872 873 /* 874 //??? ConstRefRingElem aliasg(ring(this), rawg); 875 //??? std::clog<<"g="<<aliasg<<std::endl; 876 PPMonoidElem LPPf = myReprRing->myLPP(f); 877 PPMonoidElem LPPg = myReprRing->myLPP(g); 878 PPMonoidElem q = LPPf/LPPg; // quotient exists 879 RingElem LCf(CoeffRing(myReprRing)); 880 CoeffRing(myReprRing)->myAssign(raw(LCf), myReprRing->myRawLC(f)); 881 RingElem LCg(CoeffRing(myReprRing)); 882 CoeffRing(myReprRing)->myAssign(raw(LCg), myReprRing->myRawLC(g)); 883 RingElem c = -LCf/LCg; 884 /// RingElem c(myCoeffRing()); 885 /// myCoeffRing()->myDiv(raw(c), myReprRing->myRawLC(f), myReprRing->myRawLC(g)); 886 RingElem g1(myReprRing); 887 //??? std::clog<<"ReductionStep: q="<<q<<std::endl; 888 //??? std::clog<<"ReductionStep: c="<<c<<std::endl; 889 myReprRing->myAssign(raw(g1), rawg); 890 //??? std::clog<<"ReductionStep: g="<<g1<<std::endl; 891 myMul(raw(g1), raw(q)); // g1 = q*g; 892 myReprRing->myMulByCoeff(raw(g1), raw(c)); 893 //??? std::clog<<"ReductionStep: prod="<<g1<<std::endl; 894 { 895 //??? ConstRefRingElem aliasf(ring(this),f); 896 //??? std::clog<<"REDUCING f="<<aliasf<<std::endl; 897 //??? std::clog<<"REDN by g="<<aliasg<<std::endl; 898 myAdd(f, f, raw(g1)); 899 //??? std::clog<<"RESULT is "<<aliasf<<std::endl<<std::endl; 900 } 901 */ 902 } 903 904 myReductionStepGCD(RawPtr,ConstRawPtr,RingElem &)905 void RingExtAlgImpl::myReductionStepGCD(RawPtr /*rawf*/, ConstRawPtr /*rawg*/, RingElem& /*fscale*/) const 906 { 907 CoCoA_THROW_ERROR(ERR::NYI, "RingExtAlgImpl::ReductionStepGCD"); 908 } 909 910 911 //--------------------------------------------------------------------------- 912 // Functions to do with RingExtAlgImpl::HomImpl 913 914 HomImpl(const SparsePolyRing & domain,const ring & codomain,const RingHom & CoeffHom,const std::vector<RingElem> & IndetImages)915 RingExtAlgImpl::HomImpl::HomImpl(const SparsePolyRing& domain, const ring& codomain, const RingHom& CoeffHom, const std::vector<RingElem>& IndetImages): 916 SparsePolyRingBase::HomImpl(domain, codomain, CoeffHom, IndetImages) 917 { 918 CoCoA_THROW_ERROR(ERR::NYI, "RingExtAlgImpl::HomImpl::HomImpl"); 919 } 920 921 922 923 //--------------------------------------------------------------------------- 924 // Functions for the class RingExtAlgImpl::IdealImpl 925 926 // inheritance is delicate here: this function is **necessary** myIdealCtor(const std::vector<RingElem> & gens)927 ideal RingExtAlgImpl::myIdealCtor(const std::vector<RingElem>& gens) const 928 { 929 return ideal(new IdealImpl(SparsePolyRing(this), gens)); //??? ugly ??? 930 } 931 932 IdealImpl(const SparsePolyRing & P,const std::vector<RingElem> & gens)933 RingExtAlgImpl::IdealImpl::IdealImpl(const SparsePolyRing& P, const std::vector<RingElem>& gens): 934 SparsePolyRingBase::IdealImpl(P, gens) 935 {} 936 937 myTestIsMaximal()938 void RingExtAlgImpl::IdealImpl::myTestIsMaximal() const 939 { CoCoA_THROW_ERROR(ERR::NYI, "RingExtAlgImpl::IdealImpl::myTestIsMaximal()"); } 940 941 myTestIsPrimary()942 void RingExtAlgImpl::IdealImpl::myTestIsPrimary() const 943 { CoCoA_THROW_ERROR(ERR::NYI, "RingExtAlgImpl::IdealImpl::myTestIsPrimary()"); } 944 945 myTestIsPrime()946 void RingExtAlgImpl::IdealImpl::myTestIsPrime() const 947 { CoCoA_THROW_ERROR(ERR::NYI, "RingExtAlgImpl::IdealImpl::myTestIsPrime()"); } 948 949 myTestIsRadical()950 void RingExtAlgImpl::IdealImpl::myTestIsRadical() const 951 { CoCoA_THROW_ERROR(ERR::NYI, "RingExtAlgImpl::IdealImpl::myTestIsRadical()"); } 952 953 myReduceMod(RingElemRawPtr)954 void RingExtAlgImpl::IdealImpl::myReduceMod(RingElemRawPtr /*rawr*/) const 955 { CoCoA_THROW_ERROR(ERR::NYI, "RingExtAlgImpl::WeylIdeal::IdealImpl::myReduceMod"); } 956 957 IhaveElem(RingElemConstRawPtr)958 bool RingExtAlgImpl::IdealImpl::IhaveElem(RingElemConstRawPtr /*rawr*/) const 959 { 960 CoCoA_THROW_ERROR(ERR::NYI, "RingExtAlgImpl::WeylIdeal::IhaveElem"); 961 return false; /* just to keep compiler quiet */ 962 } 963 964 myIntersect(const ideal &)965 void RingExtAlgImpl::IdealImpl::myIntersect(const ideal& /*J*/) 966 { CoCoA_THROW_ERROR(ERR::NYI, "RingExtAlgImpl::WeylIdeal::myIntersect"); }//??? 967 968 myColon(const ideal &)969 void RingExtAlgImpl::IdealImpl::myColon(const ideal& /*J*/) 970 { CoCoA_THROW_ERROR(ERR::NYI, "RingExtAlgImpl::WeylIdeal::myColon"); }//??? 971 972 myDivMod(RingElemRawPtr,RingElemConstRawPtr,RingElemConstRawPtr)973 bool RingExtAlgImpl::IdealImpl::myDivMod(RingElemRawPtr /*rawlhs*/, RingElemConstRawPtr /*rawnum*/, RingElemConstRawPtr /*rawden*/) const 974 { 975 CoCoA_THROW_ERROR(ERR::NYI, "RingExtAlgImpl::WeylIdeal::myDivMod"); 976 return false; /* just to keep compiler quiet */ 977 } 978 979 myGBasis(const CpuTimeLimit & CheckForTimeout)980 const std::vector<RingElem>& RingExtAlgImpl::IdealImpl::myGBasis(const CpuTimeLimit& CheckForTimeout) const 981 { 982 if (IhaveGBasis()) return myGBasisValue; 983 CoCoA_ASSERT(myGBasisValue.empty()); 984 vector<RingElem> GensList, GBList; 985 GensList.insert(GensList.end(), myGensValue.begin(), myGensValue.end()); 986 bool IsHomog=false; 987 bool IsSatAlg=false; 988 GRingInfo GRI(myP, IsHomog, IsSatAlg, NewDivMaskEvenPowers(), CheckForTimeout); 989 GBCriteria criteria(GBCriteria::DontUseCoprime, GBCriteria::UseGM, 990 GBCriteria::UseBack, GBCriteria::DontUseDiv); 991 GReductor GR(GRI, GensList, 992 GReductor::AffineAlg, 993 Reductors::DontUseBorel, GReductor::DontUseDynamicAlg, 994 criteria); 995 GR.myDoGBasis(); 996 // GR.myDoAFFGBasis(); 997 GR.myGBasis(GBList); 998 myGBasisValue.insert(myGBasisValue.end(), GBList.begin(), GBList.end()); 999 IhaveGBasisValue = true; 1000 return myGBasisValue; 1001 } 1002 1003 1004 //---------------------------------------------------------------------- 1005 // Pseudo-ctors for (sparse) polynomial rings. 1006 1007 NewExtAlgebra(const ring & CoeffRing,long NumIndets)1008 SparsePolyRing NewExtAlgebra(const ring& CoeffRing, long NumIndets) 1009 { 1010 return SparsePolyRing(new RingExtAlgImpl(CoeffRing, SymbolRange("x",1,NumIndets))); 1011 } 1012 1013 NewExtAlgebra(const ring & CoeffRing,const std::vector<symbol> & names)1014 SparsePolyRing NewExtAlgebra(const ring& CoeffRing, const std::vector<symbol>& names) 1015 { 1016 return SparsePolyRing(new RingExtAlgImpl(CoeffRing, names)); 1017 } 1018 1019 1020 // const RingElem& indet(const RingWeyl& RW, long var) 1021 // { 1022 // if (var > CoCoA::NumIndets(RW)) CoCoA_THROW_ERROR("Indeterminate index too large", "indet(RW,var)"); 1023 // return RW->myIndetVector[var]; 1024 // } 1025 1026 1027 // const RingElem& derivation(const RingWeyl& RW, long var) 1028 // { 1029 // if (var > CoCoA::NumIndets(RW)) CoCoA_THROW_ERROR("Indeterminate index too large", "derivation(RW,var)"); 1030 // return RW->myDerivationVector[var]; 1031 // } 1032 1033 1034 } // end of namespace CoCoA 1035 1036 // #error "JUNK AFTER THIS LINE" 1037 // ????????????????????????????????????????????????????????????????????????????? 1038 // #include <algorithm> 1039 // #include <vector> 1040 // #include <iostream> 1041 1042 // using std::max; 1043 // using std::swap; 1044 // using std::vector; 1045 // using std::ostream; 1046 // using std::endl; // just for debugging 1047 1048 1049 // #include "CoCoA/deriv.H" 1050 // #include "CoCoA/ring_weyl.H" 1051 1052 // namespace // unnamed, for file local functions 1053 // { 1054 1055 // using namespace CoCoA; 1056 1057 1058 // //---------------------------------------------------------------------- 1059 1060 1061 // // // f = pp*g where the product is in the Weyl algebra 1062 // // void act(RingElem& f, const RingElem& pp, const RingElem& g) 1063 // // { 1064 // // ASSERT(IsPolyRing(owner(f))); 1065 // // const PolyRing& P = PolyRing::owner(f); 1066 // // ASSERT(&owner(g) == &P && &owner(pp) == &P); 1067 // // ASSERT(!IsZero(pp) && NumTerms(pp) == 1); 1068 // // // std::clog<<"entered ucha's action" << endl; 1069 // // // std::clog << "pp=" << pp << endl; 1070 // // f = g; 1071 // // if (IsZero(f)) return; 1072 // // const long nvars = NumIndets(P); 1073 1074 // // vector<long> expv(nvars); 1075 // // PPM(P).exponents(expv, raw(LPP(pp))); 1076 1077 // // for (long var = nvars/2; var < nvars; ++var) 1078 // // { 1079 // // // std::clog << "doing D var=" << var << endl; 1080 // // const long n = expv[var]; 1081 // // // std::clog << "order = " << n << endl; 1082 // // RingElem derf = f; 1083 // // f *= P.IndetPower(var, n); 1084 // // for (long i=1; i <= n; ++i) 1085 // // { 1086 // // derf = deriv(derf, var-nvars/2); 1087 // // f += binomial(n, i)*derf*P.IndetPower(var, n-i); // *IndetPower(h, 2*i); // for homog case 1088 // // std::clog<<"binomial("<<n<<","<<i<<")="<<binomial(n,i)<<std::endl; 1089 // // } 1090 // // } 1091 // // { // f *= var^deg(pp, var); for the early vars 1092 // // for (long var = nvars/2; var < nvars; ++var) 1093 // // expv[var] = 0; 1094 // // PPMonoid::elem qq(PPM(P), expv); 1095 // // f *= P.monomial(RingElem(CoeffRing(P), 1), qq); 1096 // // } 1097 // // } 1098 // //---------------------------------------------------------------------- 1099 // } // end of unnamed namespace 1100 1101 1102 // namespace CoCoA 1103 // { 1104 1105 1106 1107 1108 // RingExtAlgImpl::ring_weyl(const AbstractRing& R, const PPMonoid& PPM): 1109 // myCoeffRing(R), 1110 // myPPM(PPM), 1111 // myWeylPolyPool(sizeof(WeylPoly), "RingExtAlgImpl::myWeylPolyPool"), 1112 // myNumIndets(NumIndets(PPM)), 1113 // myOrdvWords(OrdvWords(ordering(PPM))), 1114 // mySummandSize(sizeof(WeylPoly::summand) + sizeof(int)*(myOrdvWords-1)), 1115 // mySummandPool(mySummandSize, "RingExtAlgImpl::mySummandPool") 1116 // { 1117 // myNumPolys = 0; 1118 // myZero = new RingElem(*this); 1119 // myIndetVector.resize(myNumIndets, RingElem(*this)); 1120 // vector<long> expv(myNumIndets); 1121 // RingElem one(myCoeffRing, 1); 1122 // for (long i=0; i < myNumIndets; ++i) 1123 // { 1124 // expv[i] = 1; 1125 // PushFront(raw(myIndetVector[i]), raw(one), expv); 1126 // expv[i] = 0; 1127 // } 1128 // } 1129 1130 1131 // RingExtAlgImpl::~ring_weyl() 1132 // { 1133 // myIndetVector.clear(); 1134 // delete myZero; 1135 // ASSERT(myNumPolys == 0); 1136 // } 1137 1138 1139 // void RingExtAlgImpl::MakeWritable(RawPtr rawx) const 1140 // { 1141 // if (x.WeylPolyPtr->myRefCount == 1) return; 1142 // --x.WeylPolyPtr->myRefCount; 1143 // WeylPoly* copy = static_cast<WeylPoly*>(myWeylPolyPool.alloc(sizeof(WeylPoly))); 1144 // const WeylPoly* orig = x.WeylPolyPtr; 1145 // x.WeylPolyPtr = copy; 1146 // copy->myRefCount = 1; 1147 // copy->mySummands = nullptr; 1148 // copy->myEnd = ©->mySummands; 1149 // for (const WeylPoly::summand* it = orig->mySummands; it != nullptr; it = it->myNext) 1150 // { 1151 // // more or less hand inlined body of PushBack -- NB using PushBack is "circular" 1152 // *copy->myEnd = CopySummand(it); 1153 // copy->myEnd = &((*copy->myEnd)->myNext); 1154 // } 1155 1156 // /// myCoeffRing.init(copy->myDenom); 1157 // // new (©->myLC) RingElem(myCoeffRing, AbstractRing::elem::ALIAS); 1158 // } 1159 1160 1161 // inline WeylPoly::summand* RingExtAlgImpl::AllocSummand() const 1162 // { 1163 // return static_cast<WeylPoly::summand*>(mySummandPool.alloc(mySummandSize)); 1164 // } 1165 1166 1167 // WeylPoly::summand* RingExtAlgImpl::InitSummand(WeylPoly::summand* ptr) const 1168 // { 1169 // myCoeffRing.init(ptr->myCoeff); 1170 // ptr->myNext = nullptr; 1171 // ptr->myModulePosn = 0; 1172 // return ptr; 1173 // } 1174 1175 1176 // WeylPoly::summand* RingExtAlgImpl::InitSummand(WeylPoly::summand* ptr, ConstRawPtr rawc, const vector<long>& expv) const 1177 // { 1178 // myCoeffRing.init(ptr->myCoeff, c); 1179 // ptr->myNext = nullptr; 1180 // ptr->myModulePosn = 0; 1181 // ordering(myPPM).ComputeOrdv(ptr->myOrdv, &expv[0]); // &expv[0] converts vector<T> to T* 1182 // return ptr; 1183 // } 1184 1185 1186 // WeylPoly::summand* RingExtAlgImpl::CopySummand(const WeylPoly::summand* original) const 1187 // { 1188 // WeylPoly::summand* copy = AllocSummand(); 1189 // copy->myNext = nullptr; 1190 // myCoeffRing.init(copy->myCoeff, original->myCoeff); 1191 // copy->myModulePosn = original->myModulePosn; 1192 // for (long i=0; i < myOrdvWords; ++i) 1193 // copy->myOrdv[i] = original->myOrdv[i]; 1194 // return copy; 1195 // } 1196 1197 1198 // void RingExtAlgImpl::SetSummandMOrdv(WeylPoly::summand* dest, const WeylPoly::summand* src) const 1199 // { 1200 // dest->myModulePosn = src->myModulePosn; 1201 // for (long i=0; i < myOrdvWords; ++i) 1202 // dest->myOrdv[i] = src->myOrdv[i]; 1203 // } 1204 1205 1206 // void RingExtAlgImpl::DeleteSummands(WeylPoly::summand* ptr) const 1207 // { 1208 // WeylPoly::summand* next; 1209 // while (ptr != 0) 1210 // { 1211 // next = ptr->myNext; 1212 // myCoeffRing.kill(ptr->myCoeff); 1213 // mySummandPool.free(ptr, mySummandSize); 1214 // ptr = next; 1215 // } 1216 // } 1217 1218 1219 // bool RingExtAlgImpl::EqualSummands(const WeylPoly::summand& lhs, const WeylPoly::summand& x) const 1220 // { 1221 // if (lhs.myModulePosn != x.myModulePosn) return false; 1222 // const PPOrdering::OrdvElem* const lordv = lhs.myOrdv; 1223 // const PPOrdering::OrdvElem* const rordv = x.myOrdv; 1224 // for (long i = 0; i < myOrdvWords; ++i) 1225 // if (lordv[i] != rordv[i]) return false; 1226 // return myCoeffRing.IsEqual(lhs.myCoeff, x.myCoeff); 1227 // } 1228 1229 1230 // inline void RingExtAlgImpl::MulOrdv(PPOrdering::OrdvElem* ov, const PPOrdering::OrdvElem* ov1, const PPOrdering::OrdvElem* ov2) const 1231 // { 1232 // for (long i=0; i < myOrdvWords; ++i) 1233 // ov[i] = ov1[i]+ov2[i]; 1234 // } 1235 1236 1237 // inline void RingExtAlgImpl::DivOrdv(PPOrdering::OrdvElem* ov, const PPOrdering::OrdvElem* ov1, const PPOrdering::OrdvElem* ov2) const 1238 // { 1239 // for (long i=0; i < myOrdvWords; ++i) 1240 // ov[i] = ov1[i]-ov2[i]; 1241 // } 1242 1243 1244 1245 1246 // long RingExtAlgImpl::NumIndets() const 1247 // { 1248 // return myNumIndets; 1249 // } 1250 1251 1252 // const AbstractRing& RingExtAlgImpl::CoeffRing() const 1253 // { 1254 // return myCoeffRing; 1255 // } 1256 1257 1258 // const PPMonoid& RingExtAlgImpl::PPM() const 1259 // { 1260 // return myPPM; 1261 // } 1262 1263 1264 // long RingExtAlgImpl::NumTerms(ConstRawPtr rawx) const 1265 // { 1266 // long nsummands = 0; 1267 // for (const WeylPoly::summand* it = AsWeylPoly(rawx).mySummands; it != nullptr; it = it->myNext) ++nsummands; 1268 // return nsummands; 1269 // } 1270 1271 1272 // PolyIter RingExtAlgImpl::BeginIter(AbstractRing::RawPtr rawx) const 1273 // { 1274 // return PolyIter(*this, &AsWeylPoly(rawx).mySummands); 1275 // } 1276 1277 1278 // PolyIter RingExtAlgImpl::EndIter(AbstractRing::RawPtr rawx) const 1279 // { 1280 // return PolyIter(*this, AsWeylPoly(rawx).myEnd); 1281 // } 1282 1283 1284 // const RingElem& RingExtAlgImpl::indet(long var) const 1285 // { 1286 // ASSERT(var < myNumIndets); 1287 // return myIndetVector[var]; 1288 // } 1289 1290 1291 // RingElem RingExtAlgImpl::IndetPower(long var, long n) const 1292 // { 1293 // ASSERT(0 <= var && var < myNumIndets); 1294 // return monomial(CoCoA::IndetPower(myPPM, var, n)); 1295 // } 1296 1297 1298 // RingElem RingExtAlgImpl::monomial(const RingElem& c, const PPMonoid::alias& pp) const 1299 // { 1300 // vector<long> expv(myNumIndets); 1301 // myPPM.exponents(expv, raw(pp)); 1302 // RingElem ans(*this); 1303 // PushFront(raw(ans), raw(c), expv); 1304 // return ans; 1305 // } 1306 1307 1308 // RingElem RingExtAlgImpl::monomial(const PPMonoid::alias& pp) const 1309 // { 1310 // RingElem c(myCoeffRing, 1); 1311 // vector<long> expv(myNumIndets); 1312 // myPPM.exponents(expv, raw(pp)); 1313 // RingElem ans(*this); 1314 // PushFront(raw(ans), raw(c), expv); 1315 // return ans; 1316 // } 1317 1318 1319 // RingElem RingExtAlgImpl::monomial(const RingElem& c) const 1320 // { 1321 // vector<long> expv(myNumIndets); 1322 // RingElem ans(*this); 1323 // PushFront(raw(ans), raw(c), expv); 1324 // return ans; 1325 // } 1326 1327 1328 // long RingExtAlgImpl::deg(ConstRawPtr rawf) const 1329 // { 1330 // if (IsZero(f)) CoCoA_THROW_ERROR("RingExtAlgImpl::deg: cannot compute degree of zero polynomial"); 1331 // if (GradingDim(myPPM) > 0) 1332 // return ordering(myPPM).deg(AsWeylPoly(f).mySummands->myOrdv); //// BUG???? "valid" only if grading dim == 1 1333 // // return ???; the vector in Z^0 -- ring not graded!!! 1334 // return -1;//?????????? BUG BUG INCOMPLETE 1335 // } 1336 1337 1338 // int RingExtAlgImpl::deg(ConstRawPtr rawf, long var) const 1339 // { 1340 // if (IsZero(f)) CoCoA_THROW_ERROR("RingExtAlgImpl::deg: cannot compute degree of zero polynomial"); 1341 // long d = 0; 1342 // for (WeylPoly::summand* it = AsWeylPoly(f).mySummands; it != nullptr; it = it->myNext) 1343 // d = max(d, ordering(myPPM).exponent(it->myOrdv, var)); 1344 // return d; 1345 // } 1346 1347 1348 // // int RingExtAlgImpl::deg(ConstRawPtr rawf, const PPGrading& G) const 1349 // // { 1350 // // if (IsZero(f)) CoCoA_THROW_ERROR("RingExtAlgImpl::deg: cannot compute degree of zero polynomial"); 1351 // // int d = 0; 1352 // // for (WeylPoly::summand* it = AsWeylPoly(f).mySummands; it != nullptr; it = it->myNext) 1353 // // d = max(d, deg(it, G)); // CANNOT JUST USE MAX HERE!! MUST USE LEX MAX FOR VECTORS 1354 // // return d; 1355 // // } 1356 1357 1358 1359 // const RingElem RingExtAlgImpl::LC(ConstRawPtr rawf) const 1360 // { 1361 // ASSERT(!IsZero(f)); 1362 // // if (IsZero(f)) return ::zero(myCoeffRing); 1363 // return RingElem(myCoeffRing, AsWeylPoly(f).mySummands->myCoeff); 1364 // // AsWeylPoly(f).myLC.reseat(AsWeylPoly(f).mySummands->myCoeff); 1365 // // return AsWeylPoly(f).myLC; 1366 // } 1367 1368 1369 // AbstractRing::RawPtr RingExtAlgImpl::RawLC(RawPtr rawf) const 1370 // { 1371 // MakeWritable(f);//????????? 1372 // ASSERT(!IsZero(f)); 1373 // return AsWeylPoly(f).mySummands->myCoeff; 1374 // } 1375 1376 1377 // const AbstractRing::RawPtr RingExtAlgImpl::RawLC(ConstRawPtr rawf) const 1378 // { 1379 // ASSERT(!IsZero(f)); 1380 // return AsWeylPoly(f).mySummands->myCoeff; 1381 // } 1382 1383 1384 // RingElem RingExtAlgImpl::content(ConstRawPtr rawf) const 1385 // { 1386 // ASSERT(::IsTrueGCDDomain(myCoeffRing)); 1387 // ASSERT(!IsZero(f)); 1388 // RingElem cont(myCoeffRing); 1389 // for (WeylPoly::summand* it = AsWeylPoly(f).mySummands; it != nullptr; it = it->myNext) 1390 // myCoeffRing.gcd(raw(cont), raw(cont), it->myCoeff); // be clever if cont == 1?? 1391 // return cont; 1392 // } 1393 1394 1395 1396 // void RingExtAlgImpl::MoveLMToFront(RawPtr rawf, RawPtr rawg) const 1397 // { 1398 // ASSERT(!IsZero(g)); 1399 // ASSERT(f.WeylPolyPtr->myRefCount == 1); 1400 // // ASSERT(g.WeylPolyPtr->myRefCount == 1); 1401 // // MakeWritable(f);//???????? 1402 // MakeWritable(g);//???????? 1403 // WeylPoly& G = AsWeylPoly(g); 1404 // WeylPoly::summand* ltg = G.mySummands; 1405 // G.mySummands = G.mySummands->myNext; 1406 // if (G.mySummands == nullptr) G.myEnd = &(G.mySummands); 1407 // PushFront(f, ltg); 1408 // } 1409 1410 1411 // void RingExtAlgImpl::DeleteLM(RawPtr rawf) const 1412 // { 1413 // ASSERT(!IsZero(f)); 1414 // // ASSERT(f.WeylPolyPtr->myRefCount == 1); 1415 // MakeWritable(f);//???????? 1416 // WeylPoly& F = AsWeylPoly(f); 1417 // WeylPoly::summand* old_ltf = F.mySummands; 1418 // F.mySummands = old_ltf->myNext; 1419 // if (F.mySummands == nullptr) F.myEnd = &F.mySummands; 1420 // old_ltf->myNext = nullptr; 1421 // DeleteSummands(old_ltf); 1422 // } 1423 1424 1425 // void RingExtAlgImpl::AddMul(RawPtr rawf, const WeylPoly::summand* s, ConstRawPtr rawg, bool SkipLM) const 1426 // { 1427 // //// std::clog << "AddMul: Doing funny product of the following two polys" << endl; 1428 // //// output(std::clog, rawg); 1429 // ASSERT(f.WeylPolyPtr->myRefCount == 1); 1430 // // MakeWritable(f); 1431 1432 // RingElem ppg(*this); 1433 // assign(raw(ppg), rawg); 1434 // vector<long> expv(myNumIndets); 1435 // ordering(myPPM).ComputeExpv(&expv[0], s->myOrdv); 1436 // //// std::clog << "expv: "; for (int i=0; i<myNumIndets;++i) std::clog << expv[i] << " "; std::clog << endl; 1437 // for (long var = myNumIndets/2; var < myNumIndets; ++var) 1438 // { 1439 // const long n = expv[var]; 1440 // if (n == 0) continue; 1441 // //// std::clog << "AddMul: doing D variable with index " << n << endl; 1442 // RingElem der(*this); 1443 // assign(raw(der), raw(ppg)); 1444 // // ppg *= IndetPower(var, n); CANNOT DO THIS --> INFINITE RECURSION 1445 // { 1446 // PlainMul(raw(ppg),raw(ppg),raw(IndetPower(var, n))); 1447 // } 1448 // // mul(raw(ppg), raw(ppg), raw(IndetPower(var, n))); 1449 // for (long i=1; i <= n; ++i) 1450 // { 1451 // deriv(raw(der), raw(der), var-myNumIndets/2); 1452 // //// std::clog << "der(" << i << ")="; output(std::clog, raw(der)); std::clog << endl; 1453 // // ppg += binomial(n, i)*der*IndetPower(var, n-i); // *IndetPower(h, 2*i); // for homog case 1454 // { 1455 // vector<long> expv2(myNumIndets); 1456 // expv2[var] = n-i; 1457 // RingElem shift(*this); 1458 // PushBack(raw(shift), raw(RingElem(myCoeffRing, binomial(n, i))), expv2); 1459 // RingElem tmp(*this); 1460 // PlainMul(raw(tmp), raw(shift), raw(der)); 1461 // //// std::clog << "AddMul: adding "; output(std::clog, raw(tmp)); std::clog << endl; 1462 // add(raw(ppg),raw(ppg),raw(tmp)); 1463 // } 1464 // } 1465 // } 1466 // { // f *= var^deg(pp, var); for the early vars 1467 // for (long var = myNumIndets/2; var < myNumIndets; ++var) 1468 // expv[var] = 0; 1469 // PPMonoid::elem qq(myPPM, expv); 1470 // RingElem c(myCoeffRing); 1471 // myCoeffRing.assign(raw(c), s->myCoeff); 1472 // PlainMul(raw(ppg), raw(ppg), raw(monomial(c, qq))); 1473 // /// f *= P.monomial(RingElem(CoeffRing(P), 1), qq); 1474 // } 1475 // //// std::clog << "AddMul: OUTPUT "; output(std::clog, raw(ppg)); std::clog << endl; 1476 // add(f, f, raw(ppg)); 1477 // } 1478 1479 1480 // void RingExtAlgImpl::AddMul2(RawPtr rawf, ConstRawPtr rawh, ConstRawPtr rawg, bool SkipLM) const //???? delete me??? 1481 // { //??? 1482 // AddMul(f, (AsWeylPoly(h).mySummands), rawg, SkipLM); //??? 1483 // } //??? 1484 1485 // void RingExtAlgImpl::PlainMul(RawPtr rawlhs, ConstRawPtr rawx, ConstRawPtr rawy) const 1486 // { 1487 // if (NumTerms(x) > NumTerms(y)) { PlainMul(lhs, rawy, rawx); return; } 1488 1489 // RingElem ans(*this); 1490 1491 // for (const WeylPoly::summand* xterm = AsWeylPoly(x).mySummands; xterm; xterm = xterm->myNext) 1492 // PlainAddMul(raw(ans), xterm, rawy, false);//????? 1493 1494 // swap(raw(ans), lhs); // really an assignment 1495 // } 1496 // void RingExtAlgImpl::PlainAddMul(RawPtr rawf, const WeylPoly::summand* s, ConstRawPtr rawg, bool SkipLM) const 1497 // { 1498 // // ASSERT(f.DMPIPtr->myRefCount == 1); 1499 // // MakeWritable(f); 1500 // // std::clog << "\nF := "; output(std::clog,f); 1501 // // std::clog<<";\nG := "; output(std::clog,g); 1502 // // std::clog<<endl; 1503 // // std::clog<<"s = "; 1504 // // myCoeffRing.output(std::clog, s->myCoeff); 1505 // // std::clog<<"x^("; 1506 // // for(long i=0;i<myOrdvWords;++i)std::clog<<s->myOrdv[i]<<" "; 1507 // // std::clog<<")"<<endl; 1508 // const AbstractRing& R = myCoeffRing; 1509 // typedef WeylPoly::summand summand; 1510 // const summand* g_smnd = AsWeylPoly(g).mySummands; 1511 // if (SkipLM) g_smnd = g_smnd->myNext; 1512 // summand** f_prev = &(AsWeylPoly(f).mySummands); 1513 // summand* f_smnd = *f_prev; 1514 1515 // summand* tmp_smnd = InitSummand(AllocSummand()); // just sets coeff = 0 1516 1517 // int CMP=0; 1518 1519 // // bool qIsOne = (myPPM.cmp(q, tmpPP)==0); 1520 // bool qIsOne = false; 1521 1522 // for (; f_smnd != nullptr && g_smnd != nullptr; g_smnd = g_smnd->myNext) 1523 // { 1524 // if (qIsOne) 1525 // while (f_smnd != nullptr && (CMP=ordering(myPPM).CmpOrdvs(f_smnd->myOrdv,g_smnd->myOrdv)) >0) 1526 // f_smnd = *(f_prev = &f_smnd->myNext); 1527 // else 1528 // { 1529 // MulOrdv(tmp_smnd->myOrdv, s->myOrdv, g_smnd->myOrdv); 1530 // while (f_smnd != nullptr && (CMP=ordering(myPPM).CmpOrdvs(f_smnd->myOrdv,tmp_smnd->myOrdv)) >0) 1531 // f_smnd = *(f_prev = &f_smnd->myNext); 1532 // } 1533 // if (f_smnd == nullptr) 1534 // { 1535 // R.mul(tmp_smnd->myCoeff, s->myCoeff, g_smnd->myCoeff); 1536 // PushBack(f, tmp_smnd); 1537 // tmp_smnd = InitSummand(AllocSummand()); 1538 // g_smnd = g_smnd->myNext; 1539 // break; 1540 // } 1541 // if (CMP == 0) 1542 // { 1543 // if (R.IsZeroAddMul(f_smnd->myCoeff, s->myCoeff, g_smnd->myCoeff)) 1544 // RemoveSmnd(f, f_prev); // f_prev = f_prev; 1545 // else 1546 // f_prev = &f_smnd->myNext; 1547 // f_smnd = *f_prev; 1548 // } 1549 // else // (CMP < 0) 1550 // { 1551 // R.mul(tmp_smnd->myCoeff, s->myCoeff, g_smnd->myCoeff); 1552 // InsertSmnd(f, tmp_smnd, f_prev); 1553 // tmp_smnd = InitSummand(AllocSummand()); 1554 // f_prev = &(*f_prev)->myNext; 1555 // // f_smnd = f_smnd; 1556 // } 1557 // } 1558 // for (;g_smnd != nullptr; g_smnd = g_smnd->myNext) 1559 // { 1560 // MulOrdv(tmp_smnd->myOrdv, s->myOrdv, g_smnd->myOrdv); 1561 // R.mul(tmp_smnd->myCoeff, s->myCoeff, g_smnd->myCoeff); 1562 // PushBack(f, tmp_smnd); 1563 // tmp_smnd = InitSummand(AllocSummand()); 1564 // } 1565 // DeleteSummands(tmp_smnd); // next ptr will be zero (set by InitSummand) 1566 // // std::clog << "AddMul: produced f=";output(std::clog,f);std::clog<<endl; 1567 // // std::clog << "------------------------------------------------------"<<endl; 1568 1569 // } 1570 1571 1572 1573 1574 1575 // void RingExtAlgImpl::ReductionStep(RawPtr rawf, ConstRawPtr rawg) const 1576 // { 1577 // // std::clog << "\nRingExtAlgImpl::reduce" << endl; 1578 // // std::clog << "\nF := "; output(std::clog,f); 1579 // // std::clog<<";\nG := "; output(std::clog,g); 1580 // // std::clog<<";"<<endl; 1581 // ASSERT(&g!=&f); 1582 // const AbstractRing& R = myCoeffRing; 1583 // const WeylPoly::summand* g_smnd = AsWeylPoly(g).mySummands; 1584 // const WeylPoly::summand* f_smnd = AsWeylPoly(f).mySummands; 1585 // WeylPoly::summand* tmp_smnd = InitSummand(AllocSummand()); // just sets coeff = 0 1586 1587 // DivOrdv(tmp_smnd->myOrdv, f_smnd->myOrdv, g_smnd->myOrdv); 1588 // R.div(tmp_smnd->myCoeff, f_smnd->myCoeff, g_smnd->myCoeff); 1589 // R.negate(tmp_smnd->myCoeff, tmp_smnd->myCoeff); 1590 1591 // // std::clog<<"-- S := "; 1592 // // myCoeffRing.output(std::clog, tmp_smnd->myCoeff); 1593 // // std::clog<<"x^("; 1594 // // for(long i=0;i<myOrdvWords;++i)std::clog<<tmp_smnd->myOrdv[i]<<" "; 1595 // // std::clog<<")"<<endl; 1596 1597 // DeleteLM(f); 1598 // AddMul(f, tmp_smnd, g, true /*SkipLM*/); 1599 1600 // DeleteSummands(tmp_smnd); // next ptr will be zero (set by InitSummand) 1601 // // std::clog << "H := "; output(std::clog,f); 1602 // // std::clog << ";\n--------------------------------------------------"<<endl; 1603 // } 1604 1605 1606 // void RingExtAlgImpl::AddClear(RawPtr rawf, RawPtr rawg) const 1607 // { 1608 // ASSERT(f.WeylPolyPtr->myRefCount == 1); 1609 // // MakeWritable(f); 1610 // MakeWritable(g); 1611 // // input polynomial are copied 1612 // //if (g.WeylPolyPtr->myRefCount != 1) 1613 // // std::clog << "AddClear: g.myRefCount == " << g.WeylPolyPtr->myRefCount << endl; 1614 // const AbstractRing& R = myCoeffRing; 1615 // typedef WeylPoly::summand summand; 1616 // WeylPoly& F = AsWeylPoly(f); 1617 // WeylPoly& G = AsWeylPoly(g); 1618 // summand* g_smnd = G.mySummands; 1619 // summand** f_prev = &(F.mySummands); 1620 // summand* f_smnd = *f_prev; 1621 // int CMP=0; 1622 // ASSERT(*(G.myEnd)==nullptr);//BUG HUNTING ??? 1623 1624 // // std::clog << "input f = "; output(std::clog, f) ;std::clog << endl; 1625 // while ( f_smnd!=nullptr && g_smnd!=nullptr ) 1626 // { 1627 // while (f_smnd!=nullptr && 1628 // (CMP=ordering(myPPM).CmpOrdvs(f_smnd->myOrdv,g_smnd->myOrdv)) >0) 1629 // f_smnd = *(f_prev = &f_smnd->myNext); 1630 // if (f_smnd == nullptr) break; 1631 // //std::clog << "(AddClear error: should never happen for Basic Reduction)" << endl; 1632 // G.mySummands = G.mySummands->myNext; 1633 // g_smnd->myNext = nullptr; 1634 // if (CMP == 0) 1635 // { 1636 // R.add(f_smnd->myCoeff, f_smnd->myCoeff, g_smnd->myCoeff); 1637 // if (R.IsZero(f_smnd->myCoeff)) 1638 // RemoveSmnd(f, f_prev); 1639 // DeleteSummands(g_smnd); 1640 // } 1641 // else // (CMP < 0) 1642 // { 1643 // InsertSmnd(f, g_smnd, f_prev); 1644 // f_prev = &(*f_prev)->myNext; 1645 // } 1646 // f_smnd = *f_prev; 1647 // g_smnd = G.mySummands; 1648 // } 1649 // if (G.mySummands!=nullptr) 1650 // { 1651 // *(F.myEnd) = G.mySummands; 1652 // F.myEnd = G.myEnd; 1653 // G.mySummands = nullptr; 1654 // } 1655 // G.myEnd = &G.mySummands; 1656 // // if (rare) {std::clog << "f2 = "; output(std::clog, f) ;std::clog << endl;} 1657 // } 1658 1659 1660 // void RingExtAlgImpl::AppendClear(RawPtr rawf, RawPtr rawg) const 1661 // { 1662 // ASSERT(f.WeylPolyPtr->myRefCount == 1); 1663 // // MakeWritable(f); 1664 // MakeWritable(g); 1665 // // input polynomial are copied 1666 // //if (g.WeylPolyPtr->myRefCount != 1) 1667 // // std::clog << "AppendClear: g.myRefCount == " << g.WeylPolyPtr->myRefCount << endl; 1668 // WeylPoly& F = AsWeylPoly(f); 1669 // WeylPoly& G = AsWeylPoly(g); 1670 // if (G.mySummands!=nullptr) 1671 // { 1672 // *(F.myEnd) = G.mySummands; 1673 // F.myEnd = G.myEnd; 1674 // G.mySummands = nullptr; 1675 // } 1676 // G.myEnd = &G.mySummands; 1677 // // if (rare) {std::clog << "f2 = "; output(std::clog, f) ;std::clog << endl;} 1678 // } 1679 1680 1681 // int RingExtAlgImpl::CmpLPP(ConstRawPtr rawf, ConstRawPtr rawg) const 1682 // { 1683 // ASSERT(!IsZero(f)); 1684 // ASSERT(!IsZero(g)); 1685 // return ordering(myPPM).CmpOrdvs(AsWeylPoly(f).mySummands->myOrdv,AsWeylPoly(g).mySummands->myOrdv); 1686 // } 1687 1688 1689 // void RingExtAlgImpl::DivLM(RawPtr rawlhs, ConstRawPtr rawf, ConstRawPtr rawg) const 1690 // { 1691 // // std::clog << "DivLM" << endl; 1692 // const AbstractRing& R = myCoeffRing; 1693 // typedef WeylPoly::summand summand; 1694 // const summand* f_smnd = AsWeylPoly(f).mySummands; 1695 // const summand* g_smnd = AsWeylPoly(g).mySummands; 1696 // MakeWritable(lhs); 1697 // assign(lhs,0); 1698 // summand* SpareSummand = InitSummand(AllocSummand()); 1699 // R.div(SpareSummand->myCoeff, f_smnd->myCoeff, g_smnd->myCoeff); 1700 // DivOrdv(SpareSummand->myOrdv, f_smnd->myOrdv, g_smnd->myOrdv); 1701 // PushBack(lhs, SpareSummand); 1702 // } 1703 1704 1705 // void RingExtAlgImpl::mul(RawPtr rawf, const PPMonoid::elem& pp) const 1706 // { 1707 // // bool qIsOne = (myPPM.cmp(q, tmpPP)==0); 1708 // MakeWritable(f); 1709 // std::vector<long> v(myNumIndets); 1710 // myPPM.exponents(v, raw(pp)); 1711 1712 // WeylPoly::summand* f_smnd = AsWeylPoly(f).mySummands; 1713 // WeylPoly::summand* s = InitSummand(AllocSummand()); 1714 1715 // ordering(myPPM).ComputeOrdv(s->myOrdv, &v[0]); // &v[0] converts vector<T> to T* 1716 1717 // for (; f_smnd != nullptr ; f_smnd = f_smnd->myNext) 1718 // MulOrdv(f_smnd->myOrdv, f_smnd->myOrdv, s->myOrdv); 1719 // } 1720 1721 1722 // void RingExtAlgImpl::PushFront(RawPtr rawf, ConstRawPtr rawc, const std::vector<long>& expv) const 1723 // { 1724 // if (CoeffRing().IsZero(c)) return; 1725 // MakeWritable(f); 1726 // WeylPoly::summand* t = AllocSummand(); 1727 // InitSummand(t, c, expv); 1728 // t->myNext = f.WeylPolyPtr->mySummands; 1729 // if (f.WeylPolyPtr->mySummands == nullptr) f.WeylPolyPtr->myEnd = &t->myNext; 1730 // f.WeylPolyPtr->mySummands = t; 1731 // } 1732 1733 1734 // void RingExtAlgImpl::PushBack(RawPtr rawf, ConstRawPtr rawc, const std::vector<long>& expv) const 1735 // { 1736 // if (CoeffRing().IsZero(c)) return; 1737 // MakeWritable(f); 1738 // WeylPoly::summand* t = AllocSummand(); 1739 // InitSummand(t, c, expv); 1740 // *(f.WeylPolyPtr->myEnd) = t; 1741 // f.WeylPolyPtr->myEnd = &t->myNext; 1742 // } 1743 1744 1745 // void RingExtAlgImpl::PushFront(RawPtr rawx, WeylPoly::summand* t) const 1746 // { 1747 // MakeWritable(x); 1748 // WeylPoly& f = AsWeylPoly(x); 1749 // t->myNext = f.mySummands; 1750 // f.mySummands = t; 1751 // if (f.myEnd == &f.mySummands) f.myEnd = &t->myNext; 1752 // } 1753 1754 1755 // void RingExtAlgImpl::PushBack(RawPtr rawx, WeylPoly::summand* t) const 1756 // { 1757 // MakeWritable(x); 1758 // WeylPoly& f = AsWeylPoly(x); 1759 // *f.myEnd = t; 1760 // f.myEnd = &t->myNext; 1761 // } 1762 1763 1764 // void RingExtAlgImpl::RemoveSmnd(RawPtr rawx, WeylPoly::summand** prev_link) const 1765 // { 1766 // ASSERT(x.WeylPolyPtr->myRefCount == 1); 1767 // // MakeWritable(x); 1768 // WeylPoly::summand* tmp = *prev_link; 1769 // ASSERT(tmp != 0); 1770 // if (tmp->myNext==nullptr) // f.myEnd == &(tmp->myNext) 1771 // { 1772 // WeylPoly& f = AsWeylPoly(x); 1773 // f.myEnd = prev_link; 1774 // } 1775 // *prev_link = tmp->myNext; 1776 // tmp->myNext = nullptr; 1777 // DeleteSummands(tmp); 1778 // } 1779 1780 1781 // void RingExtAlgImpl::InsertSmnd(RawPtr rawx, WeylPoly::summand* s, WeylPoly::summand** prev_link) const 1782 // { 1783 // ASSERT(x.WeylPolyPtr->myRefCount == 1); 1784 // // MakeWritable(x); 1785 // WeylPoly& f = AsWeylPoly(x); 1786 // s->myNext = (*prev_link); 1787 // (*prev_link) = s; 1788 // if (f.myEnd == prev_link) f.myEnd = &(s->myNext); 1789 // } 1790 1791 1792 // PPMonoid::elem RingExtAlgImpl::LPP(ConstRawPtr rawf) const 1793 // { 1794 // ASSERT(!IsZero(f)); 1795 // return PPMonoid::elem(PPM(), PPMonoid::elem::FromOrdv, AsWeylPoly(f).mySummands->myOrdv); 1796 // } 1797 1798 1799 // bool RingExtAlgImpl::IsZeroAddLCs(RawPtr rawf, RawPtr rawg) const 1800 // { 1801 // ASSERT(!IsZero(f) && !IsZero(g)); 1802 // ASSERT( CmpLPP(f,g) == 0); 1803 // WeylPoly& F = AsWeylPoly(f); 1804 // WeylPoly& G = AsWeylPoly(g); 1805 // ASSERT(F.myRefCount==1 && G.myRefCount==1); 1806 // myCoeffRing.add(F.mySummands->myCoeff, F.mySummands->myCoeff, G.mySummands->myCoeff); 1807 // DeleteLM(g); 1808 // if (!myCoeffRing.IsZero(F.mySummands->myCoeff)) return false; 1809 // DeleteLM(f); 1810 // return true; 1811 // } 1812 1813 1814 // void RingExtAlgImpl::deriv(RawPtr rawdest, ConstRawPtr rawf, long var) const 1815 // { 1816 // const WeylPoly& F = AsWeylPoly(f); 1817 // RingElem ans(*this); 1818 // vector<long> expv(myNumIndets); 1819 // for (WeylPoly::summand* i=F.mySummands; i; i = i->myNext) 1820 // { 1821 // ordering(myPPM).ComputeExpv(&expv[0], i->myOrdv); 1822 // if (expv[var] == 0) continue; 1823 // RingElem c(myCoeffRing, expv[var]); 1824 // if (CoCoA::IsZero(c)) continue; 1825 // myCoeffRing.mul(raw(c), raw(c), i->myCoeff); 1826 // if (CoCoA::IsZero(c)) continue; 1827 // --expv[var]; 1828 // PushBack(raw(ans), raw(c), expv); 1829 // } 1830 // swap(raw(ans), dest); 1831 // } 1832 1833 1834 // void RingExtAlgImpl::negate(RawPtr rawlhs, ConstRawPtr rawx) const 1835 // { 1836 // if (lhs.WeylPolyPtr == x.WeylPolyPtr) 1837 // { 1838 // MakeWritable(lhs); 1839 // typedef WeylPoly::summand summand; 1840 // // std::clog << "-- negate"; output(std::clog, lhs); std::clog << endl; 1841 // for (summand* smnd = AsWeylPoly(lhs).mySummands; smnd!=nullptr; smnd=smnd->myNext ) 1842 // myCoeffRing.negate(smnd->myCoeff, smnd->myCoeff); 1843 // // std::clog << "-> negate"; output(std::clog, lhs); std::clog << endl; 1844 // } 1845 // else 1846 // std::clog << "RingExtAlgImpl::negate: not yet implemented" << endl; 1847 // } 1848 1849 1850 // void RingExtAlgImpl::add(RawPtr rawlhs, ConstRawPtr rawx, ConstRawPtr rawy) const 1851 // { 1852 // const AbstractRing& R = myCoeffRing; 1853 // RawValue ans; 1854 // // ans.WeylPolyPtr = static_cast<WeylPoly*>(myWeylPolyPool.alloc(sizeof(WeylPoly))); 1855 // init(ans); 1856 // /// WeylPoly& sum = AsWeylPoly(ans); 1857 // typedef WeylPoly::summand summand; 1858 // const summand* gterm = AsWeylPoly(x).mySummands; 1859 // const summand* hterm = AsWeylPoly(y).mySummands; 1860 // summand* SpareSummand = InitSummand(AllocSummand()); // just sets coeff = 0 1861 // while (gterm != null && hterm != nullptr) 1862 // { 1863 // const int cmp = ordering(myPPM).CmpOrdvs(gterm->myOrdv, hterm->myOrdv); 1864 1865 // if (cmp < 0) 1866 // { 1867 // summand* hcopy = CopySummand(hterm); 1868 // PushBack(ans, hcopy); 1869 // hterm = hterm->myNext; 1870 // continue; 1871 // } 1872 1873 // if (cmp > 0) 1874 // { 1875 // summand* gcopy = CopySummand(gterm); 1876 // PushBack(ans, gcopy); 1877 // gterm = gterm->myNext; 1878 // continue; 1879 // } 1880 1881 // // Must have cmp == 0 here. 1882 // // The leading PPs are the same, so we must sum the coeffs. 1883 // R.add(SpareSummand->myCoeff, gterm->myCoeff, hterm->myCoeff); 1884 // if (!R.IsZero(SpareSummand->myCoeff)) 1885 // { 1886 // SetSummandMOrdv(SpareSummand, gterm); // set module posn and PP 1887 // PushBack(ans, SpareSummand); 1888 // SpareSummand = InitSummand(AllocSummand());// just sets coeff = 0 1889 // } 1890 // gterm = gterm->myNext; 1891 // hterm = hterm->myNext; 1892 // } 1893 // while (gterm != nullptr) 1894 // { 1895 // summand* gcopy = CopySummand(gterm); 1896 // PushBack(ans, gcopy); 1897 // gterm = gterm->myNext; 1898 // } 1899 // while (hterm != nullptr) 1900 // { 1901 // summand* hcopy = CopySummand(hterm); 1902 // PushBack(ans, hcopy); 1903 // hterm = hterm->myNext; 1904 // } 1905 // DeleteSummands(SpareSummand); // next ptr will be zero (set by InitSummand) 1906 // swap(lhs, ans); // really an assignment 1907 // kill(ans); 1908 // } 1909 1910 1911 // void RingExtAlgImpl::sub(RawPtr rawlhs, ConstRawPtr rawx, ConstRawPtr rawy) const 1912 // { 1913 // // This code copied from RingExtAlgImpl::add... 1914 1915 // const AbstractRing& R = myCoeffRing; 1916 // RawValue ans; 1917 // // ans.WeylPolyPtr = static_cast<WeylPoly*>(myWeylPolyPool.alloc(sizeof(WeylPoly))); 1918 // init(ans); 1919 // /// WeylPoly& sum = AsWeylPoly(ans); 1920 // typedef WeylPoly::summand summand; 1921 // const summand* gterm = AsWeylPoly(x).mySummands; 1922 // const summand* hterm = AsWeylPoly(y).mySummands; 1923 // summand* SpareSummand = InitSummand(AllocSummand()); // just sets coeff = 0 1924 // while (gterm != nullptr && hterm != nullptr) 1925 // { 1926 // const int ord = ordering(myPPM).CmpOrdvs(gterm->myOrdv, hterm->myOrdv); 1927 1928 // if (ord < 0) 1929 // { 1930 // summand* hcopy = CopySummand(hterm); 1931 // R.negate(hcopy->myCoeff, hcopy->myCoeff); 1932 // // sum.push_front(hcopy); 1933 // PushBack(ans, hcopy); 1934 // hterm = hterm->myNext; 1935 // continue; 1936 // } 1937 1938 // if (ord > 0) 1939 // { 1940 // summand* gcopy = CopySummand(gterm); 1941 // // sum.push_front(gcopy); 1942 // PushBack(ans, gcopy); 1943 // gterm = gterm->myNext; 1944 // continue; 1945 // } 1946 1947 // // The leading PPs are the same, so we must sum the coeffs. 1948 // R.sub(SpareSummand->myCoeff, gterm->myCoeff, hterm->myCoeff); 1949 // if (!R.IsZero(SpareSummand->myCoeff)) 1950 // { 1951 // SetSummandMOrdv(SpareSummand, gterm); // set module posn and PP 1952 // // sum.push_front(SpareSummand); 1953 // PushBack(ans, SpareSummand); 1954 // SpareSummand = InitSummand(AllocSummand());// just sets coeff = 0 1955 // } 1956 // gterm = gterm->myNext; 1957 // hterm = hterm->myNext; 1958 // } 1959 // while (gterm != nullptr) 1960 // { 1961 // summand* gcopy = CopySummand(gterm); 1962 // // sum.push_front(gcopy); 1963 // PushBack(ans, gcopy); 1964 // gterm = gterm->myNext; 1965 // } 1966 // while (hterm != nullptr) 1967 // { 1968 // summand* hcopy = CopySummand(hterm); 1969 // // sum.push_front(hcopy); 1970 // R.negate(hcopy->myCoeff, hcopy->myCoeff); 1971 // PushBack(ans, hcopy); 1972 // hterm = hterm->myNext; 1973 // } 1974 // DeleteSummands(SpareSummand); // next ptr will be zero (set by InitSummand) 1975 // /// NO LONGER NEEDED sum.reverse(); 1976 // swap(lhs, ans); // really an assignment 1977 // kill(ans); 1978 // } 1979 1980 1981 // void RingExtAlgImpl::mul(RawPtr rawlhs, ConstRawPtr rawx, ConstRawPtr rawy) const 1982 // { 1983 // // NO!! NOT COMMUTATIVE!! if (NumTerms(x) > NumTerms(y)) { mul(lhs, y, x); return; } 1984 1985 // //// std::clog << "MUL on "; output(std::clog, x); std::clog << " and "; output(std::clog, y); std::clog << endl; 1986 // RingElem ans(*this); 1987 1988 // for (const WeylPoly::summand* xterm = AsWeylPoly(x).mySummands; xterm; xterm = xterm->myNext) 1989 // AddMul(raw(ans), xterm, y, false);//????? 1990 1991 // swap(raw(ans), lhs); // really an assignment 1992 // } 1993 1994 1995 1996 1997 1998 // RCS header/log in the next few lines 1999 // $Header: /Volumes/Home_1/cocoa/cvs-repository/CoCoALib-0.99/src/AlgebraicCore/RingExtAlg.C,v 1.14 2020/06/17 15:49:26 abbott Exp $ 2000 // $Log: RingExtAlg.C,v $ 2001 // Revision 1.14 2020/06/17 15:49:26 abbott 2002 // Summary: Changed CoCoA_ERROR into CoCoA_THROW_ERROR 2003 // 2004 // Revision 1.13 2020/02/12 09:01:47 bigatti 2005 // -- changed myTestIsMaximal etc to return void (and consequences) 2006 // 2007 // Revision 1.12 2020/02/11 16:56:41 abbott 2008 // Summary: Corrected last update (see redmine 969) 2009 // 2010 // Revision 1.11 2020/02/11 16:12:19 abbott 2011 // Summary: Added some checks for bad ostream (even to mem fns myOutput); see redmine 969 2012 // 2013 // Revision 1.10 2019/10/15 11:54:08 abbott 2014 // Summary: Changed 0 into nullptr (where appropriate) 2015 // 2016 // Revision 1.9 2019/03/04 16:16:07 abbott 2017 // Summary: Changed auto_ptr into unique_ptr 2018 // 2019 // Revision 1.8 2018/06/27 08:50:39 abbott 2020 // Summary: Revised to work with new CpuTimeLimit 2021 // 2022 // Revision 1.7 2018/05/25 09:24:46 abbott 2023 // Summary: Major redesign of CpuTimeLimit (many consequences) 2024 // 2025 // Revision 1.6 2018/05/18 12:15:56 bigatti 2026 // -- renamed IntOperations --> BigIntOps 2027 // 2028 // Revision 1.5 2018/05/17 15:41:33 bigatti 2029 // -- renamed MatrixOperations --> MatrixOps 2030 // 2031 // Revision 1.4 2018/04/18 14:31:23 abbott 2032 // Summary: Added some missing returns (in NYI fns) 2033 // 2034 // Revision 1.3 2018/03/29 09:36:40 bigatti 2035 // -- added member functions myTestIsRadical, myTestIsPrimary and flags 2036 // 2037 // Revision 1.2 2018/03/20 11:38:08 bigatti 2038 // -- changed iAm***Test --> myTestIs***; and it returns bool 2039 // 2040 // Revision 1.1 2018/01/31 10:01:29 abbott 2041 // Summary: Added new files RingExtAlg (exterior algebra) 2042 // 2043 // 2044