1 // Copyright (c) 2005-2013 John Abbott, Anna M. 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 // Implementation file for the class SubmoduleImpl 20 21 #include "CoCoA/submodule.H" 22 23 #include "CoCoA/BigIntOps.H" 24 #include "CoCoA/DenseMatrix.H" // for GensAsRows, GensAsCols 25 #include "CoCoA/FreeModule.H" 26 #include "CoCoA/MemPool.H" 27 #include "CoCoA/OpenMath.H" 28 #include "CoCoA/SparsePolyOps-RingElem.H" 29 #include "CoCoA/TmpGOperations.H" // for ComputeGBasis 30 #include "CoCoA/VectorOps.H" // for HasUniqueOwner 31 #include "CoCoA/ideal.H" // for syzygies 32 #include "CoCoA/matrix.H" // for ConstMatrixView 33 #include "CoCoA/ring.H" 34 //#include "CoCoA/MatrixView.H" 35 36 #include <iostream> 37 using std::ostream; 38 //#include <vector> 39 using std::vector; 40 41 42 namespace CoCoA 43 { 44 45 class SubmoduleImpl: public FGModuleBase 46 { 47 // Two typedefs to save typing. 48 typedef ModuleBase::RawPtr RawPtr; 49 typedef const ModuleBase::RawPtr& ConstRawPtr; 50 51 public: 52 SubmoduleImpl(const module& M, const std::vector<ModuleElem>& gens); myNumCompts()53 long myNumCompts() const {return NumCompts(myM);} myRing()54 const ring& myRing() const {return RingOf(myM);} myAmbientFreeModule()55 const FreeModule& myAmbientFreeModule() const {return myM;} myGens()56 const std::vector<ModuleElem>& myGens() const {return myGensValue;} 57 const std::vector<ModuleElem>& myMinGens(const CpuTimeLimit& CheckForTimeOut) const; 58 const std::vector<ModuleElem>& myTidyGens(const CpuTimeLimit& CheckForTimeOut) const; 59 const std::vector<ModuleElem>& myGBasis(const CpuTimeLimit& CheckForTimeOut) const; // for SparsePolyRing 60 myZero()61 const ModuleElem& myZero() const {return zero(myM);} myNew(RawPtr & rawv)62 void myNew(RawPtr& rawv) const {myM->myNew(rawv);} myNew(RawPtr & rawv,ConstRawPtr rawt)63 void myNew(RawPtr& rawv, ConstRawPtr rawt) const {myM->myNew(rawv, rawt);} myDelete(RawPtr & rawv)64 void myDelete(RawPtr& rawv) const {myM->myDelete(rawv);} // destroys v (incl all resources) mySwap(RawPtr & rawv,RawPtr & raww)65 void mySwap(RawPtr& rawv, RawPtr& raww) const {myM->mySwap(rawv, raww);} myAssign(RawPtr & rawlhs,ConstRawPtr rawv)66 void myAssign(RawPtr& rawlhs, ConstRawPtr rawv) const {myM->myAssign(rawlhs, rawv);} // lhs = v; 67 ConstRefRingElem myCompt(const RawPtr& rawv, long pos) const; ///< v[pos] (READ ONLY) myNegate(RawPtr & rawlhs,ConstRawPtr rawv)68 void myNegate(RawPtr& rawlhs, ConstRawPtr rawv) const {myM->myNegate(rawlhs, rawv);} // lhs = -v myAdd(RawPtr & rawlhs,ConstRawPtr rawv,ConstRawPtr raww)69 void myAdd(RawPtr& rawlhs, ConstRawPtr rawv, ConstRawPtr raww) const {myM->myAdd(rawlhs, rawv, raww);} // lhs = v+w; mySub(RawPtr & rawlhs,ConstRawPtr rawv,ConstRawPtr raww)70 void mySub(RawPtr& rawlhs, ConstRawPtr rawv, ConstRawPtr raww) const {myM->mySub(rawlhs, rawv, raww);} // lhs = v-w; 71 myMul(RawPtr & rawlhs,RingElemConstRawPtr rawx,ConstRawPtr rawv)72 void myMul(RawPtr& rawlhs, RingElemConstRawPtr rawx, ConstRawPtr rawv) const {myM->myMul(rawlhs, rawx, rawv);} // lhs = r*v; myDiv(RawPtr & rawlhs,RingElemConstRawPtr rawx,ConstRawPtr rawv)73 void myDiv(RawPtr& rawlhs, RingElemConstRawPtr rawx, ConstRawPtr rawv) const {myM->myDiv(rawlhs, rawx, rawv);} // lhs = (1/r)*v; myOutput(std::ostream & out,ConstRawPtr rawv)74 void myOutput(std::ostream& out, ConstRawPtr rawv) const {myM->myOutput(out, rawv);} // out << v 75 void myOutputSelf(std::ostream& out) const; // out << M 76 void myOutput(OpenMathOutput& OMOut, ConstRawPtr rawv) const; // OMOut << v 77 void myOutputSelf(OpenMathOutput& OMOut) const; // OMOut << M myIsZero(ConstRawPtr rawv)78 bool myIsZero(ConstRawPtr rawv) const {return myM->myIsZero(rawv);} // v == 0 79 //??? bool IsZeroAddMul(RawPtr& rawlhs, RingElemConstRawPtr rawy, ConstRawPtr rawz) const; // lhs += y*z, result says whether lhs == 0. myIsEqual(ConstRawPtr rawx,ConstRawPtr rawy)80 bool myIsEqual(ConstRawPtr rawx, ConstRawPtr rawy) const {return myM->myIsEqual(rawx, rawy);} 81 82 private: // data members 83 const FreeModule myM; 84 std::vector<ModuleElem> myGensValue; 85 // mutable member fields 86 mutable bool myTidyGensIsValid; 87 mutable std::vector<ModuleElem> myMinGensValue; 88 mutable std::vector<ModuleElem> myTidyGensValue; 89 //??? std::vector<ModuleElem>& ComputeTidyGens() const; 90 }; 91 92 93 SubmoduleImpl(const module & M,const std::vector<ModuleElem> & gens)94 SubmoduleImpl::SubmoduleImpl(const module& M, const std::vector<ModuleElem>& gens): 95 myM(M), 96 myGensValue(gens), 97 myTidyGensIsValid(false) 98 { 99 CoCoA_ASSERT(IsFreeModule(M)); 100 for (long i=0; i < len(gens); ++i) 101 if (owner(gens[i]) != M) 102 CoCoA_ERROR(ERR::MixedModules, "SubmoduleImpl(M, gens)"); 103 myRefCountZero(); 104 } 105 106 107 // ideal::ideal(const std::vector<RingElem>& gens) 108 // { 109 // if (gens.empty()) CoCoA_ERROR("Empty list of generators: need ring", "ideal(gens)"); 110 // if (!HasUniqueOwner(gens)) CoCoA_ERROR(ERR::MixedRings, "ideal(gens)"); 111 // ideal tmp = owner(gens[0])->myIdealCtor(gens); 112 // myPtr = tmp.myPtr; 113 // myPtr->myRefCountInc(); 114 // } 115 116 myGBasis(const CpuTimeLimit & CheckForTimeOut)117 const std::vector<ModuleElem>& SubmoduleImpl::myGBasis(const CpuTimeLimit& CheckForTimeOut) const 118 { 119 CoCoA_ASSERT(IsSparsePolyRing(myRing())); 120 if (!IsField(CoeffRing(myRing()))) 121 CoCoA_ERROR("ERR:NYI coeffs not in a field", "SubmoduleImpl::myGBasis");//??? 122 123 // if (IhaveMonomialGens()) return myGBasisMonId(); 124 if (myTidyGensIsValid) return myTidyGensValue; 125 CoCoA_ASSERT(myTidyGensValue.empty()); 126 // if (IamZero()) return myTidyGensValue; 127 ComputeGBasis(myTidyGensValue, myMinGensValue, myGens(), CheckForTimeOut); 128 myTidyGensIsValid = true; 129 return myTidyGensValue; 130 } 131 132 myMinGens(const CpuTimeLimit & CheckForTimeOut)133 const std::vector<ModuleElem>& SubmoduleImpl::myMinGens(const CpuTimeLimit& CheckForTimeOut) const 134 { 135 if (!myMinGensValue.empty()) return myMinGensValue; 136 if (GradingDim(myRing())==0 || !IsHomog(myGensValue)) 137 CoCoA_ERROR("Input is not homogeneous", "myMinGens"); 138 myGBasis(CheckForTimeOut); 139 return myMinGensValue; 140 } 141 142 myTidyGens(const CpuTimeLimit & CheckForTimeOut)143 const std::vector<ModuleElem>& SubmoduleImpl::myTidyGens(const CpuTimeLimit& CheckForTimeOut) const 144 { 145 // if (!myTidyGensIsValid) 146 if (!IsSparsePolyRing(myRing())) 147 CoCoA_ERROR(ERR::NYI, "SubmoduleImpl::myTidyGens"); 148 return myGBasis(CheckForTimeOut); 149 } 150 151 myCompt(const RawPtr & rawv,long pos)152 ConstRefRingElem SubmoduleImpl::myCompt(const RawPtr& rawv, long pos) const 153 { 154 CoCoA_ASSERT(0 <= pos && pos < myNumCompts()); 155 return myM->myCompt(rawv, pos); 156 } 157 158 159 namespace{ // anonymous 160 //??? the following functions to compute NR will be replaced by GBMill 161 FindReducerIndex(ConstRefPPMonoidElem pp,long posn,const vector<ModuleElem> & g)162 int FindReducerIndex(ConstRefPPMonoidElem pp, long posn, const vector<ModuleElem>& g) 163 { 164 const long nelems = len(g); 165 long posn_gi; 166 for (long i=0; i < nelems; ++i) 167 if (posn == (posn_gi=LPosn(g[i]))) 168 if (IsDivisible(pp, LPP(g[i][posn_gi]))) 169 return i; 170 return -1; 171 } 172 173 FindReducerIndex(const ModuleElem & F,const vector<ModuleElem> & g)174 inline int FindReducerIndex(const ModuleElem& F, const vector<ModuleElem>& g) 175 { 176 if ( IsZero(F) ) return -1; 177 return FindReducerIndex(LPP(F), LPosn(F), g); 178 } 179 180 ReduceLM(ModuleElem & F,const vector<ModuleElem> & g)181 void ReduceLM(ModuleElem& F, const vector<ModuleElem>& g) 182 { 183 long i, pg, pF; 184 while ( (i = FindReducerIndex(F, g) ) != -1) 185 { 186 pg = LPosn(g[i]); 187 pF = LPosn(g[i]); 188 F -= g[i]*monomial(RingOf(owner(F)), 189 LC(F[pF])/LC(g[i][pg]), LPP(F[pF])/LPP(g[i][pg])); 190 } 191 } 192 193 reduce(ModuleElem & F,const vector<ModuleElem> & g)194 void reduce(ModuleElem& F, const vector<ModuleElem>& g) 195 { 196 ReduceLM(F, g); 197 // while ( !IsActiveZero(F) ) 198 // { 199 // F->myMoveToNextLM(); 200 // ReduceActiveLM(F, v); 201 // } 202 } 203 NR(const ModuleElem & f,const vector<ModuleElem> & g)204 ModuleElem NR(const ModuleElem& f, const vector<ModuleElem>& g) 205 { 206 if (!IsField(CoeffRing(RingOf(owner(f))))) 207 CoCoA_ERROR("ERR:NYI coeffs not in a field", "NR");//??? 208 if ( IsZero(f) ) return f; 209 ModuleElem F=f; 210 reduce(F, g); 211 return F; 212 } 213 214 } // anonymous namespace 215 216 IsElem(const ModuleElem & v,const module & M)217 bool IsElem(const ModuleElem& v, const module& M) 218 { 219 CoCoA_ASSERT(IsFGModule(M)); 220 if (owner(v) != AmbientFreeModule(M)) 221 CoCoA_ERROR(ERR::MixedModules, "IsElem(v, M)"); 222 // return I->IhaveElem(raw(r)); 223 //??? for FGmodule only 224 return IsZero(NR(v, TidyGens(M))); 225 } 226 227 myOutputSelf(std::ostream & out)228 void SubmoduleImpl::myOutputSelf(std::ostream& out) const 229 { 230 if (!out) return; // short-cut for bad ostreams 231 232 out << "submodule(" << myM << ", ["; 233 if (!myGensValue.empty()) out << myGensValue[0]; 234 for (long i=1; i < len(myGensValue); ++i) 235 { 236 out << ", " << myGensValue[i]; 237 } 238 out << "])"; 239 } 240 241 myOutput(OpenMathOutput & OMOut,ConstRawPtr rawv)242 void SubmoduleImpl::myOutput(OpenMathOutput& OMOut, ConstRawPtr rawv) const 243 { 244 OMOut->mySendApplyStart(); 245 OMOut << OpenMathSymbol("???", "ModuleElement"); // BUG: what should this OMSymbol be??? 246 OMOut << myM; 247 OMOut->mySendApplyStart(); 248 OMOut << OpenMathSymbol("???", "list"); // BUG: what should this OMSymbol be??? 249 OMOut << myNumCompts(); 250 myM->myOutput(OMOut, rawv); // BUG: this should be a "naked" output??? 251 OMOut->mySendApplyEnd(); 252 OMOut->mySendApplyEnd(); 253 } 254 255 myOutputSelf(OpenMathOutput & OMOut)256 void SubmoduleImpl::myOutputSelf(OpenMathOutput& OMOut) const 257 { 258 OMOut->mySendApplyStart(); 259 OMOut << OpenMathSymbol("???", "submodule"); // BUG: what should this OMSymbol be??? 260 OMOut << myM; 261 OMOut->mySendApplyStart(); 262 OMOut << OpenMathSymbol("???", "list"); // BUG: what should this OMSymbol be??? 263 OMOut << len(myGensValue); 264 for (long i=0; i < len(myGensValue); ++i) 265 OMOut << myGensValue[i]; // BUG: this should be a "naked" output??? 266 OMOut->mySendApplyEnd(); 267 OMOut->mySendApplyEnd(); 268 } 269 270 271 //??? bool IsZeroAddMul(RawPtr& rawlhs, RingElemConstRawPtr rawy, ConstRawPtr rawz) const; // lhs += y*z, result says whether lhs == 0. 272 273 //-- pseudo-ctors 274 submodule(const FGModule & M,const std::vector<ModuleElem> & gens)275 FGModule submodule(const FGModule& M, const std::vector<ModuleElem>& gens) 276 {return FGModule(new SubmoduleImpl(M, gens));} 277 278 submodule(const std::vector<ModuleElem> & gens)279 FGModule submodule(const std::vector<ModuleElem>& gens) 280 { 281 if (gens.empty()) CoCoA_ERROR(ERR::Empty, "submodule(gens)"); 282 if (!HasUniqueOwner(gens)) CoCoA_ERROR(ERR::MixedModules, "submodule(gens)"); 283 return submodule(owner(gens[0]), gens); 284 } 285 286 submodule(const ModuleElem & v1)287 FGModule submodule(const ModuleElem& v1) 288 { 289 vector<ModuleElem> gens; 290 gens.push_back(v1); 291 return submodule(gens); 292 } 293 294 submodule(const ModuleElem & v1,const ModuleElem & v2)295 FGModule submodule(const ModuleElem& v1, const ModuleElem& v2) 296 { 297 vector<ModuleElem> gens; 298 gens.push_back(v1);gens.push_back(v2); 299 return submodule(gens); 300 } 301 302 submodule(const ModuleElem & v1,const ModuleElem & v2,const ModuleElem & v3)303 FGModule submodule(const ModuleElem& v1, const ModuleElem& v2, const ModuleElem& v3) 304 { 305 vector<ModuleElem> gens; 306 gens.push_back(v1);gens.push_back(v2);gens.push_back(v3); 307 return submodule(gens); 308 } 309 310 submodule(const ModuleElem & v1,const ModuleElem & v2,const ModuleElem & v3,const ModuleElem & v4)311 FGModule submodule(const ModuleElem& v1, const ModuleElem& v2, const ModuleElem& v3, const ModuleElem& v4) 312 { 313 vector<ModuleElem> gens; 314 gens.push_back(v1);gens.push_back(v2);gens.push_back(v3);gens.push_back(v4); 315 return submodule(gens); 316 } 317 318 SubmoduleCols(const FGModule & F,ConstMatrixView M)319 FGModule SubmoduleCols(const FGModule& F, ConstMatrixView M) 320 { 321 const std::vector<ModuleElem>& e = gens(F); 322 if (len(e)!=NumRows(M)) 323 CoCoA_ERROR(ERR::IncompatDims,"SubmoduleCols"); 324 std::vector<ModuleElem> g(NumCols(M), zero(F)); 325 for (long i=0; i<NumRows(M); ++i) 326 for (long j=0; j<NumCols(M); ++j) 327 g[j] += M(i,j) * e[i]; 328 return FGModule(new SubmoduleImpl(F, g)); 329 } 330 331 SubmoduleRows(const FGModule & F,ConstMatrixView M)332 FGModule SubmoduleRows(const FGModule& F, ConstMatrixView M) 333 { 334 const std::vector<ModuleElem>& e = gens(F); 335 if (len(e)!=NumCols(M)) 336 CoCoA_ERROR(ERR::IncompatDims,"SubmoduleRows"); 337 std::vector<ModuleElem> g(NumRows(M), zero(F)); 338 for (long i=0; i<NumRows(M); ++i) 339 for (long j=0; j<NumCols(M); ++j) 340 g[i] += M(i,j) * e[j]; 341 return submodule(F, g); 342 } 343 344 SubmoduleOfMinGens(const FGModule & F)345 FGModule SubmoduleOfMinGens(const FGModule& F) 346 { 347 if (IsFreeModule(F)) return F; 348 return submodule(AmbientFreeModule(F), MinGens(F)); 349 } 350 351 GensAsRows(const FGModule & Mod)352 matrix GensAsRows(const FGModule& Mod) 353 { 354 const std::vector<ModuleElem>& g = gens(Mod); 355 matrix M = NewDenseMat(RingOf(Mod), len(g), NumCompts(Mod)); 356 for (long i=0; i<NumRows(M); ++i) 357 for (long j=0; j<NumCols(M); ++j) 358 SetEntry(M,i,j, g[i][j]); 359 return M; 360 } 361 362 GensAsCols(const FGModule & Mod)363 matrix GensAsCols(const FGModule& Mod) 364 { 365 const std::vector<ModuleElem>& g = gens(Mod); 366 matrix M = NewDenseMat(RingOf(Mod), NumCompts(Mod), len(g)); 367 for (long i=0; i<NumRows(M); ++i) 368 for (long j=0; j<NumCols(M); ++j) 369 SetEntry(M,i,j, g[j][i]); 370 return M; 371 } 372 373 374 namespace // anonymous 375 { 376 // template? ??? 377 InsertZeroes(const FreeModule & F,const vector<RingElem> & L,const ModuleElem & v)378 ModuleElem InsertZeroes(const FreeModule& F, const vector<RingElem>& L, const ModuleElem& v) 379 { 380 const std::vector<ModuleElem>& e = gens(F); 381 ModuleElem w(F); 382 long j=0; 383 for (long i=0; i<len(L); ++i) 384 if (IsZero(L[i])) ++j; else w += v[i-j]*e[i]; 385 return w; 386 } 387 InsertZeroes(const FreeModule & F,const vector<ModuleElem> & L,const ModuleElem & v)388 ModuleElem InsertZeroes(const FreeModule& F, const vector<ModuleElem>& L, const ModuleElem& v) 389 { 390 const std::vector<ModuleElem>& e = gens(F); 391 ModuleElem w(F); 392 long j=0; 393 for (long i=0; i<len(L); ++i) 394 if (IsZero(L[i])) ++j; else w += v[i-j]*e[i]; 395 return w; 396 } 397 398 } 399 400 SyzOfGens(const FreeModule & F,const ideal & I)401 FGModule SyzOfGens(const FreeModule& F, const ideal& I) 402 { 403 if (!IsField(CoeffRing(RingOf(F)))) 404 CoCoA_ERROR("ERR:NYI coeffs not in a field", "SyzOfGens");//??? 405 if (NumCompts(F)!=len(gens(I))) 406 CoCoA_ERROR("wrong number of components in free module", "SyzOfGens"); 407 const vector<RingElem>& g = gens(I); 408 vector<RingElem> g_non0; 409 //-- remove zero gens 410 for (long i=0; i<len(g); ++i) 411 if (!IsZero(g[i])) g_non0.push_back(g[i]); 412 vector<ModuleElem> SyzVec_non0; 413 ComputeSyz(SyzVec_non0, F, g_non0); 414 if (len(g_non0)==len(g)) return submodule(F, SyzVec_non0); 415 const std::vector<ModuleElem>& e = gens(F); 416 //-- syzygies of zero gens 417 vector<ModuleElem> SyzVec; 418 for (long i=0; i<len(g); ++i) 419 if (IsZero(g[i])) SyzVec.push_back(e[i]); 420 //-- interweave 0 in SyzVec_non0 421 for (long i=0; i<len(SyzVec_non0); ++i) 422 SyzVec.push_back(InsertZeroes(F, g, SyzVec_non0[i])); 423 return submodule(SyzVec); 424 } 425 426 SyzOfGens(const FreeModule & F,const FGModule & N)427 FGModule SyzOfGens(const FreeModule& F, const FGModule& N) 428 { 429 if (!IsField(CoeffRing(RingOf(F)))) 430 CoCoA_ERROR("ERR:NYI coeffs not in a field", "SyzOfGens");//??? 431 if (NumCompts(F)!=len(gens(N))) 432 CoCoA_ERROR("wrong number of components in free module", "SyzOfGens"); 433 const vector<ModuleElem>& g = gens(N); 434 vector<ModuleElem> g_non0; 435 //-- remove zero gens 436 for (long i=0; i<len(g); ++i) 437 if (!IsZero(g[i])) g_non0.push_back(g[i]); 438 vector<ModuleElem> SyzVec_non0; 439 ComputeSyz(SyzVec_non0, F, g_non0); 440 if (len(g_non0)==len(g)) return submodule(F, SyzVec_non0); 441 const std::vector<ModuleElem>& e = gens(F); 442 //-- syzygies of zero gens 443 vector<ModuleElem> SyzVec; 444 for (long i=0; i<len(g); ++i) 445 if (IsZero(g[i])) SyzVec.push_back(e[i]); 446 //-- interweave 0 in SyzVec_non0 447 for (long i=0; i<len(SyzVec_non0); ++i) 448 SyzVec.push_back(InsertZeroes(F, g, SyzVec_non0[i])); 449 return submodule(SyzVec); 450 } 451 452 SyzOfGens(const ideal & I)453 FGModule SyzOfGens(const ideal& I) 454 { 455 if (!IsField(CoeffRing(RingOf(I)))) 456 CoCoA_ERROR("ERR:NYI coeffs not in a field", "SyzOfGens");//??? 457 const vector<RingElem>& g = gens(I); 458 for (long i=0; i<len(g); ++i) 459 if (IsZero(g[i])) 460 CoCoA_ERROR("Zero generator(s): first arg must be the output free module", 461 "SyzOfGens"); 462 vector<ModuleElem> syzvec; 463 FreeModule F = NewFreeModuleForSyz(gens(I)); 464 return SyzOfGens(F, I); 465 } 466 467 SyzOfGens(const FGModule & N)468 FGModule SyzOfGens(const FGModule& N) 469 { 470 if (!IsField(CoeffRing(RingOf(N)))) 471 CoCoA_ERROR("ERR:NYI coeffs not in a field", "SyzOfGens");//??? 472 const vector<ModuleElem>& g = gens(N); 473 for (long i=0; i<len(g); ++i) 474 if (IsZero(g[i])) 475 CoCoA_ERROR("Zero generator(s): first arg must be the output free module", 476 "SyzOfGens"); 477 vector<ModuleElem> syzvec; 478 FreeModule F = NewFreeModuleForSyz(gens(N)); 479 return SyzOfGens(F, N); 480 } 481 482 IsContained(const module & M,const module & N)483 bool IsContained(const module& M, const module& N) 484 { 485 if (!IsSparsePolyRing(RingOf(M))) 486 CoCoA_ERROR(ERR::NYI, "SubmoduleImpl::IsContained"); 487 const vector<ModuleElem>& g = gens(M); 488 for (long i=0; i < len(g); ++i) 489 if (!IsElem(g[i], N)) return false; 490 return true; 491 } 492 493 IsHomog(const module & M)494 bool IsHomog(const module& M) 495 { 496 if (!IsSparsePolyRing(RingOf(M))) 497 CoCoA_ERROR(ERR::NotSparsePolyRing, "IsHomog(submodule)"); 498 if (GradingDim(RingOf(M))==0) 499 CoCoA_ERROR(ERR::ZeroGradingDim, "IsHomog(submodule)"); 500 if (IsZero(M)) return true; 501 // Now we know I is non-trivial. 502 const vector<ModuleElem>& GB = TidyGens(M); 503 const long GBsize = len(GB); // MUST BE A REDUCED GBASIS !!! 504 for (long i=0; i < GBsize; ++i) 505 if (!IsHomog(GB[i])) return false; 506 return true; 507 } 508 509 510 // intersection 511 512 LT(const module & M)513 FGModule LT(const module& M) 514 { 515 if (!IsSparsePolyRing(RingOf(M))) 516 CoCoA_ERROR(ERR::NotSparsePolyRing, "LT(submodule)"); 517 const SparsePolyRing P = RingOf(M); 518 if (GradingDim(P)==0) 519 CoCoA_ERROR(ERR::ZeroGradingDim, "LT(submodule)"); 520 const vector<ModuleElem>& e = gens(AmbientFreeModule(M)); 521 const vector<ModuleElem>& GB = TidyGens(M); 522 vector<ModuleElem> LTs; 523 const long GBsize = len(GB); 524 for (long i=0; i < GBsize; ++i) 525 { 526 long j = LPosn(GB[i]); 527 LTs.push_back(monomial(P, LPP(GB[i][j]))*e[j]); 528 } 529 return submodule(AmbientFreeModule(M), LTs); 530 } 531 532 533 // FGModule SubmoduleOfGBasis(const module& M) 534 // { 535 // ideal J(RingOf(I), GBasis(I)); 536 // SetGBasisAsGens(J); 537 // return J; 538 // } 539 540 541 } // end of namespace CoCoA 542 543 // RCS header/log in the next few lines 544 // $Header: /Volumes/Home_1/cocoa/cvs-repository/CoCoALib-0.99/src/AlgebraicCore/submodule.C,v 1.39 2020/02/11 16:56:43 abbott Exp $ 545 // $Log: submodule.C,v $ 546 // Revision 1.39 2020/02/11 16:56:43 abbott 547 // Summary: Corrected last update (see redmine 969) 548 // 549 // Revision 1.38 2020/02/11 16:12:20 abbott 550 // Summary: Added some checks for bad ostream (even to mem fns myOutput); see redmine 969 551 // 552 // Revision 1.37 2018/08/02 16:48:43 bigatti 553 // -- just cleaned up some commented code 554 // 555 // Revision 1.36 2018/08/01 15:12:15 bigatti 556 // -- fixed SyzOfGens in case of generators = 0 557 // 558 // Revision 1.35 2018/05/25 09:24:47 abbott 559 // Summary: Major redesign of CpuTimeLimit (many consequences) 560 // 561 // Revision 1.34 2018/05/18 16:42:11 bigatti 562 // -- added include SparsePolyOps-RingElem.H 563 // 564 // Revision 1.33 2018/05/18 12:25:54 bigatti 565 // -- renamed IntOperations --> BigIntOps 566 // 567 // Revision 1.32 2018/05/17 15:58:40 bigatti 568 // -- renamed VectorOperations --> VectorOps 569 // 570 // Revision 1.31 2017/12/21 12:19:41 bigatti 571 // -- added check for coeffs in a field on some operations 572 // 573 // Revision 1.30 2017/11/20 20:10:26 bigatti 574 // -- mimimalized --> SubmoduleOfMinGens 575 // 576 // Revision 1.29 2015/06/11 16:57:24 bigatti 577 // -- using new functions monomial(ring, pp) and monomial(ring, expv) 578 // 579 // Revision 1.28 2015/04/13 15:44:46 abbott 580 // Summary: Changed error code in IsIn and submodule (pseudo-ctor) 581 // Author: JAA 582 // 583 // Revision 1.27 2014/07/31 14:45:19 abbott 584 // Summary: Merged io.H and UtilsTemplate.H into new header VectorOperations.H 585 // Author: JAA 586 // 587 // Revision 1.26 2014/07/30 14:13:56 abbott 588 // Summary: Changed BaseRing into RingOf; myBaseRing --> myRing 589 // Author: JAA 590 // 591 // Revision 1.25 2014/07/14 15:10:05 abbott 592 // Summary: Changed include of tmp.H into UtilsTemplate.H 593 // Author: JAA 594 // 595 // Revision 1.24 2014/07/09 14:27:53 abbott 596 // Summary: Removed AsFreeModule and AsFGModule 597 // Author: JAA 598 // 599 // Revision 1.23 2014/07/07 13:29:54 abbott 600 // Summary: Removed AsSparsePolyRing 601 // Author: JAA 602 // 603 // Revision 1.22 2014/04/17 13:39:54 bigatti 604 // -- MatrixViews --> MatrixView 605 // 606 // Revision 1.21 2014/04/10 13:04:55 bigatti 607 // -- minimalized(FGModule) 608 // 609 // Revision 1.20 2014/04/09 13:11:06 bigatti 610 // -- added submodule(vector<ModuleElem>) 611 // 612 // Revision 1.19 2014/03/26 15:23:44 bigatti 613 // -- added MinGens for submodules 614 // 615 // Revision 1.18 2013/08/02 14:41:41 bigatti 616 // -- changed LPos --> LPosn 617 // 618 // Revision 1.17 2013/07/31 14:47:17 bigatti 619 // added LT(module) 620 // 621 // Revision 1.16 2013/07/31 10:20:33 bigatti 622 // -- added IsZero, IsHomog 623 // -- move inliners into class definition 624 // 625 // Revision 1.15 2013/06/06 05:47:34 bigatti 626 // -- pseudoctor is now called "submodule" instead of "NewSubmodule" 627 // -- added pseudoctor with 1,2,3,4 generators 628 // 629 // Revision 1.14 2013/06/03 10:05:59 bigatti 630 // -- added IsElem, IsContained for modules 631 // 632 // Revision 1.13 2013/03/26 14:57:18 abbott 633 // Corrected silly typo. 634 // 635 // Revision 1.12 2013/03/25 17:29:59 abbott 636 // Changed formal parameter names (M for matrix, N for submodule). 637 // 638 // Revision 1.11 2013/03/15 14:58:48 bigatti 639 // -- added SyzOfGens for modules (something inside is not working though) 640 // 641 // Revision 1.10 2013/02/21 16:56:16 bigatti 642 // -- added GensAsRows, GensAsRows, SyzOfGens 643 // 644 // Revision 1.9 2013/01/30 15:46:11 bigatti 645 // -- added NewSubmoduleCols/Rows 646 // 647 // Revision 1.8 2013/01/25 16:15:06 bigatti 648 // -- added function myGBasis (for SparsePolyRing) 649 // -- modified myTidyGens 650 // -- changed myGensArray/myTidyGensArray --> myGensValue/myTidyGensValue 651 // -- fixed myTidyGensIsValid in constructor 652 // 653 // Revision 1.7 2012/10/12 12:38:18 abbott 654 // Removed element accessor (via operator[]) and non-const mem fn ModuleBase::myCompt. 655 // 656 // Revision 1.6 2012/05/28 09:18:20 abbott 657 // Created IntOperations which gathers together all operations on 658 // integers (both big and small). Many consequential changes. 659 // 660 // Revision 1.5 2011/03/10 16:39:33 abbott 661 // Replaced (very many) size_t by long in function interfaces (for rings, 662 // PPMonoids and modules). Also replaced most size_t inside fn defns. 663 // 664 // Revision 1.4 2009/12/03 17:26:34 abbott 665 // Renamed EFGModule to FGModule. 666 // Renamed ModuleBase member fns myInit -> myNew, myKill -> myDelete. 667 // Removed some cruft (old code that was not used by anyone). 668 // 669 // Revision 1.3 2008/05/30 12:50:48 abbott 670 // Aligned some comments. 671 // 672 // Revision 1.2 2007/10/30 17:14:06 abbott 673 // Changed licence from GPL-2 only to GPL-3 or later. 674 // New version for such an important change. 675 // 676 // Revision 1.1.1.1 2007/03/09 15:16:11 abbott 677 // Imported files 678 // 679 // Revision 1.5 2007/03/08 18:22:28 cocoa 680 // Just whitespace cleaning. 681 // 682 // Revision 1.4 2007/01/15 14:39:12 bigatti 683 // -- added prefix "raw" to RawPtr arguments names 684 // 685 // Revision 1.3 2006/11/02 13:25:43 cocoa 686 // Simplification of header files: the OpenMath classes have been renamed. 687 // Many minor consequential changes. 688 // 689 // Revision 1.2 2006/10/06 10:15:52 cocoa 690 // In response to Susan's bug: a fiasco when compiling with CoCoA_MEMPOOL_DEBUG 691 // set wrongly. Moved several implementation classes out of their header files 692 // into the implementation files. Several functions had to be uninlined. 693 // Also corrected position of #include, etc. 694 // 695 // Revision 1.1.1.1 2006/05/30 11:39:37 cocoa 696 // Imported files 697 // 698 // Revision 1.7 2006/05/12 16:10:58 cocoa 699 // Added OpenMathFwd.H, and tidied OpenMath.H. 700 // Many consequential but trivial changes. 701 // 702 // Revision 1.6 2006/04/21 14:56:33 cocoa 703 // Changed return type of myCompt member function: now it returns a 704 // ConstRefRingElem instead of a RingElem (i.e. a copy). 705 // 706 // Revision 1.5 2006/03/15 18:09:31 cocoa 707 // Changed names of member functions which print out their object 708 // into myOutputSelf -- hope this will appease the Intel C++ compiler. 709 // 710 // Revision 1.4 2006/03/12 21:28:33 cocoa 711 // Major check in after many changes 712 // 713 // Revision 1.3 2005/11/29 13:04:47 cocoa 714 // -- added "const" to myCompt argument 715 // 716 // Revision 1.2 2005/11/24 16:09:38 cocoa 717 // -- added operator[] for ModuleElem 718 // 719 // Revision 1.1.1.1 2005/10/17 10:46:54 cocoa 720 // Imported files 721 // 722 // Revision 1.1.1.1 2005/05/03 15:47:31 cocoa 723 // Imported files 724 // 725 // Revision 1.4 2005/04/20 15:40:47 cocoa 726 // Major change: modified the standard way errors are to be signalled 727 // (now via a macro which records filename and line number). Updated 728 // documentation in error.txt accordingly. 729 // 730 // Improved the documentation in matrix.txt (still more work to be done). 731 // 732 // Revision 1.3 2005/04/19 14:06:03 cocoa 733 // Added GPL and GFDL licence stuff. 734 // 735 // Revision 1.2 2005/02/11 14:15:20 cocoa 736 // New style ring elements and references to ring elements; 737 // I hope I have finally got it right! 738 // 739 // Revision 1.1.1.1 2005/01/27 15:12:13 cocoa 740 // Imported files 741 // 742 // Revision 1.6 2004/11/12 15:49:29 cocoa 743 // Tidying prior to 0.90 release. 744 // (a) documentation improved (or marked as poor) 745 // (b) sundry minor improvements to the code 746 // 747 // Revision 1.5 2004/11/11 14:06:20 cocoa 748 // -- moved CVS log to the bottom 749 // -- minor changes for doxygen 750 // 751 // Revision 1.4 2004/06/29 17:10:22 cocoa 752 // Partially tidied use of "protected" and "private" in various 753 // base classes. Checking in at the end of the day -- it works, 754 // and I wouldn't want it to be lost next time point's disk 755 // misbehaves. 756 // 757 // Revision 1.3 2004/05/24 15:52:13 cocoa 758 // Major update: 759 // new error mechanism 760 // many fixes 761 // RingHoms almost work now 762 // RingFloat much improved 763 // 764 // Revision 1.2 2004/01/28 15:37:58 cocoa 765 // Fairly major update: resuscitated "old style" code which didn't compile 766 // under the current organization. 767 // 768 // Revision 1.1.1.1 2003/09/24 12:55:43 cocoa 769 // Imported files 770 // 771