Changeset a04c5e in git
- Timestamp:
- Nov 5, 2010, 3:58:04 PM (13 years ago)
- Branches:
- (u'spielwiese', 'd1ba061a762c62d3a25159d8da8b6e17332291fa')
- Children:
- f34215cd2606c6fc99bffc25e1a276b416786dca
- Parents:
- 356ffbba88cc2728b3ebccc4ab980a11e23ac7d7
- git-author:
- Hans Schoenemann <hannes@mathematik.uni-kl.de>2010-11-05 15:58:04+01:00
- git-committer:
- Mohamed Barakat <mohamed.barakat@rwth-aachen.de>2011-11-09 11:55:35+01:00
- Location:
- polys
- Files:
-
- 2 deleted
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
polys/monomials/monomials.h
r356ffbb ra04c5e 41 41 #define __p_GetComp(p, r) (p)->exp[r->pCompIndex] 42 42 #define p_GetComp(p, r) ((long) (r->pCompIndex >= 0 ? __p_GetComp(p, r) : 0)) 43 44 /***************************************************************45 *46 * What should be inlined and debugged?47 *48 ***************************************************************/49 // determines inlining of poly procs which iter through polys50 #if defined(DO_PINLINE0) && !defined(PDEBUG)51 #define PINLINE0 static inline52 #else53 #define PINLINE054 #endif55 56 // determines inlining of poly procs which iter over ExpVector57 #undef NO_PINLINE158 #if PDEBUG <= 0 && !defined(NO_INLINE1)59 #define PINLINE1 static inline60 #else61 #define PINLINE162 #define NO_PINLINE1 163 #endif64 65 // determines inlining of constant time poly procs66 #undef NO_PINLINE267 #if PDEBUG <= 1 && !defined(NO_INLINE2)68 #define PINLINE2 static inline69 #else70 #define PINLINE271 #define NO_PINLINE2 172 #endif73 74 // determines inlining of stuff from polys-impl.h75 #undef NO_PINLINE376 #if PDEBUG <= 2 && !defined(NO_INLINE3)77 #define PINLINE3 static inline78 #else79 #define PINLINE380 #define NO_PINLINE3 181 #endif82 43 83 44 /*************************************************************** -
polys/monomials/p_polys.h
r356ffbb ra04c5e 15 15 #include "ring.h" 16 16 #include "polys-impl.h" 17 /*18 Some general remarks:19 We divide poly operations into roughly 4 categories:20 Level 2: operations on monomials/polynomials with constant time,21 or operations which are just dispatchers to other22 poly routines23 - implemented in: pInline2.h24 - debugging only if PDEBUG >= 225 - normally inlined, unless PDEBUG >= 2 || NO_INLINE226 Level 1: operations on monomials with time proportional to length27 - implemented in: pInline1.h28 - debugging only if PDEBUG >= 129 - normally inlined, unless PDEBUG >= 1 || NO_INLINE130 Level 0: short operations on polynomials with time proportional to31 length of poly32 - implemented in pInline0.cc33 - debugging if PDEBUG34 - normally _not_ inlined: can be forced with35 #define DO_PINLINE036 #include "pInline0.h"37 Misc : operations on polynomials which do not fit in any of the38 above categories39 - implemented in: polys*.cc40 - never inlined41 - debugging if PDEBUG >= 042 43 You can set PDEBUG on a per-file basis, before including "mod2.h" like44 #define PDEBUG 245 #include "mod2.h"46 However, PDEBUG will only be in effect, if !NDEBUG.47 */48 17 49 18 /*************************************************************** … … 64 33 #define p_SetCoeff0(p,n,r) pSetCoeff0(p,n) 65 34 // deletes old p->coef and sets new one 66 PINLINE2number p_SetCoeff(poly p, number n, ring r);35 static inline number p_SetCoeff(poly p, number n, ring r); 67 36 68 37 // get Order 69 PINLINE2long p_GetOrder(poly p, ring r);38 static inline long p_GetOrder(poly p, ring r); 70 39 71 40 // Component 72 41 #define p_GetComp(p, r) _p_GetComp(p, r) 73 PINLINE2unsigned long p_SetComp(poly p, unsigned long c, ring r);74 PINLINE2unsigned long p_AddComp(poly p, unsigned long v, ring r);75 PINLINE2unsigned long p_SubComp(poly p, unsigned long v, ring r);42 static inline unsigned long p_SetComp(poly p, unsigned long c, ring r); 43 static inline unsigned long p_AddComp(poly p, unsigned long v, ring r); 44 static inline unsigned long p_SubComp(poly p, unsigned long v, ring r); 76 45 77 46 // Exponent 78 PINLINE2long p_GetExp(poly p, int v, ring r);79 PINLINE2long p_SetExp(poly p, int v, long e, ring r);80 PINLINE2long p_IncrExp(poly p, int v, ring r);81 PINLINE2long p_DecrExp(poly p, int v, ring r);82 PINLINE2long p_AddExp(poly p, int v, long ee, ring r);83 PINLINE2long p_SubExp(poly p, int v, long ee, ring r);84 PINLINE2long p_MultExp(poly p, int v, long ee, ring r);85 PINLINE2long p_GetExpSum(poly p1, poly p2, int i, ring r);86 PINLINE2long p_GetExpDiff(poly p1, poly p2, int i, ring r);47 static inline long p_GetExp(poly p, int v, ring r); 48 static inline long p_SetExp(poly p, int v, long e, ring r); 49 static inline long p_IncrExp(poly p, int v, ring r); 50 static inline long p_DecrExp(poly p, int v, ring r); 51 static inline long p_AddExp(poly p, int v, long ee, ring r); 52 static inline long p_SubExp(poly p, int v, long ee, ring r); 53 static inline long p_MultExp(poly p, int v, long ee, ring r); 54 static inline long p_GetExpSum(poly p1, poly p2, int i, ring r); 55 static inline long p_GetExpDiff(poly p1, poly p2, int i, ring r); 87 56 88 57 /*************************************************************** … … 92 61 * 93 62 ***************************************************************/ 94 PINLINE2poly p_New(ring r);95 PINLINE2poly p_New(ring r, omBin bin);96 PINLINE1poly p_Init(ring r);97 PINLINE1poly p_Init(ring r, omBin bin);98 PINLINE1poly p_LmInit(poly p, ring r);99 PINLINE1poly p_LmInit(poly s_p, ring s_r, ring d_p);100 PINLINE1poly p_LmInit(poly s_p, ring s_r, ring d_p, omBin d_bin);101 PINLINE1poly p_Head(poly p, ring r);102 PINLINE2void p_LmFree(poly p, ring r);103 PINLINE2void p_LmFree(poly *p, ring r);104 PINLINE2poly p_LmFreeAndNext(poly p, ring r);105 PINLINE2void p_LmDelete(poly p, ring r);106 PINLINE2void p_LmDelete(poly *p, ring r);107 PINLINE2poly p_LmDeleteAndNext(poly p, ring r);63 static inline poly p_New(ring r); 64 static inline poly p_New(ring r, omBin bin); 65 static inline poly p_Init(ring r); 66 static inline poly p_Init(ring r, omBin bin); 67 static inline poly p_LmInit(poly p, ring r); 68 static inline poly p_LmInit(poly s_p, ring s_r, ring d_p); 69 static inline poly p_LmInit(poly s_p, ring s_r, ring d_p, omBin d_bin); 70 static inline poly p_Head(poly p, ring r); 71 static inline void p_LmFree(poly p, ring r); 72 static inline void p_LmFree(poly *p, ring r); 73 static inline poly p_LmFreeAndNext(poly p, ring r); 74 static inline void p_LmDelete(poly p, ring r); 75 static inline void p_LmDelete(poly *p, ring r); 76 static inline poly p_LmDeleteAndNext(poly p, ring r); 108 77 109 78 /*************************************************************** … … 113 82 ***************************************************************/ 114 83 // ExpVextor(d_p) = ExpVector(s_p) 115 PINLINE1void p_ExpVectorCopy(poly d_p, poly s_p, ring r);84 static inline void p_ExpVectorCopy(poly d_p, poly s_p, ring r); 116 85 // adjustments for negative weights 117 PINLINE1void p_MemAdd_NegWeightAdjust(poly p, ring r);118 PINLINE1void p_MemSub_NegWeightAdjust(poly p, ring r);86 static inline void p_MemAdd_NegWeightAdjust(poly p, ring r); 87 static inline void p_MemSub_NegWeightAdjust(poly p, ring r); 119 88 // ExpVector(p1) += ExpVector(p2) 120 PINLINE1void p_ExpVectorAdd(poly p1, poly p2, ring r);89 static inline void p_ExpVectorAdd(poly p1, poly p2, ring r); 121 90 // ExpVector(p1) -= ExpVector(p2) 122 PINLINE1void p_ExpVectorSub(poly p1, poly p2, ring r);91 static inline void p_ExpVectorSub(poly p1, poly p2, ring r); 123 92 // ExpVector(p1) += ExpVector(p2) - ExpVector(p3) 124 PINLINE1void p_ExpVectorAddSub(poly p1, poly p2, poly p3, ring r);93 static inline void p_ExpVectorAddSub(poly p1, poly p2, poly p3, ring r); 125 94 // ExpVector(pr) = ExpVector(p1) + ExpVector(p2) 126 PINLINE1void p_ExpVectorSum(poly pr, poly p1, poly p2, ring r);95 static inline void p_ExpVectorSum(poly pr, poly p1, poly p2, ring r); 127 96 /// ExpVector(pr) = ExpVector(p1) + ExpVector(p2) 128 PINLINE1void p_ExpVectorDiff(poly pr, poly p1, poly p2, ring r);97 static inline void p_ExpVectorDiff(poly pr, poly p1, poly p2, ring r); 129 98 /// returns TRUE if ExpVector(p1) == ExpVector(p2), FALSE, otherwise 130 PINLINE1BOOLEAN p_ExpVectorEqual(poly p1, poly p2, ring r);99 static inline BOOLEAN p_ExpVectorEqual(poly p1, poly p2, ring r); 131 100 /// compute the degree of the leading monomial of p 132 101 /// with respect to weigths 1 133 102 /// the ordering may not be compatible with degree so do not use p->Order 134 PINLINE1long p_Totaldegree(poly p, ring r);135 136 PINLINE1void p_GetExpV(poly p, int *ev, ring r);137 PINLINE1void p_SetExpV(poly p, int *ev, ring r);103 static inline long p_Totaldegree(poly p, ring r); 104 105 static inline void p_GetExpV(poly p, int *ev, ring r); 106 static inline void p_SetExpV(poly p, int *ev, ring r); 138 107 139 108 … … 143 112 * 144 113 ***************************************************************/ 145 PINLINE1int p_LmCmp(poly p, poly q, ring r);114 static inline int p_LmCmp(poly p, poly q, ring r); 146 115 #define p_LmCmpAction(p, q, r, actionE, actionG, actionS) \ 147 116 _p_LmCmpAction(p, q, r, actionE, actionG, actionS) … … 152 121 // pCmp: args may be NULL 153 122 // returns: (p2==NULL ? 1 : (p1 == NULL ? -1 : p_LmCmp(p1, p2))) 154 PINLINE2int p_Cmp(poly p1, poly p2, ring r);123 static inline int p_Cmp(poly p1, poly p2, ring r); 155 124 156 125 … … 161 130 * 162 131 ***************************************************************/ 163 PINLINE1BOOLEAN p_DivisibleBy(poly a, poly b, ring r);164 PINLINE1BOOLEAN p_LmDivisibleBy(poly a, poly b, ring r);165 PINLINE1BOOLEAN p_LmDivisibleByNoComp(poly a, poly b, ring r);132 static inline BOOLEAN p_DivisibleBy(poly a, poly b, ring r); 133 static inline BOOLEAN p_LmDivisibleBy(poly a, poly b, ring r); 134 static inline BOOLEAN p_LmDivisibleByNoComp(poly a, poly b, ring r); 166 135 unsigned long p_GetShortExpVector(poly a, ring r); 167 PINLINE1BOOLEAN p_LmShortDivisibleBy(poly a, unsigned long sev_a,136 static inline BOOLEAN p_LmShortDivisibleBy(poly a, unsigned long sev_a, 168 137 poly b, unsigned long not_sev_b, ring r); 169 138 170 PINLINE1BOOLEAN p_DivisibleBy(poly a, ring r_a, poly b, ring r_b);171 PINLINE1BOOLEAN p_LmDivisibleBy(poly a, ring r_a, poly b, ring r_b);172 PINLINE1BOOLEAN p_LmShortDivisibleBy(poly a, unsigned long sev_a, ring r_a,139 static inline BOOLEAN p_DivisibleBy(poly a, ring r_a, poly b, ring r_b); 140 static inline BOOLEAN p_LmDivisibleBy(poly a, ring r_a, poly b, ring r_b); 141 static inline BOOLEAN p_LmShortDivisibleBy(poly a, unsigned long sev_a, ring r_a, 173 142 poly b, unsigned long not_sev_b, ring r_b); 174 143 … … 180 149 // test if the monomial is a constant as a vector component 181 150 // i.e., test if all exponents are zero 182 PINLINE1BOOLEAN p_LmIsConstantComp(const poly p, const ring r);183 PINLINE1BOOLEAN p_LmIsConstant(const poly p, const ring r);151 static inline BOOLEAN p_LmIsConstantComp(const poly p, const ring r); 152 static inline BOOLEAN p_LmIsConstant(const poly p, const ring r); 184 153 185 154 // return TRUE, if p_LmExpVectorAdd stays within ExpBound of ring r, 186 155 // FALSE, otherwise 187 PINLINE1BOOLEAN p_LmExpVectorAddIsOk(const poly p1, const poly p2, ring r);156 static inline BOOLEAN p_LmExpVectorAddIsOk(const poly p1, const poly p2, ring r); 188 157 189 158 /*************************************************************** … … 193 162 ***************************************************************/ 194 163 // return the maximal exponent of p 195 PINLINE2unsigned long p_GetMaxExp(poly p, ring r);164 static inline unsigned long p_GetMaxExp(poly p, ring r); 196 165 // return the maximal exponent of p in form of the maximal long var 197 166 unsigned long p_GetMaxExpL(poly p, const ring r, unsigned long l_max = 0); … … 201 170 202 171 // suppose that l is a long var in r, return maximal exponent of l 203 PINLINE2unsigned long p_GetMaxExp(const unsigned long l, const ring r);172 static inline unsigned long p_GetMaxExp(const unsigned long l, const ring r); 204 173 205 174 // return the TotalDegree of the long var l 206 PINLINE2unsigned long p_GetTotalDegree(const unsigned long l, const ring r);175 static inline unsigned long p_GetTotalDegree(const unsigned long l, const ring r); 207 176 // return the total degree of the long var l containing number_of_exp exponents 208 PINLINE2unsigned long p_GetTotalDegree(const unsigned long l, const ring r, const int number_of_exps);177 static inline unsigned long p_GetTotalDegree(const unsigned long l, const ring r, const int number_of_exps); 209 178 210 179 211 180 // like the respective p_LmIs* routines, except that p might be empty 212 PINLINE1BOOLEAN p_IsConstantComp(const poly p, const ring r);213 PINLINE1BOOLEAN p_IsConstant(const poly p, const ring r);181 static inline BOOLEAN p_IsConstantComp(const poly p, const ring r); 182 static inline BOOLEAN p_IsConstant(const poly p, const ring r); 214 183 PINLINE0 BOOLEAN p_IsConstantPoly(const poly p, const ring r); 215 184 … … 239 208 ***************************************************************/ 240 209 // returns a copy of p 241 PINLINE2poly p_Copy(poly p, const ring r);210 static inline poly p_Copy(poly p, const ring r); 242 211 // returns a copy of p with Lm(p) from lmRing and Tail(p) from tailRing 243 PINLINE2poly p_Copy(poly p, const ring lmRing, const ring tailRing);212 static inline poly p_Copy(poly p, const ring lmRing, const ring tailRing); 244 213 // deletes *p, and sets *p to NULL 245 PINLINE2void p_Delete(poly *p, const ring r);246 PINLINE2void p_Delete(poly *p, const ring lmRing, const ring tailRing);214 static inline void p_Delete(poly *p, const ring r); 215 static inline void p_Delete(poly *p, const ring lmRing, const ring tailRing); 247 216 248 217 // copys monomials of p, allocates new monomials from bin, 249 218 // deletes monomoals of p 250 PINLINE2poly p_ShallowCopyDelete(poly p, const ring r, omBin bin);219 static inline poly p_ShallowCopyDelete(poly p, const ring r, omBin bin); 251 220 // simial but does it only for leading monomial 252 PINLINE1poly p_LmShallowCopyDelete(poly p, const ring r, omBin bin);221 static inline poly p_LmShallowCopyDelete(poly p, const ring r, omBin bin); 253 222 // simply deletes monomials, does not free coeffs 254 223 void p_ShallowDelete(poly *p, const ring r); … … 267 236 ***************************************************************/ 268 237 // returns -p, p is destroyed 269 PINLINE2poly p_Neg(poly p, const ring r);238 static inline poly p_Neg(poly p, const ring r); 270 239 271 240 // returns p*n, p is const (i.e. copied) 272 PINLINE2poly pp_Mult_nn(poly p, number n, const ring r);241 static inline poly pp_Mult_nn(poly p, number n, const ring r); 273 242 // returns p*n, destroys p 274 PINLINE2poly p_Mult_nn(poly p, number n, const ring r);275 PINLINE2poly p_Mult_nn(poly p, number n, const ring lmRing, const ring tailRing);243 static inline poly p_Mult_nn(poly p, number n, const ring r); 244 static inline poly p_Mult_nn(poly p, number n, const ring lmRing, const ring tailRing); 276 245 277 246 // returns p*m, does neither destroy p nor m 278 PINLINE2poly pp_Mult_mm(poly p, poly m, const ring r);247 static inline poly pp_Mult_mm(poly p, poly m, const ring r); 279 248 // returns p*m, destroys p, const: m 280 PINLINE2poly p_Mult_mm(poly p, poly m, const ring r);249 static inline poly p_Mult_mm(poly p, poly m, const ring r); 281 250 282 251 // returns p+q, destroys p and q 283 PINLINE2poly p_Add_q(poly p, poly q, const ring r);252 static inline poly p_Add_q(poly p, poly q, const ring r); 284 253 // like p_Add_q, except that if lp == pLength(lp) lq == pLength(lq) 285 254 // then lp == pLength(p+q) 286 PINLINE2poly p_Add_q(poly p, poly q, int &lp, int lq, const ring r);255 static inline poly p_Add_q(poly p, poly q, int &lp, int lq, const ring r); 287 256 288 257 // return p - m*q, destroys p; const: q,m 289 PINLINE2poly p_Minus_mm_Mult_qq(poly p, poly m, poly q, const ring r);258 static inline poly p_Minus_mm_Mult_qq(poly p, poly m, poly q, const ring r); 290 259 // like p_Minus_mm_Mult_qq, except that if lp == pLength(lp) lq == pLength(lq) 291 260 // then lp == pLength(p -m*q) 292 PINLINE2poly p_Minus_mm_Mult_qq(poly p, poly m, poly q, int &lp, int lq,261 static inline poly p_Minus_mm_Mult_qq(poly p, poly m, poly q, int &lp, int lq, 293 262 poly spNoether, const ring r); 294 263 // returns p + m*q destroys p, const: q, m 295 PINLINE2poly p_Plus_mm_Mult_qq(poly p, poly m, poly q, const ring r);264 static inline poly p_Plus_mm_Mult_qq(poly p, poly m, poly q, const ring r); 296 265 297 266 // returns p + m*q destroys p, const: q, m 298 PINLINE2poly p_Plus_mm_Mult_qq(poly p, poly m, poly q, int &lp, int lq,267 static inline poly p_Plus_mm_Mult_qq(poly p, poly m, poly q, int &lp, int lq, 299 268 const ring r); 300 269 301 270 // returns p*q, destroys p and q 302 PINLINE2poly p_Mult_q(poly p, poly q, const ring r);271 static inline poly p_Mult_q(poly p, poly q, const ring r); 303 272 // returns p*q, does neither destroy p nor q 304 PINLINE2poly pp_Mult_qq(poly p, poly q, const ring r);273 static inline poly pp_Mult_qq(poly p, poly q, const ring r); 305 274 306 275 // returns p*Coeff(m) for such monomials pm of p, for which m is divisble by pm 307 PINLINE2poly pp_Mult_Coeff_mm_DivSelect(poly p, const poly m, const ring r);276 static inline poly pp_Mult_Coeff_mm_DivSelect(poly p, const poly m, const ring r); 308 277 309 278 // returns p*Coeff(m) for such monomials pm of p, for which m is divisble by pm 310 279 // if lp is length of p on input then lp is length of returned poly on output 311 PINLINE2poly pp_Mult_Coeff_mm_DivSelect(poly p, int &lp, const poly m, const ring r);280 static inline poly pp_Mult_Coeff_mm_DivSelect(poly p, int &lp, const poly m, const ring r); 312 281 313 282 // returns merged p and q, assumes p and q have no monomials which are equal 314 PINLINE2poly p_Merge_q(poly p, poly c, const ring r);283 static inline poly p_Merge_q(poly p, poly c, const ring r); 315 284 // sorts p using bucket sort: returns sorted poly 316 285 // assumes that monomials of p are all different 317 286 // reverses it first, if revert == TRUE, use this if input p is "almost" sorted 318 287 // correctly 319 PINLINE2poly p_SortMerge(poly p, const ring r, BOOLEAN revert = FALSE);288 static inline poly p_SortMerge(poly p, const ring r, BOOLEAN revert = FALSE); 320 289 // like SortMerge, except that p may have equal monimals 321 PINLINE2poly p_SortAdd(poly p, const ring r, BOOLEAN revert = FALSE);290 static inline poly p_SortAdd(poly p, const ring r, BOOLEAN revert = FALSE); 322 291 323 292 /*************************************************************** … … 326 295 * 327 296 ***************************************************************/ 328 PINLINE2void p_Setm(poly p, const ring r);297 static inline void p_Setm(poly p, const ring r); 329 298 p_SetmProc p_GetSetmProc(ring r); 330 299 … … 362 331 void p_wrp(poly p, ring lmRing, ring tailRing); 363 332 364 PINLINE2char* p_String(poly p, ring p_ring);365 PINLINE2char* p_String0(poly p, ring p_ring);366 PINLINE2void p_Write(poly p, ring p_ring);367 PINLINE2void p_Write0(poly p, ring p_ring);368 PINLINE2void p_wrp(poly p, ring p_ring);333 static inline char* p_String(poly p, ring p_ring); 334 static inline char* p_String0(poly p, ring p_ring); 335 static inline void p_Write(poly p, ring p_ring); 336 static inline void p_Write0(poly p, ring p_ring); 337 static inline void p_wrp(poly p, ring p_ring); 369 338 370 339 … … 447 416 #endif 448 417 449 #include <kernel/pInline2.h> 450 #include <kernel/pInline1.h> 451 418 /*************************************************************** 419 * 420 * Primitives for accessing and setting fields of a poly 421 * 422 ***************************************************************/ 423 424 static inline number p_SetCoeff(poly p, number n, ring r) 425 { 426 p_LmCheckPolyRing2(p, r); 427 n_Delete(&(p->coef), r); 428 (p)->coef=n; 429 return n; 430 } 431 432 // order 433 static inline long p_GetOrder(poly p, ring r) 434 { 435 p_LmCheckPolyRing2(p, r); 436 if (r->typ==NULL) return ((p)->exp[r->pOrdIndex]); 437 int i=0; 438 loop 439 { 440 switch(r->typ[i].ord_typ) 441 { 442 case ro_wp_neg: 443 return (((long)((p)->exp[r->pOrdIndex]))-POLY_NEGWEIGHT_OFFSET); 444 case ro_syzcomp: 445 case ro_syz: 446 case ro_cp: 447 i++; 448 break; 449 //case ro_dp: 450 //case ro_wp: 451 default: 452 return ((p)->exp[r->pOrdIndex]); 453 } 454 } 455 } 456 457 // Setm 458 static inline void p_Setm(poly p, const ring r) 459 { 460 p_CheckRing2(r); 461 r->p_Setm(p, r); 462 } 463 464 // component 465 static inline unsigned long p_SetComp(poly p, unsigned long c, ring r) 466 { 467 p_LmCheckPolyRing2(p, r); 468 pAssume2(rRing_has_Comp(r)); 469 __p_GetComp(p,r) = c; 470 return c; 471 } 472 static inline unsigned long p_AddComp(poly p, unsigned long v, ring r) 473 { 474 p_LmCheckPolyRing2(p, r); 475 pAssume2(rRing_has_Comp(r)); 476 return __p_GetComp(p,r) += v; 477 } 478 static inline unsigned long p_SubComp(poly p, unsigned long v, ring r) 479 { 480 p_LmCheckPolyRing2(p, r); 481 pAssume2(rRing_has_Comp(r)); 482 pPolyAssume2(__p_GetComp(p,r) >= v,p,r); 483 return __p_GetComp(p,r) -= v; 484 } 485 static inline int p_Comp_k_n(poly a, poly b, int k, ring r) 486 { 487 if ((a==NULL) || (b==NULL) ) return FALSE; 488 p_LmCheckPolyRing2(a, r); 489 p_LmCheckPolyRing2(b, r); 490 pAssume2(k > 0 && k <= r->N); 491 int i=k; 492 for(;i<=r->N;i++) 493 { 494 if (p_GetExp(a,i,r) != p_GetExp(b,i,r)) return FALSE; 495 // if (a->exp[(r->VarOffset[i] & 0xffffff)] != b->exp[(r->VarOffset[i] & 0xffffff)]) return FALSE; 496 } 497 return TRUE; 498 } 499 500 #ifndef HAVE_EXPSIZES 501 502 /// get a single variable exponent 503 /// @Note: 504 /// the integer VarOffset encodes: 505 /// 1. the position of a variable in the exponent vector p->exp (lower 24 bits) 506 /// 2. number of bits to shift to the right in the upper 8 bits (which takes at most 6 bits for 64 bit) 507 /// Thus VarOffset always has 2 zero higher bits! 508 static inline long p_GetExp(const poly p, const unsigned long iBitmask, const int VarOffset) 509 { 510 pAssume2((VarOffset >> (24 + 6)) == 0); 511 #if 0 512 int pos=(VarOffset & 0xffffff); 513 int bitpos=(VarOffset >> 24); 514 unsigned long exp=(p->exp[pos] >> bitmask) & iBitmask; 515 return exp; 516 #else 517 return (long) 518 ((p->exp[(VarOffset & 0xffffff)] >> (VarOffset >> 24)) 519 & iBitmask); 520 #endif 521 } 522 523 524 /// set a single variable exponent 525 /// @Note: 526 /// VarOffset encodes the position in p->exp @see p_GetExp 527 static inline unsigned long p_SetExp(poly p, const unsigned long e, const unsigned long iBitmask, const int VarOffset) 528 { 529 pAssume2(e>=0); 530 pAssume2(e<=iBitmask); 531 pAssume2((VarOffset >> (24 + 6)) == 0); 532 533 // shift e to the left: 534 register int shift = VarOffset >> 24; 535 unsigned long ee = e << shift /*(VarOffset >> 24)*/; 536 // find the bits in the exponent vector 537 register int offset = (VarOffset & 0xffffff); 538 // clear the bits in the exponent vector: 539 p->exp[offset] &= ~( iBitmask << shift ); 540 // insert e with | 541 p->exp[ offset ] |= ee; 542 return e; 543 } 544 545 546 #else // #ifdef HAVE_EXPSIZES // EXPERIMENTAL!!! 547 548 static inline unsigned long BitMask(unsigned long bitmask, int twobits) 549 { 550 // bitmask = 00000111111111111 551 // 0 must give bitmask! 552 // 1, 2, 3 - anything like 00011..11 553 pAssume2((twobits >> 2) == 0); 554 static const unsigned long _bitmasks[4] = {-1, 0x7fff, 0x7f, 0x3}; 555 return bitmask & _bitmasks[twobits]; 556 } 557 558 559 /// @Note: we may add some more info (6 ) into VarOffset and thus encode 560 static inline long p_GetExp(const poly p, const unsigned long iBitmask, const int VarOffset) 561 { 562 int pos =(VarOffset & 0xffffff); 563 int hbyte= (VarOffset >> 24); // the highest byte 564 int bitpos = hbyte & 0x3f; // last 6 bits 565 long bitmask = BitMask(iBitmask, hbyte >> 6); 566 567 long exp=(p->exp[pos] >> bitpos) & bitmask; 568 return exp; 569 570 } 571 572 static inline long p_SetExp(poly p, const long e, const unsigned long iBitmask, const int VarOffset) 573 { 574 pAssume2(e>=0); 575 pAssume2(e <= BitMask(iBitmask, VarOffset >> 30)); 576 577 // shift e to the left: 578 register int hbyte = VarOffset >> 24; 579 int bitmask = BitMask(iBitmask, hbyte >> 6); 580 register int shift = hbyte & 0x3f; 581 long ee = e << shift; 582 // find the bits in the exponent vector 583 register int offset = (VarOffset & 0xffffff); 584 // clear the bits in the exponent vector: 585 p->exp[offset] &= ~( bitmask << shift ); 586 // insert e with | 587 p->exp[ offset ] |= ee; 588 return e; 589 } 590 591 #endif // #ifndef HAVE_EXPSIZES 592 593 594 static inline long p_GetExp(const poly p, const ring r, const int VarOffset) 595 { 596 p_LmCheckPolyRing2(p, r); 597 pAssume2(VarOffset != -1); 598 return p_GetExp(p, r->bitmask, VarOffset); 599 } 600 601 static inline long p_SetExp(poly p, const long e, const ring r, const int VarOffset) 602 { 603 p_LmCheckPolyRing2(p, r); 604 pAssume2(VarOffset != -1); 605 return p_SetExp(p, e, r->bitmask, VarOffset); 606 } 607 608 609 610 /// get v^th exponent for a monomial 611 static inline long p_GetExp(const poly p, const int v, const ring r) 612 { 613 p_LmCheckPolyRing2(p, r); 614 pAssume2(v>0 && v <= r->N); 615 pAssume2(r->VarOffset[v] != -1); 616 return p_GetExp(p, r->bitmask, r->VarOffset[v]); 617 } 618 619 620 /// set v^th exponent for a monomial 621 static inline long p_SetExp(poly p, const int v, const long e, const ring r) 622 { 623 p_LmCheckPolyRing2(p, r); 624 pAssume2(v>0 && v <= r->N); 625 pAssume2(r->VarOffset[v] != -1); 626 return p_SetExp(p, e, r->bitmask, r->VarOffset[v]); 627 } 628 629 630 631 632 633 // the following should be implemented more efficiently 634 static inline long p_IncrExp(poly p, int v, ring r) 635 { 636 p_LmCheckPolyRing2(p, r); 637 int e = p_GetExp(p,v,r); 638 e++; 639 return p_SetExp(p,v,e,r); 640 } 641 static inline long p_DecrExp(poly p, int v, ring r) 642 { 643 p_LmCheckPolyRing2(p, r); 644 int e = p_GetExp(p,v,r); 645 pAssume2(e > 0); 646 e--; 647 return p_SetExp(p,v,e,r); 648 } 649 static inline long p_AddExp(poly p, int v, long ee, ring r) 650 { 651 p_LmCheckPolyRing2(p, r); 652 int e = p_GetExp(p,v,r); 653 e += ee; 654 return p_SetExp(p,v,e,r); 655 } 656 static inline long p_SubExp(poly p, int v, long ee, ring r) 657 { 658 p_LmCheckPolyRing2(p, r); 659 long e = p_GetExp(p,v,r); 660 pAssume2(e >= ee); 661 e -= ee; 662 return p_SetExp(p,v,e,r); 663 } 664 static inline long p_MultExp(poly p, int v, long ee, ring r) 665 { 666 p_LmCheckPolyRing2(p, r); 667 long e = p_GetExp(p,v,r); 668 e *= ee; 669 return p_SetExp(p,v,e,r); 670 } 671 672 static inline long p_GetExpSum(poly p1, poly p2, int i, ring r) 673 { 674 p_LmCheckPolyRing2(p1, r); 675 p_LmCheckPolyRing2(p2, r); 676 return p_GetExp(p1,i,r) + p_GetExp(p2,i,r); 677 } 678 static inline long p_GetExpDiff(poly p1, poly p2, int i, ring r) 679 { 680 return p_GetExp(p1,i,r) - p_GetExp(p2,i,r); 681 } 682 683 684 /*************************************************************** 685 * 686 * Allocation/Initalization/Deletion 687 * 688 ***************************************************************/ 689 static inline poly p_New(ring r, omBin bin) 690 { 691 p_CheckRing2(r); 692 pAssume2(bin != NULL && r->PolyBin->sizeW == bin->sizeW); 693 poly p; 694 omTypeAllocBin(poly, p, bin); 695 p_SetRingOfLm(p, r); 696 return p; 697 } 698 699 static inline poly p_New(ring r) 700 { 701 return p_New(r, r->PolyBin); 702 } 703 704 static inline void p_LmFree(poly p, ring r) 705 { 706 p_LmCheckPolyRing2(p, r); 707 omFreeBinAddr(p); 708 } 709 static inline void p_LmFree(poly *p, ring r) 710 { 711 p_LmCheckPolyRing2(*p, r); 712 poly h = *p; 713 *p = pNext(h); 714 omFreeBinAddr(h); 715 } 716 static inline poly p_LmFreeAndNext(poly p, ring r) 717 { 718 p_LmCheckPolyRing2(p, r); 719 poly pnext = pNext(p); 720 omFreeBinAddr(p); 721 return pnext; 722 } 723 static inline void p_LmDelete(poly p, ring r) 724 { 725 p_LmCheckPolyRing2(p, r); 726 n_Delete(&pGetCoeff(p), r); 727 omFreeBinAddr(p); 728 } 729 static inline void p_LmDelete(poly *p, ring r) 730 { 731 p_LmCheckPolyRing2(*p, r); 732 poly h = *p; 733 *p = pNext(h); 734 n_Delete(&pGetCoeff(h), r); 735 omFreeBinAddr(h); 736 } 737 static inline poly p_LmDeleteAndNext(poly p, ring r) 738 { 739 p_LmCheckPolyRing2(p, r); 740 poly pnext = pNext(p); 741 n_Delete(&pGetCoeff(p), r); 742 omFreeBinAddr(p); 743 return pnext; 744 } 745 746 /*************************************************************** 747 * 748 * Misc routines 749 * 750 ***************************************************************/ 751 static inline int p_Cmp(poly p1, poly p2, ring r) 752 { 753 if (p2==NULL) 754 return 1; 755 if (p1==NULL) 756 return -1; 757 return p_LmCmp(p1,p2,r); 758 } 759 760 static inline unsigned long p_GetMaxExp(const poly p, const ring r) 761 { 762 return p_GetMaxExp(p_GetMaxExpL(p, r), r); 763 } 764 765 static inline unsigned long p_GetMaxExp(const unsigned long l, const ring r) 766 { 767 unsigned long bitmask = r->bitmask; 768 unsigned long max = (l & bitmask); 769 unsigned long j = r->ExpPerLong - 1; 770 771 if (j > 0) 772 { 773 unsigned long i = r->BitsPerExp; 774 long e; 775 loop 776 { 777 e = ((l >> i) & bitmask); 778 if ((unsigned long) e > max) 779 max = e; 780 j--; 781 if (j==0) break; 782 i += r->BitsPerExp; 783 } 784 } 785 return max; 786 } 787 788 static inline unsigned long 789 p_GetTotalDegree(const unsigned long l, const ring r, const int number_of_exps) 790 { 791 const unsigned long bitmask = r->bitmask; 792 unsigned long sum = (l & bitmask); 793 unsigned long j = number_of_exps - 1; 794 795 if (j > 0) 796 { 797 unsigned long i = r->BitsPerExp; 798 loop 799 { 800 sum += ((l >> i) & bitmask); 801 j--; 802 if (j==0) break; 803 i += r->BitsPerExp; 804 } 805 } 806 return sum; 807 } 808 809 static inline unsigned long 810 p_GetTotalDegree(const unsigned long l, const ring r) 811 { 812 return p_GetTotalDegree(l, r, r->ExpPerLong); 813 } 814 815 /*************************************************************** 816 * 817 * Dispatcher to r->p_Procs, they do the tests/checks 818 * 819 ***************************************************************/ 820 // returns a copy of p 821 static inline poly p_Copy(poly p, const ring r) 822 { 823 #ifdef PDEBUG 824 poly pp= r->p_Procs->p_Copy(p, r); 825 p_Test(pp,r); 826 return pp; 827 #else 828 return r->p_Procs->p_Copy(p, r); 829 #endif 830 } 831 832 static inline poly p_Copy(poly p, const ring lmRing, const ring tailRing) 833 { 834 #ifndef PDEBUG 835 if (tailRing == lmRing) 836 return tailRing->p_Procs->p_Copy(p, tailRing); 837 #endif 838 if (p != NULL) 839 { 840 poly pres = p_Head(p, lmRing); 841 pNext(pres) = tailRing->p_Procs->p_Copy(pNext(p), tailRing); 842 return pres; 843 } 844 else 845 return NULL; 846 } 847 848 // deletes *p, and sets *p to NULL 849 static inline void p_Delete(poly *p, const ring r) 850 { 851 r->p_Procs->p_Delete(p, r); 852 } 853 854 static inline void p_Delete(poly *p, const ring lmRing, const ring tailRing) 855 { 856 #ifndef PDEBUG 857 if (tailRing == lmRing) 858 { 859 tailRing->p_Procs->p_Delete(p, tailRing); 860 return; 861 } 862 #endif 863 if (*p != NULL) 864 { 865 if (pNext(*p) != NULL) 866 tailRing->p_Procs->p_Delete(&pNext(*p), tailRing); 867 p_LmDelete(p, lmRing); 868 } 869 } 870 871 static inline poly p_ShallowCopyDelete(poly p, const ring r, omBin bin) 872 { 873 p_LmCheckPolyRing2(p, r); 874 pAssume2(r->PolyBin->sizeW == bin->sizeW); 875 return r->p_Procs->p_ShallowCopyDelete(p, r, bin); 876 } 877 878 // returns p+q, destroys p and q 879 static inline poly p_Add_q(poly p, poly q, const ring r) 880 { 881 int shorter; 882 return r->p_Procs->p_Add_q(p, q, shorter, r); 883 } 884 885 static inline poly p_Add_q(poly p, poly q, int &lp, int lq, const ring r) 886 { 887 int shorter; 888 poly res = r->p_Procs->p_Add_q(p, q, shorter, r); 889 lp = (lp + lq) - shorter; 890 return res; 891 } 892 893 // returns p*n, destroys p 894 static inline poly p_Mult_nn(poly p, number n, const ring r) 895 { 896 if (n_IsOne(n, r)) 897 return p; 898 else 899 return r->p_Procs->p_Mult_nn(p, n, r); 900 } 901 902 static inline poly p_Mult_nn(poly p, number n, const ring lmRing, 903 const ring tailRing) 904 { 905 #ifndef PDEBUG 906 if (lmRing == tailRing) 907 { 908 return p_Mult_nn(p, n, tailRing); 909 } 910 #endif 911 poly pnext = pNext(p); 912 pNext(p) = NULL; 913 p = lmRing->p_Procs->p_Mult_nn(p, n, lmRing); 914 pNext(p) = tailRing->p_Procs->p_Mult_nn(pnext, n, tailRing); 915 return p; 916 } 917 918 // returns p*n, does not destroy p 919 static inline poly pp_Mult_nn(poly p, number n, const ring r) 920 { 921 if (n_IsOne(n, r)) 922 return p_Copy(p, r); 923 else 924 return r->p_Procs->pp_Mult_nn(p, n, r); 925 } 926 927 // returns Copy(p)*m, does neither destroy p nor m 928 static inline poly pp_Mult_mm(poly p, poly m, const ring r) 929 { 930 if (p_LmIsConstant(m, r)) 931 return pp_Mult_nn(p, pGetCoeff(m), r); 932 else 933 { 934 poly last; 935 return r->p_Procs->pp_Mult_mm(p, m, r, last); 936 } 937 } 938 939 // returns p*m, destroys p, const: m 940 static inline poly p_Mult_mm(poly p, poly m, const ring r) 941 { 942 if (p_LmIsConstant(m, r)) 943 return p_Mult_nn(p, pGetCoeff(m), r); 944 else 945 return r->p_Procs->p_Mult_mm(p, m, r); 946 } 947 948 // return p - m*Copy(q), destroys p; const: p,m 949 static inline poly p_Minus_mm_Mult_qq(poly p, poly m, poly q, const ring r) 950 { 951 #ifdef HAVE_PLURAL 952 if (rIsPluralRing(r)) 953 { 954 int lp, lq; 955 poly spNoether; 956 return nc_p_Minus_mm_Mult_qq(p, m, q, lp, lq, spNoether, r); 957 } 958 #endif 959 960 int shorter; 961 poly last; 962 963 return r->p_Procs->p_Minus_mm_Mult_qq(p, m, q, shorter, NULL, r, last); // !!! 964 } 965 966 static inline poly p_Minus_mm_Mult_qq(poly p, poly m, poly q, int &lp, int lq, 967 poly spNoether, const ring r) 968 { 969 #ifdef HAVE_PLURAL 970 if (rIsPluralRing(r)) 971 return nc_p_Minus_mm_Mult_qq(p, m, q, lp, lq, spNoether, r); 972 #endif 973 974 int shorter; 975 poly last,res; 976 res = r->p_Procs->p_Minus_mm_Mult_qq(p, m, q, shorter, spNoether, r, last); 977 lp = (lp + lq) - shorter; 978 return res; 979 } 980 981 static inline poly pp_Mult_Coeff_mm_DivSelect(poly p, const poly m, const ring r) 982 { 983 int shorter; 984 return r->p_Procs->pp_Mult_Coeff_mm_DivSelect(p, m, shorter, r); 985 } 986 987 static inline poly pp_Mult_Coeff_mm_DivSelect(poly p, int &lp, const poly m, const ring r) 988 { 989 int shorter; 990 poly pp = r->p_Procs->pp_Mult_Coeff_mm_DivSelect(p, m, shorter, r); 991 lp -= shorter; 992 return pp; 993 } 994 995 // returns -p, destroys p 996 static inline poly p_Neg(poly p, const ring r) 997 { 998 return r->p_Procs->p_Neg(p, r); 999 } 1000 1001 extern poly _p_Mult_q(poly p, poly q, const int copy, const ring r); 1002 // returns p*q, destroys p and q 1003 static inline poly p_Mult_q(poly p, poly q, const ring r) 1004 { 1005 if (p == NULL) 1006 { 1007 r->p_Procs->p_Delete(&q, r); 1008 return NULL; 1009 } 1010 if (q == NULL) 1011 { 1012 r->p_Procs->p_Delete(&p, r); 1013 return NULL; 1014 } 1015 1016 if (pNext(p) == NULL) 1017 { 1018 #ifdef HAVE_PLURAL 1019 if (rIsPluralRing(r)) 1020 q = nc_mm_Mult_p(p, q, r); 1021 else 1022 #endif /* HAVE_PLURAL */ 1023 q = r->p_Procs->p_Mult_mm(q, p, r); 1024 1025 r->p_Procs->p_Delete(&p, r); 1026 return q; 1027 } 1028 1029 if (pNext(q) == NULL) 1030 { 1031 // NEEDED 1032 #ifdef HAVE_PLURAL 1033 /* if (rIsPluralRing(r)) 1034 p = gnc_p_Mult_mm(p, q, r); // ??? 1035 else*/ 1036 #endif /* HAVE_PLURAL */ 1037 p = r->p_Procs->p_Mult_mm(p, q, r); 1038 1039 r->p_Procs->p_Delete(&q, r); 1040 return p; 1041 } 1042 #ifdef HAVE_PLURAL 1043 if (rIsPluralRing(r)) 1044 return _nc_p_Mult_q(p, q, r); 1045 else 1046 #endif 1047 return _p_Mult_q(p, q, 0, r); 1048 } 1049 1050 // returns p*q, does neither destroy p nor q 1051 static inline poly pp_Mult_qq(poly p, poly q, const ring r) 1052 { 1053 poly last; 1054 if (p == NULL || q == NULL) return NULL; 1055 1056 if (pNext(p) == NULL) 1057 { 1058 #ifdef HAVE_PLURAL 1059 if (rIsPluralRing(r)) 1060 return nc_mm_Mult_pp(p, q, r); 1061 #endif 1062 return r->p_Procs->pp_Mult_mm(q, p, r, last); 1063 } 1064 1065 if (pNext(q) == NULL) 1066 { 1067 return r->p_Procs->pp_Mult_mm(p, q, r, last); 1068 } 1069 1070 poly qq = q; 1071 if (p == q) 1072 qq = p_Copy(q, r); 1073 1074 poly res; 1075 #ifdef HAVE_PLURAL 1076 if (rIsPluralRing(r)) 1077 res = _nc_pp_Mult_qq(p, qq, r); 1078 else 1079 #endif 1080 res = _p_Mult_q(p, qq, 1, r); 1081 1082 if (qq != q) 1083 p_Delete(&qq, r); 1084 return res; 1085 } 1086 1087 // returns p + m*q destroys p, const: q, m 1088 static inline poly p_Plus_mm_Mult_qq(poly p, poly m, poly q, int &lp, int lq, 1089 const ring r) 1090 { 1091 #ifdef HAVE_PLURAL 1092 if (rIsPluralRing(r)) 1093 return nc_p_Plus_mm_Mult_qq(p, m, q, lp, lq, r); 1094 #endif 1095 1096 // this should be implemented more efficiently 1097 poly res, last; 1098 int shorter; 1099 number n_old = pGetCoeff(m); 1100 number n_neg = n_Copy(n_old, r); 1101 n_neg = n_Neg(n_neg, r); 1102 pSetCoeff0(m, n_neg); 1103 res = r->p_Procs->p_Minus_mm_Mult_qq(p, m, q, shorter, NULL, r, last); 1104 lp = (lp + lq) - shorter; 1105 pSetCoeff0(m, n_old); 1106 n_Delete(&n_neg, r); 1107 return res; 1108 } 1109 1110 static inline poly p_Plus_mm_Mult_qq(poly p, poly m, poly q, const ring r) 1111 { 1112 int lp = 0, lq = 0; 1113 return p_Plus_mm_Mult_qq(p, m, q, lp, lq, r); 1114 } 1115 1116 static inline poly p_Merge_q(poly p, poly q, const ring r) 1117 { 1118 return r->p_Procs->p_Merge_q(p, q, r); 1119 } 1120 1121 static inline poly p_SortAdd(poly p, const ring r, BOOLEAN revert) 1122 { 1123 if (revert) p = pReverse(p); 1124 return sBucketSortAdd(p, r); 1125 } 1126 1127 static inline poly p_SortMerge(poly p, const ring r, BOOLEAN revert) 1128 { 1129 if (revert) p = pReverse(p); 1130 return sBucketSortMerge(p, r); 1131 } 1132 1133 /*************************************************************** 1134 * 1135 * I/O 1136 * 1137 ***************************************************************/ 1138 static inline char* p_String(poly p, ring p_ring) 1139 { 1140 return p_String(p, p_ring, p_ring); 1141 } 1142 static inline char* p_String0(poly p, ring p_ring) 1143 { 1144 return p_String0(p, p_ring, p_ring); 1145 } 1146 static inline void p_Write(poly p, ring p_ring) 1147 { 1148 p_Write(p, p_ring, p_ring); 1149 } 1150 static inline void p_Write0(poly p, ring p_ring) 1151 { 1152 p_Write0(p, p_ring, p_ring); 1153 } 1154 static inline void p_wrp(poly p, ring p_ring) 1155 { 1156 p_wrp(p, p_ring, p_ring); 1157 } 1158 1159 /*************************************************************** 1160 * Purpose: implementation of poly procs which iter over ExpVector 1161 * Author: obachman (Olaf Bachmann) 1162 * Created: 8/00 1163 * Version: $Id$ 1164 *******************************************************************/ 1165 #include <mylimits.h> 1166 #include "p_MemCmp.h" 1167 #include "structs.h" 1168 #include "ring.h" 1169 #include <coeffs.h> 1170 1171 #if PDEBUG > 0 1172 1173 #define _p_LmCmpAction(p, q, r, actionE, actionG, actionS) \ 1174 do \ 1175 { \ 1176 int _cmp = p_LmCmp(p,q,r); \ 1177 if (_cmp == 0) actionE; \ 1178 if (_cmp == 1) actionG; \ 1179 actionS; \ 1180 } \ 1181 while(0) 1182 1183 #else 1184 1185 #define _p_LmCmpAction(p, q, r, actionE, actionG, actionS) \ 1186 p_MemCmp_LengthGeneral_OrdGeneral(p->exp, q->exp, r->CmpL_Size, r->ordsgn, \ 1187 actionE, actionG, actionS) 1188 1189 #endif 1190 1191 #define pDivAssume(x) ((void)0) 1192 1193 #include <omalloc.h> 1194 #include <coeffs.h> 1195 #include "p_polys.h" 1196 #include "p_MemAdd.h" 1197 #include "p_MemCopy.h" 1198 1199 /*************************************************************** 1200 * 1201 * Allocation/Initalization/Deletion 1202 * 1203 ***************************************************************/ 1204 // adjustments for negative weights 1205 static inline void p_MemAdd_NegWeightAdjust(poly p, const ring r) 1206 { 1207 if (r->NegWeightL_Offset != NULL) 1208 { 1209 for (int i=r->NegWeightL_Size-1; i>=0; i--) 1210 { 1211 p->exp[r->NegWeightL_Offset[i]] -= POLY_NEGWEIGHT_OFFSET; 1212 } 1213 } 1214 } 1215 static inline void p_MemSub_NegWeightAdjust(poly p, const ring r) 1216 { 1217 if (r->NegWeightL_Offset != NULL) 1218 { 1219 for (int i=r->NegWeightL_Size-1; i>=0; i--) 1220 { 1221 p->exp[r->NegWeightL_Offset[i]] += POLY_NEGWEIGHT_OFFSET; 1222 } 1223 } 1224 } 1225 // ExpVextor(d_p) = ExpVector(s_p) 1226 static inline void p_ExpVectorCopy(poly d_p, poly s_p, const ring r) 1227 { 1228 p_LmCheckPolyRing1(d_p, r); 1229 p_LmCheckPolyRing1(s_p, r); 1230 p_MemCopy_LengthGeneral(d_p->exp, s_p->exp, r->ExpL_Size); 1231 } 1232 1233 static inline poly p_Init(const ring r, omBin bin) 1234 { 1235 p_CheckRing1(r); 1236 pAssume1(bin != NULL && r->PolyBin->sizeW == bin->sizeW); 1237 poly p; 1238 omTypeAlloc0Bin(poly, p, bin); 1239 p_MemAdd_NegWeightAdjust(p, r); 1240 p_SetRingOfLm(p, r); 1241 return p; 1242 } 1243 static inline poly p_Init(const ring r) 1244 { 1245 return p_Init(r, r->PolyBin); 1246 } 1247 1248 static inline poly p_LmInit(poly p, const ring r) 1249 { 1250 p_LmCheckPolyRing1(p, r); 1251 poly np; 1252 omTypeAllocBin(poly, np, r->PolyBin); 1253 p_SetRingOfLm(np, r); 1254 p_MemCopy_LengthGeneral(np->exp, p->exp, r->ExpL_Size); 1255 pNext(np) = NULL; 1256 pSetCoeff0(np, NULL); 1257 return np; 1258 } 1259 static inline poly p_LmInit(poly s_p, const ring s_r, const ring d_r, omBin d_bin) 1260 { 1261 p_LmCheckPolyRing1(s_p, s_r); 1262 p_CheckRing(d_r); 1263 pAssume1(d_r->N <= s_r->N); 1264 poly d_p = p_Init(d_r, d_bin); 1265 for (int i=d_r->N; i>0; i--) 1266 { 1267 p_SetExp(d_p, i, p_GetExp(s_p, i,s_r), d_r); 1268 } 1269 if (rRing_has_Comp(d_r)) 1270 { 1271 p_SetComp(d_p, p_GetComp(s_p,s_r), d_r); 1272 } 1273 p_Setm(d_p, d_r); 1274 return d_p; 1275 } 1276 static inline poly p_LmInit(poly s_p, const ring s_r, const ring d_r) 1277 { 1278 pAssume1(d_r != NULL); 1279 return p_LmInit(s_p, s_r, d_r, d_r->PolyBin); 1280 } 1281 static inline poly p_Head(poly p, const ring r) 1282 { 1283 if (p == NULL) return NULL; 1284 p_LmCheckPolyRing1(p, r); 1285 poly np; 1286 omTypeAllocBin(poly, np, r->PolyBin); 1287 p_SetRingOfLm(np, r); 1288 p_MemCopy_LengthGeneral(np->exp, p->exp, r->ExpL_Size); 1289 pNext(np) = NULL; 1290 pSetCoeff0(np, n_Copy(pGetCoeff(p), r)); 1291 return np; 1292 } 1293 // set all exponents l..k to 0, assume exp. k+1..n and 1..l-1 are in 1294 // different blocks 1295 // set coeff to 1 1296 static inline poly p_GetExp_k_n(poly p, int l, int k, const ring r) 1297 { 1298 if (p == NULL) return NULL; 1299 p_LmCheckPolyRing1(p, r); 1300 poly np; 1301 omTypeAllocBin(poly, np, r->PolyBin); 1302 p_SetRingOfLm(np, r); 1303 p_MemCopy_LengthGeneral(np->exp, p->exp, r->ExpL_Size); 1304 pNext(np) = NULL; 1305 pSetCoeff0(np, n_Init(1, r)); 1306 int i; 1307 for(i=l;i<=k;i++) 1308 { 1309 //np->exp[(r->VarOffset[i] & 0xffffff)] =0; 1310 p_SetExp(np,i,0,r); 1311 } 1312 p_Setm(np,r); 1313 return np; 1314 } 1315 1316 static inline poly p_LmShallowCopyDelete(poly p, const ring r, omBin bin) 1317 { 1318 p_LmCheckPolyRing1(p, r); 1319 pAssume1(bin->sizeW == r->PolyBin->sizeW); 1320 poly new_p = p_New(r); 1321 p_MemCopy_LengthGeneral(new_p->exp, p->exp, r->ExpL_Size); 1322 pSetCoeff0(new_p, pGetCoeff(p)); 1323 pNext(new_p) = pNext(p); 1324 omFreeBinAddr(p); 1325 return new_p; 1326 } 1327 1328 /*************************************************************** 1329 * 1330 * Operation on ExpVectors 1331 * 1332 ***************************************************************/ 1333 // ExpVector(p1) += ExpVector(p2) 1334 static inline void p_ExpVectorAdd(poly p1, poly p2, const ring r) 1335 { 1336 p_LmCheckPolyRing1(p1, r); 1337 p_LmCheckPolyRing1(p2, r); 1338 #if PDEBUG >= 1 1339 for (int i=1; i<=r->N; i++) 1340 pAssume1((unsigned long) (p_GetExp(p1, i, r) + p_GetExp(p2, i, r)) <= r->bitmask); 1341 pAssume1(p_GetComp(p1, r) == 0 || p_GetComp(p2, r) == 0); 1342 #endif 1343 1344 p_MemAdd_LengthGeneral(p1->exp, p2->exp, r->ExpL_Size); 1345 p_MemAdd_NegWeightAdjust(p1, r); 1346 } 1347 // ExpVector(p1) -= ExpVector(p2) 1348 static inline void p_ExpVectorSub(poly p1, poly p2, const ring r) 1349 { 1350 p_LmCheckPolyRing1(p1, r); 1351 p_LmCheckPolyRing1(p2, r); 1352 #if PDEBUG >= 1 1353 for (int i=1; i<=r->N; i++) 1354 pAssume1(p_GetExp(p1, i, r) >= p_GetExp(p2, i, r)); 1355 pAssume1(p_GetComp(p1, r) == 0 || p_GetComp(p2, r) == 0 || 1356 p_GetComp(p1, r) == p_GetComp(p2, r)); 1357 #endif 1358 1359 p_MemSub_LengthGeneral(p1->exp, p2->exp, r->ExpL_Size); 1360 p_MemSub_NegWeightAdjust(p1, r); 1361 1362 } 1363 // ExpVector(p1) += ExpVector(p2) - ExpVector(p3) 1364 static inline void p_ExpVectorAddSub(poly p1, poly p2, poly p3, const ring r) 1365 { 1366 p_LmCheckPolyRing1(p1, r); 1367 p_LmCheckPolyRing1(p2, r); 1368 p_LmCheckPolyRing1(p3, r); 1369 #if PDEBUG >= 1 1370 for (int i=1; i<=r->N; i++) 1371 pAssume1(p_GetExp(p1, i, r) + p_GetExp(p2, i, r) >= p_GetExp(p3, i, r)); 1372 pAssume1(p_GetComp(p1, r) == 0 || 1373 (p_GetComp(p2, r) - p_GetComp(p3, r) == 0) || 1374 (p_GetComp(p1, r) == p_GetComp(p2, r) - p_GetComp(p3, r))); 1375 #endif 1376 1377 p_MemAddSub_LengthGeneral(p1->exp, p2->exp, p3->exp, r->ExpL_Size); 1378 // no need to adjust in case of NegWeights 1379 } 1380 1381 // ExpVector(pr) = ExpVector(p1) + ExpVector(p2) 1382 static inline void p_ExpVectorSum(poly pr, poly p1, poly p2, const ring r) 1383 { 1384 p_LmCheckPolyRing1(p1, r); 1385 p_LmCheckPolyRing1(p2, r); 1386 p_LmCheckPolyRing1(pr, r); 1387 #if PDEBUG >= 1 1388 for (int i=1; i<=r->N; i++) 1389 pAssume1((unsigned long) (p_GetExp(p1, i, r) + p_GetExp(p2, i, r)) <= r->bitmask); 1390 pAssume1(p_GetComp(p1, r) == 0 || p_GetComp(p2, r) == 0); 1391 #endif 1392 1393 p_MemSum_LengthGeneral(pr->exp, p1->exp, p2->exp, r->ExpL_Size); 1394 p_MemAdd_NegWeightAdjust(pr, r); 1395 } 1396 // ExpVector(pr) = ExpVector(p1) - ExpVector(p2) 1397 static inline void p_ExpVectorDiff(poly pr, poly p1, poly p2, const ring r) 1398 { 1399 p_LmCheckPolyRing1(p1, r); 1400 p_LmCheckPolyRing1(p2, r); 1401 p_LmCheckPolyRing1(pr, r); 1402 #if PDEBUG >= 2 1403 for (int i=1; i<=r->N; i++) 1404 pAssume1(p_GetExp(p1, i, r) >= p_GetExp(p2, i, r)); 1405 pAssume1(!rRing_has_Comp(r) || p_GetComp(p1, r) == p_GetComp(p2, r)); 1406 #endif 1407 1408 p_MemDiff_LengthGeneral(pr->exp, p1->exp, p2->exp, r->ExpL_Size); 1409 p_MemSub_NegWeightAdjust(pr, r); 1410 } 1411 1412 static inline BOOLEAN p_ExpVectorEqual(poly p1, poly p2, const ring r) 1413 { 1414 p_LmCheckPolyRing1(p1, r); 1415 p_LmCheckPolyRing1(p2, r); 1416 1417 int i = r->ExpL_Size; 1418 unsigned long *ep = p1->exp; 1419 unsigned long *eq = p2->exp; 1420 1421 do 1422 { 1423 i--; 1424 if (ep[i] != eq[i]) return FALSE; 1425 } 1426 while (i); 1427 return TRUE; 1428 } 1429 1430 static inline long p_Totaldegree(poly p, const ring r) 1431 { 1432 p_LmCheckPolyRing1(p, r); 1433 unsigned long s = p_GetTotalDegree(p->exp[r->VarL_Offset[0]], 1434 r, 1435 r->MinExpPerLong); 1436 for (int i=r->VarL_Size-1; i>0; i--) 1437 { 1438 s += p_GetTotalDegree(p->exp[r->VarL_Offset[i]], r); 1439 } 1440 return (long)s; 1441 } 1442 1443 static inline void p_GetExpV(poly p, int *ev, const ring r) 1444 { 1445 p_LmCheckPolyRing1(p, r); 1446 for (int j = r->N; j; j--) 1447 ev[j] = p_GetExp(p, j, r); 1448 1449 ev[0] = p_GetComp(p, r); 1450 } 1451 static inline void p_SetExpV(poly p, int *ev, const ring r) 1452 { 1453 p_LmCheckPolyRing1(p, r); 1454 for (int j = r->N; j; j--) 1455 p_SetExp(p, j, ev[j], r); 1456 1457 p_SetComp(p, ev[0],r); 1458 p_Setm(p, r); 1459 } 1460 1461 /*************************************************************** 1462 * 1463 * Comparison w.r.t. monomial ordering 1464 * 1465 ***************************************************************/ 1466 static inline int p_LmCmp(poly p, poly q, const ring r) 1467 { 1468 p_LmCheckPolyRing1(p, r); 1469 p_LmCheckPolyRing1(q, r); 1470 1471 p_MemCmp_LengthGeneral_OrdGeneral(p->exp, q->exp, r->CmpL_Size, r->ordsgn, 1472 return 0, return 1, return -1); 1473 } 1474 1475 1476 /*************************************************************** 1477 * 1478 * divisibility 1479 * 1480 ***************************************************************/ 1481 // return: FALSE, if there exists i, such that a->exp[i] > b->exp[i] 1482 // TRUE, otherwise 1483 // (1) Consider long vars, instead of single exponents 1484 // (2) Clearly, if la > lb, then FALSE 1485 // (3) Suppose la <= lb, and consider first bits of single exponents in l: 1486 // if TRUE, then value of these bits is la ^ lb 1487 // if FALSE, then la-lb causes an "overflow" into one of those bits, i.e., 1488 // la ^ lb != la - lb 1489 static inline BOOLEAN _p_LmDivisibleByNoComp(poly a, poly b, const ring r) 1490 { 1491 int i=r->VarL_Size - 1; 1492 unsigned long divmask = r->divmask; 1493 unsigned long la, lb; 1494 1495 if (r->VarL_LowIndex >= 0) 1496 { 1497 i += r->VarL_LowIndex; 1498 do 1499 { 1500 la = a->exp[i]; 1501 lb = b->exp[i]; 1502 if ((la > lb) || 1503 (((la & divmask) ^ (lb & divmask)) != ((lb - la) & divmask))) 1504 { 1505 pDivAssume(p_DebugLmDivisibleByNoComp(a, b, r) == FALSE); 1506 return FALSE; 1507 } 1508 i--; 1509 } 1510 while (i>=r->VarL_LowIndex); 1511 } 1512 else 1513 { 1514 do 1515 { 1516 la = a->exp[r->VarL_Offset[i]]; 1517 lb = b->exp[r->VarL_Offset[i]]; 1518 if ((la > lb) || 1519 (((la & divmask) ^ (lb & divmask)) != ((lb - la) & divmask))) 1520 { 1521 pDivAssume(p_DebugLmDivisibleByNoComp(a, b, r) == FALSE); 1522 return FALSE; 1523 } 1524 i--; 1525 } 1526 while (i>=0); 1527 } 1528 #ifdef HAVE_RINGS 1529 pDivAssume(p_DebugLmDivisibleByNoComp(a, b, r) == nDivBy(p_GetCoeff(b, r), p_GetCoeff(a, r))); 1530 return (!rField_is_Ring(r)) || nDivBy(p_GetCoeff(b, r), p_GetCoeff(a, r)); 1531 #else 1532 pDivAssume(p_DebugLmDivisibleByNoComp(a, b, r) == TRUE); 1533 return TRUE; 1534 #endif 1535 } 1536 1537 static inline BOOLEAN _p_LmDivisibleByNoComp(poly a, const ring r_a, poly b, const ring r_b) 1538 { 1539 int i=r_a->N; 1540 pAssume1(r_a->N == r_b->N); 1541 1542 do 1543 { 1544 if (p_GetExp(a,i,r_a) > p_GetExp(b,i,r_b)) 1545 return FALSE; 1546 i--; 1547 } 1548 while (i); 1549 #ifdef HAVE_RINGS 1550 return nDivBy(p_GetCoeff(b, r), p_GetCoeff(a, r)); 1551 #else 1552 return TRUE; 1553 #endif 1554 } 1555 1556 #ifdef HAVE_RATGRING 1557 static inline BOOLEAN _p_LmDivisibleByNoCompPart(poly a, const ring r_a, poly b, const ring r_b,const int start, const int end) 1558 { 1559 int i=end; 1560 pAssume1(r_a->N == r_b->N); 1561 1562 do 1563 { 1564 if (p_GetExp(a,i,r_a) > p_GetExp(b,i,r_b)) 1565 return FALSE; 1566 i--; 1567 } 1568 while (i>=start); 1569 #ifdef HAVE_RINGS 1570 return nDivBy(p_GetCoeff(b, r), p_GetCoeff(a, r)); 1571 #else 1572 return TRUE; 1573 #endif 1574 } 1575 static inline BOOLEAN _p_LmDivisibleByPart(poly a, const ring r_a, poly b, const ring r_b,const int start, const int end) 1576 { 1577 if (p_GetComp(a, r_a) == 0 || p_GetComp(a,r_a) == p_GetComp(b,r_b)) 1578 return _p_LmDivisibleByNoCompPart(a, r_a, b, r_b,start,end); 1579 return FALSE; 1580 } 1581 static inline BOOLEAN p_LmDivisibleByPart(poly a, poly b, const ring r,const int start, const int end) 1582 { 1583 p_LmCheckPolyRing1(b, r); 1584 pIfThen1(a != NULL, p_LmCheckPolyRing1(b, r)); 1585 if (p_GetComp(a, r) == 0 || p_GetComp(a,r) == p_GetComp(b,r)) 1586 return _p_LmDivisibleByNoCompPart(a, r, b, r,start, end); 1587 return FALSE; 1588 } 1589 #endif 1590 static inline BOOLEAN _p_LmDivisibleBy(poly a, poly b, const ring r) 1591 { 1592 if (p_GetComp(a, r) == 0 || p_GetComp(a,r) == p_GetComp(b,r)) 1593 return _p_LmDivisibleByNoComp(a, b, r); 1594 return FALSE; 1595 } 1596 static inline BOOLEAN _p_LmDivisibleBy(poly a, const ring r_a, poly b, const ring r_b) 1597 { 1598 if (p_GetComp(a, r_a) == 0 || p_GetComp(a,r_a) == p_GetComp(b,r_b)) 1599 return _p_LmDivisibleByNoComp(a, r_a, b, r_b); 1600 return FALSE; 1601 } 1602 static inline BOOLEAN p_LmDivisibleByNoComp(poly a, poly b, const ring r) 1603 { 1604 p_LmCheckPolyRing1(a, r); 1605 p_LmCheckPolyRing1(b, r); 1606 return _p_LmDivisibleByNoComp(a, b, r); 1607 } 1608 static inline BOOLEAN p_LmDivisibleBy(poly a, poly b, const ring r) 1609 { 1610 p_LmCheckPolyRing1(b, r); 1611 pIfThen1(a != NULL, p_LmCheckPolyRing1(b, r)); 1612 if (p_GetComp(a, r) == 0 || p_GetComp(a,r) == p_GetComp(b,r)) 1613 return _p_LmDivisibleByNoComp(a, b, r); 1614 return FALSE; 1615 } 1616 1617 static inline BOOLEAN p_DivisibleBy(poly a, poly b, const ring r) 1618 { 1619 pIfThen1(b!=NULL, p_LmCheckPolyRing1(b, r)); 1620 pIfThen1(a!=NULL, p_LmCheckPolyRing1(a, r)); 1621 1622 if (a != NULL && (p_GetComp(a, r) == 0 || p_GetComp(a,r) == p_GetComp(b,r))) 1623 return _p_LmDivisibleByNoComp(a,b,r); 1624 return FALSE; 1625 } 1626 static inline BOOLEAN p_DivisibleBy(poly a, const ring r_a, poly b, const ring r_b) 1627 { 1628 pIfThen1(b!=NULL, p_LmCheckPolyRing1(b, r_b)); 1629 pIfThen1(a!=NULL, p_LmCheckPolyRing1(a, r_a)); 1630 if (a != NULL) { 1631 return _p_LmDivisibleBy(a, r_a, b, r_b); 1632 } 1633 return FALSE; 1634 } 1635 static inline BOOLEAN p_LmDivisibleBy(poly a, const ring r_a, poly b, const ring r_b) 1636 { 1637 p_LmCheckPolyRing(a, r_a); 1638 p_LmCheckPolyRing(b, r_b); 1639 return _p_LmDivisibleBy(a, r_a, b, r_b); 1640 } 1641 static inline BOOLEAN p_LmShortDivisibleBy(poly a, unsigned long sev_a, 1642 poly b, unsigned long not_sev_b, const ring r) 1643 { 1644 p_LmCheckPolyRing1(a, r); 1645 p_LmCheckPolyRing1(b, r); 1646 #ifndef PDIV_DEBUG 1647 pPolyAssume2(p_GetShortExpVector(a, r) == sev_a, a, r); 1648 pPolyAssume2(p_GetShortExpVector(b, r) == ~ not_sev_b, b, r); 1649 1650 if (sev_a & not_sev_b) 1651 { 1652 pAssume1(p_LmDivisibleByNoComp(a, b, r) == FALSE); 1653 return FALSE; 1654 } 1655 return p_LmDivisibleBy(a, b, r); 1656 #else 1657 return pDebugLmShortDivisibleBy(a, sev_a, r, b, not_sev_b, r); 1658 #endif 1659 } 1660 1661 static inline BOOLEAN p_LmShortDivisibleBy(poly a, unsigned long sev_a, const ring r_a, 1662 poly b, unsigned long not_sev_b, const ring r_b) 1663 { 1664 p_LmCheckPolyRing1(a, r_a); 1665 p_LmCheckPolyRing1(b, r_b); 1666 #ifndef PDIV_DEBUG 1667 pPolyAssume2(p_GetShortExpVector(a, r_a) == sev_a, a, r_a); 1668 pPolyAssume2(p_GetShortExpVector(b, r_b) == ~ not_sev_b, b, r_b); 1669 1670 if (sev_a & not_sev_b) 1671 { 1672 pAssume1(_p_LmDivisibleByNoComp(a, r_a, b, r_b) == FALSE); 1673 return FALSE; 1674 } 1675 return _p_LmDivisibleBy(a, r_a, b, r_b); 1676 #else 1677 return pDebugLmShortDivisibleBy(a, sev_a, r_a, b, not_sev_b, r_b); 1678 #endif 1679 } 1680 1681 /*************************************************************** 1682 * 1683 * Misc things on Lm 1684 * 1685 ***************************************************************/ 1686 // test if the monomial is a constant as a vector component 1687 // i.e., test if all exponents are zero 1688 static inline BOOLEAN p_LmIsConstantComp(const poly p, const ring r) 1689 { 1690 //p_LmCheckPolyRing(p, r); 1691 int i = r->VarL_Size - 1; 1692 1693 do 1694 { 1695 if (p->exp[r->VarL_Offset[i]] != 0) 1696 return FALSE; 1697 i--; 1698 } 1699 while (i >= 0); 1700 return TRUE; 1701 } 1702 // test if monomial is a constant, i.e. if all exponents and the component 1703 // is zero 1704 static inline BOOLEAN p_LmIsConstant(const poly p, const ring r) 1705 { 1706 if (p_LmIsConstantComp(p, r)) 1707 return (p_GetComp(p, r) == 0); 1708 return FALSE; 1709 } 1710 1711 // like the respective p_LmIs* routines, except that p might be empty 1712 static inline BOOLEAN p_IsConstantComp(const poly p, const ring r) 1713 { 1714 if (p == NULL) return TRUE; 1715 return (pNext(p)==NULL) && p_LmIsConstantComp(p, r); 1716 } 1717 1718 static inline BOOLEAN p_IsConstant(const poly p, const ring r) 1719 { 1720 if (p == NULL) return TRUE; 1721 return (pNext(p)==NULL) && p_LmIsConstant(p, r); 1722 } 1723 1724 static inline BOOLEAN p_IsUnit(const poly p, const ring r) 1725 { 1726 if (p == NULL) return FALSE; 1727 #ifdef HAVE_RINGS 1728 if (rField_is_Ring(r)) 1729 return (p_LmIsConstant(p, r) && nIsUnit(pGetCoeff(p),r->cf)); 1730 #endif 1731 return p_LmIsConstant(p, r); 1732 } 1733 1734 static inline BOOLEAN p_LmExpVectorAddIsOk(const poly p1, const poly p2, 1735 const ring r) 1736 { 1737 p_LmCheckPolyRing(p1, r); 1738 p_LmCheckPolyRing(p2, r); 1739 unsigned long l1, l2, divmask = r->divmask; 1740 int i; 1741 1742 for (i=0; i<r->VarL_Size; i++) 1743 { 1744 l1 = p1->exp[r->VarL_Offset[i]]; 1745 l2 = p2->exp[r->VarL_Offset[i]]; 1746 // do the divisiblity trick 1747 if ( (l1 > ULONG_MAX - l2) || 1748 (((l1 & divmask) ^ (l2 & divmask)) != ((l1 + l2) & divmask))) 1749 return FALSE; 1750 } 1751 return TRUE; 1752 } 452 1753 #endif // P_POLYS_H 453 1754
Note: See TracChangeset
for help on using the changeset viewer.