Changeset 9fa5ff in git
- Timestamp:
- Apr 26, 2018, 5:16:38 PM (5 years ago)
- Branches:
- (u'spielwiese', '8e0ad00ce244dfd0756200662572aef8402f13d5')
- Children:
- 945000cb5ab9a7e19901cbd2d68659fde7c7b939
- Parents:
- cbd574852be7b5156dd605a13e277523b6c99045
- Location:
- Singular/dyn_modules/syzextra
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
Singular/dyn_modules/syzextra/mod_main.cc
rcbd574 r9fa5ff 36 36 37 37 #include "Singular/mod_lib.h" 38 39 40 #if GOOGLE_PROFILE_ENABLED41 #include <google/profiler.h>42 #endif // #if GOOGLE_PROFILE_ENABLED43 38 44 39 … … 258 253 } 259 254 260 // proc SchreyerSyzygyNF(vector syz_lead, vector syz_2, def L, def T, list #)261 static BOOLEAN _SchreyerSyzygyNF(leftv res, leftv h)262 {263 const SchreyerSyzygyComputationFlags attributes(currRingHdl);264 265 // const BOOLEAN OPT__SYZCHECK = attributes.OPT__SYZCHECK;266 // const BOOLEAN OPT__LEAD2SYZ = attributes.OPT__LEAD2SYZ;267 const BOOLEAN OPT__HYBRIDNF = attributes.OPT__HYBRIDNF;268 const BOOLEAN OPT__TAILREDSYZ = attributes.OPT__TAILREDSYZ;269 270 const char* usage = "`SchreyerSyzygyNF(<vector>, <vector>, <ideal/module>, <ideal/module>[,<module>])` expected";271 const ring r = attributes.m_rBaseRing;272 273 NoReturn(res);274 275 assume( OPT__HYBRIDNF ); // ???276 277 if ((h==NULL) || (h->Typ() != VECTOR_CMD) || (h->Data() == NULL))278 {279 WerrorS(usage);280 return TRUE;281 }282 283 const poly syz_lead = (poly) h->Data(); assume (syz_lead != NULL);284 285 286 h = h->Next();287 if ((h==NULL) || (h->Typ() != VECTOR_CMD) || (h->Data() == NULL))288 {289 WerrorS(usage);290 return TRUE;291 }292 293 const poly syz_2 = (poly) h->Data(); assume (syz_2 != NULL);294 295 h = h->Next();296 if ((h==NULL) || (h->Typ()!=IDEAL_CMD && h->Typ() !=MODUL_CMD) || (h->Data() == NULL))297 {298 WerrorS(usage);299 return TRUE;300 }301 302 const ideal L = (ideal) h->Data(); assume( IDELEMS(L) > 0 );303 304 305 h = h->Next();306 if ((h==NULL) || (h->Typ()!=IDEAL_CMD && h->Typ() !=MODUL_CMD) || (h->Data() == NULL))307 {308 WerrorS(usage);309 return TRUE;310 }311 312 const ideal T = (ideal) h->Data();313 314 assume( IDELEMS(L) == IDELEMS(T) );315 316 ideal LS = NULL;317 318 h = h->Next();319 if ((h != NULL) && (h->Typ() ==MODUL_CMD) && (h->Data() != NULL))320 {321 LS = (ideal)h->Data();322 h = h->Next();323 }324 325 #ifndef SING_NDEBUG326 if( LIKELY( OPT__TAILREDSYZ) )327 assume (LS != NULL);328 #endif329 330 assume( h == NULL );331 332 res->rtyp = VECTOR_CMD;333 res->data = SchreyerSyzygyNF(syz_lead,334 (syz_2!=NULL)? p_Copy(syz_2, r): syz_2, L, T, LS, attributes);335 336 return FALSE;337 }338 339 340 341 /// proc SSReduceTerm(poly m, def t, def syzterm, def L, def T, list #)342 static BOOLEAN _ReduceTerm(leftv res, leftv h)343 {344 const SchreyerSyzygyComputationFlags attributes(currRingHdl);345 346 // const BOOLEAN OPT__SYZCHECK = attributes.OPT__SYZCHECK;347 // const BOOLEAN OPT__LEAD2SYZ = attributes.OPT__LEAD2SYZ;348 // const BOOLEAN OPT__HYBRIDNF = attributes.OPT__HYBRIDNF;349 const BOOLEAN OPT__TAILREDSYZ = attributes.OPT__TAILREDSYZ;350 351 const char* usage = "`ReduceTerm(<poly>, <poly/vector>, <vector/0>, <ideal/module>, <ideal/module>[,<module>])` expected";352 const ring r = attributes.m_rBaseRing;353 354 NoReturn(res);355 356 if ((h==NULL) || (h->Typ() !=POLY_CMD) || (h->Data() == NULL))357 {358 WerrorS(usage);359 return TRUE;360 }361 362 const poly multiplier = (poly) h->Data(); assume (multiplier != NULL);363 364 365 h = h->Next();366 if ((h==NULL) || (h->Typ()!=VECTOR_CMD && h->Typ() !=POLY_CMD) || (h->Data() == NULL))367 {368 WerrorS(usage);369 return TRUE;370 }371 372 const poly term4reduction = (poly) h->Data(); assume( term4reduction != NULL );373 374 375 poly syztermCheck = NULL;376 377 h = h->Next();378 if ((h==NULL) || !((h->Typ()==VECTOR_CMD) || (h->Data() == NULL)) )379 {380 WerrorS(usage);381 return TRUE;382 }383 384 if(h->Typ()==VECTOR_CMD)385 syztermCheck = (poly) h->Data();386 387 388 h = h->Next();389 if ((h==NULL) || (h->Typ()!=IDEAL_CMD && h->Typ() !=MODUL_CMD) || (h->Data() == NULL))390 {391 WerrorS(usage);392 return TRUE;393 }394 395 const ideal L = (ideal) h->Data(); assume( IDELEMS(L) > 0 );396 397 398 h = h->Next();399 if ((h==NULL) || (h->Typ()!=IDEAL_CMD && h->Typ() !=MODUL_CMD) || (h->Data() == NULL))400 {401 WerrorS(usage);402 return TRUE;403 }404 405 const ideal T = (ideal) h->Data();406 407 assume( IDELEMS(L) == IDELEMS(T) );408 409 ideal LS = NULL;410 411 h = h->Next();412 if ((h != NULL) && (h->Typ() ==MODUL_CMD) && (h->Data() != NULL))413 {414 LS = (ideal)h->Data();415 h = h->Next();416 }417 418 #ifndef SING_NDEBUG419 if( LIKELY( OPT__TAILREDSYZ) )420 assume (LS != NULL);421 #endif422 423 assume( h == NULL );424 425 res->rtyp = VECTOR_CMD;426 res->data = ReduceTerm(multiplier, term4reduction, syztermCheck, L, T, LS, attributes);427 428 return FALSE;429 }430 431 432 433 434 // proc SSTraverseTail(poly m, def @tail, def L, def T, list #)435 static BOOLEAN _TraverseTail(leftv res, leftv h)436 {437 const SchreyerSyzygyComputationFlags attributes(currRingHdl);438 439 // const BOOLEAN OPT__SYZCHECK = attributes.OPT__SYZCHECK;440 // const BOOLEAN OPT__LEAD2SYZ = attributes.OPT__LEAD2SYZ;441 // const BOOLEAN OPT__HYBRIDNF = attributes.OPT__HYBRIDNF;442 const BOOLEAN OPT__TAILREDSYZ = attributes.OPT__TAILREDSYZ;443 444 const char* usage = "`TraverseTail(<poly>, <poly/vector>, <ideal/module>, <ideal/module>[,<module>])` expected";445 const ring r = attributes.m_rBaseRing;446 447 NoReturn(res);448 449 if ((h==NULL) || (h->Typ() !=POLY_CMD) || (h->Data() == NULL))450 {451 WerrorS(usage);452 return TRUE;453 }454 455 const poly multiplier = (poly) h->Data(); assume (multiplier != NULL);456 457 h = h->Next();458 if ((h==NULL) || (h->Typ()!=VECTOR_CMD && h->Typ() !=POLY_CMD))459 {460 WerrorS(usage);461 return TRUE;462 }463 464 const poly tail = (poly) h->Data();465 466 h = h->Next();467 468 if ((h==NULL) || (h->Typ()!=IDEAL_CMD && h->Typ() !=MODUL_CMD) || (h->Data() == NULL))469 {470 WerrorS(usage);471 return TRUE;472 }473 474 const ideal L = (ideal) h->Data();475 476 assume( IDELEMS(L) > 0 );477 478 h = h->Next();479 if ((h==NULL) || (h->Typ()!=IDEAL_CMD && h->Typ() !=MODUL_CMD) || (h->Data() == NULL))480 {481 WerrorS(usage);482 return TRUE;483 }484 485 const ideal T = (ideal) h->Data();486 487 assume( IDELEMS(L) == IDELEMS(T) );488 489 h = h->Next();490 491 ideal LS = NULL;492 493 if ((h != NULL) && (h->Typ() ==MODUL_CMD) && (h->Data() != NULL))494 {495 LS = (ideal)h->Data();496 h = h->Next();497 }498 499 #ifndef SING_NDEBUG500 if( LIKELY( OPT__TAILREDSYZ) )501 assume (LS != NULL);502 #endif503 504 assume( h == NULL );505 506 res->rtyp = VECTOR_CMD;507 res->data = TraverseTail(multiplier, tail, L, T, LS, attributes);508 509 return FALSE;510 }511 512 513 static BOOLEAN _ComputeResolution(leftv res, leftv h)514 {515 const SchreyerSyzygyComputationFlags attributes(currRingHdl);516 517 const char* usage = "`ComputeResolution(<ideal/module>, <same as before>, <same as before>[,int])` expected";518 const ring r = attributes.m_rBaseRing;519 520 NoReturn(res);521 522 // input523 if ((h==NULL) || (h->Typ()!=IDEAL_CMD && h->Typ() !=MODUL_CMD) || (h->Data() == NULL))524 {525 WerrorS(usage);526 return TRUE;527 }528 529 const int type = h->Typ();530 ideal M = (ideal)(h->CopyD()); // copy for resolution...!???531 int size = IDELEMS(M);532 533 assume( size >= 0 );534 535 h = h->Next();536 537 // lead538 if ((h==NULL) || (h->Typ()!=type) || (h->Data() == NULL))539 {540 WerrorS(usage);541 return TRUE;542 }543 544 ideal L = (ideal)(h->CopyD()); // no copy!545 assume( IDELEMS(L) == size );546 547 h = h->Next();548 if ((h==NULL) || (h->Typ()!=type) || (h->Data() == NULL))549 {550 WerrorS(usage);551 return TRUE;552 }553 554 ideal T = (ideal)(h->CopyD()); // no copy!555 assume( IDELEMS(T) == size );556 557 h = h->Next();558 559 // length..?560 long length = 0;561 562 if ((h!=NULL) && (h->Typ()==INT_CMD))563 {564 length = (long)(h->Data());565 h = h->Next();566 }567 568 assume( h == NULL );569 570 if( length <= 0 )571 length = 1 + rVar(r);572 573 syStrategy _res=(syStrategy)omAlloc0(sizeof(ssyStrategy));574 575 // class ssyStrategy; typedef ssyStrategy * syStrategy;576 // typedef ideal * resolvente;577 578 _res->length = length + 1; // index + 1;579 _res->fullres = (resolvente)omAlloc0((_res->length+1)*sizeof(ideal));580 int index = 0;581 _res->fullres[index++] = M;582 583 // if (UNLIKELY(attributes.OPT__TREEOUTPUT))584 // Print("{ \"RESOLUTION: HYBRIDNF:%d, TAILREDSYZ: %d, LEAD2SYZ: %d, IGNORETAILS: %d\": [\n", attributes.OPT__HYBRIDNF, attributes.OPT__TAILREDSYZ, attributes.OPT__LEAD2SYZ, attributes.OPT__IGNORETAILS);585 586 while( (!idIs0(L)) && (index < length))587 {588 attributes.nextSyzygyLayer();589 ideal LL, TT;590 591 ComputeSyzygy(L, T, LL, TT, attributes);592 593 size = IDELEMS(LL);594 595 assume( size == IDELEMS(TT) );596 597 id_Delete(&L, r); id_Delete(&T, r);598 599 L = LL; T = TT;600 601 // id_Add(T, L, r);602 M = idInit(size, 0);603 for( int i = size-1; i >= 0; i-- )604 {605 M->m[i] = p_Add_q(p_Copy(T->m[i], r), p_Copy(L->m[i], r), r); // TODO: :(((606 }607 M->rank = id_RankFreeModule(M, r);608 609 _res->fullres[index++] = M; // ???610 }611 // if ( UNLIKELY(attributes.OPT__TREEOUTPUT) )612 // PrintS("] }\n");613 614 id_Delete(&L, r); id_Delete(&T, r);615 616 res->data = _res;617 res->rtyp = RESOLUTION_CMD;618 619 // omFreeSize(_res, sizeof(ssyStrategy));620 621 return FALSE;622 623 }624 625 626 /// module (LL, TT) = SSComputeSyzygy(L, T);627 /// Compute Syz(L ++ T) = N = LL ++ TT628 // proc SSComputeSyzygy(def L, def T)629 static BOOLEAN _ComputeSyzygy(leftv res, leftv h)630 {631 const SchreyerSyzygyComputationFlags attributes(currRingHdl);632 633 // const BOOLEAN OPT__SYZCHECK = attributes.OPT__SYZCHECK;634 // const BOOLEAN OPT__LEAD2SYZ = attributes.OPT__LEAD2SYZ;635 // const BOOLEAN OPT__HYBRIDNF = attributes.OPT__HYBRIDNF;636 // const BOOLEAN OPT__TAILREDSYZ = attributes.OPT__TAILREDSYZ;637 638 const char* usage = "`ComputeSyzygy(<ideal/module>, <ideal/module>)` expected";639 const ring r = attributes.m_rBaseRing;640 641 NoReturn(res);642 643 if ((h==NULL) || (h->Typ()!=IDEAL_CMD && h->Typ() !=MODUL_CMD) || (h->Data() == NULL))644 {645 WerrorS(usage);646 return TRUE;647 }648 649 const ideal L = (ideal) h->Data();650 651 assume( IDELEMS(L) > 0 );652 653 h = h->Next();654 if ((h==NULL) || (h->Typ()!=IDEAL_CMD && h->Typ() !=MODUL_CMD) || (h->Data() == NULL))655 {656 WerrorS(usage);657 return TRUE;658 }659 660 const ideal T = (ideal) h->Data();661 assume( IDELEMS(L) == IDELEMS(T) );662 663 664 h = h->Next(); assume( h == NULL );665 666 ideal LL, TT;667 668 ComputeSyzygy(L, T, LL, TT, attributes);669 670 lists l = (lists)omAllocBin(slists_bin); l->Init(2);671 672 l->m[0].rtyp = MODUL_CMD; l->m[0].data = reinterpret_cast<void *>(LL);673 674 l->m[1].rtyp = MODUL_CMD; l->m[1].data = reinterpret_cast<void *>(TT);675 676 res->data = l; res->rtyp = LIST_CMD;677 678 return FALSE;679 680 }681 682 255 /// Get leading component 683 256 static BOOLEAN leadcomp(leftv res, leftv h) 684 257 { 685 NoReturn(res);686 687 258 if ((h!=NULL) && (h->Typ()==VECTOR_CMD || h->Typ()==POLY_CMD)) 688 259 { … … 701 272 702 273 res->data = reinterpret_cast<void *>(jjLONG2N(iComp)); 703 } else 274 } 275 else 704 276 res->data = reinterpret_cast<void *>(jjLONG2N(0)); 705 277 … … 716 288 static BOOLEAN MakeInducedSchreyerOrdering(leftv res, leftv h) 717 289 { 718 719 NoReturn(res);720 721 290 int sign = 1; 722 291 if ((h!=NULL) && (h->Typ()==INT_CMD)) … … 744 313 static BOOLEAN GetInducedData(leftv res, leftv h) 745 314 { 746 NoReturn(res);747 748 315 const ring r = currRing; 749 316 … … 802 369 static BOOLEAN SetInducedReferrence(leftv res, leftv h) 803 370 { 371 res->Init(); 804 372 NoReturn(res); 805 373 … … 839 407 return TRUE; 840 408 } 841 842 843 409 844 410 // F & componentWeights belong to that ordering block of currRing now: … … 947 513 948 514 949 // #define ADD(A,B,C,D,E) ADD0(iiAddCproc, "", C, D, E)950 951 //#define ADD0(A,B,C,D,E) A(B, (char*)C, D, E)952 // #define ADD(A,B,C,D,E) ADD0(A->iiAddCproc, B, C, D, E)953 515 ADD("ClearContent", FALSE, _ClearContent); 954 516 ADD("ClearDenominators", FALSE, _ClearDenominators); … … 964 526 ADD("Tail", FALSE, Tail); 965 527 966 ADD("ReduceTerm", FALSE, _ReduceTerm);967 ADD("TraverseTail", FALSE, _TraverseTail);968 969 970 ADD("SchreyerSyzygyNF", FALSE, _SchreyerSyzygyNF);971 ADD("ComputeSyzygy", FALSE, _ComputeSyzygy);972 973 ADD("ComputeResolution", FALSE, _ComputeResolution);974 975 // ADD("", FALSE, );976 977 528 #undef ADD 978 529 return MAX_TOK; -
Singular/dyn_modules/syzextra/syzextra.cc
rcbd574 r9fa5ff 27 27 28 28 #include "misc/intvec.h" 29 #include "misc/options.h"30 29 31 30 #include "coeffs/coeffs.h" … … 35 34 #include "polys/simpleideals.h" 36 35 37 #include "polys/kbuckets.h" // for kBucket*38 #include "polys/sbuckets.h" // for sBucket*39 //#include "polys/nc/summator.h" // for CPolynomialSummator40 #include "polys/operations/p_Mult_q.h" // for MIN_LENGTH_BUCKET41 42 #include "kernel/GBEngine/kstd1.h"43 36 #include "kernel/polys.h" 44 #include "kernel/GBEngine/syz.h"45 37 #include "kernel/ideals.h" 46 47 #include "kernel/oswrapper/timer.h"48 49 #include "Singular/tok.h"50 #include "Singular/ipid.h"51 #include "Singular/lists.h"52 #include "Singular/attrib.h"53 54 #include "Singular/ipid.h"55 #include "Singular/ipshell.h" // For iiAddCproc56 38 57 39 #include <stdio.h> 58 40 #include <stdlib.h> 59 60 #ifndef RTIMER_BENCHMARKING61 # define RTIMER_BENCHMARKING 062 #endif63 64 SBucketFactory::Bucket SBucketFactory::_CreateBucket(const ring r)65 {66 const Bucket bt = sBucketCreate(r);67 68 assume( bt != NULL );69 return bt;70 }71 72 void SBucketFactory::_DestroyBucket(SBucketFactory::Bucket & bt)73 {74 if( bt != NULL )75 {76 sBucketDestroy( &bt );77 bt = NULL;78 }79 }80 81 class SBucketWrapper82 {83 typedef SBucketFactory::Bucket Bucket;84 85 private:86 Bucket m_bucket;87 88 SBucketFactory& m_factory;89 public:90 SBucketWrapper(const ring r, SBucketFactory& factory):91 m_bucket( factory.getBucket(r) ),92 m_factory( factory )93 {}94 95 ~SBucketWrapper()96 {97 m_factory.putBucket( m_bucket );98 }99 100 public:101 102 /// adds p to the internal bucket103 /// destroys p, l == length(p)104 inline void Add( poly p, const int l )105 {106 assume( pLength(p) == l );107 sBucket_Add_p( m_bucket, p, l );108 }109 110 /// adds p to the internal bucket111 /// destroys p112 inline void Add( poly p ){ Add(p, pLength(p)); }113 114 poly ClearAdd()115 {116 poly p; int l;117 sBucketClearAdd(m_bucket, &p, &l);118 assume( pLength(p) == l );119 return p;120 }121 };122 123 static FORCE_INLINE poly pp_Add_qq( const poly a, const poly b, const ring R)124 {125 return p_Add_q( p_Copy(a, R), p_Copy(b, R), R );126 }127 128 static FORCE_INLINE poly p_VectorProductLT( poly s, const ideal& L, const ideal& T, const ring& R)129 {130 assume( IDELEMS(L) == IDELEMS(T) );131 poly vp = NULL; // resulting vector product132 133 while( s != NULL )134 {135 const poly nxt = pNext(s);136 pNext(s) = NULL;137 138 if( !n_IsZero( pGetCoeff(s), R->cf) )139 {140 const int i = p_GetComp(s, R) - 1;141 assume( i >= 0 ); assume( i < IDELEMS(L) );142 p_SetComp(s, 0, R); p_SetmComp(s, R);143 144 vp = p_Add_q( vp, pp_Mult_qq( s, L->m[i], R ), R);145 vp = p_Add_q( vp, pp_Mult_qq( s, T->m[i], R ), R);146 }147 148 p_Delete(&s, R);149 150 s = nxt;151 };152 153 assume( s == NULL );154 155 return vp;156 }157 158 static FORCE_INLINE int atGetInt(idhdl rootRingHdl, const char* attribute, long def)159 {160 return ((int)(long)(atGet(rootRingHdl, attribute, INT_CMD, (void*)def)));161 }162 163 #if (defined(HAVE_QSORT_R) && (defined __APPLE__ || defined __MACH__ || defined __DARWIN__ || defined __FreeBSD__ || defined __BSD__ || defined OpenBSD3_1 || defined OpenBSD3_9))164 static int cmp_c_ds(void *R, const void *p1, const void *p2){165 #elif (defined(HAVE_QSORT_R) && (defined _GNU_SOURCE || defined __GNU__ || defined __linux__))166 static int cmp_c_ds(const void *p1, const void *p2, void *R){167 #else168 static int cmp_c_ds(const void *p1, const void *p2){ void *R = currRing;169 #endif170 assume(R != NULL);171 const int YES = 1;172 const int NO = -1;173 174 const ring r = (const ring) R; // TODO/NOTE: the structure is known: C, lp!!!175 176 assume( r == currRing ); // for now...177 178 const poly a = *(const poly*)p1;179 const poly b = *(const poly*)p2;180 181 assume( a != NULL );182 assume( b != NULL );183 184 p_LmTest(a, r);185 p_LmTest(b, r);186 187 188 const signed long iCompDiff = p_GetComp(a, r) - p_GetComp(b, r);189 190 // TODO: test this!!!!!!!!!!!!!!!!191 192 //return -( compare (c, qsorts) )193 194 if( iCompDiff > 0 )195 return YES;196 197 if( iCompDiff < 0 )198 return NO;199 200 assume( iCompDiff == 0 );201 202 const signed long iDegDiff = p_Totaldegree(a, r) - p_Totaldegree(b, r);203 204 if( iDegDiff > 0 )205 return YES;206 207 if( iDegDiff < 0 )208 return NO;209 210 assume( iDegDiff == 0 );211 212 for (int v = rVar(r); v > 0; v--)213 {214 assume( v > 0 );215 assume( v <= rVar(r) );216 217 const signed int d = p_GetExp(a, v, r) - p_GetExp(b, v, r);218 219 if( d > 0 )220 return YES;221 222 if( d < 0 )223 return NO;224 225 assume( d == 0 );226 }227 228 return 0;229 }230 231 /*232 static int cmp_poly(const poly &a, const poly &b)233 {234 const int YES = 1;235 const int NO = -1;236 237 const ring r = (const ring) currRing; // TODO/NOTE: the structure is known: C, lp!!!238 239 assume( r == currRing );240 241 assume( a != NULL );242 assume( b != NULL );243 244 p_LmTest(a, r);245 p_LmTest(b, r);246 assume( p_GetComp(a, r) == 0 );247 assume( p_GetComp(b, r) == 0 );248 249 for (int v = rVar(r); v > 0; v--)250 {251 assume( v > 0 );252 assume( v <= rVar(r) );253 254 const signed int d = p_GetExp(a, v, r) - p_GetExp(b, v, r);255 256 if( d > 0 )257 return YES;258 259 if( d < 0 )260 return NO;261 262 assume( d == 0 );263 }264 265 return 0;266 }267 */268 269 /* namespace SORT_c_ds */270 271 static FORCE_INLINE poly myp_Head(const poly p, const bool bIgnoreCoeff, const ring r)272 {273 assume( p != NULL ); p_LmCheckPolyRing1(p, r);274 275 poly np; omTypeAllocBin(poly, np, r->PolyBin);276 p_SetRingOfLm(np, r);277 memcpy(np->exp, p->exp, r->ExpL_Size*sizeof(long));278 pNext(np) = NULL;279 pSetCoeff0(np, (bIgnoreCoeff)? NULL : n_Copy(pGetCoeff(p), r->cf));280 281 p_LmCheckPolyRing1(np, r);282 return np;283 }284 285 286 /// return a new term: leading coeff * leading monomial of p287 /// with 0 leading component!288 poly leadmonom(const poly p, const ring r, const bool bSetZeroComp)289 {290 if( UNLIKELY(p == NULL ) )291 return NULL;292 293 assume( p != NULL );294 p_LmTest(p, r);295 296 poly m = p_LmInit(p, r);297 p_SetCoeff0(m, n_Copy(pGetCoeff(p), r->cf), r);298 299 if( bSetZeroComp )300 p_SetComp(m, 0, r);301 302 p_Setm(m, r);303 304 assume( m != NULL );305 assume( pNext(m) == NULL );306 p_LmTest(m, r);307 308 if( bSetZeroComp )309 assume( p_GetComp(m, r) == 0 );310 311 return m;312 }313 314 315 41 316 42 poly p_Tail(const poly p, const ring r) … … 321 47 return p_Copy( pNext(p), r ); 322 48 } 323 324 49 325 50 ideal id_Tail(const ideal id, const ring r) … … 338 63 } 339 64 340 341 342 void Sort_c_ds(const ideal id, const ring r)343 {344 const int sizeNew = IDELEMS(id);345 346 #if ( (defined(HAVE_QSORT_R)) && (defined __APPLE__ || defined __MACH__ || defined __DARWIN__ || defined __FreeBSD__ || defined __BSD__ || defined OpenBSD3_1 || defined OpenBSD3_9) )347 #define qsort_my(m, s, ss, r, cmp) qsort_r(m, s, ss, r, cmp)348 #elif ( (defined(HAVE_QSORT_R)) && (defined _GNU_SOURCE || defined __GNU__ || defined __linux__))349 #define qsort_my(m, s, ss, r, cmp) qsort_r(m, s, ss, cmp, r)350 #else351 #define qsort_my(m, s, ss, r, cmp) qsort(m, s, ss, cmp)352 #endif353 354 if( sizeNew >= 2 )355 qsort_my(id->m, sizeNew, sizeof(poly), r, FROM_NAMESPACE(SORT_c_ds, cmp_c_ds));356 357 #undef qsort_my358 359 id->rank = id_RankFreeModule(id, r);360 }361 362 /// Clean up all the accumulated data363 void SchreyerSyzygyComputation::CleanUp()364 {365 id_Delete(const_cast<ideal*>(&m_idTails), m_rBaseRing); // TODO!!!366 367 /*if( m_sum_bucket != NULL )368 {369 assume ( sIsEmpty(m_sum_bucket) );370 sBucketDestroy(&m_sum_bucket);371 m_sum_bucket = NULL;372 }*/373 374 if( m_spoly_bucket != NULL )375 {376 kBucketDestroy(&m_spoly_bucket);377 m_spoly_bucket = NULL;378 }379 380 for( TCache::iterator it = m_cache.begin(); it != m_cache.end(); it++ )381 {382 TP2PCache& T = it->second;383 384 for(TP2PCache::iterator vit = T.begin(); vit != T.end(); vit++ )385 {386 p_Delete( (&(vit->second)), m_rBaseRing);387 p_Delete( const_cast<poly*>(&(vit->first)), m_rBaseRing);388 }389 }390 }391 /*392 for( TTailTerms::const_iterator it = m_idTailTerms.begin(); it != m_idTailTerms.end(); it++ )393 {394 const TTail& v = *it;395 for(TTail::const_iterator vit = v.begin(); vit != v.end(); vit++ )396 delete const_cast<CTailTerm*>(*vit);397 }398 */399 400 401 402 int CReducerFinder::PreProcessTerm(const poly t, CReducerFinder& syzChecker) const403 {404 assume( t != NULL );405 406 const ring r = m_rBaseRing;407 408 409 if( LIKELY(OPT__TAILREDSYZ) )410 if( p_LmIsConstant(t, r) ) // most basic case of baing coprime with L, whatever that is...411 return 1; // TODO: prove this...?412 413 // return false; // appears to be fine414 415 const long comp = p_GetComp(t, r);416 417 CReducersHash::const_iterator itr = m_hash.find(comp);418 419 if ( itr == m_hash.end() )420 return 2; // no such leading component!!!421 422 assume( itr->first == comp );423 424 const bool bIdealCase = (comp == 0);425 const bool bSyzCheck = syzChecker.IsNonempty(); // need to check even in ideal case????? proof? "&& !bIdealCase"426 427 if( LIKELY(OPT__TAILREDSYZ && (bIdealCase || bSyzCheck)) )428 {429 const TReducers& v = itr->second;430 const int N = rVar(r);431 // TODO: extract exps of t beforehand?!432 bool coprime = true;433 for(TReducers::const_iterator vit = v.begin(); (vit != v.end()) && coprime; ++vit )434 {435 assume( (*vit)->CheckLT( m_L ) );436 437 const poly p = (*vit)->lt();438 439 assume( p_GetComp(p, r) == comp );440 441 // TODO: check if coprime with Leads... if OPT__TAILREDSYZ !442 for( int var = N; var > 0; --var )443 if( (p_GetExp(p, var, r) != 0) && (p_GetExp(t, var, r) != 0) )444 {445 coprime = false; // t not coprime with p!446 break;447 }448 449 if( bSyzCheck && coprime )450 {451 poly ss = p_LmInit(t, r);452 p_SetCoeff0(ss, n_Init(1, r->cf), r); // for delete & printout only!...453 p_SetComp(ss, (*vit)->label() + 1, r); // coeff?454 p_Setm(ss, r);455 456 coprime = ( syzChecker.IsDivisible(ss) );457 458 p_LmDelete(&ss, r); // deletes coeff as well???459 }460 461 assume( p == (*vit)->lt() );462 assume( (*vit)->CheckLT( m_L ) );463 }464 465 return coprime? 3: 0; // t was coprime with all of leading terms!!!466 467 }468 // return true; // delete the term469 470 return 0;471 }472 473 474 void SchreyerSyzygyComputation::SetUpTailTerms()475 {476 const ideal idTails = m_idTails;477 assume( idTails != NULL );478 assume( idTails->m != NULL );479 const ring r = m_rBaseRing;480 481 unsigned long pp[4] = {0,0,0,0}; // count preprocessed terms...482 483 for( int p = IDELEMS(idTails) - 1; p >= 0; --p )484 for( poly* tt = &(idTails->m[p]); (*tt) != NULL; )485 {486 const poly t = *tt;487 const int k = m_div.PreProcessTerm(t, m_checker); // 0..3488 assume( 0 <= k && k <= 3 );489 490 pp[k]++; // collect stats491 492 if( k )493 {494 (*tt) = p_LmDeleteAndNext(t, r); // delete the lead and next...495 }496 else497 tt = &pNext(t); // go next?498 499 }500 501 if( UNLIKELY(OPT__PROT) )502 {503 Print("(PP/ST: {c: %lu, C: %lu, P: %lu} + %lu)", pp[1], pp[2], pp[3], pp[0]);504 m_stat[0] += pp [0]; m_stat[1] += pp [1]; m_stat[2] += pp [2]; m_stat[3] += pp [3];505 }506 }507 508 /*509 m_idTailTerms.resize( IDELEMS(idTails) );510 511 for( unsigned int p = IDELEMS(idTails) - 1; p >= 0; p -- )512 {513 TTail& v = m_idTailTerms[p];514 poly t = idTails->m[p];515 v.resize( pLength(t) );516 517 unsigned int pp = 0;518 519 while( t != NULL )520 {521 assume( t != NULL );522 // TODO: compute L:t!523 // ideal reducers;524 // CReducerFinder m_reducers525 526 CTailTerm* d = v[pp] = new CTailTerm();527 528 ++pp; pIter(t);529 }530 }531 */532 533 void SchreyerSyzygyComputation::PrintStats() const534 {535 Print("SchreyerSyzygyComputation Stats: (PP/ST: {c: %lu, C: %lu, P: %lu} + %lu, LOT: %lu, LCM: %lu, ST:%lu, LK: %lu {*: %lu})\n",536 m_stat[1], m_stat[2], m_stat[3], m_stat[0],537 m_stat[4], m_stat[5],538 m_stat[8],539 m_stat[6] + m_stat[7], m_stat[7]540 );541 }542 543 544 ideal SchreyerSyzygyComputation::Compute1LeadingSyzygyTerms()545 {546 const ideal& id = m_idLeads;547 const ring& r = m_rBaseRing;548 // const SchreyerSyzygyComputationFlags& attributes = m_atttributes;549 550 assume(!OPT__LEAD2SYZ);551 552 // 1. set of components S?553 // 2. for each component c from S: set of indices of leading terms554 // with this component?555 // 3. short exp. vectors for each leading term?556 557 const int size = IDELEMS(id);558 559 if( size < 2 )560 {561 const ideal newid = idInit(1, 0); newid->m[0] = NULL; // zero ideal...562 return newid;563 }564 565 // TODO/NOTE: input is supposed to be (reverse-) sorted wrt "(c,ds)"!??566 567 // components should come in groups: count elements in each group568 // && estimate the real size!!!569 570 571 // use just a vector instead???572 const ideal newid = idInit( (size * (size-1))/2, size); // maximal size: ideal case!573 574 int k = 0;575 576 for (int j = 0; j < size; j++)577 {578 const poly p = id->m[j];579 assume( p != NULL );580 const int c = p_GetComp(p, r);581 582 for (int i = j - 1; i >= 0; i--)583 {584 const poly pp = id->m[i];585 assume( pp != NULL );586 const int cc = p_GetComp(pp, r);587 588 if( c != cc )589 continue;590 591 const poly m = p_Init(r); // p_New???592 593 // m = LCM(p, pp) / p! // TODO: optimize: knowing the ring structure: (C/lp)!594 for (int v = rVar(r); v > 0; v--)595 {596 assume( v > 0 );597 assume( v <= rVar(r) );598 599 const short e1 = p_GetExp(p , v, r);600 const short e2 = p_GetExp(pp, v, r);601 602 if( e1 >= e2 )603 p_SetExp(m, v, 0, r);604 else605 p_SetExp(m, v, e2 - e1, r);606 607 }608 609 assume( (j > i) && (i >= 0) );610 611 p_SetComp(m, j + 1, r);612 pNext(m) = NULL;613 p_SetCoeff0(m, n_Init(1, r->cf), r); // for later...614 615 p_Setm(m, r); // should not do anything!!!616 617 newid->m[k++] = m;618 }619 }620 621 // the rest of newid is assumed to be zeroes...622 623 // simplify(newid, 2 + 32)??624 // sort(newid, "C,ds")[1]???625 id_DelDiv(newid, r); // #define SIMPL_LMDIV 32626 627 idSkipZeroes(newid); // #define SIMPL_NULL 2628 629 Sort_c_ds(newid, r);630 631 return newid;632 }633 634 ideal SchreyerSyzygyComputation::Compute2LeadingSyzygyTerms()635 {636 const ideal& id = m_idLeads;637 const ring& r = m_rBaseRing;638 // const SchreyerSyzygyComputationFlags& attributes = m_atttributes;639 640 // 1. set of components S?641 // 2. for each component c from S: set of indices of leading terms642 // with this component?643 // 3. short exp. vectors for each leading term?644 645 const int size = IDELEMS(id);646 647 if( size < 2 )648 {649 const ideal newid = idInit(1, 1); newid->m[0] = NULL; // zero module...650 return newid;651 }652 653 654 // TODO/NOTE: input is supposed to be sorted wrt "C,ds"!??655 656 // components should come in groups: count elements in each group657 // && estimate the real size!!!658 659 660 // use just a vector instead???661 ideal newid = idInit( (size * (size-1))/2, size); // maximal size: ideal case!662 663 int k = 0;664 665 for (int j = 0; j < size; j++)666 {667 const poly p = id->m[j];668 assume( p != NULL );669 const int c = p_GetComp(p, r);670 671 for (int i = j - 1; i >= 0; i--)672 {673 const poly pp = id->m[i];674 assume( pp != NULL );675 const int cc = p_GetComp(pp, r);676 677 if( c != cc )678 continue;679 680 // allocate memory & zero it out!681 const poly m = p_Init(r); const poly mm = p_Init(r);682 683 684 // m = LCM(p, pp) / p! mm = LCM(p, pp) / pp!685 // TODO: optimize: knowing the ring structure: (C/lp)!686 687 for (int v = rVar(r); v > 0; v--)688 {689 assume( v > 0 );690 assume( v <= rVar(r) );691 692 const short e1 = p_GetExp(p , v, r);693 const short e2 = p_GetExp(pp, v, r);694 695 if( e1 >= e2 )696 p_SetExp(mm, v, e1 - e2, r); // p_SetExp(m, v, 0, r);697 else698 p_SetExp(m, v, e2 - e1, r); // p_SetExp(mm, v, 0, r);699 700 }701 702 assume( (j > i) && (i >= 0) );703 704 p_SetComp(m, j + 1, r);705 p_SetComp(mm, i + 1, r);706 707 const number& lc1 = p_GetCoeff(p , r);708 const number& lc2 = p_GetCoeff(pp, r);709 710 #if NODIVISION711 assume( n_IsOne(lc1, r->cf) );712 assume( n_IsOne(lc2, r->cf) );713 714 p_SetCoeff0( m, n_Init( 1, r->cf), r );715 p_SetCoeff0(mm, n_Init(-1, r->cf), r );716 #else717 number g = n_Lcm( lc1, lc2, r->cf );718 p_SetCoeff0(m , n_Div(g, lc1, r), r);719 p_SetCoeff0(mm, n_InpNeg(n_Div(g, lc2, r), r), r);720 n_Delete(&g, r);721 #endif722 723 p_Setm(m, r); // should not do anything!!!724 p_Setm(mm, r); // should not do anything!!!725 726 pNext(m) = mm; // pNext(mm) = NULL;727 728 newid->m[k++] = m;729 }730 }731 732 if( UNLIKELY(!OPT__TAILREDSYZ) )733 {734 // simplify(newid, 2 + 32)??735 // sort(newid, "C,ds")[1]???736 id_DelDiv(newid, r); // #define SIMPL_LMDIV 32737 }738 else739 {740 // option(redSB); option(redTail);741 // TEST_OPT_REDSB742 // TEST_OPT_REDTAIL743 assume( r == currRing );744 745 BITSET _save_test; SI_SAVE_OPT1(_save_test);746 SI_RESTORE_OPT1(Sy_bit(OPT_REDTAIL) | Sy_bit(OPT_REDSB) | _save_test);747 748 intvec* w=new intvec(IDELEMS(newid));749 ideal tmp = kStd(newid, currRing->qideal, isHomog, &w);750 delete w;751 752 SI_RESTORE_OPT1(_save_test)753 754 id_Delete(&newid, r);755 newid = tmp;756 }757 758 idSkipZeroes(newid);759 760 Sort_c_ds(newid, r);761 762 return newid;763 }764 765 poly SchreyerSyzygyComputation::TraverseNF(const poly a, const poly a2) const766 {767 const ideal& L = m_idLeads;768 const ideal& T = m_idTails;769 770 const ring& R = m_rBaseRing;771 772 const int r = p_GetComp(a, R) - 1;773 774 assume( r >= 0 && r < IDELEMS(T) );775 assume( r >= 0 && r < IDELEMS(L) );776 777 assume( a != NULL );778 779 poly aa = leadmonom(a, R); assume( aa != NULL); // :(780 781 poly t = TraverseTail(aa, r);782 783 if( a2 != NULL )784 {785 assume( OPT__LEAD2SYZ );786 787 // replace the following... ?788 const int r2 = p_GetComp(a2, R) - 1; poly aa2 = leadmonom(a2, R); // :(789 790 assume( r2 >= 0 && r2 < IDELEMS(T) );791 792 poly s = TraverseTail(aa2, r2);793 794 p_Delete(&aa2, R);795 796 t = p_Add_q(a2, p_Add_q(t, s, R), R);797 798 } else799 t = p_Add_q(t, ReduceTerm(aa, L->m[r], a), R); // should be identical to bove with a2800 801 p_Delete(&aa, R);802 803 return t;804 }805 806 void SchreyerSyzygyComputation::ComputeSyzygy()807 {808 assume( m_idLeads != NULL );809 assume( m_idTails != NULL );810 811 const ideal& L = m_idLeads;812 const ideal& T = m_idTails;813 814 ideal& TT = m_syzTails;815 const ring& R = m_rBaseRing;816 817 // if( m_sum_bucket == NULL )818 // m_sum_bucket = sBucketCreate(R);819 // assume ( sIsEmpty(m_sum_bucket) );820 821 if( m_spoly_bucket == NULL )822 m_spoly_bucket = kBucketCreate(R);823 824 825 assume( IDELEMS(L) == IDELEMS(T) );826 827 #ifdef SING_NDEBUG828 int t, r; // for rtimer benchmarking in prot realease mode829 #endif830 831 if( UNLIKELY(OPT__TREEOUTPUT) )832 Print("\n{ \"syzygylayer\": \"%d\", \"hybridnf\": \"%d\", \"diagrams\": \n[", OPT__SYZNUMBER, OPT__HYBRIDNF );833 834 if( UNLIKELY(OPT__PROT) ) Print("\n[%d]", OPT__SYZNUMBER );835 836 if( m_syzLeads == NULL )837 {838 #ifdef SING_NDEBUG839 if( UNLIKELY(OPT__PROT & RTIMER_BENCHMARKING) )840 {841 t = getTimer(); r = getRTimer();842 Print("\n%% %5d **!TIME4!** SchreyerSyzygyComputation::ComputeSyzygy::ComputeLeadingSyzygyTerms: t: %d, r: %d\n", r, t, r);843 }844 #endif845 846 ComputeLeadingSyzygyTerms( OPT__LEAD2SYZ && !OPT__IGNORETAILS ); // 2 terms OR 1 term!847 848 #ifdef SING_NDEBUG849 if( UNLIKELY(OPT__PROT & RTIMER_BENCHMARKING) )850 {851 t = getTimer() - t; r = getRTimer() - r;852 Print("\n%% %5d **!TIME4!** SchreyerSyzygyComputation::ComputeSyzygy::ComputeLeadingSyzygyTerms: dt: %d, dr: %d\n", getRTimer(), t, r);853 }854 #endif855 856 }857 858 assume( m_syzLeads != NULL );859 ideal& LL = m_syzLeads;860 const int size = IDELEMS(LL);861 862 TT = idInit(size, 0);863 864 if( size == 1 && LL->m[0] == NULL )865 {866 if( UNLIKELY(OPT__TREEOUTPUT) )867 PrintS("]},");868 return;869 }870 871 872 // use hybrid (Schreyer NF) method?873 const bool method = (OPT__HYBRIDNF == 1); // || (OPT__HYBRIDNF == 2 && OPT__SYZNUMBER < 3);874 875 if( UNLIKELY(OPT__PROT) ) Print("[%s NF|%s]",(method) ? "PR" : "TT", (NOPRODUCT == 1)? "_,_": "^*^" );876 877 878 if( LIKELY(!OPT__IGNORETAILS) )879 {880 if( T != NULL )881 {882 #ifdef SING_NDEBUG883 if( UNLIKELY(OPT__PROT & RTIMER_BENCHMARKING) )884 {885 t = getTimer(); r = getRTimer();886 Print("\n%% %5d **!TIME4!** SchreyerSyzygyComputation::ComputeSyzygy::SetUpTailTerms(): t: %d, r: %d\n", r, t, r);887 }888 #endif889 890 SetUpTailTerms();891 892 #ifdef SING_NDEBUG893 if( UNLIKELY(OPT__PROT & RTIMER_BENCHMARKING) )894 {895 t = getTimer() - t; r = getRTimer() - r;896 Print("\n%% %5d **!TIME4!** SchreyerSyzygyComputation::ComputeSyzygy::SetUpTailTerms(): dt: %d, dr: %d\n", getRTimer(), t, r);897 }898 #endif899 }900 }901 902 #ifdef SING_NDEBUG903 if( UNLIKELY(OPT__PROT & RTIMER_BENCHMARKING) )904 {905 t = getTimer(); r = getRTimer();906 Print("\n%% %5d **!TIME4!** SchreyerSyzygyComputation::ComputeSyzygy::SyzygyLift: t: %d, r: %d\n", r, t, r);907 }908 #endif909 910 // for( int k = 0; k < size; ++k ) // TODO: should be fine now!911 for( int k = size - 1; k >= 0; --k )912 {913 const poly a = LL->m[k]; assume( a != NULL );914 915 poly a2 = pNext(a);916 917 // Splitting 2-terms Leading syzygy module918 if( a2 != NULL )919 pNext(a) = NULL;920 921 if( UNLIKELY(OPT__IGNORETAILS) )922 {923 TT->m[k] = NULL;924 925 assume( a2 != NULL );926 927 if( a2 != NULL )928 p_Delete(&a2, R);929 930 continue;931 }932 933 // TT->m[k] = a2;934 935 poly nf;936 937 if( method )938 nf = SchreyerSyzygyNF(a, a2);939 else940 nf = TraverseNF(a, a2);941 942 TT->m[k] = nf;943 944 if( UNLIKELY(OPT__SYZCHECK) )945 {946 // TODO: check the correctness (syzygy property): a + TT->m[k] should be a syzygy!!!947 948 poly s = pp_Add_qq( a, TT->m[k], R); // current syzygy949 950 poly vp = p_VectorProductLT(s, L, T, R);951 952 assume( vp == NULL );953 954 if( UNLIKELY( OPT__PROT && (vp != NULL) ) ) Warn("ERROR: SyzCheck failed, wrong tail: [%d]\n\n", k); // check k'th syzygy failed955 956 p_Delete(&vp, R);957 }958 }959 960 #ifdef SING_NDEBUG961 if( UNLIKELY( OPT__PROT & RTIMER_BENCHMARKING ) )962 {963 t = getTimer() - t; r = getRTimer() - r;964 Print("\n%% %5d **!TIME4!** SchreyerSyzygyComputation::ComputeSyzygy::SyzygyLift: dt: %d, dr: %d\n", getRTimer(), t, r);965 }966 #endif967 968 TT->rank = id_RankFreeModule(TT, R);969 970 if( UNLIKELY(OPT__TREEOUTPUT) )971 PrintS("\n]},");972 973 if( UNLIKELY(OPT__PROT) ) PrintLn();974 }975 976 void SchreyerSyzygyComputation::ComputeLeadingSyzygyTerms(bool bComputeSecondTerms)977 {978 // const SchreyerSyzygyComputationFlags& attributes = m_atttributes;979 980 // const BOOLEAN OPT__LEAD2SYZ = attributes.OPT__LEAD2SYZ;981 // const BOOLEAN OPT__TAILREDSYZ = attributes.OPT__TAILREDSYZ;982 983 assume( m_syzLeads == NULL );984 985 if( UNLIKELY(bComputeSecondTerms) )986 {987 assume( OPT__LEAD2SYZ );988 // m_syzLeads = FROM_NAMESPACE(INTERNAL, _Compute2LeadingSyzygyTerms(m_idLeads, m_rBaseRing, m_atttributes));989 m_syzLeads = Compute2LeadingSyzygyTerms();990 }991 else992 {993 assume( !OPT__LEAD2SYZ );994 995 m_syzLeads = Compute1LeadingSyzygyTerms();996 }997 // m_syzLeads = FROM_NAMESPACE(INTERNAL, _ComputeLeadingSyzygyTerms(m_idLeads, m_rBaseRing, m_atttributes));998 999 // NOTE: set m_LS if tails are to be reduced!1000 assume( m_syzLeads!= NULL );1001 1002 if ( LIKELY( OPT__TAILREDSYZ && !OPT__IGNORETAILS && (IDELEMS(m_syzLeads) > 0) && !((IDELEMS(m_syzLeads) == 1) && (m_syzLeads->m[0] == NULL)) ) )1003 {1004 m_LS = m_syzLeads;1005 m_checker.Initialize(m_syzLeads);1006 assume( m_checker.IsNonempty() ); // TODO: this always fails... BUG????1007 }1008 1009 if( UNLIKELY( OPT__PROT ) ) Print("(L%dS:%d)", bComputeSecondTerms ? 2 : 1, IDELEMS(m_syzLeads));1010 1011 }1012 1013 poly SchreyerSyzygyComputation::SchreyerSyzygyNF(const poly syz_lead, poly syz_2) const1014 {1015 assume( !OPT__IGNORETAILS );1016 1017 const ideal& L = m_idLeads;1018 const ideal& T = m_idTails;1019 const ring& r = m_rBaseRing;1020 1021 assume( syz_lead != NULL );1022 1023 if( syz_2 == NULL )1024 {1025 const int rr = p_GetComp(syz_lead, r) - 1;1026 1027 assume( rr >= 0 && rr < IDELEMS(T) );1028 assume( rr >= 0 && rr < IDELEMS(L) );1029 1030 #if NOPRODUCT1031 syz_2 = m_div.FindReducer(syz_lead, L->m[rr], syz_lead, m_checker);1032 p_Test(syz_2, r);1033 1034 #else1035 poly aa = leadmonom(syz_lead, r); assume( aa != NULL); // :(1036 aa = p_Mult_mm(aa, L->m[rr], r);1037 1038 syz_2 = m_div.FindReducer(aa, syz_lead, m_checker);1039 p_Test(syz_2, r);1040 1041 p_Delete(&aa, r);1042 #endif1043 1044 }1045 1046 assume( syz_2 != NULL ); // by construction of S-Polynomial1047 1048 assume( L != NULL );1049 assume( T != NULL );1050 1051 assume( IDELEMS(L) == IDELEMS(T) );1052 1053 int c = p_GetComp(syz_lead, r) - 1;1054 1055 assume( c >= 0 && c < IDELEMS(T) );1056 1057 if( m_spoly_bucket == NULL )1058 m_spoly_bucket = kBucketCreate(r);1059 1060 SBucketWrapper tail(r, m_sum_bucket_factory);1061 1062 1063 kBucket_pt bucket = m_spoly_bucket; assume( bucket != NULL ); kbTest(bucket); m_spoly_bucket = NULL;1064 1065 // kBucketInit(bucket, NULL, 0); // not needed!?1066 1067 poly p = leadmonom(syz_lead, r); // :(1068 // poly spoly = pp_Mult_qq(p, T->m[c], r);1069 kBucket_Plus_mm_Mult_pp(bucket, p, T->m[c], 0); // TODO: store pLength(T->m[c]) separately!?1070 p_Delete(&p, r);1071 1072 kbTest(bucket);1073 1074 c = p_GetComp(syz_2, r) - 1;1075 assume( c >= 0 && c < IDELEMS(T) );1076 1077 p = leadmonom(syz_2, r); // :(1078 // spoly = p_Add_q(spoly, pp_Mult_qq(p, T->m[c], r), r);1079 kBucket_Plus_mm_Mult_pp(bucket, p, T->m[c], 0); // pLength(T->m[c])?!1080 kbTest(bucket);1081 p_Delete(&p, r);1082 1083 // const bool bUsePolynomial = TEST_OPT_NOT_BUCKETS; // || (pLength(spoly) < MIN_LENGTH_BUCKET);1084 // CPolynomialSummator tail(r, bUsePolynomial);1085 tail.Add(syz_2, 1);1086 1087 kbTest(bucket);1088 for( poly spoly = kBucketExtractLm(bucket); spoly != NULL; p_LmDelete(&spoly, r), spoly = kBucketExtractLm(bucket))1089 {1090 kbTest(bucket);1091 poly t = m_div.FindReducer(spoly, NULL, m_checker);1092 p_Test(t, r);1093 1094 if( t != NULL )1095 {1096 p = leadmonom(t, r); // :(1097 c = p_GetComp(t, r) - 1;1098 1099 assume( c >= 0 && c < IDELEMS(T) );1100 1101 kBucket_Plus_mm_Mult_pp(bucket, p, T->m[c], 0); // pLength(T->m[c])?1102 // spoly = p_Add_q(spoly, pp_Mult_qq(p, T->m[c], r), r);1103 1104 p_Delete(&p, r);1105 1106 tail.Add(t, 1);1107 } // otherwise discard that leading term altogether!1108 else1109 if( UNLIKELY(OPT__PROT) ) ++ m_stat[4]; // PrintS("$"); // LOT1110 1111 kbTest(bucket);1112 }1113 1114 kbTest(bucket);1115 1116 // now bucket must be empty!1117 assume( kBucketClear(bucket) == NULL );1118 1119 const poly result = tail.ClearAdd(); // TODO: use Merge with sBucket???1120 1121 1122 if( m_spoly_bucket == NULL )1123 m_spoly_bucket = bucket;1124 else1125 kBucketDestroy(&bucket);1126 1127 1128 if( UNLIKELY(OPT__TREEOUTPUT) )1129 {1130 PrintS("]},");1131 }1132 return result;1133 }1134 1135 // namespace {1136 1137 // };1138 1139 1140 bool my_p_LmCmp (poly a, poly b, const ring r) { return p_LmCmp(a, b, r) == -1; } // TODO: change to simple lex. memory compare!1141 1142 // NOTE: need p_Copy?????? for image + multiplier!!???1143 // NOTE: better store complete syz. terms!!?1144 poly SchreyerSyzygyComputation::TraverseTail(poly multiplier, const int tail) const1145 {1146 const ring& r = m_rBaseRing;1147 1148 assume(m_idTails != NULL && m_idTails->m != NULL);1149 assume( tail >= 0 && tail < IDELEMS(m_idTails) );1150 1151 p_Test(multiplier, r);1152 1153 if( UNLIKELY(OPT__NOCACHING) )1154 return ComputeImage(multiplier, tail);1155 1156 // TODO: store (multiplier, tail) -.-^-.-^-.--> !1157 TCache::iterator top_itr = m_cache.find(tail);1158 1159 if ( top_itr != m_cache.end() )1160 {1161 assume( top_itr->first == tail );1162 1163 TP2PCache& T = top_itr->second;1164 1165 TP2PCache::iterator itr = T.find(multiplier);1166 1167 if( itr != T.end() ) // Yey - Reuse!!!1168 {1169 assume( p_LmEqual(itr->first, multiplier, r) );1170 1171 if( itr->second == NULL ) // leadcoeff plays no role if value is NULL!1172 return (NULL);1173 1174 poly p = p_Copy(itr->second, r); // COPY!!!1175 1176 p_Test(multiplier, r);1177 1178 if( !n_Equal( pGetCoeff(multiplier), pGetCoeff(itr->first), r->cf) ) // normalize coeffs!?1179 {1180 number n = n_Div( pGetCoeff(multiplier), pGetCoeff(itr->first), r->cf); // new number1181 1182 if( UNLIKELY( OPT__TREEOUTPUT ) )1183 {1184 StringSetS("");1185 n_Write(n, r->cf);1186 char* s = StringEndS();1187 Print("\"recale\": \"%s\", ", s);1188 omFree(s);1189 }1190 1191 if( UNLIKELY( OPT__PROT ) ) ++ m_stat[7]; // PrintS("l*"); // lookup & rescale1192 1193 p = p_Mult_nn(p, n, r); // !1194 n_Delete(&n, r->cf);1195 } else1196 if( UNLIKELY( OPT__PROT ) ) ++ m_stat[6]; // PrintS("l"); // lookup no rescale1197 1198 p_Test(multiplier, r);1199 1200 return p;1201 }1202 1203 1204 p_Test(multiplier, r);1205 1206 const poly p = ComputeImage(multiplier, tail);1207 1208 if( UNLIKELY(OPT__PROT) ) ++ m_stat[8]; // PrintS("S"); // store1209 1210 p_Test(multiplier, r);1211 1212 T.insert( TP2PCache::value_type(myp_Head(multiplier, (p==NULL), r), p) ); // T[ multiplier ] = p;1213 1214 p_Test(multiplier, r);1215 1216 // if( p == NULL )1217 // return (NULL);1218 1219 return p_Copy(p, r);1220 }1221 1222 CCacheCompare o(r); TP2PCache T(o);1223 1224 const poly p = ComputeImage(multiplier, tail);1225 1226 if( UNLIKELY( OPT__PROT ) ) ++ m_stat[8]; // PrintS("S"); // store // %d", tail + 1);1227 1228 T.insert( TP2PCache::value_type(myp_Head(multiplier, (p==NULL), r), p) );1229 1230 m_cache.insert( TCache::value_type(tail, T) );1231 1232 // if( p == NULL )1233 // return (NULL);1234 1235 return p_Copy(p, r);1236 }1237 1238 poly SchreyerSyzygyComputation::ComputeImage(poly multiplier, const int tail) const1239 {1240 const ring& r = m_rBaseRing;1241 1242 assume(m_idTails != NULL && m_idTails->m != NULL);1243 assume( tail >= 0 && tail < IDELEMS(m_idTails) );1244 1245 p_Test(multiplier, r);1246 1247 const poly t = m_idTails->m[tail]; // !!!1248 1249 if(t != NULL)1250 {1251 const poly p = TraverseTail(multiplier, t);1252 1253 p_Test(multiplier, r);1254 return p;1255 }1256 1257 return NULL;1258 }1259 1260 1261 poly SchreyerSyzygyComputation::TraverseTail(poly multiplier, poly tail) const1262 {1263 assume( !OPT__IGNORETAILS );1264 1265 const ideal& L = m_idLeads;1266 const ideal& T = m_idTails;1267 const ring& r = m_rBaseRing;1268 1269 assume( multiplier != NULL );1270 1271 assume( L != NULL );1272 assume( T != NULL );1273 1274 p_Test(multiplier, r);1275 1276 if( UNLIKELY( !( (!OPT__TAILREDSYZ) || m_lcm.Check(multiplier) )) )1277 {1278 if( UNLIKELY(OPT__TAILREDSYZ && OPT__PROT) )1279 {1280 ++ m_stat[5]; // PrintS("%"); // check LCM !1281 }1282 return NULL;1283 }1284 1285 // const bool bUsePolynomial = TEST_OPT_NOT_BUCKETS; // || (pLength(tail) < MIN_LENGTH_BUCKET);1286 1287 SBucketWrapper sum(r, m_sum_bucket_factory);1288 /*1289 sBucket_pt sum;1290 1291 if( m_sum_bucket == NULL )1292 sum = sBucketCreate(r);1293 else1294 {1295 if( !sIsEmpty(m_sum_bucket) )1296 sum = sBucketCreate(r);1297 else1298 {1299 sum = m_sum_bucket;1300 m_sum_bucket = NULL;1301 }1302 }1303 1304 1305 assume( sum != NULL ); assume ( sIsEmpty(sum) );1306 assume( r == sBucketGetRing(sum) );1307 */1308 1309 // poly s; int len;1310 1311 // CPolynomialSummator sum(r, bUsePolynomial);1312 // poly s = NULL;1313 1314 // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!1315 // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!1316 for(poly p = tail; p != NULL; p = pNext(p)) // iterate over the tail1317 {1318 // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!1319 const poly rt = ReduceTerm(multiplier, p, NULL); // TODO: also return/store length?1320 sum.Add(rt);1321 // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!1322 // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!1323 // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!1324 1325 // const int lp = pLength(rt);1326 // if( rt != NULL && lp != 0 )1327 // sBucket_Add_p(sum, rt, lp);1328 }1329 // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!1330 // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!1331 1332 // sBucketClearAdd(sum, &s, &len); // Will Not Clear?!?1333 const poly s = sum.ClearAdd();1334 1335 // assume( sum != NULL ); assume ( sIsEmpty(sum) );1336 /*1337 if( m_sum_bucket == NULL )1338 m_sum_bucket = sum;1339 else1340 sBucketDestroy(&sum);1341 1342 assume( pLength(s) == len );1343 */1344 1345 p_Test(multiplier, r);1346 1347 return s;1348 }1349 1350 1351 1352 1353 poly SchreyerSyzygyComputation::ReduceTerm(poly multiplier, poly term4reduction, poly syztermCheck) const1354 {1355 assume( !OPT__IGNORETAILS );1356 1357 const ideal& L = m_idLeads;1358 const ideal& T = m_idTails;1359 const ring& r = m_rBaseRing;1360 1361 assume( multiplier != NULL );1362 assume( term4reduction != NULL );1363 1364 1365 assume( L != NULL );1366 assume( T != NULL );1367 1368 p_Test(multiplier, r);1369 1370 // simple implementation with FindReducer:1371 poly s = NULL;1372 1373 if( (!OPT__TAILREDSYZ) || m_lcm.Check(multiplier) ) // TODO: UNLIKELY / LIKELY ????1374 {1375 #if NOPRODUCT1376 s = m_div.FindReducer(multiplier, term4reduction, syztermCheck, m_checker); // s ????1377 p_Test(s, r);1378 1379 p_Test(multiplier, r);1380 1381 if( s == NULL ) // No Reducer?1382 {1383 if( UNLIKELY(OPT__PROT) ) ++ m_stat[4]; // PrintS("$"); // LOT1384 return NULL;1385 }1386 1387 #else1388 // NOTE: only LT(term4reduction) should be used in the following:1389 poly product = pp_Mult_mm(multiplier, term4reduction, r);1390 p_Test(product, r);1391 1392 s = m_div.FindReducer(product, syztermCheck, m_checker); // ??1393 p_Test(s, r);1394 1395 p_Test(multiplier, r);1396 1397 if( s == NULL ) // No Reducer?1398 {1399 if( UNLIKELY(OPT__PROT) ) ++ m_stat[4]; // PrintS("$"); // LOT1400 return NULL;1401 }1402 1403 p_Delete(&product, r);1404 #endif1405 }1406 1407 if( s == NULL ) // No Reducer?1408 {1409 if( UNLIKELY( OPT__TAILREDSYZ && OPT__PROT) )1410 {1411 ++ m_stat[5]; // PrintS("%"); // check LCM !1412 }1413 return NULL;1414 }1415 1416 p_Test(multiplier, r);1417 p_Test(s, r);1418 1419 poly b = leadmonom(s, r);1420 1421 p_Test(b, r);1422 1423 const int c = p_GetComp(s, r) - 1;1424 assume( c >= 0 && c < IDELEMS(T) );1425 1426 1427 if( UNLIKELY( OPT__TREEOUTPUT ) )1428 PrintS("\", \"children\": [");1429 1430 const poly t = TraverseTail(b, c); // T->m[c];1431 1432 p_Test(multiplier, r);1433 1434 if( t != NULL )1435 s = p_Add_q(s, t, r);1436 1437 p_Test(multiplier, r);1438 1439 return s;1440 }1441 1442 SchreyerSyzygyComputationFlags::SchreyerSyzygyComputationFlags(idhdl rootRingHdl):1443 OPT__DEBUG( atGetInt(rootRingHdl,"DEBUG", 0) ),1444 OPT__LEAD2SYZ( atGetInt(rootRingHdl, "LEAD2SYZ", 0) ),1445 OPT__TAILREDSYZ( atGetInt(rootRingHdl, "TAILREDSYZ", 1) ),1446 OPT__HYBRIDNF( atGetInt(rootRingHdl, "HYBRIDNF", 0) ),1447 OPT__IGNORETAILS( atGetInt(rootRingHdl, "IGNORETAILS", 0) ),1448 OPT__SYZNUMBER( atGetInt(rootRingHdl, "SYZNUMBER", 0) ),1449 OPT__TREEOUTPUT( atGetInt(rootRingHdl, "TREEOUTPUT", 0) ),1450 OPT__SYZCHECK( atGetInt(rootRingHdl, "SYZCHECK", 0) ),1451 OPT__PROT(TEST_OPT_PROT),1452 OPT__NOCACHING( atGetInt(rootRingHdl, "NOCACHING", 0) ),1453 m_rBaseRing( rootRingHdl->data.uring )1454 {1455 // TODO: just current setting!1456 assume( rootRingHdl == currRingHdl );1457 assume( rootRingHdl->typ == RING_CMD );1458 assume( m_rBaseRing == currRing );1459 // move the global ring here inside???1460 }1461 1462 1463 1464 CLeadingTerm::CLeadingTerm(unsigned int _label, const poly _lt, const ring R):1465 m_sev( p_GetShortExpVector(_lt, R) ), m_label( _label ), m_lt( _lt )1466 {1467 assume( sev() == p_GetShortExpVector(lt(), R) );1468 }1469 1470 CReducerFinder::~CReducerFinder()1471 {1472 for( CReducersHash::const_iterator it = m_hash.begin(); it != m_hash.end(); it++ )1473 {1474 const TReducers& v = it->second;1475 for(TReducers::const_iterator vit = v.begin(); vit != v.end(); vit++ )1476 delete const_cast<CLeadingTerm*>(*vit);1477 }1478 }1479 1480 1481 void CReducerFinder::Initialize(const ideal L)1482 {1483 assume( m_L == NULL || m_L == L );1484 if( m_L == NULL )1485 m_L = L;1486 1487 assume( m_L == L );1488 1489 if( L != NULL )1490 {1491 const ring& R = m_rBaseRing;1492 assume( R != NULL );1493 1494 for( int k = IDELEMS(L) - 1; k >= 0; k-- )1495 {1496 const poly a = L->m[k]; // assume( a != NULL );1497 1498 // NOTE: label is k \in 0 ... |L|-1!!!1499 if( a != NULL )1500 m_hash[p_GetComp(a, R)].push_back( new CLeadingTerm(k, a, R) );1501 }1502 }1503 }1504 1505 CReducerFinder::CReducerFinder(const ideal L, const SchreyerSyzygyComputationFlags& flags):1506 SchreyerSyzygyComputationFlags(flags),1507 m_L(const_cast<ideal>(L)), // for debug anyway1508 m_hash()1509 {1510 assume( flags.m_rBaseRing == m_rBaseRing );1511 if( L != NULL )1512 Initialize(L);1513 }1514 1515 /// _p_LmDivisibleByNoComp for a | b*c1516 static inline BOOLEAN _p_LmDivisibleByNoComp(const poly a, const poly b, const poly c, const ring r)1517 {1518 int i=r->VarL_Size - 1;1519 unsigned long divmask = r->divmask;1520 unsigned long la, lb;1521 1522 if (r->VarL_LowIndex >= 0)1523 {1524 i += r->VarL_LowIndex;1525 do1526 {1527 la = a->exp[i];1528 lb = b->exp[i] + c->exp[i];1529 if ((la > lb) ||1530 (((la & divmask) ^ (lb & divmask)) != ((lb - la) & divmask)))1531 {1532 pDivAssume(p_DebugLmDivisibleByNoComp(a, b, r) == FALSE);1533 return FALSE;1534 }1535 i--;1536 }1537 while (i>=r->VarL_LowIndex);1538 }1539 else1540 {1541 do1542 {1543 la = a->exp[r->VarL_Offset[i]];1544 lb = b->exp[r->VarL_Offset[i]] + c->exp[r->VarL_Offset[i]];1545 if ((la > lb) ||1546 (((la & divmask) ^ (lb & divmask)) != ((lb - la) & divmask)))1547 {1548 pDivAssume(p_DebugLmDivisibleByNoComp(a, b, r) == FALSE);1549 return FALSE;1550 }1551 i--;1552 }1553 while (i>=0);1554 }1555 #ifdef HAVE_RINGS1556 assume( !rField_is_Ring(r) ); // not implemented for rings...!1557 #endif1558 return TRUE;1559 }1560 1561 1562 bool CLeadingTerm::CheckLT( const ideal & L ) const1563 {1564 // for( int i = IDELEMS(L); i >= 0; --i) assume( pNext(L->m[i]) == NULL ); // ???1565 return ( L->m[label()] == lt() );1566 }1567 1568 bool CLeadingTerm::DivisibilityCheck(const poly product, const unsigned long not_sev, const ring r) const1569 {1570 // may have no coeff yet1571 // assume ( !n_IsZero( p_GetCoeff(product, r), r ) );1572 1573 assume ( !n_IsZero( pGetCoeff(lt()), r->cf ) );1574 assume( sev() == p_GetShortExpVector(lt(), r) );1575 1576 assume( product != NULL );1577 assume( (p_GetComp(lt(), r) == p_GetComp(product, r)) || (p_GetComp(lt(), r) == 0) );1578 1579 // const int k = label();1580 // assume( m_L->m[k] == p );1581 1582 return p_LmShortDivisibleByNoComp(lt(), sev(), product, not_sev, r);1583 1584 }1585 1586 #if NOPRODUCT1587 /// as DivisibilityCheck(multiplier * t, ...) for monomial 'm'1588 /// and a module term 't'1589 bool CLeadingTerm::DivisibilityCheck(const poly m, const poly t, const unsigned long not_sev, const ring r) const1590 {1591 assume ( !n_IsZero( pGetCoeff(lt()), r->cf ) );1592 assume( sev() == p_GetShortExpVector(lt(), r) );1593 1594 assume( m != NULL );1595 assume( t != NULL );1596 assume ( !n_IsZero( pGetCoeff(m), r->cf ) );1597 assume ( !n_IsZero( pGetCoeff(t), r->cf ) );1598 1599 // assume( p_GetComp(m, r) == 0 );1600 assume( (p_GetComp(lt(), r) == p_GetComp(t, r)) || (p_GetComp(lt(), r) == 0) );1601 1602 p_Test(m, r);1603 p_Test(t, r);1604 // const int k = label();1605 // assume( m_L->m[k] == p );1606 1607 if (sev() & not_sev)1608 return false;1609 1610 return _p_LmDivisibleByNoComp(lt(), m, t, r);1611 // return p_LmShortDivisibleByNoComp(p, p_sev, product, not_sev, r);1612 }1613 #endif1614 1615 1616 /// TODO:1617 class CDivisorEnumerator: public SchreyerSyzygyComputationFlags1618 {1619 private:1620 const CReducerFinder& m_reds;1621 const poly m_product;1622 const unsigned long m_not_sev;1623 const long m_comp;1624 1625 CReducerFinder::CReducersHash::const_iterator m_itr;1626 CReducerFinder::TReducers::const_iterator m_current, m_finish;1627 1628 bool m_active;1629 1630 public:1631 CDivisorEnumerator(const CReducerFinder& self, const poly product):1632 SchreyerSyzygyComputationFlags(self),1633 m_reds(self),1634 m_product(product),1635 m_not_sev(~p_GetShortExpVector(product, m_rBaseRing)),1636 m_comp(p_GetComp(product, m_rBaseRing)),1637 m_itr(), m_current(), m_finish(),1638 m_active(false)1639 {1640 assume( m_comp >= 0 );1641 assume( m_reds.m_L != NULL ); /// TODO: m_L should stay the same!!!1642 1643 assume( product != NULL ); // may have no coeff yet :(1644 // assume ( !n_IsZero( p_GetCoeff(product, m_rBaseRing), m_rBaseRing ) );1645 }1646 1647 inline bool Reset()1648 {1649 m_active = false;1650 1651 m_itr = m_reds.m_hash.find(m_comp);1652 1653 if( m_itr == m_reds.m_hash.end() )1654 return false;1655 1656 assume( m_itr->first == m_comp );1657 1658 m_current = (m_itr->second).begin();1659 m_finish = (m_itr->second).end();1660 1661 if (m_current == m_finish)1662 return false;1663 1664 // m_active = true;1665 return true;1666 }1667 1668 const CLeadingTerm& Current() const1669 {1670 assume( m_active );1671 assume( m_current != m_finish );1672 1673 return *(*m_current);1674 }1675 1676 inline bool MoveNext()1677 {1678 assume( m_current != m_finish );1679 1680 if( m_active )1681 ++m_current;1682 else1683 m_active = true; // for Current()1684 1685 // looking for the next good entry1686 for( ; m_current != m_finish; ++m_current )1687 {1688 assume( Current().CheckLT( m_reds.m_L ) );1689 1690 if( Current().DivisibilityCheck(m_product, m_not_sev, m_rBaseRing) )1691 {1692 // m_active = true;1693 assume( Current().CheckLT( m_reds.m_L ) );1694 return true;1695 }1696 assume( Current().CheckLT( m_reds.m_L ) );1697 }1698 1699 // the end... :(1700 assume( m_current == m_finish );1701 1702 m_active = false;1703 return false;1704 }1705 };1706 1707 1708 bool CReducerFinder::IsDivisible(const poly product) const1709 {1710 assume( product != NULL );1711 1712 // NOTE: q may have no coeff!!!1713 1714 CDivisorEnumerator itr(*this, product);1715 if( !itr.Reset() )1716 return false;1717 1718 return itr.MoveNext();1719 1720 }1721 1722 #if NOPRODUCT1723 1724 /// TODO:1725 class CDivisorEnumerator2: public SchreyerSyzygyComputationFlags1726 {1727 private:1728 const CReducerFinder& m_reds;1729 const poly m_multiplier, m_term;1730 const unsigned long m_not_sev;1731 const long m_comp;1732 1733 CReducerFinder::CReducersHash::const_iterator m_itr;1734 CReducerFinder::TReducers::const_iterator m_current, m_finish;1735 1736 bool m_active;1737 1738 public:1739 CDivisorEnumerator2(const CReducerFinder& self, const poly m, const poly t):1740 SchreyerSyzygyComputationFlags(self),1741 m_reds(self),1742 m_multiplier(m), m_term(t),1743 m_not_sev(~p_GetShortExpVector(m, t, m_rBaseRing)),1744 m_comp(p_GetComp(t, m_rBaseRing)),1745 m_itr(), m_current(), m_finish(),1746 m_active(false)1747 {1748 assume( m_comp >= 0 );1749 assume( m_reds.m_L != NULL );1750 assume( m_multiplier != NULL );1751 assume( m_term != NULL );1752 1753 assume( m != NULL );1754 assume( t != NULL );1755 assume ( !n_IsZero( pGetCoeff(m), m_rBaseRing->cf ) );1756 assume ( !n_IsZero( pGetCoeff(t), m_rBaseRing->cf ) );1757 1758 p_Test(m, m_rBaseRing);1759 1760 }1761 1762 inline bool Reset()1763 {1764 m_active = false;1765 1766 m_itr = m_reds.m_hash.find(m_comp);1767 1768 if( m_itr == m_reds.m_hash.end() )1769 return false;1770 1771 assume( m_itr->first == m_comp );1772 1773 m_current = (m_itr->second).begin();1774 m_finish = (m_itr->second).end();1775 1776 if (m_current == m_finish)1777 return false;1778 1779 return true;1780 }1781 1782 const CLeadingTerm& Current() const1783 {1784 assume( m_active );1785 assume( m_current != m_finish );1786 1787 return *(*m_current);1788 }1789 1790 inline bool MoveNext()1791 {1792 assume( m_current != m_finish );1793 1794 if( m_active )1795 ++m_current;1796 else1797 m_active = true;1798 1799 1800 // looking for the next good entry1801 for( ; m_current != m_finish; ++m_current )1802 {1803 assume( Current().CheckLT( m_reds.m_L ) );1804 1805 if( Current().DivisibilityCheck(m_multiplier, m_term, m_not_sev, m_rBaseRing) )1806 {1807 // m_active = true;1808 assume( Current().CheckLT( m_reds.m_L ) );1809 return true;1810 1811 }1812 assume( Current().CheckLT( m_reds.m_L ) );1813 }1814 1815 // the end... :(1816 assume( m_current == m_finish );1817 1818 m_active = false;1819 return false;1820 }1821 };1822 1823 poly CReducerFinder::FindReducer(const poly multiplier, const poly t,1824 const poly syzterm,1825 const CReducerFinder& syz_checker) const1826 {1827 const ring& r = m_rBaseRing;1828 1829 p_Test(multiplier, r);1830 1831 CDivisorEnumerator2 itr(*this, multiplier, t);1832 if( !itr.Reset() )1833 return NULL;1834 1835 // don't care about the module component of multiplier (as it may be the syzygy term)1836 // product = multiplier * t?1837 1838 assume( multiplier != NULL ); assume( t != NULL );1839 1840 const ideal& L = m_L; assume( L != NULL ); // for debug/testing only!1841 1842 long c = 0;1843 1844 if (syzterm != NULL)1845 c = p_GetComp(syzterm, r) - 1;1846 1847 assume( c >= 0 && c < IDELEMS(L) );1848 1849 p_Test(multiplier, r);1850 1851 const BOOLEAN to_check = (syz_checker.IsNonempty()); // OPT__TAILREDSYZ &&1852 1853 // const poly q = p_One(r);1854 const poly q = p_New(r); pNext(q) = NULL;1855 1856 assume( pNext(q) == NULL );1857 1858 p_Test(multiplier, r);1859 while( itr.MoveNext() )1860 {1861 assume( itr.Current().CheckLT( L ) ); // ???1862 1863 const poly p = itr.Current().lt(); // ???1864 const int k = itr.Current().label();1865 1866 p_ExpVectorSum(q, multiplier, t, r); // q == product == multiplier * t // TODO: do it once?1867 p_ExpVectorDiff(q, q, p, r); // (LM(product) / LM(L[k]))1868 1869 p_SetComp(q, k + 1, r);1870 p_Setm(q, r);1871 1872 p_Test(multiplier, r);1873 1874 // cannot allow something like: a*gen(i) - a*gen(i)1875 if (syzterm != NULL && (k == c))1876 if (p_ExpVectorEqual(syzterm, q, r))1877 {1878 assume( itr.Current().CheckLT( L ) ); // ???1879 continue;1880 }1881 1882 // while the complement (the fraction) is not reducible by leading syzygies1883 if( to_check && syz_checker.IsDivisible(q) )1884 {1885 assume( itr.Current().CheckLT( L ) ); // ???1886 continue;1887 }1888 1889 number n = n_Mult( pGetCoeff(multiplier), pGetCoeff(t), r->cf);1890 1891 #if NODIVISION1892 // we assume all leading coeffs to be 1!1893 assume( n_IsOne(pGetCoeff(p), r->cf) );1894 #else1895 if( !n_IsOne( pGetCoeff(p), r ) )1896 n = n_Div(n, pGetCoeff(p), r->cf);1897 #endif1898 1899 p_SetCoeff0(q, n_InpNeg(n, r->cf), r);1900 // n_Delete(&n, r);1901 1902 p_Test(multiplier, r);1903 p_Test(q, r);1904 1905 assume( itr.Current().CheckLT( L ) ); // ???1906 return q;1907 }1908 1909 p_LmFree(q, r);1910 1911 p_Test(multiplier, r);1912 1913 return NULL;1914 1915 }1916 #endif1917 1918 1919 poly CReducerFinder::FindReducer(const poly product, const poly syzterm, const CReducerFinder& syz_checker) const1920 {1921 CDivisorEnumerator itr(*this, product);1922 if( !itr.Reset() )1923 return NULL;1924 1925 1926 1927 const ring& r = m_rBaseRing;1928 1929 assume( product != NULL );1930 1931 const ideal& L = m_L; assume( L != NULL ); // for debug/testing only!1932 1933 long c = 0;1934 1935 if (syzterm != NULL)1936 c = p_GetComp(syzterm, r) - 1;1937 1938 assume( c >= 0 && c < IDELEMS(L) );1939 1940 const BOOLEAN to_check = (syz_checker.IsNonempty()); // OPT__TAILREDSYZ &&1941 1942 const poly q = p_New(r); pNext(q) = NULL;1943 1944 while( itr.MoveNext() )1945 {1946 assume( itr.Current().CheckLT( L ) ); // ???1947 1948 const poly p = itr.Current().lt(); // ??1949 const int k = itr.Current().label();1950 1951 p_ExpVectorDiff(q, product, p, r); // (LM(product) / LM(L[k]))1952 p_SetComp(q, k + 1, r);1953 p_Setm(q, r);1954 1955 // cannot allow something like: a*gen(i) - a*gen(i)1956 if (syzterm != NULL && (k == c))1957 if (p_ExpVectorEqual(syzterm, q, r))1958 {1959 assume( itr.Current().CheckLT( L ) ); // ???1960 continue;1961 }1962 1963 // while the complement (the fraction) is not reducible by leading syzygies1964 if( to_check && syz_checker.IsDivisible(q) ) // ?????1965 {1966 assume( itr.Current().CheckLT( L ) ); // ???1967 continue;1968 }1969 1970 1971 #if NODIVISION1972 assume( n_IsOne(p_GetCoeff(p, r), r->cf) );1973 p_SetCoeff0(q, n_InpNeg( n_Copy(pGetCoeff(product), r->cf), r->cf), r);1974 #else1975 p_SetCoeff0(q, n_InpNeg( n_Div( pGetCoeff(product), p_GetCoeff(p), r->cf), r->cf), r);1976 #endif1977 1978 assume( itr.Current().CheckLT( L ) ); // ???1979 return q;1980 }1981 1982 1983 1984 /*1985 const long comp = p_GetComp(product, r);1986 const unsigned long not_sev = ~p_GetShortExpVector(product, r);1987 1988 assume( comp >= 0 );1989 1990 // for( int k = IDELEMS(L)-1; k>= 0; k-- )1991 // {1992 // const poly p = L->m[k];1993 //1994 // if ( p_GetComp(p, r) != comp )1995 // continue;1996 //1997 // const unsigned long p_sev = p_GetShortExpVector(p, r); // to be stored in m_hash!!!1998 1999 // looking for an appropriate diviser p = L[k]...2000 CReducersHash::const_iterator it = m_hash.find(comp); // same module component2001 2002 if( it == m_hash.end() )2003 return NULL;2004 2005 assume( m_L != NULL );2006 2007 const TReducers& reducers = it->second;2008 2009 const BOOLEAN to_check = (syz_checker.IsNonempty()); // OPT__TAILREDSYZ &&2010 2011 const poly q = p_New(r); pNext(q) = NULL;2012 2013 for(TReducers::const_iterator vit = reducers.begin(); vit != reducers.end(); vit++ )2014 {2015 const poly p = (*vit)->lt(); // ???2016 2017 assume( p_GetComp(p, r) == comp );2018 2019 const int k = (*vit)->label();2020 2021 assume( L->m[k] == p ); // CheckLT2022 2023 const unsigned long p_sev = (*vit)->sev();2024 2025 assume( p_sev == p_GetShortExpVector(p, r) );2026 2027 if( !p_LmShortDivisibleByNoComp(p, p_sev, product, not_sev, r) )2028 continue;2029 2030 // // ... which divides the product, looking for the _1st_ appropriate one!2031 // if( !p_LmDivisibleByNoComp(p, product, r) ) // included inside p_LmShortDivisibleBy!2032 // continue;2033 2034 p_ExpVectorDiff(q, product, p, r); // (LM(product) / LM(L[k]))2035 p_SetComp(q, k + 1, r);2036 p_Setm(q, r);2037 2038 // cannot allow something like: a*gen(i) - a*gen(i)2039 if (syzterm != NULL && (k == c))2040 if (p_ExpVectorEqual(syzterm, q, r))2041 {2042 continue;2043 }2044 2045 // while the complement (the fraction) is not reducible by leading syzygies2046 if( to_check && syz_checker.IsDivisible(q) )2047 {2048 continue;2049 }2050 2051 p_SetCoeff0(q, n_InpNeg( n_Div( p_GetCoeff(product, r), p_GetCoeff(p, r), r), r), r);2052 return q;2053 }2054 */2055 2056 p_LmFree(q, r);2057 return NULL;2058 }2059 2060 2061 CLCM::CLCM(const ideal& L, const SchreyerSyzygyComputationFlags& flags):2062 SchreyerSyzygyComputationFlags(flags), std::vector<bool>(),2063 m_compute(false), m_N(rVar(flags.m_rBaseRing))2064 {2065 const ring& R = m_rBaseRing;2066 assume( flags.m_rBaseRing == R );2067 assume( R != NULL );2068 2069 assume( L != NULL );2070 2071 if( LIKELY( OPT__TAILREDSYZ && !OPT__HYBRIDNF && (L != NULL) )) // TODO: not hybrid!?2072 {2073 const int l = IDELEMS(L);2074 2075 assume( l > 0 );2076 2077 resize(l, false);2078 2079 for( int k = l - 1; k >= 0; k-- )2080 {2081 const poly a = L->m[k]; assume( a != NULL );2082 2083 for (unsigned int j = m_N; j > 0; j--)2084 if ( !(*this)[j] )2085 (*this)[j] = (p_GetExp(a, j, R) > 0);2086 }2087 2088 m_compute = true;2089 }2090 }2091 2092 2093 bool CLCM::Check(const poly m) const2094 {2095 assume( m != NULL );2096 if( m_compute && (m != NULL))2097 {2098 const ring& R = m_rBaseRing;2099 2100 assume( OPT__TAILREDSYZ && !OPT__HYBRIDNF );2101 2102 for (unsigned int j = m_N; j > 0; j--)2103 if ( (*this)[j] )2104 if(p_GetExp(m, j, R) > 0)2105 return true;2106 2107 return false;2108 2109 } else return true;2110 }2111 2112 2113 2114 2115 2116 // Vi-modeline: vim: filetype=c:syntax:shiftwidth=2:tabstop=8:textwidth=0:expandtab -
Singular/dyn_modules/syzextra/syzextra.h
rcbd574 r9fa5ff 153 153 }; 154 154 155 156 157 158 159 160 161 155 /// Computation attribute storage 162 156 struct SchreyerSyzygyComputationFlags … … 437 431 poly ComputeImage(poly multiplier, const int tail) const; 438 432 439 440 441 433 public: 442 434 /// just for testing via the wrapper below
Note: See TracChangeset
for help on using the changeset viewer.