1 // Copyright (c) 2005,2007,2010 John Abbott 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 // Implementation of class PPMonoidEvOvImpl 20 21 #include "CoCoA/PPMonoidEvOv.H" 22 23 #include "CoCoA/BigIntOps.H" 24 #include "CoCoA/DivMask.H" 25 #include "CoCoA/MemPool.H" 26 #include "CoCoA/OrdvArith.H" 27 #include "CoCoA/PPMonoid.H" 28 #include "CoCoA/PPOrdering.H" 29 #include "CoCoA/assert.H" 30 #include "CoCoA/convert.H" 31 #include "CoCoA/degree.H" 32 #include "CoCoA/error.H" 33 #include "CoCoA/matrix.H" 34 #include "CoCoA/symbol.H" 35 36 #include <algorithm> 37 using std::min; 38 using std::max; 39 //using std::swap; 40 #include <cstring> 41 using std::memcpy; 42 #include <iostream> 43 using std::ostream; 44 #include<limits> 45 using std::numeric_limits; 46 #include <memory> 47 using std::unique_ptr; 48 #include <vector> 49 using std::vector; 50 51 52 namespace CoCoA 53 { 54 55 /*-- class PPMonoidEvOvImpl ---------------------------------------*/ 56 /** 57 58 \brief Implementation of power product monoid for fast generic use 59 60 PPMonoidEvOv implements a power product monoid for generic use as 61 it stores exp vector and order vector. 62 Compared with PPMonoidSafe, PPMonoidEvOv is: 63 - slower for gcd/lcm because it has to update the order vector; 64 - faster for comparisons expecially with matrix defined orderings. 65 66 So this type is good for you if 67 (1) you do not perform many gcd/lcm 68 (2) you need efficiency in ordering test 69 70 */ 71 /*-----------------------------------------------------------------*/ 72 73 class PPMonoidEvOvImpl: public PPMonoidBase 74 { 75 typedef PPMonoidElemRawPtr RawPtr; // just to save typing 76 typedef PPMonoidElemConstRawPtr ConstRawPtr; // just to save typing 77 typedef OrdvArith::OrdvElem OrdvElem; // just to save typing 78 79 static const unsigned long ourMaxExp; // defined below; value is just numeric_limits<SmallExponent_t>::max() 80 81 public: 82 PPMonoidEvOvImpl(const std::vector<symbol>& IndetNames, const PPOrdering& ord); 83 ~PPMonoidEvOvImpl(); 84 private: // disable copy ctor and assignment 85 explicit PPMonoidEvOvImpl(const PPMonoidEvOvImpl& copy); // NEVER DEFINED -- copy ctor disabled 86 PPMonoidEvOvImpl& operator=(const PPMonoidEvOvImpl& rhs); // NEVER DEFINED -- assignment disabled 87 88 public: 89 void contents() const; // FOR DEBUGGING ONLY 90 91 const std::vector<PPMonoidElem>& myIndets() const; ///< std::vector whose n-th entry is n-th indet as PPMonoidElem 92 93 // The functions below are operations on power products owned by PPMonoidEvOvImpl 94 const PPMonoidElem& myOne() const; 95 using PPMonoidBase::myNew; // disable warnings of overloading 96 PPMonoidElemRawPtr myNew() const; ///< ctor from nothing 97 PPMonoidElemRawPtr myNew(PPMonoidElemConstRawPtr rawpp) const; ///< ctor by assuming ownership 98 PPMonoidElemRawPtr myNew(const std::vector<long>& expv) const; ///< ctor from exp vector 99 //NYI PPMonoidElemRawPtr myNew(const std::vector<BigInt>& EXPV) const;///< ctor from exp vector 100 void myDelete(RawPtr rawpp) const; ///< dtor, frees pp 101 void mySwap(RawPtr rawpp1, RawPtr rawpp2) const; ///< swap(pp1, pp2); 102 void myAssignOne(RawPtr rawpp) const; ///< pp = 1 103 void myAssign(RawPtr rawpp, ConstRawPtr rawpp1) const; ///< p = pp1 104 void myAssign(RawPtr rawpp, const std::vector<long>& expv) const; ///< pp = expv (assign from exp vector) 105 106 void myMul(RawPtr rawpp, ConstRawPtr rawpp1, ConstRawPtr rawpp2) const; ///< pp = pp1*pp2 107 using PPMonoidBase::myMulIndetPower; // disable warnings of overloading 108 void myMulIndetPower(RawPtr rawpp, long indet, long exp) const; ///< pp *= indet^exp, assumes exp >= 0 109 void myDiv(RawPtr rawpp, ConstRawPtr rawpp1, ConstRawPtr rawpp2) const; ///< pp = pp1/pp2 110 void myColon(RawPtr rawpp, ConstRawPtr rawpp1, ConstRawPtr rawpp2) const; ///< pp = pp1/gcd(pp1,pp2) 111 void myGcd(RawPtr rawpp, ConstRawPtr rawpp1, ConstRawPtr rawpp2) const; ///< pp = gcd(pp1,pp2) 112 void myLcm(RawPtr rawpp, ConstRawPtr rawpp1, ConstRawPtr rawpp2) const; ///< pp = lcm(pp1,pp2) 113 void myRadical(RawPtr rawpp, ConstRawPtr rawpp1) const; ///< pp = radical(pp1) 114 void myPowerSmallExp(RawPtr rawpp, ConstRawPtr rawpp1, long exp) const; ///< pp = pp1^exp, assumes exp >= 0 115 void myPowerOverflowCheck(ConstRawPtr rawpp1, long exp) const; ///< throw if pp1^exp would overflow, assumes exp >= 0 116 117 bool myIsOne(ConstRawPtr rawpp) const; ///< is pp = 1? 118 bool myIsIndet(long& index, ConstRawPtr rawpp) const; ///< true iff pp is an indet 119 bool myIsCoprime(ConstRawPtr rawpp1, ConstRawPtr rawpp2) const; ///< are pp1 & pp2 coprime? 120 bool myIsEqual(ConstRawPtr rawpp1, ConstRawPtr rawpp2) const; ///< is pp1 equal to pp2? 121 bool myIsDivisible(ConstRawPtr rawpp1, ConstRawPtr rawpp2) const; ///< does pp2 divide pp1? 122 bool myIsSqFree(ConstRawPtr rawpp) const; ///< is pp equal to its radical? 123 124 int myCmp(ConstRawPtr rawpp1, ConstRawPtr rawpp2) const; ///< -1,0,1 as pp1 < = > pp2 125 long myStdDeg(ConstRawPtr rawpp) const; ///< standard degree of pp 126 void myWDeg(degree& d, ConstRawPtr rawpp) const; ///< d = grading(pp) 127 int myCmpWDeg(ConstRawPtr rawpp1, ConstRawPtr rawpp2) const; ///< <0, =0, >0 as wdeg(pp1) < = > wdeg(pp2) 128 int myCmpWDegPartial(ConstRawPtr rawpp1, ConstRawPtr rawpp2, long) const; ///< as myCmpWDeg wrt the first weights 129 long myExponent(ConstRawPtr rawpp, long indet) const; ///< exponent of indet in pp 130 void myBigExponent(BigInt& EXP, ConstRawPtr rawpp, long indet) const; ///< EXP = exponent of indet in pp 131 void myExponents(std::vector<long>& expv, ConstRawPtr rawpp) const; ///< expv[i] = exponent(pp,i) 132 void myBigExponents(std::vector<BigInt>& v, ConstRawPtr rawpp) const; ///< get exponents, SHOULD BE myExponents ??? 133 void myIndetsIn(std::vector<bool>& v, ConstRawPtr rawpp) const; ///< v[i] = true if i-th indet has exponent != 0 134 void myOutputSelf(std::ostream& out) const; ///< out << PPM 135 // INHERITED DEFINITION of virtual void myOutput(std::ostream& out, ConstRawPtr rawpp) const; 136 void myDebugPrint(std::ostream& out, ConstRawPtr rawpp) const; ///< print pp in debugging format??? 137 138 139 private: // auxiliary functions 140 SmallExponent_t* myExpv(RawPtr) const; 141 const SmallExponent_t* myExpv(ConstRawPtr) const; 142 OrdvElem* myOrdv(RawPtr) const; 143 const OrdvElem* myOrdv(ConstRawPtr) const; 144 145 void myComputeDivMask(DivMask& dm, const DivMaskRule& DivMaskImpl, ConstRawPtr rawpp) const; ///< used by PPWithMask 146 void myComputeOrdv(RawPtr) const; 147 bool myCheckExponents(const std::vector<long>& expv) const; 148 149 private: // data members 150 ///@name Class members 151 //@{ 152 OrdvArith::reference myOrdvArith; //??? should be const 153 const long myOrdvSize; ///< used only in myExpv 154 const long myEntrySize; ///< size in bytes 155 mutable MemPool myMemMgr; // IMPORTANT: this must come *before* myIndetVector and myOnePtr. 156 //??? vector<SmallExponent_t> myDelta; 157 vector<PPMonoidElem> myIndetVector; ///< the indets as PPMonoidElems 158 unique_ptr<PPMonoidElem> myOnePtr; 159 //@} 160 }; 161 162 163 // static variable 164 const unsigned long PPMonoidEvOvImpl::ourMaxExp = numeric_limits<SmallExponent_t>::max(); 165 166 167 // File local inline functions 168 myExpv(RawPtr rawpp)169 inline SmallExponent_t* PPMonoidEvOvImpl::myExpv(RawPtr rawpp) const 170 { 171 return reinterpret_cast<SmallExponent_t*>(static_cast<char*>(rawpp.myRawPtr()) + myOrdvSize); 172 } 173 174 myExpv(ConstRawPtr rawpp)175 inline const SmallExponent_t* PPMonoidEvOvImpl::myExpv(ConstRawPtr rawpp) const 176 { 177 return reinterpret_cast<const SmallExponent_t*>(static_cast<const char*>(rawpp.myRawPtr()) + myOrdvSize); 178 } 179 180 myOrdv(RawPtr rawpp)181 inline PPMonoidEvOvImpl::OrdvElem* PPMonoidEvOvImpl::myOrdv(RawPtr rawpp) const 182 { 183 return static_cast<OrdvElem*>(rawpp.myRawPtr()); 184 185 } 186 myOrdv(ConstRawPtr rawpp)187 inline const PPMonoidEvOvImpl::OrdvElem* PPMonoidEvOvImpl::myOrdv(ConstRawPtr rawpp) const 188 { 189 return static_cast<const OrdvElem*>(rawpp.myRawPtr()); 190 } 191 192 myCheckExponents(const std::vector<long> & expv)193 bool PPMonoidEvOvImpl::myCheckExponents(const std::vector<long>& expv) const 194 { 195 // Check expv.size == myNumIndets. 196 // Check exps are non-neg and not too big. 197 if (len(expv) != myNumIndets) return false; 198 for (long i=0; i < myNumIndets; ++i) 199 if (expv[i] < 0 || static_cast<unsigned long>(expv[i]) > numeric_limits<SmallExponent_t>::max()) return false; 200 return true; 201 } 202 203 204 //---- Constructors & destructor ----// 205 PPMonoidEvOvImpl(const std::vector<symbol> & IndetNames,const PPOrdering & ord)206 PPMonoidEvOvImpl::PPMonoidEvOvImpl(const std::vector<symbol>& IndetNames, const PPOrdering& ord): 207 PPMonoidBase(ord, IndetNames), 208 myOrdvArith(NewOrdvArith(ord)), 209 myOrdvSize(sizeof(OrdvElem)*OrdvWords(myOrdvArith)), 210 myEntrySize(myOrdvSize + sizeof(SmallExponent_t)*myNumIndets), 211 myMemMgr(myEntrySize, "PPMonoidEvOvImpl.myMemMgr"), 212 myIndetVector() 213 { 214 // std::cout << "------PPMonoidEvOvImpl:NewOrdvArith-called" << std::endl; 215 myRefCountInc(); // this is needed for exception cleanliness, in case one of the lines below throws 216 myOnePtr.reset(new PPMonoidElem(PPMonoid(this))); 217 { 218 // IMPORTANT: this block destroys pp *before* the call to myRefCountZero. 219 PPMonoidElem pp(PPMonoid(this)); 220 vector<long> expv(myNumIndets); 221 for (long i=0; i < myNumIndets; ++i) 222 { 223 expv[i] = 1; 224 myAssign(raw(pp), expv); 225 myIndetVector.push_back(pp); 226 expv[i] = 0; 227 } 228 } 229 myRefCountZero(); 230 } 231 232 ~PPMonoidEvOvImpl()233 PPMonoidEvOvImpl::~PPMonoidEvOvImpl() 234 {} 235 236 ///////////////////////////////////////////////////////////////////////////// 237 238 myComputeOrdv(RawPtr rawpp)239 inline void PPMonoidEvOvImpl::myComputeOrdv(RawPtr rawpp) const 240 { 241 const SmallExponent_t* const expv = myExpv(rawpp); 242 vector<long> ExpvCopy(myNumIndets); 243 for (long i=0; i < myNumIndets; ++i) 244 ExpvCopy[i] = NumericCast<long>(expv[i]); 245 myOrdvArith->myAssignFromExpv(myOrdv(rawpp), ExpvCopy); 246 } 247 248 myIndets()249 const std::vector<PPMonoidElem>& PPMonoidEvOvImpl::myIndets() const 250 { 251 return myIndetVector; 252 } 253 254 myOne()255 const PPMonoidElem& PPMonoidEvOvImpl::myOne() const 256 { 257 return *myOnePtr; 258 } 259 260 myNew()261 PPMonoidElemRawPtr PPMonoidEvOvImpl::myNew() const 262 { 263 PPMonoidElemRawPtr rawpp(myMemMgr.alloc()); 264 myAssignOne(rawpp); // cannot throw 265 return rawpp; 266 } 267 myNew(PPMonoidElemConstRawPtr rawcopypp)268 PPMonoidElemRawPtr PPMonoidEvOvImpl::myNew(PPMonoidElemConstRawPtr rawcopypp) const 269 { 270 PPMonoidElemRawPtr rawpp(myMemMgr.alloc()); 271 myAssign(rawpp, rawcopypp); // cannot throw 272 return rawpp; 273 } 274 275 myNew(const std::vector<long> & expv)276 PPMonoidElemRawPtr PPMonoidEvOvImpl::myNew(const std::vector<long>& expv) const 277 { 278 CoCoA_ASSERT(myCheckExponents(expv)); 279 PPMonoidElemRawPtr rawpp(myMemMgr.alloc()); 280 myAssign(rawpp, expv); // cannot throw 281 return rawpp; 282 } 283 284 myAssignOne(RawPtr rawpp)285 void PPMonoidEvOvImpl::myAssignOne(RawPtr rawpp) const 286 { 287 SmallExponent_t* const expv = myExpv(rawpp); 288 for (long i = 0; i < myNumIndets; ++i) 289 expv[i] = 0; 290 myOrdvArith->myAssignZero(myOrdv(rawpp)); 291 } 292 293 myAssign(RawPtr rawpp,ConstRawPtr rawpp1)294 void PPMonoidEvOvImpl::myAssign(RawPtr rawpp, ConstRawPtr rawpp1) const 295 { 296 if (rawpp == rawpp1) return; 297 // // This code assumes that myEntrySize is an exact multiple of sizeof(int). 298 // int* const expv = static_cast<int*>(rawpp.myRawPtr()); 299 // const int* const expv1 = static_cast<const int*>(rawpp1.myRawPtr()); 300 // const long NumWords = myEntrySize/sizeof(int); 301 // std::copy(expv1, expv1+NumWords, expv); // does this work??? 302 303 memcpy(myOrdv(rawpp), myOrdv(rawpp1), myEntrySize); 304 305 // This would be a cleaner (but slower) way of achieving the same result... 306 // SmallExponent_t* const exp = myExpv(rawpp); 307 // const SmallExponent_t* const exp_src = myExpv(src); 308 // for (long i=0 ; i<myNumIndets ; ++i ) exp[i] = exp_src[i]; 309 // myOrdvArith->myAssign(myOrdv(rawpp), myOrdv(src)); 310 } 311 myAssign(RawPtr rawpp,const vector<long> & expv)312 void PPMonoidEvOvImpl::myAssign(RawPtr rawpp, const vector<long>& expv) const 313 { 314 CoCoA_ASSERT(myCheckExponents(expv)); 315 316 SmallExponent_t* const expv2 = myExpv(rawpp); 317 for (long i = 0; i < myNumIndets; ++i) 318 expv2[i] = NumericCast<SmallExponent_t>(expv[i]); 319 320 myOrdvArith->myAssignFromExpv(myOrdv(rawpp), expv); 321 } 322 323 myDelete(RawPtr rawpp)324 void PPMonoidEvOvImpl::myDelete(RawPtr rawpp) const 325 { 326 myMemMgr.free(rawpp.myRawPtr()); 327 } 328 329 mySwap(RawPtr rawpp1,RawPtr rawpp2)330 void PPMonoidEvOvImpl::mySwap(RawPtr rawpp1, RawPtr rawpp2) const 331 { 332 if (rawpp1 == rawpp2) return; 333 // This code assumes that myEntrySize is an exact multiple of sizeof(int) 334 int* v1 = static_cast<int*>(rawpp1.myRawPtr()); 335 int* v2 = static_cast<int*>(rawpp2.myRawPtr()); 336 const long NumWords = myEntrySize/sizeof(int); 337 for (long i=0; i < NumWords; ++i) 338 std::swap(v1[i], v2[i]); 339 } 340 341 myMul(RawPtr rawpp,ConstRawPtr rawpp1,ConstRawPtr rawpp2)342 void PPMonoidEvOvImpl::myMul(RawPtr rawpp, ConstRawPtr rawpp1, ConstRawPtr rawpp2) const 343 { 344 // No worries about aliasing. 345 SmallExponent_t* const expv = myExpv(rawpp); 346 const SmallExponent_t* const expv1 = myExpv(rawpp1); 347 const SmallExponent_t* const expv2 = myExpv(rawpp2); 348 for (long i=0; i < myNumIndets; ++i) 349 { 350 CoCoA_ASSERT("Exponent Overflow" && expv1[i] <= std::numeric_limits<SmallExponent_t>::max()-expv2[i]); 351 expv[i] = expv1[i] + expv2[i]; 352 } 353 myOrdvArith->myMul(myOrdv(rawpp), myOrdv(rawpp1), myOrdv(rawpp2)); 354 } 355 356 myMulIndetPower(RawPtr rawpp,long indet,long exp)357 void PPMonoidEvOvImpl::myMulIndetPower(RawPtr rawpp, long indet, long exp) const // assumes exp >= 0 358 { 359 CoCoA_ASSERT(exp >= 0); 360 CoCoA_ASSERT(0 <= indet && indet < myNumIndets); 361 SmallExponent_t* const expv = myExpv(rawpp); 362 // If CoCoA_DEBUG active, check for exponent overflow... 363 CoCoA_ASSERT("Exponent Overflow" && ourMaxExp - expv[indet] >= static_cast<unsigned long>(exp)); 364 expv[indet] += static_cast<SmallExponent_t>(exp); // cast to keep M$ compiler quiet 365 myOrdvArith->myMulIndetPower(myOrdv(rawpp), indet, exp); 366 } 367 368 myDiv(RawPtr rawpp,ConstRawPtr rawpp1,ConstRawPtr rawpp2)369 void PPMonoidEvOvImpl::myDiv(RawPtr rawpp, ConstRawPtr rawpp1, ConstRawPtr rawpp2) const 370 { 371 // No worries about aliasing. 372 SmallExponent_t* const expv = myExpv(rawpp); 373 const SmallExponent_t* const expv1 = myExpv(rawpp1); 374 const SmallExponent_t* const expv2 = myExpv(rawpp2); 375 for (long i=0; i < myNumIndets; ++i) 376 { 377 CoCoA_ASSERT("Exponent Underflow" && expv1[i] >= expv2[i]); 378 expv[i] = expv1[i] - expv2[i]; 379 } 380 myOrdvArith->myDiv(myOrdv(rawpp), myOrdv(rawpp1), myOrdv(rawpp2)); 381 } 382 383 myColon(RawPtr rawpp,ConstRawPtr rawpp1,ConstRawPtr rawpp2)384 void PPMonoidEvOvImpl::myColon(RawPtr rawpp, ConstRawPtr rawpp1, ConstRawPtr rawpp2) const 385 { 386 // No worries about aliasing. 387 SmallExponent_t* const expv = myExpv(rawpp); 388 const SmallExponent_t* const expv1 = myExpv(rawpp1); 389 const SmallExponent_t* const expv2 = myExpv(rawpp2); 390 391 for (long i = 0; i < myNumIndets; ++i) 392 { 393 if (expv1[i] > expv2[i]) 394 expv[i] = expv1[i] - expv2[i]; 395 else 396 expv[i] = 0; 397 } 398 myComputeOrdv(rawpp); 399 } 400 401 myGcd(RawPtr rawpp,ConstRawPtr rawpp1,ConstRawPtr rawpp2)402 void PPMonoidEvOvImpl::myGcd(RawPtr rawpp, ConstRawPtr rawpp1, ConstRawPtr rawpp2) const 403 { 404 // No worries about aliasing. 405 SmallExponent_t* const expv = myExpv(rawpp); 406 const SmallExponent_t* const expv1 = myExpv(rawpp1); 407 const SmallExponent_t* const expv2 = myExpv(rawpp2); 408 409 for (long i = 0; i < myNumIndets; ++i) 410 expv[i] = min(expv1[i], expv2[i]); 411 412 myComputeOrdv(rawpp); 413 } 414 415 myLcm(RawPtr rawpp,ConstRawPtr rawpp1,ConstRawPtr rawpp2)416 void PPMonoidEvOvImpl::myLcm(RawPtr rawpp, ConstRawPtr rawpp1, ConstRawPtr rawpp2) const 417 { 418 // No worries about aliasing. 419 SmallExponent_t* const expv = myExpv(rawpp); 420 const SmallExponent_t* const expv1 = myExpv(rawpp1); 421 const SmallExponent_t* const expv2 = myExpv(rawpp2); 422 423 for (long i = 0; i < myNumIndets; ++i) 424 expv[i] = max(expv1[i], expv2[i]); 425 426 myComputeOrdv(rawpp); 427 } 428 429 myRadical(RawPtr rawpp,ConstRawPtr rawpp1)430 void PPMonoidEvOvImpl::myRadical(RawPtr rawpp, ConstRawPtr rawpp1) const 431 { 432 SmallExponent_t* const expv = myExpv(rawpp); 433 const SmallExponent_t* const expv1 = myExpv(rawpp1); 434 435 for (long i = 0; i < myNumIndets; ++i) 436 expv[i] = (expv1[i] > 0); 437 438 myComputeOrdv(rawpp); 439 } 440 441 myPowerSmallExp(RawPtr rawpp,ConstRawPtr rawpp1,long LongExp)442 void PPMonoidEvOvImpl::myPowerSmallExp(RawPtr rawpp, ConstRawPtr rawpp1, long LongExp) const // assumes exp >= 0 443 { 444 CoCoA_ASSERT(LongExp >= 0); 445 #ifdef CoCoA_DEBUG 446 myPowerOverflowCheck(rawpp1, LongExp); 447 #endif 448 if (static_cast<unsigned long>(LongExp) > ourMaxExp) 449 CoCoA_THROW_ERROR(ERR::ExpTooBig, "PPMonoidEvOvImpl::myPowerSmallExp"); 450 const SmallExponent_t exp = static_cast<SmallExponent_t>(LongExp); 451 452 SmallExponent_t* const expv = myExpv(rawpp); 453 const SmallExponent_t* const expv1 = myExpv(rawpp1); 454 for (long i = 0; i < myNumIndets; ++i) 455 expv[i] = exp * expv1[i]; 456 myOrdvArith->myPower(myOrdv(rawpp), myOrdv(rawpp1), exp); 457 } 458 459 myPowerOverflowCheck(ConstRawPtr rawpp,long LongExp)460 void PPMonoidEvOvImpl::myPowerOverflowCheck(ConstRawPtr rawpp, long LongExp) const 461 { 462 if (LongExp == 0 || LongExp == 1) return; 463 CoCoA_ASSERT(LongExp >= 0); 464 const char* const FnName = "PPMonoidEvOvImpl::myPowerOverflowCheck"; 465 if (static_cast<unsigned long>(LongExp) > ourMaxExp) 466 CoCoA_THROW_ERROR(ERR::ExpTooBig, FnName); 467 const SmallExponent_t exp = static_cast<SmallExponent_t>(LongExp); 468 const SmallExponent_t limit = ourMaxExp/exp; 469 470 const SmallExponent_t* const expv = myExpv(rawpp); 471 for (long i = 0; i < myNumIndets; ++i) 472 { 473 if (expv[i] > limit) 474 CoCoA_THROW_ERROR(ERR::ExpTooBig, FnName); 475 } 476 // Check separately for overflow in ordv 477 myOrdvArith->myPowerOverflowCheck(myOrdv(rawpp), exp); 478 } 479 480 myIsOne(ConstRawPtr rawpp)481 bool PPMonoidEvOvImpl::myIsOne(ConstRawPtr rawpp) const 482 { 483 const SmallExponent_t* const expv = myExpv(rawpp); 484 485 for (long i = 0; i < myNumIndets; ++i) 486 if (expv[i] != 0) return false; 487 488 return true; 489 } 490 491 myIsIndet(long & index,ConstRawPtr rawpp)492 bool PPMonoidEvOvImpl::myIsIndet(long& index, ConstRawPtr rawpp) const 493 { 494 const SmallExponent_t* const expv = myExpv(rawpp); 495 long j = myNumIndets; 496 for (long i = 0; i < myNumIndets; ++i) 497 { 498 if (expv[i] == 0) continue; 499 if (j != myNumIndets || expv[i] != 1) return false; 500 j = i; 501 } 502 if (j == myNumIndets) return false; 503 index = j; 504 return true; 505 } 506 507 myIsCoprime(ConstRawPtr rawpp1,ConstRawPtr rawpp2)508 bool PPMonoidEvOvImpl::myIsCoprime(ConstRawPtr rawpp1, ConstRawPtr rawpp2) const 509 { 510 const SmallExponent_t* const expv1 = myExpv(rawpp1); 511 const SmallExponent_t* const expv2 = myExpv(rawpp2); 512 513 for (long i = 0; i < myNumIndets; ++i) 514 if (expv1[i] != 0 && expv2[i] != 0) return false; 515 516 return true; 517 } 518 519 myIsEqual(ConstRawPtr rawpp1,ConstRawPtr rawpp2)520 bool PPMonoidEvOvImpl::myIsEqual(ConstRawPtr rawpp1, ConstRawPtr rawpp2) const 521 { 522 return myOrdvArith->myCmp(myOrdv(rawpp1), myOrdv(rawpp2)) == 0; 523 } 524 525 myIsDivisible(ConstRawPtr rawpp1,ConstRawPtr rawpp2)526 bool PPMonoidEvOvImpl::myIsDivisible(ConstRawPtr rawpp1, ConstRawPtr rawpp2) const 527 { 528 const SmallExponent_t* const expv1 = myExpv(rawpp1); 529 const SmallExponent_t* const expv2 = myExpv(rawpp2); 530 531 for (long i = 0; i < myNumIndets; ++i) 532 if (expv1[i] < expv2[i]) return false; 533 534 return true; 535 } 536 537 myIsSqFree(ConstRawPtr rawpp)538 bool PPMonoidEvOvImpl::myIsSqFree(ConstRawPtr rawpp) const 539 { 540 const SmallExponent_t* const expv = myExpv(rawpp); 541 542 for (long i = 0; i < myNumIndets; ++i) 543 if (expv[i] > 1) return false; 544 545 return true; 546 } 547 548 myCmp(ConstRawPtr rawpp1,ConstRawPtr rawpp2)549 int PPMonoidEvOvImpl::myCmp(ConstRawPtr rawpp1, ConstRawPtr rawpp2) const 550 { 551 return myOrdvArith->myCmp(myOrdv(rawpp1), myOrdv(rawpp2)); 552 } 553 554 555 // // should potentially skip the first few packed ordv entries??? 556 // int PPMonoidEvOvImpl::myHomogCmp(ConstRawPtr rawpp1, ConstRawPtr rawpp2) const 557 // { 558 // return myOrdvArith->myCmp(myOrdv(rawpp1), myOrdv(rawpp2)); 559 // } 560 561 myStdDeg(ConstRawPtr rawpp)562 long PPMonoidEvOvImpl::myStdDeg(ConstRawPtr rawpp) const 563 { 564 const SmallExponent_t* const expv = myExpv(rawpp); 565 long d=0; 566 for (long i=0; i < myNumIndets; ++i) 567 d += expv[i]; 568 return d; 569 } 570 571 myWDeg(degree & d,ConstRawPtr rawpp)572 void PPMonoidEvOvImpl::myWDeg(degree& d, ConstRawPtr rawpp) const 573 { 574 myOrdvArith->myWDeg(d, myOrdv(rawpp)); 575 } 576 577 myCmpWDeg(ConstRawPtr rawpp1,ConstRawPtr rawpp2)578 int PPMonoidEvOvImpl::myCmpWDeg(ConstRawPtr rawpp1, ConstRawPtr rawpp2) const 579 { 580 return myOrdvArith->myCmpWDeg(myOrdv(rawpp1), myOrdv(rawpp2)); 581 } 582 583 myCmpWDegPartial(ConstRawPtr rawpp1,ConstRawPtr rawpp2,long i)584 int PPMonoidEvOvImpl::myCmpWDegPartial(ConstRawPtr rawpp1, ConstRawPtr rawpp2, long i) const 585 { 586 return myOrdvArith->myCmpWDegPartial(myOrdv(rawpp1), myOrdv(rawpp2), i); 587 } 588 589 myExponent(ConstRawPtr rawpp,long indet)590 long PPMonoidEvOvImpl::myExponent(ConstRawPtr rawpp, long indet) const 591 { 592 CoCoA_ASSERT(0 <= indet && indet < myNumIndets); 593 return NumericCast<long>(myExpv(rawpp)[indet]); 594 } 595 myBigExponent(BigInt & EXP,ConstRawPtr rawpp,long indet)596 void PPMonoidEvOvImpl::myBigExponent(BigInt& EXP, ConstRawPtr rawpp, long indet) const 597 { 598 CoCoA_ASSERT(0 <= indet && indet < myNumIndets); 599 EXP = myExpv(rawpp)[indet]; 600 } 601 602 myExponents(std::vector<long> & expv,ConstRawPtr rawpp)603 void PPMonoidEvOvImpl::myExponents(std::vector<long>& expv, ConstRawPtr rawpp) const 604 { 605 CoCoA_ASSERT(len(expv) == myNumIndets); 606 const SmallExponent_t* const v = myExpv(rawpp); 607 for (long i=0; i < myNumIndets; ++i) 608 expv[i] = NumericCast<long>(v[i]); 609 } 610 611 myBigExponents(std::vector<BigInt> & expv,ConstRawPtr rawpp)612 void PPMonoidEvOvImpl::myBigExponents(std::vector<BigInt>& expv, ConstRawPtr rawpp) const 613 { 614 CoCoA_ASSERT(len(expv) == myNumIndets); 615 const SmallExponent_t* const v = myExpv(rawpp); 616 for (long i=0; i < myNumIndets; ++i) expv[i] = v[i]; 617 } 618 619 myIndetsIn(std::vector<bool> & v,ConstRawPtr rawpp)620 void PPMonoidEvOvImpl::myIndetsIn(std::vector<bool>& v, ConstRawPtr rawpp) const 621 { 622 CoCoA_ASSERT(len(v) == myNumIndets); 623 const SmallExponent_t* const expv = myExpv(rawpp); 624 for (long i=0; i < myNumIndets; ++i) 625 if (expv[i] != 0) v[i] = true; 626 } 627 628 myComputeDivMask(DivMask & dm,const DivMaskRule & DivMaskImpl,ConstRawPtr rawpp)629 void PPMonoidEvOvImpl::myComputeDivMask(DivMask& dm, const DivMaskRule& DivMaskImpl, ConstRawPtr rawpp) const 630 { 631 DivMaskImpl->myAssignFromExpv(dm, myExpv(rawpp), myNumIndets); 632 } 633 634 myOutputSelf(std::ostream & out)635 void PPMonoidEvOvImpl::myOutputSelf(std::ostream& out) const 636 { 637 if (!out) return; // short-cut for bad ostreams 638 out << "PPMonoidEvOv(" << myNumIndets << ", " << myOrd << ")"; 639 } 640 641 myDebugPrint(std::ostream & out,ConstRawPtr rawpp)642 void PPMonoidEvOvImpl::myDebugPrint(std::ostream& out, ConstRawPtr rawpp) const 643 { 644 if (!out) return; // short-cut for bad ostreams 645 646 out << "DEBUG PP: myNumIndets=" << myNumIndets << ", exps=["; 647 for (long i=0; i < myNumIndets; ++i) 648 out << myExponent(rawpp, i) << " "; 649 out << "]" << std::endl; 650 } 651 652 NewPPMonoidEvOv(const std::vector<symbol> & IndetNames,const PPOrdering & ord)653 PPMonoid NewPPMonoidEvOv(const std::vector<symbol>& IndetNames, const PPOrdering& ord) 654 { 655 // Sanity check on the indet names given. 656 const long nvars = NumIndets(ord); 657 658 if (len(IndetNames) != nvars) 659 CoCoA_THROW_ERROR(ERR::BadNumIndets, "NewPPMonoidEvOv(IndetNames,ord)"); 660 if (!AreDistinct(IndetNames)) 661 CoCoA_THROW_ERROR(ERR::BadIndetNames, "NewPPMonoidEvOv(IndetNames,ord)"); 662 if (!AreArityConsistent(IndetNames)) 663 CoCoA_THROW_ERROR(ERR::BadIndetNames, "NewPPMonoidEvOv(IndetNames,ord)"); 664 665 // Inefficient quadratic loop -- speed is probably not important. 666 for (long i=0; i < nvars; ++i) 667 for (long j=i+1; j < nvars; ++j) 668 if (IndetNames[i] == IndetNames[j]) 669 CoCoA_THROW_ERROR(ERR::BadIndetNames, "NewPPMonoidEvOv(IndetNames,ord)"); 670 671 return PPMonoid(new PPMonoidEvOvImpl(IndetNames, ord)); 672 } 673 NewPPMonoidEvOv(const std::vector<symbol> & IndetNames,const PPOrderingCtor & OrdCtor)674 PPMonoid NewPPMonoidEvOv(const std::vector<symbol>& IndetNames, const PPOrderingCtor& OrdCtor) 675 { 676 return NewPPMonoidEvOv(IndetNames, OrdCtor(len(IndetNames))); 677 } 678 679 680 } // end of namespace CoCoA 681 682 683 // RCS header/log in the next few lines 684 // $Header: /Volumes/Home_1/cocoa/cvs-repository/CoCoALib-0.99/src/AlgebraicCore/PPMonoidEvOv.C,v 1.41 2020/06/17 15:49:25 abbott Exp $ 685 // $Log: PPMonoidEvOv.C,v $ 686 // Revision 1.41 2020/06/17 15:49:25 abbott 687 // Summary: Changed CoCoA_ERROR into CoCoA_THROW_ERROR 688 // 689 // Revision 1.40 2020/02/11 16:56:41 abbott 690 // Summary: Corrected last update (see redmine 969) 691 // 692 // Revision 1.39 2020/02/11 16:12:18 abbott 693 // Summary: Added some checks for bad ostream (even to mem fns myOutput); see redmine 969 694 // 695 // Revision 1.38 2019/03/04 10:31:45 abbott 696 // Summary: Changed auto_ptr into unqiue_ptr 697 // 698 // Revision 1.37 2018/05/18 12:15:04 bigatti 699 // -- renamed IntOperations --> BigIntOps 700 // 701 // Revision 1.36 2017/12/01 17:29:21 bigatti 702 // // -- updated Copyright line 703 // // -- removed doxygen initial comment 704 // // -- some commented out debugging info 705 // 706 // Revision 1.35 2017/04/18 12:50:06 abbott 707 // Summary: Corrected ifdef use of CoCoA_THREADSAFE_HACK and CoCoA_DEBUG 708 // 709 // Revision 1.34 2016/11/03 12:25:25 abbott 710 // Summary: Changed IsRadical (for PPMonoidElem) into IsSqFree 711 // 712 // Revision 1.33 2015/12/01 13:11:01 abbott 713 // Summary: Changed mem fn PPOrderingCtor::myCtor into operator(); also for ModuleOrderingCtor; see issue 829 714 // 715 // Revision 1.32 2015/06/30 12:54:35 abbott 716 // Summary: Added new fn myIndetsIn 717 // Author: JAA 718 // 719 // Revision 1.31 2015/04/16 20:20:22 abbott 720 // Summary: Fixed incorrectly edited code 721 // Author: JAA 722 // 723 // Revision 1.30 2015/04/16 16:36:33 abbott 724 // Summary: Cleaned impls of myPowerOverflowCheck 725 // Author: JAA 726 // 727 // Revision 1.29 2015/04/13 14:42:08 abbott 728 // Summary: Added myPowerOverflowCheck (1st version) 729 // Author: JAA 730 // 731 // Revision 1.28 2014/07/03 15:36:35 abbott 732 // Summary: Cleaned up impl of PPMonoids: moved myIndetSymbols & myNumIndets to base class 733 // Author: JAA 734 // 735 // Revision 1.27 2014/05/14 15:57:15 bigatti 736 // -- added "using" for clang with superpedantic flag 737 // 738 // Revision 1.26 2013/03/15 11:00:50 abbott 739 // Added check for exponent overflow when powering a PP. 740 // Merged PPMonoidEv and PPMonoidEvZZ implementations into a single file. 741 // Implemented new interface for pseudo-ctors for PPMonoidEv which uses a "flag" 742 // to say whether exponents are big or not. 743 // 744 // Revision 1.25 2012/05/28 09:18:21 abbott 745 // Created IntOperations which gathers together all operations on 746 // integers (both big and small). Many consequential changes. 747 // 748 // Revision 1.24 2012/01/26 16:50:55 bigatti 749 // -- changed back_inserter into insert 750 // 751 // Revision 1.23 2011/08/14 15:52:17 abbott 752 // Changed ZZ into BigInt (phase 1: just the library sources). 753 // 754 // Revision 1.22 2011/05/03 12:13:12 abbott 755 // Added static const data member ourMaxExp. 756 // Code is more readable, and compiler doesn't grumble any more. 757 // 758 // Revision 1.21 2011/03/22 22:38:15 abbott 759 // Fixed some wrong static_casts inside some CoCoA_ASSERTs. 760 // 761 // Revision 1.20 2011/03/10 17:27:11 bigatti 762 // -- changed unsigned long into long in some CoCoA_ASSERT 763 // -- removed assert in myCmpWDegPartial (done in OrdvArith) 764 // 765 // Revision 1.19 2011/03/10 16:39:34 abbott 766 // Replaced (very many) size_t by long in function interfaces (for rings, 767 // PPMonoids and modules). Also replaced most size_t inside fn defns. 768 // 769 // Revision 1.18 2010/12/17 16:09:51 abbott 770 // Corrected used of myIndetSymbols in some assertions. 771 // 772 // Revision 1.17 2010/11/30 11:18:11 bigatti 773 // -- renamed IndetName --> IndetSymbol 774 // 775 // Revision 1.16 2010/11/05 16:21:08 bigatti 776 // -- added ZZExponents 777 // 778 // Revision 1.15 2010/10/06 14:10:24 abbott 779 // Added increments to the ref count in ring and PPMonoid ctors to make 780 // them exception safe. 781 // 782 // Revision 1.14 2010/02/03 16:13:52 abbott 783 // Added new single word tags for specifying the ordering in PPMonoid 784 // pseudo-ctors. 785 // 786 // Revision 1.13 2010/02/02 16:44:31 abbott 787 // Added radical & IsRadical (via mem fns myRadical & myIsRadical) 788 // for PPMonoidElems. 789 // 790 // Revision 1.12 2009/12/23 18:53:52 abbott 791 // Major change to conversion functions: 792 // convert(..) is now a procedure instead of a function 793 // IsConvertible(..) replaces the former convert(..) function 794 // Added new NumericCast conversion function (placeholder for BOOST feature) 795 // Consequent changes in code which uses these features. 796 // 797 // Revision 1.11 2009/09/22 14:01:33 bigatti 798 // -- added myCmpWDegPartial (ugly name, I know....) 799 // -- cleaned up and realigned code in PPMonoid*.C files 800 // 801 // Revision 1.10 2008/03/26 16:52:04 abbott 802 // Added exponent overflow checks (also for ordvs) when CoCoA_DEBUG is active. 803 // 804 // Revision 1.9 2007/12/05 11:06:24 bigatti 805 // -- changed "size_t StdDeg/myStdDeg(f)" into "long" (and related functions) 806 // -- changed "log/myLog(f, i)" into "MaxExponent/myMaxExponent(f, i)" 807 // -- fixed bug in "IsOne(ideal)" in SparsePolyRing.C 808 // 809 // Revision 1.8 2007/12/04 14:27:06 bigatti 810 // -- changed "log(pp, i)" into "exponent(pp, i)" 811 // 812 // Revision 1.7 2007/10/30 17:14:07 abbott 813 // Changed licence from GPL-2 only to GPL-3 or later. 814 // New version for such an important change. 815 // 816 // Revision 1.6 2007/09/25 16:32:30 abbott 817 // Several minor changes to silence gcc-4.3: 818 // more #includes, 819 // and fixed a template problemm in RegisterServerOps.C 820 // 821 // Revision 1.5 2007/05/31 14:54:31 bigatti 822 // -- now using AreDistinct and AreArityConsistent for sanity check on 823 // indet names 824 // 825 // Revision 1.3 2007/05/03 10:35:23 abbott 826 // Added new PPMonoidEvZZ with (virtually) unlimited exponents. 827 // Modified test-PPMonoid1.C accordingly. 828 // Added warning in doc about silent/unchecked exponent overflow in other 829 // PPMonoids. 830 // 831 // Revision 1.2 2007/03/23 18:38:42 abbott 832 // Separated the "convert" functions (and CheckedCast) into their own files. 833 // Many consequential changes. Also corrected conversion to doubles. 834 // 835 // Revision 1.1.1.1 2007/03/09 15:16:11 abbott 836 // Imported files 837 // 838 // Revision 1.14 2007/03/08 18:22:29 cocoa 839 // Just whitespace cleaning. 840 // 841 // Revision 1.13 2007/03/08 17:43:11 cocoa 842 // Swapped order of args to the NewPPMonoid pseudo ctors. 843 // 844 // Revision 1.12 2007/03/08 11:07:12 cocoa 845 // Made pseudo ctors for polynomial rings more uniform. This allowed me to 846 // remove an include of CoCoA/symbol.H from the RingDistrM*.H files, but then 847 // I had to put the include in several .C files. 848 // 849 // Revision 1.11 2006/12/06 17:35:58 cocoa 850 // -- style: RawPtr args are now called "raw.." 851 // 852 // Revision 1.10 2006/11/27 13:06:23 cocoa 853 // Anna and Michael made me check without writing a proper message. 854 // 855 // Revision 1.9 2006/11/24 17:04:32 cocoa 856 // -- reorganized includes of header files 857 // 858 // Revision 1.8 2006/11/23 17:39:11 cocoa 859 // -- added #include 860 // 861 // Revision 1.7 2006/11/16 11:27:20 cocoa 862 // -- reinserted myRefCountZero(): sometimes really necessary, in general safe 863 // 864 // Revision 1.6 2006/11/14 17:29:20 cocoa 865 // -- commented out myRefCountZero() (not necessary???) 866 // 867 // Revision 1.5 2006/10/16 23:18:59 cocoa 868 // Corrected use of std::swap and various special swap functions. 869 // Improved myApply memfn for homs of RingDistrMPolyInlPP. 870 // 871 // Revision 1.4 2006/10/06 14:04:14 cocoa 872 // Corrected position of #ifndef in header files. 873 // Separated CoCoA_ASSERT into assert.H from config.H; 874 // many minor consequential changes (have to #include assert.H). 875 // A little tidying of #include directives (esp. in Max's code). 876 // 877 // Revision 1.3 2006/08/07 21:23:25 cocoa 878 // Removed almost all publicly visible references to SmallExponent_t; 879 // changed to long in all PPMonoid functions and SparsePolyRing functions. 880 // DivMask remains to sorted out. 881 // 882 // Revision 1.2 2006/06/21 17:07:10 cocoa 883 // Fixed IsIndet bug -- why are there three almost identical copies of code? 884 // 885 // Revision 1.1.1.1 2006/05/30 11:39:37 cocoa 886 // Imported files 887 // 888 // Revision 1.6 2006/03/15 18:09:31 cocoa 889 // Changed names of member functions which print out their object 890 // into myOutputSelf -- hope this will appease the Intel C++ compiler. 891 // 892 // Revision 1.5 2006/03/14 17:21:18 cocoa 893 // Moved concrete PPMonoid impls entirely into their respective .C files. 894 // Now the corresponding .H files are very compact. 895 // 896 // Revision 1.4 2006/03/12 21:28:33 cocoa 897 // Major check in after many changes 898 // 899 // Revision 1.3 2006/02/20 22:41:20 cocoa 900 // All forms of the log function for power products now return SmallExponent_t 901 // (instead of int). exponents now resizes the vector rather than requiring 902 // the user to pass in the correct size. 903 // 904 // Revision 1.2 2006/01/17 10:23:08 cocoa 905 // Updated DivMask; many consequential changes. 906 // A few other minor fixes. 907 // 908 // Revision 1.1.1.1 2005/10/17 10:46:54 cocoa 909 // Imported files 910 // 911 // Revision 1.8 2005/10/11 16:37:30 cocoa 912 // Added new small prime finite field class (see RingFpDouble). 913 // 914 // Cleaned makefiles and configuration script. 915 // 916 // Tidied PPMonoid code (to eliminate compiler warnings). 917 // 918 // Fixed bug in RingFloat::myIsInteger. 919 // 920 // Revision 1.7 2005/08/08 16:36:32 cocoa 921 // Just checking in before going on holiday. 922 // Don't really recall what changes have been made. 923 // Added IsIndet function for RingElem, PPMonoidElem, 924 // and a member function of OrdvArith. 925 // Improved the way failed assertions are handled. 926 // 927 // Revision 1.6 2005/07/19 15:30:20 cocoa 928 // A first attempt at iterators over sparse polynomials. 929 // Main additions are to SparsePolyRing, DistrMPoly*. 930 // Some consequential changes to PPMonoid*. 931 // 932 // Revision 1.5 2005/07/08 15:09:28 cocoa 933 // Added new symbol class (to represent names of indets). 934 // Integrated the new class into concrete polynomial rings 935 // and PPMonoid -- many consequential changes. 936 // Change ctors for the "inline" sparse poly rings: they no 937 // longer expect a PPMonoid, but build their own instead 938 // (has to be a PPMonoidOv). 939 // 940 // Revision 1.4 2005/07/01 16:08:15 cocoa 941 // Friday check-in. Major change to structure under PolyRing: 942 // now SparsePolyRing and DUPolyRing are separated (in preparation 943 // for implementing iterators). 944 // 945 // A number of other relatively minor changes had to be chased through 946 // (e.g. IndetPower). 947 // 948 // Revision 1.3 2005/06/23 15:42:41 cocoa 949 // Fixed typo in GNU fdl -- all doc/*.txt files affected. 950 // Minor corrections to PPMonoid (discovered while writing doc). 951 // 952 // Revision 1.2 2005/06/22 14:47:56 cocoa 953 // PPMonoids and PPMonoidElems updated to mirror the structure 954 // used for rings and RingElems. Many consequential changes. 955 // 956 // Revision 1.1.1.1 2005/05/03 15:47:31 cocoa 957 // Imported files 958 // 959 // Revision 1.4 2005/04/29 15:42:02 cocoa 960 // Improved documentation for GMPAllocator. 961 // Added example program for GMPAllocator. 962 // Added example program for simple ops on polynomials. 963 // Added two new ctors for (principal) ideals (from long, and from ZZ). 964 // Added (crude) printing for PPMonoids. 965 // Updated library.H (#included GMPAllocator.H). 966 // 967 // Revision 1.3 2005/04/20 15:40:48 cocoa 968 // Major change: modified the standard way errors are to be signalled 969 // (now via a macro which records filename and line number). Updated 970 // documentation in error.txt accordingly. 971 // 972 // Improved the documentation in matrix.txt (still more work to be done). 973 // 974 // Revision 1.2 2005/04/19 14:06:04 cocoa 975 // Added GPL and GFDL licence stuff. 976 // 977 // Revision 1.1.1.1 2005/01/27 15:12:13 cocoa 978 // Imported files 979 // 980 // Revision 1.4 2004/11/25 16:14:21 cocoa 981 // (1) Fixed definition of specialization of std::swap template function 982 // so that it compiles with gcc 3.4.3 983 // (2) Implemented monomial function for polynomial rings. 984 // (3) Added one(PPM) and PPM->myOne() functions. 985 // 986 // Revision 1.3 2004/11/11 13:41:48 cocoa 987 // -- change: cout --> GlobalLogput() 988 // 989 // Revision 1.2 2004/11/02 14:56:33 cocoa 990 // -- changed *Print* into *Output* (myPrint --> myOutput) 991 // -- changed *Var* into *Indet* (myPrintVarName --> myOutputIndetName) 992 // -- removed suffix "IgnoreDivMask" 993 // -- added myComputeDivMask 994 // -- improved storing of IndetNames 995 // -- changed ExpvElem into SmallExponent_t 996 // 997 // Revision 1.1 2004/10/29 15:31:25 cocoa 998 // -- new PPMonoid for compatibility with OrdvArith (without DivMask) 999 // 1000