1 // Copyright (c) 2005-2018,2020 John Abbott and Anna M. Bigatti 2 // Authors: 2005-2018,2020 John Abbott and Anna M. Bigatti 3 4 // This file is part of the source of CoCoALib, the CoCoA Library. 5 6 // CoCoALib is free software: you can redistribute it and/or modify 7 // it under the terms of the GNU General Public License as published by 8 // the Free Software Foundation, either version 3 of the License, or 9 // (at your option) any later version. 10 11 // CoCoALib is distributed in the hope that it will be useful, 12 // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 // GNU General Public License for more details. 15 16 // You should have received a copy of the GNU General Public License 17 // along with CoCoALib. If not, see <http://www.gnu.org/licenses/>. 18 19 20 // Source code for fns related to homogeneity in SparsePolyRing 21 22 #include "CoCoA/SparsePolyOps-RingElem.H" 23 24 #include "CoCoA/SparsePolyRing.H" 25 #include "CoCoA/SparsePolyIter.H" 26 #include "CoCoA/degree.H" 27 #include "CoCoA/geobucket.H" 28 29 30 namespace CoCoA 31 { 32 33 namespace // anonymous 34 { 35 36 // These 2 are duplicates of fns in SparsePolyOps-RingElem.C 37 CheckCompatible(ConstRefRingElem x,ConstRefRingElem y,const char * const FnName)38 inline void CheckCompatible(ConstRefRingElem x, ConstRefRingElem y, const char* const FnName) 39 { 40 if (owner(x) != owner(y)) CoCoA_ERROR(ERR::MixedRings, FnName); 41 } 42 43 CheckElemSparsePolyRing(ConstRefRingElem f,const char * const FnName)44 inline void CheckElemSparsePolyRing(ConstRefRingElem f, const char* const FnName) 45 { 46 if (!IsSparsePolyRing(owner(f))) CoCoA_ERROR(ERR::NotElemSparsePolyRing, FnName); 47 } 48 49 } // end of namespace anonymous 50 51 wdeg(ConstRefRingElem f)52 degree wdeg(ConstRefRingElem f) 53 { 54 CheckElemSparsePolyRing(f, "wdeg(f)"); 55 if (IsZero(f)) CoCoA_ERROR(ERR::ZeroRingElem, "wdeg(f)"); 56 return wdeg(LPP(f)); // yes! see [KR] introduction Sec.4.3 57 } 58 59 CmpWDeg(ConstRefRingElem f1,ConstRefRingElem f2)60 int CmpWDeg(ConstRefRingElem f1, ConstRefRingElem f2) 61 { 62 CheckCompatible(f1, f2, "CmpWDeg(f1,f2)"); 63 CheckElemSparsePolyRing(f1, "CmpWDeg(f1,f2)"); 64 if (IsZero(f1) || IsZero(f2)) CoCoA_ERROR(ERR::ZeroRingElem, "CmpWDeg(f1,f2)"); 65 // Now we know that both f1 and f2 are non-zero 66 // return SparsePolyRingPtr(owner(f1))->myCmpWDeg(raw(f1), raw(f2)); 67 return CmpWDeg(LPP(f1), LPP(f2)); 68 } 69 70 CmpWDegPartial(ConstRefRingElem f1,ConstRefRingElem f2,long i)71 int CmpWDegPartial(ConstRefRingElem f1, ConstRefRingElem f2, long i) // assumes 0 <= i 72 { 73 CheckCompatible(f1, f2, "CmpWDegPartial(f1,f2,i)"); 74 CheckElemSparsePolyRing(f1, "CmpWDegPartial(f1,f2,i)"); 75 if (IsZero(f1) || IsZero(f2)) CoCoA_ERROR(ERR::ZeroRingElem, "CmpWDegPartial(f1,f2,i)"); 76 // Now we know that both f1 and f2 are non-zero 77 // return SparsePolyRingPtr(owner(f1))->myCmpWDeg(raw(f1), raw(f2)); 78 return CmpWDegPartial(LPP(f1), LPP(f2), i); 79 } 80 81 IsHomog(ConstRefRingElem f)82 bool IsHomog(ConstRefRingElem f) 83 { 84 CheckElemSparsePolyRing(f, "IsHomog(f)"); 85 if (GradingDim(owner(f))==0) 86 CoCoA_ERROR(ERR::ZeroGradingDim, "IsHomog(RingElem)"); 87 return SparsePolyRingPtr(owner(f))->myIsHomog(raw(f)); 88 } 89 90 IsHomogPartial(ConstRefRingElem f,long n)91 bool IsHomogPartial(ConstRefRingElem f, long n) // assumes n >= 0 92 { 93 CheckElemSparsePolyRing(f, "IsHomogPartial(f,n)"); 94 return SparsePolyRingPtr(owner(f))->myIsHomogPartial(raw(f), n); 95 } 96 97 homog(ConstRefRingElem f,ConstRefRingElem h)98 RingElem homog(ConstRefRingElem f, ConstRefRingElem h) 99 { 100 const char* const FnName = "homog(RingElem, RingElem)"; 101 CheckCompatible(f, h, FnName); 102 const SparsePolyRing P = owner(f); 103 if ( GradingDim(P)!=1 ) 104 CoCoA_ERROR("GrDim must be 1", FnName); 105 if ( !IsIndet(h) ) 106 CoCoA_ERROR("second arg must be an indeterminate", FnName); 107 if ( wdeg(h)[0]!=1 ) 108 CoCoA_ERROR("degree of hom.indet must be 1", FnName); 109 RingElem fHom(P); 110 P->myHomog(raw(fHom), raw(f), raw(h)); 111 return fHom; 112 } 113 114 LF(ConstRefRingElem f)115 RingElem LF(ConstRefRingElem f) 116 { 117 const char* const FnName = "LC(f)"; 118 if (!IsSparsePolyRing(owner(f))) 119 CoCoA_ERROR(ERR::NotElemSparsePolyRing, FnName); 120 const SparsePolyRing& P = owner(f); 121 if (GradingDim(P) == 0) 122 CoCoA_ERROR("GradingDim must be non-0", FnName); 123 if (IsZero(f)) CoCoA_ERROR(ERR::ZeroRingElem, FnName); 124 125 RingElem LeadingForm(P); 126 ConstRefPPMonoidElem LPPf(LPP(f)); 127 for (SparsePolyIter it=BeginIter(f) ; !IsEnded(it) ; ++it ) 128 { 129 if (CmpWDeg(PP(it), LPPf) != 0) break; 130 PushBack(LeadingForm, coeff(it), PP(it)); 131 } 132 return LeadingForm; 133 } 134 135 CutLF(RingElem & f)136 RingElem CutLF(RingElem& f) // MODIFIES f 137 { 138 const char* const FnName = "CutLF(f)"; 139 if (!IsSparsePolyRing(owner(f))) 140 CoCoA_ERROR(ERR::NotElemSparsePolyRing, FnName); 141 const SparsePolyRing& P = owner(f); 142 if (GradingDim(P) == 0) 143 CoCoA_ERROR("GradingDim must be non-0", FnName); 144 if (IsZero(f)) 145 CoCoA_ERROR(ERR::ZeroRingElem, FnName); 146 147 RingElem ans(P); 148 do 149 { 150 P->myMoveLMToBack(raw(ans), raw(f)); 151 } 152 while (!IsZero(f) && (CmpWDeg(LPP(f), LPP(ans)) == 0)); 153 return ans; 154 } 155 156 myIsHomogPartial(ConstRawPtr rawf,long n)157 bool SparsePolyRingBase::myIsHomogPartial(ConstRawPtr rawf, long n) const // assumes 0 <= n <= GrDim 158 { 159 CoCoA_ASSERT(0 <= n && n <= myGradingDim()); 160 if (myIsZero(rawf)) { return true; } 161 SparsePolyIter itf=myBeginIter(rawf); 162 const PPMonoidElem FirstPP=PP(itf); 163 for (++itf; !IsEnded(itf); ++itf) 164 { 165 CoCoA_ASSERT( cmp(FirstPP, PP(itf)) > 0 ); // assert f is correctly sorted 166 if ( CmpWDegPartial(FirstPP, PP(itf), n) != 0 ) return false; 167 } 168 return true; 169 } 170 myIsHomog(ConstRawPtr rawf)171 bool SparsePolyRingBase::myIsHomog(ConstRawPtr rawf) const 172 { 173 if (myGradingDim()==0) 174 CoCoA_ERROR(ERR::ZeroGradingDim, "SparsePolyRingBase::myIsHomog"); 175 if (myIsZero(rawf)) { return true; } 176 SparsePolyIter itf=myBeginIter(rawf); 177 const PPMonoidElem FirstPP=PP(itf); 178 for (++itf; !IsEnded(itf); ++itf) 179 { 180 CoCoA_ASSERT( cmp(FirstPP, PP(itf))>0 ); // assert f is correctly sorted 181 if ( CmpWDeg(FirstPP, PP(itf))!=0 ) return false; 182 } 183 return true; 184 } 185 186 myHomog(RawPtr rawfHom,ConstRawPtr rawf,ConstRawPtr rawh)187 void SparsePolyRingBase::myHomog(RawPtr rawfHom, ConstRawPtr rawf, ConstRawPtr rawh) const 188 { 189 const SparsePolyRing P(this); 190 RingElemAlias h(P,rawh); 191 CoCoA_ASSERT( myGradingDim()==1 ); 192 CoCoA_ASSERT( IsIndet(h) ); 193 CoCoA_ASSERT( IsOne(wdeg(h)[0]) ); 194 geobucket gbk(P); // accumulate result into a geobucket for speed 195 RingElemAlias f(P,rawf); 196 ConstRefPPMonoidElem PPh = LPP(h); 197 const BigInt d = wdeg(f)[0]; 198 for (SparsePolyIter it=BeginIter(f) ; !IsEnded(it) ; ++it ) 199 { 200 RingElem term = monomial(P, coeff(it),PP(it) * power(PPh,d-wdeg(PP(it))[0])); 201 gbk.myAddClear(term,1); 202 } 203 RingElem tmp(P); // for exception safety 204 AddClear(tmp, gbk); 205 mySwap(rawfHom, raw(tmp)); 206 } 207 208 HomogCompt(ConstRefRingElem f,long d)209 RingElem HomogCompt(ConstRefRingElem f, long d) 210 { 211 const ring& P = owner(f); 212 if (!IsSparsePolyRing(P)) CoCoA_ERROR(ERR::NotElemSparsePolyRing, "HomogCompt"); 213 if (GradingDim(P) != 1) CoCoA_ERROR("GradingDim must be 1", "HomogCompt"); 214 if (d < 0) CoCoA_ERROR(ERR::NotNonNegative, "HomogCompt"); 215 RingElem form(P); 216 for (auto it=BeginIter(f); !IsEnded(it); ++it) 217 { 218 const long DegPP = ConvertTo<long>(wdeg(PP(it))[0]); 219 // if (DegPP != d) continue; // ASSUME term-ord is wdeg compatible!! 220 if (DegPP > d) continue; 221 if (DegPP < d) break; 222 PushBack(form, coeff(it), PP(it)); 223 } 224 return form; 225 } 226 227 228 } // end of namespace CoCoA 229 230 // RCS header/log in the next few lines 231 // $Header: /Volumes/Home_1/cocoa/cvs-repository/CoCoALib-0.99/src/AlgebraicCore/SparsePolyOps-RingElem-homog.C,v 1.2 2020/03/11 17:06:55 abbott Exp $ 232 // $Log: SparsePolyOps-RingElem-homog.C,v $ 233 // Revision 1.2 2020/03/11 17:06:55 abbott 234 // Summary: Added check for GradingDim 235 // 236 // Revision 1.1 2020/03/11 17:00:27 abbott 237 // Summary: Added new fn HomogCompt; split of fns to do with homog polys into new file. Cleaned includes. 238 // 239 // 240