PageRenderTime 63ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 1ms

/kernel/ideals.cc

https://github.com/hannes14/Singular
C++ | 4429 lines | 3593 code | 286 blank | 550 comment | 823 complexity | 8410beffb9efed74f3dd9a0fe5bb46dc MD5 | raw file
Possible License(s): AGPL-1.0, GPL-3.0, Unlicense

Large files files are truncated, but you can click here to view the full file

  1. /****************************************
  2. * Computer Algebra System SINGULAR *
  3. ****************************************/
  4. /* $Id$ */
  5. /*
  6. * ABSTRACT - all basic methods to manipulate ideals
  7. */
  8. /* includes */
  9. #include <kernel/mod2.h>
  10. #ifndef NDEBUG
  11. # define MYTEST 0
  12. #else /* ifndef NDEBUG */
  13. # define MYTEST 1
  14. #endif /* ifndef NDEBUG */
  15. #include <kernel/options.h>
  16. #include <omalloc/omalloc.h>
  17. #include <kernel/febase.h>
  18. #include <kernel/numbers.h>
  19. #include <kernel/longrat.h>
  20. #include <kernel/polys.h>
  21. #include <kernel/ring.h>
  22. #include <kernel/kstd1.h>
  23. #include <kernel/matpol.h>
  24. #include <kernel/weight.h>
  25. #include <kernel/intvec.h>
  26. #include <kernel/syz.h>
  27. #include <kernel/sparsmat.h>
  28. #include <kernel/ideals.h>
  29. #include <kernel/prCopy.h>
  30. #include <kernel/gring.h>
  31. omBin sip_sideal_bin = omGetSpecBin(sizeof(sip_sideal));
  32. /* #define WITH_OLD_MINOR */
  33. #define pCopy_noCheck(p) pCopy(p)
  34. static poly * idpower;
  35. /*collects the monomials in makemonoms, must be allocated befor*/
  36. static int idpowerpoint;
  37. /*index of the actual monomial in idpower*/
  38. static poly * givenideal;
  39. /*the ideal from which a power is computed*/
  40. /*0 implementation*/
  41. /*2
  42. * initialise an ideal
  43. */
  44. ideal idInit(int idsize, int rank)
  45. {
  46. /*- initialise an ideal -*/
  47. ideal hh = (ideal )omAllocBin(sip_sideal_bin);
  48. hh->nrows = 1;
  49. hh->rank = rank;
  50. IDELEMS(hh) = idsize;
  51. if (idsize>0)
  52. {
  53. hh->m = (poly *)omAlloc0(idsize*sizeof(poly));
  54. }
  55. else
  56. hh->m=NULL;
  57. return hh;
  58. }
  59. #ifdef PDEBUG
  60. // this is only for outputting an ideal within the debugger
  61. void idShow(const ideal id, const ring lmRing, const ring tailRing, const int debugPrint)
  62. {
  63. assume( debugPrint >= 0 );
  64. if( id == NULL )
  65. PrintS("(NULL)");
  66. else
  67. {
  68. Print("Module of rank %ld,real rank %ld and %d generators.\n",
  69. id->rank,idRankFreeModule(id, lmRing, tailRing),IDELEMS(id));
  70. int j = (id->ncols*id->nrows) - 1;
  71. while ((j > 0) && (id->m[j]==NULL)) j--;
  72. for (int i = 0; i <= j; i++)
  73. {
  74. Print("generator %d: ",i); p_DebugPrint(id->m[i], lmRing, tailRing, debugPrint);
  75. }
  76. }
  77. }
  78. #endif
  79. /* index of generator with leading term in ground ring (if any);
  80. otherwise -1 */
  81. int idPosConstant(ideal id)
  82. {
  83. int k;
  84. for (k = IDELEMS(id)-1; k>=0; k--)
  85. {
  86. if (p_LmIsConstantComp(id->m[k], currRing) == TRUE)
  87. return k;
  88. }
  89. return -1;
  90. }
  91. /*2
  92. * initialise the maximal ideal (at 0)
  93. */
  94. ideal idMaxIdeal (void)
  95. {
  96. int l;
  97. ideal hh=NULL;
  98. hh=idInit(pVariables,1);
  99. for (l=0; l<pVariables; l++)
  100. {
  101. hh->m[l] = pOne();
  102. pSetExp(hh->m[l],l+1,1);
  103. pSetm(hh->m[l]);
  104. }
  105. return hh;
  106. }
  107. /*2
  108. * deletes an ideal/matrix
  109. */
  110. void id_Delete (ideal * h, ring r)
  111. {
  112. int j,elems;
  113. if (*h == NULL)
  114. return;
  115. elems=j=(*h)->nrows*(*h)->ncols;
  116. if (j>0)
  117. {
  118. do
  119. {
  120. p_Delete(&((*h)->m[--j]), r);
  121. }
  122. while (j>0);
  123. omFreeSize((ADDRESS)((*h)->m),sizeof(poly)*elems);
  124. }
  125. omFreeBin((ADDRESS)*h, sip_sideal_bin);
  126. *h=NULL;
  127. }
  128. /*2
  129. * Shallowdeletes an ideal/matrix
  130. */
  131. void id_ShallowDelete (ideal *h, ring r)
  132. {
  133. int j,elems;
  134. if (*h == NULL)
  135. return;
  136. elems=j=(*h)->nrows*(*h)->ncols;
  137. if (j>0)
  138. {
  139. do
  140. {
  141. p_ShallowDelete(&((*h)->m[--j]), r);
  142. }
  143. while (j>0);
  144. omFreeSize((ADDRESS)((*h)->m),sizeof(poly)*elems);
  145. }
  146. omFreeBin((ADDRESS)*h, sip_sideal_bin);
  147. *h=NULL;
  148. }
  149. /*2
  150. *gives an ideal the minimal possible size
  151. */
  152. void idSkipZeroes (ideal ide)
  153. {
  154. int k;
  155. int j = -1;
  156. BOOLEAN change=FALSE;
  157. for (k=0; k<IDELEMS(ide); k++)
  158. {
  159. if (ide->m[k] != NULL)
  160. {
  161. j++;
  162. if (change)
  163. {
  164. ide->m[j] = ide->m[k];
  165. }
  166. }
  167. else
  168. {
  169. change=TRUE;
  170. }
  171. }
  172. if (change)
  173. {
  174. if (j == -1)
  175. j = 0;
  176. else
  177. {
  178. for (k=j+1; k<IDELEMS(ide); k++)
  179. ide->m[k] = NULL;
  180. }
  181. pEnlargeSet(&(ide->m),IDELEMS(ide),j+1-IDELEMS(ide));
  182. IDELEMS(ide) = j+1;
  183. }
  184. }
  185. /*2
  186. * copies the first k (>= 1) entries of the given ideal
  187. * and returns these as a new ideal
  188. * (Note that the copied polynomials may be zero.)
  189. */
  190. ideal idCopyFirstK (const ideal ide, const int k)
  191. {
  192. ideal newI = idInit(k, 0);
  193. for (int i = 0; i < k; i++)
  194. newI->m[i] = pCopy(ide->m[i]);
  195. return newI;
  196. }
  197. /*2
  198. * ideal id = (id[i])
  199. * result is leadcoeff(id[i]) = 1
  200. */
  201. void idNorm(ideal id)
  202. {
  203. for (int i=IDELEMS(id)-1; i>=0; i--)
  204. {
  205. if (id->m[i] != NULL)
  206. {
  207. pNorm(id->m[i]);
  208. }
  209. }
  210. }
  211. /*2
  212. * ideal id = (id[i]), c any unit
  213. * if id[i] = c*id[j] then id[j] is deleted for j > i
  214. */
  215. void idDelMultiples(ideal id)
  216. {
  217. int i, j;
  218. int k = IDELEMS(id)-1;
  219. for (i=k; i>=0; i--)
  220. {
  221. if (id->m[i]!=NULL)
  222. {
  223. for (j=k; j>i; j--)
  224. {
  225. if (id->m[j]!=NULL)
  226. {
  227. #ifdef HAVE_RINGS
  228. if (rField_is_Ring(currRing))
  229. {
  230. /* if id[j] = c*id[i] then delete id[j].
  231. In the below cases of a ground field, we
  232. check whether id[i] = c*id[j] and, if so,
  233. delete id[j] for historical reasons (so
  234. that previous output does not change) */
  235. if (pComparePolys(id->m[j], id->m[i])) pDelete(&id->m[j]);
  236. }
  237. else
  238. {
  239. if (pComparePolys(id->m[i], id->m[j])) pDelete(&id->m[j]);
  240. }
  241. #else
  242. if (pComparePolys(id->m[i], id->m[j])) pDelete(&id->m[j]);
  243. #endif
  244. }
  245. }
  246. }
  247. }
  248. }
  249. /*2
  250. * ideal id = (id[i])
  251. * if id[i] = id[j] then id[j] is deleted for j > i
  252. */
  253. void idDelEquals(ideal id)
  254. {
  255. int i, j;
  256. int k = IDELEMS(id)-1;
  257. for (i=k; i>=0; i--)
  258. {
  259. if (id->m[i]!=NULL)
  260. {
  261. for (j=k; j>i; j--)
  262. {
  263. if ((id->m[j]!=NULL)
  264. && (pEqualPolys(id->m[i], id->m[j])))
  265. {
  266. pDelete(&id->m[j]);
  267. }
  268. }
  269. }
  270. }
  271. }
  272. //
  273. // Delete id[j], if Lm(j) == Lm(i) and both LC(j), LC(i) are units and j > i
  274. //
  275. void idDelLmEquals(ideal id)
  276. {
  277. int i, j;
  278. int k = IDELEMS(id)-1;
  279. for (i=k; i>=0; i--)
  280. {
  281. if (id->m[i] != NULL)
  282. {
  283. for (j=k; j>i; j--)
  284. {
  285. if ((id->m[j] != NULL)
  286. && pLmEqual(id->m[i], id->m[j])
  287. #ifdef HAVE_RINGS
  288. && nIsUnit(pGetCoeff(id->m[i])) && nIsUnit(pGetCoeff(id->m[j]))
  289. #endif
  290. )
  291. {
  292. pDelete(&id->m[j]);
  293. }
  294. }
  295. }
  296. }
  297. }
  298. //
  299. // delete id[j], if LT(j) == coeff*mon*LT(i) and vice versa, i.e.,
  300. // delete id[i], if LT(i) == coeff*mon*LT(j)
  301. //
  302. void idDelDiv(ideal id)
  303. {
  304. int i, j;
  305. int k = IDELEMS(id)-1;
  306. for (i=k; i>=0; i--)
  307. {
  308. if (id->m[i] != NULL)
  309. {
  310. for (j=k; j>i; j--)
  311. {
  312. if (id->m[j]!=NULL)
  313. {
  314. #ifdef HAVE_RINGS
  315. if (rField_is_Ring(currRing))
  316. {
  317. if (pDivisibleByRingCase(id->m[i], id->m[j]))
  318. {
  319. pDelete(&id->m[j]);
  320. }
  321. else if (pDivisibleByRingCase(id->m[j], id->m[i]))
  322. {
  323. pDelete(&id->m[i]);
  324. break;
  325. }
  326. }
  327. else
  328. {
  329. #endif
  330. /* the case of a ground field: */
  331. if (pDivisibleBy(id->m[i], id->m[j]))
  332. {
  333. pDelete(&id->m[j]);
  334. }
  335. else if (pDivisibleBy(id->m[j], id->m[i]))
  336. {
  337. pDelete(&id->m[i]);
  338. break;
  339. }
  340. #ifdef HAVE_RINGS
  341. }
  342. #endif
  343. }
  344. }
  345. }
  346. }
  347. }
  348. /*2
  349. *test if the ideal has only constant polynomials
  350. */
  351. BOOLEAN idIsConstant(ideal id)
  352. {
  353. int k;
  354. for (k = IDELEMS(id)-1; k>=0; k--)
  355. {
  356. if (pIsConstantPoly(id->m[k]) == FALSE)
  357. return FALSE;
  358. }
  359. return TRUE;
  360. }
  361. /*2
  362. * copy an ideal
  363. */
  364. ideal id_Copy (ideal h1, const ring r)
  365. {
  366. int i;
  367. ideal h2;
  368. //#ifdef TEST
  369. if (h1 == NULL)
  370. {
  371. h2=idInit(1,1);
  372. }
  373. else
  374. //#endif
  375. {
  376. h2=idInit(IDELEMS(h1),h1->rank);
  377. for (i=IDELEMS(h1)-1; i>=0; i--)
  378. h2->m[i] = p_Copy(h1->m[i],r);
  379. }
  380. return h2;
  381. }
  382. #ifdef PDEBUG
  383. void idDBTest(ideal h1, int level, const char *f,const int l)
  384. {
  385. int i;
  386. if (h1 != NULL)
  387. {
  388. // assume(IDELEMS(h1) > 0); for ideal/module, does not apply to matrix
  389. omCheckAddrSize(h1,sizeof(*h1));
  390. omdebugAddrSize(h1->m,h1->ncols*h1->nrows*sizeof(poly));
  391. /* to be able to test matrices: */
  392. for (i=(h1->ncols*h1->nrows)-1; i>=0; i--)
  393. _p_Test(h1->m[i], currRing, level);
  394. int new_rk=idRankFreeModule(h1);
  395. if(new_rk > h1->rank)
  396. {
  397. dReportError("wrong rank %d (should be %d) in %s:%d\n",
  398. h1->rank, new_rk, f,l);
  399. omPrintAddrInfo(stderr, h1, " for ideal");
  400. h1->rank=new_rk;
  401. }
  402. }
  403. }
  404. #endif
  405. /*3
  406. * for idSort: compare a and b revlex inclusive module comp.
  407. */
  408. static int pComp_RevLex(poly a, poly b,BOOLEAN nolex)
  409. {
  410. if (b==NULL) return 1;
  411. if (a==NULL) return -1;
  412. if (nolex)
  413. {
  414. int r=pLmCmp(a,b);
  415. if (r!=0) return r;
  416. number h=nSub(pGetCoeff(a),pGetCoeff(b));
  417. r = -1+nIsZero(h)+2*nGreaterZero(h); /* -1: <, 0:==, 1: > */
  418. nDelete(&h);
  419. return r;
  420. }
  421. int l=pVariables;
  422. while ((l>0) && (pGetExp(a,l)==pGetExp(b,l))) l--;
  423. if (l==0)
  424. {
  425. if (pGetComp(a)==pGetComp(b))
  426. {
  427. number h=nSub(pGetCoeff(a),pGetCoeff(b));
  428. int r = -1+nIsZero(h)+2*nGreaterZero(h); /* -1: <, 0:==, 1: > */
  429. nDelete(&h);
  430. return r;
  431. }
  432. if (pGetComp(a)>pGetComp(b)) return 1;
  433. }
  434. else if (pGetExp(a,l)>pGetExp(b,l))
  435. return 1;
  436. return -1;
  437. }
  438. /*2
  439. *sorts the ideal w.r.t. the actual ringordering
  440. *uses lex-ordering when nolex = FALSE
  441. */
  442. intvec *idSort(ideal id,BOOLEAN nolex)
  443. {
  444. poly p,q;
  445. intvec * result = new intvec(IDELEMS(id));
  446. int i, j, actpos=0, newpos, l;
  447. int diff, olddiff, lastcomp, newcomp;
  448. BOOLEAN notFound;
  449. for (i=0;i<IDELEMS(id);i++)
  450. {
  451. if (id->m[i]!=NULL)
  452. {
  453. notFound = TRUE;
  454. newpos = actpos / 2;
  455. diff = (actpos+1) / 2;
  456. diff = (diff+1) / 2;
  457. lastcomp = pComp_RevLex(id->m[i],id->m[(*result)[newpos]],nolex);
  458. if (lastcomp<0)
  459. {
  460. newpos -= diff;
  461. }
  462. else if (lastcomp>0)
  463. {
  464. newpos += diff;
  465. }
  466. else
  467. {
  468. notFound = FALSE;
  469. }
  470. //while ((newpos>=0) && (newpos<actpos) && (notFound))
  471. while (notFound && (newpos>=0) && (newpos<actpos))
  472. {
  473. newcomp = pComp_RevLex(id->m[i],id->m[(*result)[newpos]],nolex);
  474. olddiff = diff;
  475. if (diff>1)
  476. {
  477. diff = (diff+1) / 2;
  478. if ((newcomp==1)
  479. && (actpos-newpos>1)
  480. && (diff>1)
  481. && (newpos+diff>=actpos))
  482. {
  483. diff = actpos-newpos-1;
  484. }
  485. else if ((newcomp==-1)
  486. && (diff>1)
  487. && (newpos<diff))
  488. {
  489. diff = newpos;
  490. }
  491. }
  492. if (newcomp<0)
  493. {
  494. if ((olddiff==1) && (lastcomp>0))
  495. notFound = FALSE;
  496. else
  497. newpos -= diff;
  498. }
  499. else if (newcomp>0)
  500. {
  501. if ((olddiff==1) && (lastcomp<0))
  502. {
  503. notFound = FALSE;
  504. newpos++;
  505. }
  506. else
  507. {
  508. newpos += diff;
  509. }
  510. }
  511. else
  512. {
  513. notFound = FALSE;
  514. }
  515. lastcomp = newcomp;
  516. if (diff==0) notFound=FALSE; /*hs*/
  517. }
  518. if (newpos<0) newpos = 0;
  519. if (newpos>actpos) newpos = actpos;
  520. while ((newpos<actpos) && (pComp_RevLex(id->m[i],id->m[(*result)[newpos]],nolex)==0))
  521. newpos++;
  522. for (j=actpos;j>newpos;j--)
  523. {
  524. (*result)[j] = (*result)[j-1];
  525. }
  526. (*result)[newpos] = i;
  527. actpos++;
  528. }
  529. }
  530. for (j=0;j<actpos;j++) (*result)[j]++;
  531. return result;
  532. }
  533. /*2
  534. * concat the lists h1 and h2 without zeros
  535. */
  536. ideal idSimpleAdd (ideal h1,ideal h2)
  537. {
  538. int i,j,r,l;
  539. ideal result;
  540. if (h1==NULL) return idCopy(h2);
  541. if (h2==NULL) return idCopy(h1);
  542. j = IDELEMS(h1)-1;
  543. while ((j >= 0) && (h1->m[j] == NULL)) j--;
  544. i = IDELEMS(h2)-1;
  545. while ((i >= 0) && (h2->m[i] == NULL)) i--;
  546. r = si_max(h1->rank,h2->rank);
  547. if (i+j==(-2))
  548. return idInit(1,r);
  549. else
  550. result=idInit(i+j+2,r);
  551. for (l=j; l>=0; l--)
  552. {
  553. result->m[l] = pCopy(h1->m[l]);
  554. }
  555. r = i+j+1;
  556. for (l=i; l>=0; l--, r--)
  557. {
  558. result->m[r] = pCopy(h2->m[l]);
  559. }
  560. return result;
  561. }
  562. /*2
  563. * insert h2 into h1 (if h2 is not the zero polynomial)
  564. * return TRUE iff h2 was indeed inserted
  565. */
  566. BOOLEAN idInsertPoly (ideal h1, poly h2)
  567. {
  568. if (h2==NULL) return FALSE;
  569. int j = IDELEMS(h1)-1;
  570. while ((j >= 0) && (h1->m[j] == NULL)) j--;
  571. j++;
  572. if (j==IDELEMS(h1))
  573. {
  574. pEnlargeSet(&(h1->m),IDELEMS(h1),16);
  575. IDELEMS(h1)+=16;
  576. }
  577. h1->m[j]=h2;
  578. return TRUE;
  579. }
  580. /*2
  581. * insert h2 into h1 depending on the two boolean parameters:
  582. * - if zeroOk is true, then h2 will also be inserted when it is zero
  583. * - if duplicateOk is true, then h2 will also be inserted when it is
  584. * already present in h1
  585. * return TRUE iff h2 was indeed inserted
  586. */
  587. BOOLEAN idInsertPolyWithTests (ideal h1, const int validEntries,
  588. const poly h2, const bool zeroOk, const bool duplicateOk)
  589. {
  590. if ((!zeroOk) && (h2 == NULL)) return FALSE;
  591. if (!duplicateOk)
  592. {
  593. bool h2FoundInH1 = false;
  594. int i = 0;
  595. while ((i < validEntries) && (!h2FoundInH1))
  596. {
  597. h2FoundInH1 = pEqualPolys(h1->m[i], h2);
  598. i++;
  599. }
  600. if (h2FoundInH1) return FALSE;
  601. }
  602. if (validEntries == IDELEMS(h1))
  603. {
  604. pEnlargeSet(&(h1->m), IDELEMS(h1), 16);
  605. IDELEMS(h1) += 16;
  606. }
  607. h1->m[validEntries] = h2;
  608. return TRUE;
  609. }
  610. /*2
  611. * h1 + h2
  612. */
  613. ideal idAdd (ideal h1,ideal h2)
  614. {
  615. ideal result = idSimpleAdd(h1,h2);
  616. idCompactify(result);
  617. return result;
  618. }
  619. /*2
  620. * h1 * h2
  621. */
  622. ideal idMult (ideal h1,ideal h2)
  623. {
  624. int i,j,k;
  625. ideal hh;
  626. j = IDELEMS(h1);
  627. while ((j > 0) && (h1->m[j-1] == NULL)) j--;
  628. i = IDELEMS(h2);
  629. while ((i > 0) && (h2->m[i-1] == NULL)) i--;
  630. j = j * i;
  631. if (j == 0)
  632. hh = idInit(1,1);
  633. else
  634. hh=idInit(j,1);
  635. if (h1->rank<h2->rank)
  636. hh->rank = h2->rank;
  637. else
  638. hh->rank = h1->rank;
  639. if (j==0) return hh;
  640. k = 0;
  641. for (i=0; i<IDELEMS(h1); i++)
  642. {
  643. if (h1->m[i] != NULL)
  644. {
  645. for (j=0; j<IDELEMS(h2); j++)
  646. {
  647. if (h2->m[j] != NULL)
  648. {
  649. hh->m[k] = ppMult_qq(h1->m[i],h2->m[j]);
  650. k++;
  651. }
  652. }
  653. }
  654. }
  655. {
  656. idCompactify(hh);
  657. return hh;
  658. }
  659. }
  660. /*2
  661. *returns true if h is the zero ideal
  662. */
  663. BOOLEAN idIs0 (ideal h)
  664. {
  665. int i;
  666. if (h == NULL) return TRUE;
  667. i = IDELEMS(h)-1;
  668. while ((i >= 0) && (h->m[i] == NULL))
  669. {
  670. i--;
  671. }
  672. if (i < 0)
  673. return TRUE;
  674. else
  675. return FALSE;
  676. }
  677. /*2
  678. * return the maximal component number found in any polynomial in s
  679. */
  680. long idRankFreeModule (ideal s, ring lmRing, ring tailRing)
  681. {
  682. if (s!=NULL)
  683. {
  684. int j=0;
  685. if (rRing_has_Comp(tailRing) && rRing_has_Comp(lmRing))
  686. {
  687. int l=IDELEMS(s);
  688. poly *p=s->m;
  689. int k;
  690. for (; l != 0; l--)
  691. {
  692. if (*p!=NULL)
  693. {
  694. pp_Test(*p, lmRing, tailRing);
  695. k = p_MaxComp(*p, lmRing, tailRing);
  696. if (k>j) j = k;
  697. }
  698. p++;
  699. }
  700. }
  701. return j;
  702. }
  703. return -1;
  704. }
  705. BOOLEAN idIsModule(ideal id, ring r)
  706. {
  707. if (id != NULL && rRing_has_Comp(r))
  708. {
  709. int j, l = IDELEMS(id);
  710. for (j=0; j<l; j++)
  711. {
  712. if (id->m[j] != NULL && p_GetComp(id->m[j], r) > 0) return TRUE;
  713. }
  714. }
  715. return FALSE;
  716. }
  717. /*2
  718. *returns true if id is homogenous with respect to the aktual weights
  719. */
  720. BOOLEAN idHomIdeal (ideal id, ideal Q)
  721. {
  722. int i;
  723. BOOLEAN b;
  724. if ((id == NULL) || (IDELEMS(id) == 0)) return TRUE;
  725. i = 0;
  726. b = TRUE;
  727. while ((i < IDELEMS(id)) && b)
  728. {
  729. b = pIsHomogeneous(id->m[i]);
  730. i++;
  731. }
  732. if ((b) && (Q!=NULL) && (IDELEMS(Q)>0))
  733. {
  734. i=0;
  735. while ((i < IDELEMS(Q)) && b)
  736. {
  737. b = pIsHomogeneous(Q->m[i]);
  738. i++;
  739. }
  740. }
  741. return b;
  742. }
  743. /*2
  744. *returns a minimized set of generators of h1
  745. */
  746. ideal idMinBase (ideal h1)
  747. {
  748. ideal h2, h3,h4,e;
  749. int j,k;
  750. int i,l,ll;
  751. intvec * wth;
  752. BOOLEAN homog;
  753. homog = idHomModule(h1,currQuotient,&wth);
  754. if (rHasGlobalOrdering_currRing())
  755. {
  756. if(!homog)
  757. {
  758. WarnS("minbase applies only to the local or homogeneous case");
  759. e=idCopy(h1);
  760. return e;
  761. }
  762. else
  763. {
  764. ideal re=kMin_std(h1,currQuotient,(tHomog)homog,&wth,h2,NULL,0,3);
  765. idDelete(&re);
  766. return h2;
  767. }
  768. }
  769. e=idInit(1,h1->rank);
  770. if (idIs0(h1))
  771. {
  772. return e;
  773. }
  774. pEnlargeSet(&(e->m),IDELEMS(e),15);
  775. IDELEMS(e) = 16;
  776. h2 = kStd(h1,currQuotient,isNotHomog,NULL);
  777. h3 = idMaxIdeal();
  778. h4=idMult(h2,h3);
  779. idDelete(&h3);
  780. h3=kStd(h4,currQuotient,isNotHomog,NULL);
  781. k = IDELEMS(h3);
  782. while ((k > 0) && (h3->m[k-1] == NULL)) k--;
  783. j = -1;
  784. l = IDELEMS(h2);
  785. while ((l > 0) && (h2->m[l-1] == NULL)) l--;
  786. for (i=l-1; i>=0; i--)
  787. {
  788. if (h2->m[i] != NULL)
  789. {
  790. ll = 0;
  791. while ((ll < k) && ((h3->m[ll] == NULL)
  792. || !pDivisibleBy(h3->m[ll],h2->m[i])))
  793. ll++;
  794. if (ll >= k)
  795. {
  796. j++;
  797. if (j > IDELEMS(e)-1)
  798. {
  799. pEnlargeSet(&(e->m),IDELEMS(e),16);
  800. IDELEMS(e) += 16;
  801. }
  802. e->m[j] = pCopy(h2->m[i]);
  803. }
  804. }
  805. }
  806. idDelete(&h2);
  807. idDelete(&h3);
  808. idDelete(&h4);
  809. if (currQuotient!=NULL)
  810. {
  811. h3=idInit(1,e->rank);
  812. h2=kNF(h3,currQuotient,e);
  813. idDelete(&h3);
  814. idDelete(&e);
  815. e=h2;
  816. }
  817. idSkipZeroes(e);
  818. return e;
  819. }
  820. /*2
  821. *the minimal index of used variables - 1
  822. */
  823. int pLowVar (poly p)
  824. {
  825. int k,l,lex;
  826. if (p == NULL) return -1;
  827. k = 32000;/*a very large dummy value*/
  828. while (p != NULL)
  829. {
  830. l = 1;
  831. lex = pGetExp(p,l);
  832. while ((l < pVariables) && (lex == 0))
  833. {
  834. l++;
  835. lex = pGetExp(p,l);
  836. }
  837. l--;
  838. if (l < k) k = l;
  839. pIter(p);
  840. }
  841. return k;
  842. }
  843. /*3
  844. *multiplies p with t (!cas) or (t-1)
  845. *the index of t is:1, so we have to shift all variables
  846. *p is NOT in the actual ring, it has no t
  847. */
  848. static poly pMultWithT (poly p,BOOLEAN cas)
  849. {
  850. /*qp is the working pointer in p*/
  851. /*result is the result, qresult is the working pointer*/
  852. /*pp is p in the actual ring(shifted), qpp the working pointer*/
  853. poly result,qp,pp;
  854. poly qresult=NULL;
  855. poly qpp=NULL;
  856. int i,j,lex;
  857. number n;
  858. pp = NULL;
  859. result = NULL;
  860. qp = p;
  861. while (qp != NULL)
  862. {
  863. i = 0;
  864. if (result == NULL)
  865. {/*first monomial*/
  866. result = pInit();
  867. qresult = result;
  868. }
  869. else
  870. {
  871. qresult->next = pInit();
  872. pIter(qresult);
  873. }
  874. for (j=pVariables-1; j>0; j--)
  875. {
  876. lex = pGetExp(qp,j);
  877. pSetExp(qresult,j+1,lex);/*copy all variables*/
  878. }
  879. lex = pGetComp(qp);
  880. pSetComp(qresult,lex);
  881. n=nCopy(pGetCoeff(qp));
  882. pSetCoeff0(qresult,n);
  883. qresult->next = NULL;
  884. pSetm(qresult);
  885. /*qresult is now qp brought into the actual ring*/
  886. if (cas)
  887. { /*case: mult with t-1*/
  888. pSetExp(qresult,1,0);
  889. pSetm(qresult);
  890. if (pp == NULL)
  891. { /*first monomial*/
  892. pp = pCopy(qresult);
  893. qpp = pp;
  894. }
  895. else
  896. {
  897. qpp->next = pCopy(qresult);
  898. pIter(qpp);
  899. }
  900. pGetCoeff(qpp)=nNeg(pGetCoeff(qpp));
  901. /*now qpp contains -1*qp*/
  902. }
  903. pSetExp(qresult,1,1);/*this is mult. by t*/
  904. pSetm(qresult);
  905. pIter(qp);
  906. }
  907. /*
  908. *now p is processed:
  909. *result contains t*p
  910. * if cas: pp contains -1*p (in the new ring)
  911. */
  912. if (cas) qresult->next = pp;
  913. /* else qresult->next = NULL;*/
  914. return result;
  915. }
  916. /*2
  917. * verschiebt die Indizees der Modulerzeugenden um i
  918. */
  919. void pShift (poly * p,int i)
  920. {
  921. poly qp1 = *p,qp2 = *p;/*working pointers*/
  922. int j = pMaxComp(*p),k = pMinComp(*p);
  923. if (j+i < 0) return ;
  924. while (qp1 != NULL)
  925. {
  926. if ((pGetComp(qp1)+i > 0) || ((j == -i) && (j == k)))
  927. {
  928. pAddComp(qp1,i);
  929. pSetmComp(qp1);
  930. qp2 = qp1;
  931. pIter(qp1);
  932. }
  933. else
  934. {
  935. if (qp2 == *p)
  936. {
  937. pIter(*p);
  938. pLmDelete(&qp2);
  939. qp2 = *p;
  940. qp1 = *p;
  941. }
  942. else
  943. {
  944. qp2->next = qp1->next;
  945. if (qp1!=NULL) pLmDelete(&qp1);
  946. qp1 = qp2->next;
  947. }
  948. }
  949. }
  950. }
  951. /*2
  952. *initialized a field with r numbers between beg and end for the
  953. *procedure idNextChoise
  954. */
  955. void idInitChoise (int r,int beg,int end,BOOLEAN *endch,int * choise)
  956. {
  957. /*returns the first choise of r numbers between beg and end*/
  958. int i;
  959. for (i=0; i<r; i++)
  960. {
  961. choise[i] = 0;
  962. }
  963. if (r <= end-beg+1)
  964. for (i=0; i<r; i++)
  965. {
  966. choise[i] = beg+i;
  967. }
  968. if (r > end-beg+1)
  969. *endch = TRUE;
  970. else
  971. *endch = FALSE;
  972. }
  973. /*2
  974. *returns the next choise of r numbers between beg and end
  975. */
  976. void idGetNextChoise (int r,int end,BOOLEAN *endch,int * choise)
  977. {
  978. int i = r-1,j;
  979. while ((i >= 0) && (choise[i] == end))
  980. {
  981. i--;
  982. end--;
  983. }
  984. if (i == -1)
  985. *endch = TRUE;
  986. else
  987. {
  988. choise[i]++;
  989. for (j=i+1; j<r; j++)
  990. {
  991. choise[j] = choise[i]+j-i;
  992. }
  993. *endch = FALSE;
  994. }
  995. }
  996. /*2
  997. *takes the field choise of d numbers between beg and end, cancels the t-th
  998. *entree and searches for the ordinal number of that d-1 dimensional field
  999. * w.r.t. the algorithm of construction
  1000. */
  1001. int idGetNumberOfChoise(int t, int d, int begin, int end, int * choise)
  1002. {
  1003. int * localchoise,i,result=0;
  1004. BOOLEAN b=FALSE;
  1005. if (d<=1) return 1;
  1006. localchoise=(int*)omAlloc((d-1)*sizeof(int));
  1007. idInitChoise(d-1,begin,end,&b,localchoise);
  1008. while (!b)
  1009. {
  1010. result++;
  1011. i = 0;
  1012. while ((i<t) && (localchoise[i]==choise[i])) i++;
  1013. if (i>=t)
  1014. {
  1015. i = t+1;
  1016. while ((i<d) && (localchoise[i-1]==choise[i])) i++;
  1017. if (i>=d)
  1018. {
  1019. omFreeSize((ADDRESS)localchoise,(d-1)*sizeof(int));
  1020. return result;
  1021. }
  1022. }
  1023. idGetNextChoise(d-1,end,&b,localchoise);
  1024. }
  1025. omFreeSize((ADDRESS)localchoise,(d-1)*sizeof(int));
  1026. return 0;
  1027. }
  1028. /*2
  1029. *computes the binomial coefficient
  1030. */
  1031. int binom (int n,int r)
  1032. {
  1033. int i,result;
  1034. if (r==0) return 1;
  1035. if (n-r<r) return binom(n,n-r);
  1036. result = n-r+1;
  1037. for (i=2;i<=r;i++)
  1038. {
  1039. result *= n-r+i;
  1040. if (result<0)
  1041. {
  1042. WarnS("overflow in binomials");
  1043. return 0;
  1044. }
  1045. result /= i;
  1046. }
  1047. return result;
  1048. }
  1049. /*2
  1050. *the free module of rank i
  1051. */
  1052. ideal idFreeModule (int i)
  1053. {
  1054. int j;
  1055. ideal h;
  1056. h=idInit(i,i);
  1057. for (j=0; j<i; j++)
  1058. {
  1059. h->m[j] = pOne();
  1060. pSetComp(h->m[j],j+1);
  1061. pSetmComp(h->m[j]);
  1062. }
  1063. return h;
  1064. }
  1065. ideal idSectWithElim (ideal h1,ideal h2)
  1066. // does not destroy h1,h2
  1067. {
  1068. if (TEST_OPT_PROT) PrintS("intersect by elimination method\n");
  1069. assume(!idIs0(h1));
  1070. assume(!idIs0(h2));
  1071. assume(IDELEMS(h1)<=IDELEMS(h2));
  1072. assume(idRankFreeModule(h1)==0);
  1073. assume(idRankFreeModule(h2)==0);
  1074. // add a new variable:
  1075. int j;
  1076. ring origRing=currRing;
  1077. ring r=rCopy0(origRing);
  1078. r->N++;
  1079. r->block0[0]=1;
  1080. r->block1[0]= r->N;
  1081. omFree(r->order);
  1082. r->order=(int*)omAlloc0(3*sizeof(int*));
  1083. r->order[0]=ringorder_dp;
  1084. r->order[1]=ringorder_C;
  1085. char **names=(char**)omAlloc0(rVar(r) * sizeof(char_ptr));
  1086. for (j=0;j<r->N-1;j++) names[j]=r->names[j];
  1087. names[r->N-1]=omStrDup("@");
  1088. omFree(r->names);
  1089. r->names=names;
  1090. rComplete(r,TRUE);
  1091. // fetch h1, h2
  1092. ideal h;
  1093. h1=idrCopyR(h1,origRing,r);
  1094. h2=idrCopyR(h2,origRing,r);
  1095. // switch to temp. ring r
  1096. rChangeCurrRing(r);
  1097. // create 1-t, t
  1098. poly omt=pOne();
  1099. pSetExp(omt,r->N,1);
  1100. poly t=pCopy(omt);
  1101. pSetm(omt);
  1102. omt=pNeg(omt);
  1103. omt=pAdd(omt,pOne());
  1104. // compute (1-t)*h1
  1105. h1=(ideal)mpMultP((matrix)h1,omt);
  1106. // compute t*h2
  1107. h2=(ideal)mpMultP((matrix)h2,pCopy(t));
  1108. // (1-t)h1 + t*h2
  1109. h=idInit(IDELEMS(h1)+IDELEMS(h2),1);
  1110. int l;
  1111. for (l=IDELEMS(h1)-1; l>=0; l--)
  1112. {
  1113. h->m[l] = h1->m[l]; h1->m[l]=NULL;
  1114. }
  1115. j=IDELEMS(h1);
  1116. for (l=IDELEMS(h2)-1; l>=0; l--)
  1117. {
  1118. h->m[l+j] = h2->m[l]; h2->m[l]=NULL;
  1119. }
  1120. idDelete(&h1);
  1121. idDelete(&h2);
  1122. // eliminate t:
  1123. ideal res=idElimination(h,t);
  1124. // cleanup
  1125. idDelete(&h);
  1126. res=idrMoveR(res,r,origRing);
  1127. rChangeCurrRing(origRing);
  1128. rKill(r);
  1129. return res;
  1130. }
  1131. /*2
  1132. * h3 := h1 intersect h2
  1133. */
  1134. ideal idSect (ideal h1,ideal h2)
  1135. {
  1136. int i,j,k,length;
  1137. int flength = idRankFreeModule(h1);
  1138. int slength = idRankFreeModule(h2);
  1139. int rank=si_min(flength,slength);
  1140. if ((idIs0(h1)) || (idIs0(h2))) return idInit(1,rank);
  1141. ideal first,second,temp,temp1,result;
  1142. poly p,q;
  1143. if (IDELEMS(h1)<IDELEMS(h2))
  1144. {
  1145. first = h1;
  1146. second = h2;
  1147. }
  1148. else
  1149. {
  1150. first = h2;
  1151. second = h1;
  1152. int t=flength; flength=slength; slength=t;
  1153. }
  1154. length = si_max(flength,slength);
  1155. if (length==0)
  1156. {
  1157. if ((currQuotient==NULL)
  1158. && (currRing->OrdSgn==1)
  1159. && (!rIsPluralRing(currRing))
  1160. && ((TEST_V_INTERSECT_ELIM) || (!TEST_V_INTERSECT_SYZ)))
  1161. return idSectWithElim(first,second);
  1162. else length = 1;
  1163. }
  1164. if (TEST_OPT_PROT) PrintS("intersect by syzygy methods\n");
  1165. j = IDELEMS(first);
  1166. ring orig_ring=currRing;
  1167. ring syz_ring=rCurrRingAssure_SyzComp();
  1168. rSetSyzComp(length);
  1169. while ((j>0) && (first->m[j-1]==NULL)) j--;
  1170. temp = idInit(j /*IDELEMS(first)*/+IDELEMS(second),length+j);
  1171. k = 0;
  1172. for (i=0;i<j;i++)
  1173. {
  1174. if (first->m[i]!=NULL)
  1175. {
  1176. if (syz_ring==orig_ring)
  1177. temp->m[k] = pCopy(first->m[i]);
  1178. else
  1179. temp->m[k] = prCopyR(first->m[i], orig_ring);
  1180. q = pOne();
  1181. pSetComp(q,i+1+length);
  1182. pSetmComp(q);
  1183. if (flength==0) pShift(&(temp->m[k]),1);
  1184. p = temp->m[k];
  1185. while (pNext(p)!=NULL) pIter(p);
  1186. pNext(p) = q;
  1187. k++;
  1188. }
  1189. }
  1190. for (i=0;i<IDELEMS(second);i++)
  1191. {
  1192. if (second->m[i]!=NULL)
  1193. {
  1194. if (syz_ring==orig_ring)
  1195. temp->m[k] = pCopy(second->m[i]);
  1196. else
  1197. temp->m[k] = prCopyR(second->m[i], orig_ring);
  1198. if (slength==0) pShift(&(temp->m[k]),1);
  1199. k++;
  1200. }
  1201. }
  1202. intvec *w=NULL;
  1203. temp1 = kStd(temp,currQuotient,testHomog,&w,NULL,length);
  1204. if (w!=NULL) delete w;
  1205. idDelete(&temp);
  1206. if(syz_ring!=orig_ring)
  1207. rChangeCurrRing(orig_ring);
  1208. result = idInit(IDELEMS(temp1),rank);
  1209. j = 0;
  1210. for (i=0;i<IDELEMS(temp1);i++)
  1211. {
  1212. if ((temp1->m[i]!=NULL)
  1213. && (p_GetComp(temp1->m[i],syz_ring)>length))
  1214. {
  1215. if(syz_ring==orig_ring)
  1216. {
  1217. p = temp1->m[i];
  1218. }
  1219. else
  1220. {
  1221. p = prMoveR(temp1->m[i], syz_ring);
  1222. }
  1223. temp1->m[i]=NULL;
  1224. while (p!=NULL)
  1225. {
  1226. q = pNext(p);
  1227. pNext(p) = NULL;
  1228. k = pGetComp(p)-1-length;
  1229. pSetComp(p,0);
  1230. pSetmComp(p);
  1231. /* Warning! multiply only from the left! it's very important for Plural */
  1232. result->m[j] = pAdd(result->m[j],pMult(p,pCopy(first->m[k])));
  1233. p = q;
  1234. }
  1235. j++;
  1236. }
  1237. }
  1238. if(syz_ring!=orig_ring)
  1239. {
  1240. rChangeCurrRing(syz_ring);
  1241. idDelete(&temp1);
  1242. rChangeCurrRing(orig_ring);
  1243. rKill(syz_ring);
  1244. }
  1245. else
  1246. {
  1247. idDelete(&temp1);
  1248. }
  1249. idSkipZeroes(result);
  1250. if (TEST_OPT_RETURN_SB)
  1251. {
  1252. w=NULL;
  1253. temp1=kStd(result,currQuotient,testHomog,&w);
  1254. if (w!=NULL) delete w;
  1255. idDelete(&result);
  1256. idSkipZeroes(temp1);
  1257. return temp1;
  1258. }
  1259. else //temp1=kInterRed(result,currQuotient);
  1260. return result;
  1261. }
  1262. /*2
  1263. * ideal/module intersection for a list of objects
  1264. * given as 'resolvente'
  1265. */
  1266. ideal idMultSect(resolvente arg, int length)
  1267. {
  1268. int i,j=0,k=0,syzComp,l,maxrk=-1,realrki;
  1269. ideal bigmat,tempstd,result;
  1270. poly p;
  1271. int isIdeal=0;
  1272. intvec * w=NULL;
  1273. /* find 0-ideals and max rank -----------------------------------*/
  1274. for (i=0;i<length;i++)
  1275. {
  1276. if (!idIs0(arg[i]))
  1277. {
  1278. realrki=idRankFreeModule(arg[i]);
  1279. k++;
  1280. j += IDELEMS(arg[i]);
  1281. if (realrki>maxrk) maxrk = realrki;
  1282. }
  1283. else
  1284. {
  1285. if (arg[i]!=NULL)
  1286. {
  1287. return idInit(1,arg[i]->rank);
  1288. }
  1289. }
  1290. }
  1291. if (maxrk == 0)
  1292. {
  1293. isIdeal = 1;
  1294. maxrk = 1;
  1295. }
  1296. /* init -----------------------------------------------------------*/
  1297. j += maxrk;
  1298. syzComp = k*maxrk;
  1299. ring orig_ring=currRing;
  1300. ring syz_ring=rCurrRingAssure_SyzComp();
  1301. rSetSyzComp(syzComp);
  1302. bigmat = idInit(j,(k+1)*maxrk);
  1303. /* create unit matrices ------------------------------------------*/
  1304. for (i=0;i<maxrk;i++)
  1305. {
  1306. for (j=0;j<=k;j++)
  1307. {
  1308. p = pOne();
  1309. pSetComp(p,i+1+j*maxrk);
  1310. pSetmComp(p);
  1311. bigmat->m[i] = pAdd(bigmat->m[i],p);
  1312. }
  1313. }
  1314. /* enter given ideals ------------------------------------------*/
  1315. i = maxrk;
  1316. k = 0;
  1317. for (j=0;j<length;j++)
  1318. {
  1319. if (arg[j]!=NULL)
  1320. {
  1321. for (l=0;l<IDELEMS(arg[j]);l++)
  1322. {
  1323. if (arg[j]->m[l]!=NULL)
  1324. {
  1325. if (syz_ring==orig_ring)
  1326. bigmat->m[i] = pCopy(arg[j]->m[l]);
  1327. else
  1328. bigmat->m[i] = prCopyR(arg[j]->m[l], orig_ring);
  1329. pShift(&(bigmat->m[i]),k*maxrk+isIdeal);
  1330. i++;
  1331. }
  1332. }
  1333. k++;
  1334. }
  1335. }
  1336. /* std computation --------------------------------------------*/
  1337. tempstd = kStd(bigmat,currQuotient,testHomog,&w,NULL,syzComp);
  1338. if (w!=NULL) delete w;
  1339. idDelete(&bigmat);
  1340. if(syz_ring!=orig_ring)
  1341. rChangeCurrRing(orig_ring);
  1342. /* interprete result ----------------------------------------*/
  1343. result = idInit(IDELEMS(tempstd),maxrk);
  1344. k = 0;
  1345. for (j=0;j<IDELEMS(tempstd);j++)
  1346. {
  1347. if ((tempstd->m[j]!=NULL) && (p_GetComp(tempstd->m[j],syz_ring)>syzComp))
  1348. {
  1349. if (syz_ring==orig_ring)
  1350. p = pCopy(tempstd->m[j]);
  1351. else
  1352. p = prCopyR(tempstd->m[j], syz_ring);
  1353. pShift(&p,-syzComp-isIdeal);
  1354. result->m[k] = p;
  1355. k++;
  1356. }
  1357. }
  1358. /* clean up ----------------------------------------------------*/
  1359. if(syz_ring!=orig_ring)
  1360. rChangeCurrRing(syz_ring);
  1361. idDelete(&tempstd);
  1362. if(syz_ring!=orig_ring)
  1363. {
  1364. rChangeCurrRing(orig_ring);
  1365. rKill(syz_ring);
  1366. }
  1367. idSkipZeroes(result);
  1368. return result;
  1369. }
  1370. /*2
  1371. *computes syzygies of h1,
  1372. *if quot != NULL it computes in the quotient ring modulo "quot"
  1373. *works always in a ring with ringorder_s
  1374. */
  1375. static ideal idPrepare (ideal h1, tHomog hom, int syzcomp, intvec **w)
  1376. {
  1377. ideal h2, h3;
  1378. int i;
  1379. int j,jj=0,k;
  1380. poly p,q;
  1381. if (idIs0(h1)) return NULL;
  1382. k = idRankFreeModule(h1);
  1383. h2=idCopy(h1);
  1384. i = IDELEMS(h2)-1;
  1385. if (k == 0)
  1386. {
  1387. for (j=0; j<=i; j++) pShift(&(h2->m[j]),1);
  1388. k = 1;
  1389. }
  1390. if (syzcomp<k)
  1391. {
  1392. Warn("syzcomp too low, should be %d instead of %d",k,syzcomp);
  1393. syzcomp = k;
  1394. rSetSyzComp(k);
  1395. }
  1396. h2->rank = syzcomp+i+1;
  1397. //if (hom==testHomog)
  1398. //{
  1399. // if(idHomIdeal(h1,currQuotient))
  1400. // {
  1401. // hom=TRUE;
  1402. // }
  1403. //}
  1404. #if MYTEST
  1405. #ifdef RDEBUG
  1406. Print("Prepare::h2: ");
  1407. idPrint(h2);
  1408. for(j=0;j<IDELEMS(h2);j++) pTest(h2->m[j]);
  1409. #endif
  1410. #endif
  1411. for (j=0; j<=i; j++)
  1412. {
  1413. p = h2->m[j];
  1414. q = pOne();
  1415. pSetComp(q,syzcomp+1+j);
  1416. pSetmComp(q);
  1417. if (p!=NULL)
  1418. {
  1419. while (pNext(p)) pIter(p);
  1420. p->next = q;
  1421. }
  1422. else
  1423. h2->m[j]=q;
  1424. }
  1425. #ifdef PDEBUG
  1426. for(j=0;j<IDELEMS(h2);j++) pTest(h2->m[j]);
  1427. #if MYTEST
  1428. #ifdef RDEBUG
  1429. Print("Prepare::Input: ");
  1430. idPrint(h2);
  1431. Print("Prepare::currQuotient: ");
  1432. idPrint(currQuotient);
  1433. #endif
  1434. #endif
  1435. #endif
  1436. idTest(h2);
  1437. h3 = kStd(h2,currQuotient,hom,w,NULL,syzcomp);
  1438. #if MYTEST
  1439. #ifdef RDEBUG
  1440. Print("Prepare::Output: ");
  1441. idPrint(h3);
  1442. for(j=0;j<IDELEMS(h2);j++) pTest(h3->m[j]);
  1443. #endif
  1444. #endif
  1445. idDelete(&h2);
  1446. return h3;
  1447. }
  1448. /*2
  1449. * compute the syzygies of h1 in R/quot,
  1450. * weights of components are in w
  1451. * if setRegularity, return the regularity in deg
  1452. * do not change h1, w
  1453. */
  1454. ideal idSyzygies (ideal h1, tHomog h,intvec **w, BOOLEAN setSyzComp,
  1455. BOOLEAN setRegularity, int *deg)
  1456. {
  1457. ideal s_h1;
  1458. poly p;
  1459. int j, k, length=0,reg;
  1460. BOOLEAN isMonomial=TRUE;
  1461. int ii, idElemens_h1;
  1462. assume(h1 != NULL);
  1463. idElemens_h1=IDELEMS(h1);
  1464. #ifdef PDEBUG
  1465. for(ii=0;ii<idElemens_h1 /*IDELEMS(h1)*/;ii++) pTest(h1->m[ii]);
  1466. #endif
  1467. if (idIs0(h1))
  1468. {
  1469. ideal result=idFreeModule(idElemens_h1/*IDELEMS(h1)*/);
  1470. int curr_syz_limit=rGetCurrSyzLimit();
  1471. if (curr_syz_limit>0)
  1472. for (ii=0;ii<idElemens_h1/*IDELEMS(h1)*/;ii++)
  1473. {
  1474. if (h1->m[ii]!=NULL)
  1475. pShift(&h1->m[ii],curr_syz_limit);
  1476. }
  1477. return result;
  1478. }
  1479. int slength=(int)idRankFreeModule(h1);
  1480. k=si_max(1,slength /*idRankFreeModule(h1)*/);
  1481. assume(currRing != NULL);
  1482. ring orig_ring=currRing;
  1483. ring syz_ring=rCurrRingAssure_SyzComp();
  1484. if (setSyzComp)
  1485. rSetSyzComp(k);
  1486. if (orig_ring != syz_ring)
  1487. {
  1488. s_h1=idrCopyR_NoSort(h1,orig_ring);
  1489. }
  1490. else
  1491. {
  1492. s_h1 = h1;
  1493. }
  1494. idTest(s_h1);
  1495. ideal s_h3=idPrepare(s_h1,h,k,w); // main (syz) GB computation
  1496. if (s_h3==NULL)
  1497. {
  1498. return idFreeModule( idElemens_h1 /*IDELEMS(h1)*/);
  1499. }
  1500. if (orig_ring != syz_ring)
  1501. {
  1502. idDelete(&s_h1);
  1503. for (j=0; j<IDELEMS(s_h3); j++)
  1504. {
  1505. if (s_h3->m[j] != NULL)
  1506. {
  1507. if (p_MinComp(s_h3->m[j],syz_ring) > k)
  1508. pShift(&s_h3->m[j], -k);
  1509. else
  1510. pDelete(&s_h3->m[j]);
  1511. }
  1512. }
  1513. idSkipZeroes(s_h3);
  1514. s_h3->rank -= k;
  1515. rChangeCurrRing(orig_ring);
  1516. s_h3 = idrMoveR_NoSort(s_h3, syz_ring);
  1517. rKill(syz_ring);
  1518. #ifdef HAVE_PLURAL
  1519. if (rIsPluralRing(currRing))
  1520. {
  1521. idDelMultiples(s_h3);
  1522. idSkipZeroes(s_h3);
  1523. }
  1524. #endif
  1525. idTest(s_h3);
  1526. return s_h3;
  1527. }
  1528. ideal e = idInit(IDELEMS(s_h3), s_h3->rank);
  1529. for (j=IDELEMS(s_h3)-1; j>=0; j--)
  1530. {
  1531. if (s_h3->m[j] != NULL)
  1532. {
  1533. if (p_MinComp(s_h3->m[j],syz_ring) <= k)
  1534. {
  1535. e->m[j] = s_h3->m[j];
  1536. isMonomial=isMonomial && (pNext(s_h3->m[j])==NULL);
  1537. pDelete(&pNext(s_h3->m[j]));
  1538. s_h3->m[j] = NULL;
  1539. }
  1540. }
  1541. }
  1542. idSkipZeroes(s_h3);
  1543. idSkipZeroes(e);
  1544. if ((deg != NULL)
  1545. && (!isMonomial)
  1546. && (!TEST_OPT_NOTREGULARITY)
  1547. && (setRegularity)
  1548. && (h==isHomog)
  1549. && (!rIsPluralRing(currRing))
  1550. )
  1551. {
  1552. ring dp_C_ring = rCurrRingAssure_dp_C();
  1553. if (dp_C_ring != syz_ring)
  1554. e = idrMoveR_NoSort(e, syz_ring);
  1555. resolvente res = sySchreyerResolvente(e,-1,&length,TRUE, TRUE);
  1556. intvec * dummy = syBetti(res,length,&reg, *w);
  1557. *deg = reg+2;
  1558. delete dummy;
  1559. for (j=0;j<length;j++)
  1560. {
  1561. if (res[j]!=NULL) idDelete(&(res[j]));
  1562. }
  1563. omFreeSize((ADDRESS)res,length*sizeof(ideal));
  1564. idDelete(&e);
  1565. if (dp_C_ring != syz_ring)
  1566. {
  1567. rChangeCurrRing(syz_ring);
  1568. rKill(dp_C_ring);
  1569. }
  1570. }
  1571. else
  1572. {
  1573. idDelete(&e);
  1574. }
  1575. idTest(s_h3);
  1576. if (currQuotient != NULL)
  1577. {
  1578. ideal ts_h3=kStd(s_h3,currQuotient,h,w);
  1579. idDelete(&s_h3);
  1580. s_h3 = ts_h3;
  1581. }
  1582. return s_h3;
  1583. }
  1584. /*2
  1585. */
  1586. ideal idXXX (ideal h1, int k)
  1587. {
  1588. ideal s_h1;
  1589. int j;
  1590. intvec *w=NULL;
  1591. assume(currRing != NULL);
  1592. ring orig_ring=currRing;
  1593. ring syz_ring=rCurrRingAssure_SyzComp();
  1594. rSetSyzComp(k);
  1595. if (orig_ring != syz_ring)
  1596. {
  1597. s_h1=idrCopyR_NoSort(h1,orig_ring);
  1598. }
  1599. else
  1600. {
  1601. s_h1 = h1;
  1602. }
  1603. ideal s_h3=kStd(s_h1,NULL,testHomog,&w,NULL,k);
  1604. if (s_h3==NULL)
  1605. {
  1606. return idFreeModule(IDELEMS(h1));
  1607. }
  1608. if (orig_ring != syz_ring)
  1609. {
  1610. idDelete(&s_h1);
  1611. idSkipZeroes(s_h3);
  1612. rChangeCurrRing(orig_ring);
  1613. s_h3 = idrMoveR_NoSort(s_h3, syz_ring);
  1614. rKill(syz_ring);
  1615. idTest(s_h3);
  1616. return s_h3;
  1617. }
  1618. idSkipZeroes(s_h3);
  1619. idTest(s_h3);
  1620. return s_h3;
  1621. }
  1622. /*
  1623. *computes a standard basis for h1 and stores the transformation matrix
  1624. * in ma
  1625. */
  1626. ideal idLiftStd (ideal h1, matrix* ma, tHomog hi, ideal * syz)
  1627. {
  1628. int i, j, k, t, inputIsIdeal=idRankFreeModule(h1);
  1629. poly p=NULL, q, qq;
  1630. intvec *w=NULL;
  1631. idDelete((ideal*)ma);
  1632. BOOLEAN lift3=FALSE;
  1633. if (syz!=NULL) { lift3=TRUE; idDelete(syz); }
  1634. if (idIs0(h1))
  1635. {
  1636. *ma=mpNew(1,0);
  1637. if (lift3)
  1638. {
  1639. *syz=idFreeModule(IDELEMS(h1));
  1640. int curr_syz_limit=rGetCurrSyzLimit();
  1641. if (curr_syz_limit>0)
  1642. for (int ii=0;ii<IDELEMS(h1);ii++)
  1643. {
  1644. if (h1->m[ii]!=NULL)
  1645. pShift(&h1->m[ii],curr_syz_limit);
  1646. }
  1647. }
  1648. return idInit(1,h1->rank);
  1649. }
  1650. BITSET save_verbose=verbose;
  1651. k=si_max(1,(int)idRankFreeModule(h1));
  1652. if ((k==1) && (!lift3)) verbose |=Sy_bit(V_IDLIFT);
  1653. ring orig_ring = currRing;
  1654. ring syz_ring = rCurrRingAssure_SyzComp();
  1655. rSetSyzComp(k);
  1656. ideal s_h1=h1;
  1657. if (orig_ring != syz_ring)
  1658. s_h1 = idrCopyR_NoSort(h1,orig_ring);
  1659. else
  1660. s_h1 = h1;
  1661. ideal s_h3=idPrepare(s_h1,hi,k,&w); // main (syz) GB computation
  1662. ideal s_h2 = idInit(IDELEMS(s_h3), s_h3->rank);
  1663. if (lift3) (*syz)=idInit(IDELEMS(s_h3),IDELEMS(h1));
  1664. if (w!=NULL) delete w;
  1665. i = 0;
  1666. // now sort the result, SB : leave in s_h3
  1667. // T: put in s_h2
  1668. // syz: put in *syz
  1669. for (j=0; j<IDELEMS(s_h3); j++)
  1670. {
  1671. if (s_h3->m[j] != NULL)
  1672. {
  1673. //if (p_MinComp(s_h3->m[j],syz_ring) <= k)
  1674. if (pGetComp(s_h3->m[j]) <= k) // syz_ring == currRing
  1675. {
  1676. i++;
  1677. q = s_h3->m[j];
  1678. while (pNext(q) != NULL)
  1679. {
  1680. if (pGetComp(pNext(q)) > k)
  1681. {
  1682. s_h2->m[j] = pNext(q);
  1683. pNext(q) = NULL;
  1684. }
  1685. else
  1686. {
  1687. pIter(q);
  1688. }
  1689. }
  1690. if (!inputIsIdeal) pShift(&(s_h3->m[j]), -1);
  1691. }
  1692. else
  1693. {
  1694. // we a syzygy here:
  1695. if (lift3)
  1696. {
  1697. pShift(&s_h3->m[j], -k);
  1698. (*syz)->m[j]=s_h3->m[j];
  1699. s_h3->m[j]=NULL;
  1700. }
  1701. else
  1702. pDelete(&(s_h3->m[j]));
  1703. }
  1704. }
  1705. }
  1706. idSkipZeroes(s_h3);
  1707. //extern char * iiStringMatrix(matrix im, int dim,char ch);
  1708. //PrintS("SB: ----------------------------------------\n");
  1709. //PrintS(iiStringMatrix((matrix)s_h3,k,'\n'));
  1710. //PrintLn();
  1711. //PrintS("T: ----------------------------------------\n");
  1712. //PrintS(iiStringMatrix((matrix)s_h2,h1->rank,'\n'));
  1713. //PrintLn();
  1714. if (lift3) idSkipZeroes(*syz);
  1715. j = IDELEMS(s_h1);
  1716. if (syz_ring!=orig_ring)
  1717. {
  1718. idDelete(&s_h1);
  1719. rChangeCurrRing(orig_ring);
  1720. }
  1721. *ma = mpNew(j,i);
  1722. i = 1;
  1723. for (j=0; j<IDELEMS(s_h2); j++)
  1724. {
  1725. if (s_h2->m[j] != NULL)
  1726. {
  1727. q = prMoveR( s_h2->m[j], syz_ring);
  1728. s_h2->m[j] = NULL;
  1729. while (q != NULL)
  1730. {
  1731. p = q;
  1732. pIter(q);
  1733. pNext(p) = NULL;
  1734. t=pGetComp(p);
  1735. pSetComp(p,0);
  1736. pSetmComp(p);
  1737. MATELEM(*ma,t-k,i) = pAdd(MATELEM(*ma,t-k,i),p);
  1738. }
  1739. i++;
  1740. }
  1741. }
  1742. idDelete(&s_h2);
  1743. for (i=0; i<IDELEMS(s_h3); i++)
  1744. {
  1745. s_h3->m[i] = prMoveR_NoSort(s_h3->m[i], syz_ring);
  1746. }
  1747. if (lift3)
  1748. {
  1749. for (i=0; i<IDELEMS(*syz); i++)
  1750. {
  1751. (*syz)->m[i] = prMoveR_NoSort((*syz)->m[i], syz_ring);
  1752. }
  1753. }
  1754. if (syz_ring!=orig_ring) rKill(syz_ring);
  1755. verbose = save_verbose;
  1756. return s_h3;
  1757. }
  1758. static void idPrepareStd(ideal s_temp, int k)
  1759. {
  1760. int j,rk=idRankFreeModule(s_temp);
  1761. poly p,q;
  1762. if (rk == 0)
  1763. {
  1764. for (j=0; j<IDELEMS(s_temp); j++)
  1765. {
  1766. if (s_temp->m[j]!=NULL) pSetCompP(s_temp->m[j],1);
  1767. }
  1768. k = si_max(k,1);
  1769. }
  1770. for (j=0; j<IDELEMS(s_temp); j++)
  1771. {
  1772. if (s_temp->m[j]!=NULL)
  1773. {
  1774. p = s_temp->m[j];
  1775. q = pOne();
  1776. //pGetCoeff(q)=nNeg(pGetCoeff(q)); //set q to -1
  1777. pSetComp(q,k+1+j);
  1778. pSetmComp(q);
  1779. while (pNext(p)) pIter(p);
  1780. pNext(p) = q;
  1781. }
  1782. }
  1783. }
  1784. /*2
  1785. *computes a representation of the generators of submod with respect to those
  1786. * of mod
  1787. */
  1788. ideal idLift(ideal mod, ideal submod,ideal *rest, BOOLEAN goodShape,
  1789. BOOLEAN isSB, BOOLEAN divide, matrix *unit)
  1790. {
  1791. int lsmod =idRankFreeModule(submod), i, j, k;
  1792. int comps_to_add=0;
  1793. poly p;
  1794. if (idIs0(submod))
  1795. {
  1796. if (unit!=NULL)
  1797. {
  1798. *unit=mpNew(1,1);
  1799. MATELEM(*unit,1,1)=pOne();
  1800. }
  1801. if (rest!=NULL)
  1802. {
  1803. *rest=idInit(1,mod->rank);
  1804. }
  1805. return idInit(1,mod->rank);
  1806. }
  1807. if (idIs0(mod)) /* and not idIs0(submod) */
  1808. {
  1809. WerrorS("2nd module does not lie in the first");
  1810. #if 0
  1811. if (unit!=NULL)
  1812. {
  1813. i=IDELEMS(submod);
  1814. *unit=mpNew(i,i);
  1815. for (j=i;j>0;j--)
  1816. {
  1817. MATELEM(*unit,j,j)=pOne();
  1818. }
  1819. }
  1820. if (rest!=NULL)
  1821. {
  1822. *rest=idCopy(submod);
  1823. }
  1824. return idInit(1,mod->rank);
  1825. #endif
  1826. return idInit(IDELEMS(submod),submod->rank);
  1827. }
  1828. if (unit!=NULL)
  1829. {
  1830. comps_to_add = IDELEMS(submod);
  1831. while ((comps_to_add>0) && (submod->m[comps_to_add-1]==NULL))
  1832. comps_to_add--;
  1833. }
  1834. k=si_max(idRankFreeModule(mod),idRankFreeModule(submod));
  1835. if ((k!=0) && (lsmod==0)) lsmod=1;
  1836. k=si_max(k,(int)mod->rank);
  1837. if (k<submod->rank) { WarnS("rk(submod) > rk(mod) ?");k=submod->rank; }
  1838. ring orig_ring=currRing;
  1839. ring syz_ring=rCurrRingAssure_SyzComp();
  1840. rSetSyzComp(k);
  1841. ideal s_mod, s_temp;
  1842. if (orig_ring != syz_ring)
  1843. {
  1844. s_mod = idrCopyR_NoSort(mod,orig_ring);
  1845. s_temp = idrCopyR_NoSort(submod,orig_ring);
  1846. }
  1847. else
  1848. {
  1849. s_mod = mod;
  1850. s_temp = idCopy(submod);
  1851. }
  1852. ideal s_h3;
  1853. if (isSB)
  1854. {
  1855. s_h3 = idCopy(s_mod);
  1856. idPrepareStd(s_h3, k+comps_to_add);
  1857. }
  1858. else
  1859. {
  1860. s_h3 = idPrepare(s_mod,(tHomog)FALSE,k+comps_to_add,NULL);
  1861. }
  1862. if (!goodShape)
  1863. {
  1864. for (j=0;j<IDELEMS(s_h3);j++)
  1865. {
  1866. if ((s_h3->m[j] != NULL) && (pMinComp(s_h3->m[j]) > k))
  1867. pDelete(&(s_h3->m[j]));
  1868. }
  1869. }
  1870. idSkipZeroes(s_h3);
  1871. if (lsmod==0)
  1872. {
  1873. for (j=IDELEMS(s_temp);j>0;j--)
  1874. {
  1875. if (s_temp->m[j-1]!=NULL)
  1876. pShift(&(s_temp->m[j-1]),1);
  1877. }
  1878. }
  1879. if (unit!=NULL)
  1880. {
  1881. for(j = 0;j<comps_to_add;j++)
  1882. {
  1883. p = s_temp->m[j];
  1884. if (p!=NULL)
  1885. {
  1886. while (pNext(p)!=NULL) pIter(p);
  1887. pNext(p) = pOne();
  1888. pIter(p);
  1889. pSetComp(p,1+j+k);
  1890. pSetmComp(p);
  1891. p = pNeg(p);
  1892. }
  1893. }
  1894. }
  1895. ideal s_result = kNF(s_h3,currQuotient,s_temp,k);
  1896. s_result->rank = s_h3->rank;
  1897. ideal s_rest = idInit(IDELEMS(s_result),k);
  1898. idDelete(&s_h3);
  1899. idDelete(&s_temp);
  1900. for (j=0;j<IDELEMS(s_result);j++)
  1901. {
  1902. if (s_result->m[j]!=NULL)
  1903. {
  1904. if (pGetComp(s_result->m[j])<=k)
  1905. {
  1906. if (!divide)
  1907. {
  1908. if (isSB)
  1909. {
  1910. WarnS("first module not a standardbasis\n"
  1911. "// ** or second not a proper submodule");
  1912. }
  1913. else
  1914. WerrorS("2nd module does not lie in the first");
  1915. idDelete(&s_result);
  1916. idDelete(&s_rest);
  1917. s_result=idInit(IDELEMS(submod),submod->rank);
  1918. break;
  1919. }
  1920. else
  1921. {
  1922. p = s_rest->m[j] = s_result->m[j];
  1923. while ((pNext(p)!=NULL) && (pGetComp(pNext(p))<=k)) pIter(p);
  1924. s_result->m[j] = pNext(p);
  1925. pNext(p) = NULL;
  1926. }
  1927. }
  1928. pShift(&(s_result->m[j]),-k);
  1929. pNeg(s_result->m[j]);
  1930. }
  1931. }
  1932. if ((lsmod==0) && (!idIs0(s_rest)))
  1933. {
  1934. for (j=IDELEMS(s_rest);j>0;j--)
  1935. {
  1936. if (s_rest->m[j-1]!=NULL)
  1937. {
  1938. pShift(&(s_rest->m[j-1]),-1);
  1939. s_rest->m[j-1] = s_rest->m[j-1];
  1940. }
  1941. }
  1942. }
  1943. if(syz_ring!=orig_ring)
  1944. {
  1945. idDelete(&s_mod);
  1946. rChangeCurrRing(orig_ring);
  1947. s_result = idrMoveR_NoSort(s_result, syz_ring);
  1948. s_rest = idrMoveR_NoSort(s_rest, syz_ring);
  1949. rKill(syz_ring);
  1950. }
  1951. if (rest!=NULL)
  1952. *rest = s_rest;
  1953. else
  1954. idDelete(&s_rest);
  1955. //idPrint(s_result);
  1956. if (unit!=NULL)
  1957. {
  1958. *unit=mpNew(comps_to_add,comps_to_add);
  1959. int i;
  1960. for(i=0;i<IDELEMS(s_result);i++)
  1961. {
  1962. poly p=s_result->m[i];
  1963. poly q=NULL;
  1964. while(p!=NULL)
  1965. {
  1966. if(pGetComp(p)<=comps_to_add)
  1967. {
  1968. pSetComp(p,0);
  1969. if (q!=NULL)
  1970. {
  1971. pNext(q)=pNext(p);
  1972. }
  1973. else
  1974. {
  1975. pIter(s_result->m[i]);
  1976. }
  1977. pNext(p)=NULL;
  1978. MATELEM(*unit,i+1,i+1)=pAdd(MATELEM(*unit,i+1,i+1),p);
  1979. if(q!=NULL) p=pNext(q);
  1980. else p=s_result->m[i];
  1981. }
  1982. else
  1983. {
  1984. q=p;
  1985. pIter(p);
  1986. }
  1987. }
  1988. pShift(&s_result->m[i],-comps_to_add);
  1989. }
  1990. }
  1991. return s_result;
  1992. }
  1993. /*2
  1994. *computes division of P by Q with remainder up to (w-weighted) degree n
  1995. *P, Q, and w are not changed
  1996. */
  1997. void idLiftW(ideal P,ideal Q,int n,matrix &T, ideal &R,short *w)
  1998. {
  1999. long N=0;
  2000. int i;
  2001. for(i=IDELEMS(Q)-1;i>=0;i--)
  2002. if(w==NULL)
  2003. N=si_max(N,pDeg(Q->m[i]));
  2004. else
  2005. N=si_max(N,pDegW(Q->m[i],w));
  2006. N+=n;
  2007. T=mpNew(IDELEMS(Q),IDELEMS(P));
  2008. R=idInit(IDELEMS(P),P->rank);
  2009. for(i=IDELEMS(P)-1;i>=0;i--)
  2010. {
  2011. poly p;
  2012. if(w==NULL)
  2013. p=ppJet(P->m[i],N);
  2014. else
  2015. p=ppJetW(P->m[i],N,w);
  2016. int j=IDELEMS(Q)-1;
  2017. while(p!=NULL)
  2018. {
  2019. if(pDivisibleBy(Q->m[j],p))
  2020. {
  2021. poly p0=pDivideM(pHead(p),pHead(Q->m[j]));
  2022. if(w==NULL)
  2023. p=pJet(pSub(p,ppMult_mm(Q->m[j],p0)),N);
  2024. else
  2025. p=pJetW(pSub(p,ppMult_mm(Q->m[j],p0)),N,w);
  2026. pNormalize(p);
  2027. if((w==NULL)&&(pDeg(p0)>n)||(w!=NULL)&&(pDegW(p0,w)>n))
  2028. pDelete(&p0);
  2029. else
  2030. MATELEM(T,j+1,i+1)=pAdd(MATELEM(T,j+1,i+1),p0);
  2031. j=IDELEMS(Q)-1;
  2032. }
  2033. else
  2034. {
  2035. if(j==0)
  2036. {
  2037. poly p0=p;
  2038. pIter(p);
  2039. pNext(p0)=NULL;
  2040. if(((w==NULL)&&(pDeg(p0)>n))
  2041. ||((w!=NULL)&&(pDegW(p0,w)>n)))
  2042. pDelete(&p0);
  2043. else
  2044. R->m[i]=pAdd(R->m[i],p0);
  2045. j=IDELEMS(Q)-1;
  2046. }
  2047. else
  2048. j--;
  2049. }
  2050. }
  2051. }
  2052. }
  2053. /*2
  2054. *computes the quotient of h1,h2 : internal routine for idQuot
  2055. *BEWARE: the returned ideals may contain incorrectly ordered polys !
  2056. *
  2057. */
  2058. static ideal idInitializeQuot (ideal h1, ideal h2, BOOLEAN h1IsStb,
  2059. BOOLEAN *addOnlyOne, int *kkmax)
  2060. {
  2061. ideal temph1;
  2062. poly p,q = NULL;
  2063. int i,l,ll,k,kkk,kmax;
  2064. int j = 0;
  2065. int k1 = idRankFreeModule(h1);
  2066. int k2 = idRankFreeModule(h2);
  2067. tHomog hom=isNotHomog;
  2068. k=si_max(k1,k2);
  2069. if (k==0)
  2070. k = 1;
  2071. if ((k2==0) && (k>1)) *addOnlyOne = FALSE;
  2072. intvec * weights;
  2073. hom = (tHomog)idHomModule(h1,currQuotient,&weights);
  2074. if (/**addOnlyOne &&*/ (!h1IsStb))
  2075. temph1 = kStd(h1,currQuotient,hom,&weights,NULL);
  2076. else
  2077. temph1 = idCopy(h1);
  2078. if (weights!=NULL) delete weights;
  2079. idTest(temph1);
  2080. /*--- making a single vector from h2 ---------------------*/
  2081. for (i=0; i<IDELEMS(h2); i++)
  2082. {
  2083. if (h2->m[i] != NULL)
  2084. {
  2085. p = pCopy(h2->m[i]);
  2086. if (k2 == 0)
  2087. pShift(&p,j*k+1);
  2088. else
  2089. pShift(&p,j*k);
  2090. q = pAdd(q,p);
  2091. j++;
  2092. }
  2093. }
  2094. *kkmax = kmax = j*k+1;
  2095. /*--- adding a monomial for the result (syzygy) ----------*/
  2096. p = q;
  2097. while (pNext(p)!=NULL) pIter(p);
  2098. pNext(p) = pOne();
  2099. pIter(p);
  2100. pSetComp(p,kmax);
  2101. pSetmComp(p);
  2102. /*--- constructing the big matrix ------------------------*/
  2103. ideal h4 = idInit(16,kmax+k-1);
  2104. h4->m[0] = q;
  2105. if (k2 == 0)
  2106. {
  2107. if (k > IDELEMS(h4))
  2108. {
  2109. pEnlargeSet(&(h4->m),IDELEMS(h4),k-IDELEMS(h4));
  2110. IDELEMS(h4) = k;
  2111. }
  2112. for (i=1; i<k; i++)
  2113. {
  2114. if (h4->m[i-1]!=NULL)
  2115. {
  2116. p = pCopy_noCheck(h4->m[i-1]);
  2117. pShift(&p,1);
  2118. h4->m[i] = p;
  2119. }
  2120. }
  2121. }
  2122. idSkipZeroes(h4);
  2123. kkk = IDELEMS(h4);
  2124. i = IDELEMS(temph1);
  2125. for (l=0; l<i; l++)
  2126. {
  2127. if(temph1->m[l]!=NULL)
  2128. {
  2129. for (ll=0; ll<j; ll++)
  2130. {
  2131. p = pCopy(temph1->m[l]);
  2132. if (k1 == 0)
  2133. pShift(&p,ll*k+1);
  2134. else
  2135. pShift(&p,ll*k);
  2136. if (kkk >= IDELEMS(h4))
  2137. {
  2138. pEnlargeSet(&(h4->m),IDELEMS(h4),16);
  2139. IDELEMS(h4) += 16;
  2140. }
  2141. h4->m[kkk] = p;
  2142. kkk++;
  2143. }
  2144. }
  2145. }
  2146. /*--- if h2 goes in as single vector - the h1-part is just SB ---*/
  2147. if (*addOnlyOne)
  2148. {
  2149. idSkipZeroes(h4);
  2150. p = h4->m[0];
  2151. for (i=0;i<IDELEMS(h4)-1;i++)
  2152. {
  2153. h4->m[i] = h4->m[i+1];
  2154. }
  2155. h4->m[IDELEMS(h4)-1] = p;
  2156. test |= Sy_bit(OPT_SB_1);
  2157. }
  2158. idDelete(&temph1);
  2159. return h4;
  2160. }
  2161. /*2
  2162. *computes the quotient of h1,h2
  2163. */
  2164. ideal idQuot (ideal h1, ideal h2, BOOLEAN h1IsStb, BOOLEAN resultIsIdeal)
  2165. {
  2166. // first check for special case h1:(0)
  2167. if (idIs0(h2))
  2168. {
  2169. ideal res;
  2170. if (resultIsIdeal)
  2171. {
  2172. res = idInit(1,1);
  2173. res->m[0] = pOne();
  2174. }
  2175. else
  2176. res = idFreeModule(h1->rank);
  2177. return res;
  2178. }
  2179. BITSET old_test=test;
  2180. int i,l,ll,k,kkk,kmax;
  2181. BOOLEAN addOnlyOne=TRUE;
  2182. tHomog hom=isNotHomog;
  2183. intvec * weights1;
  2184. ideal s_h4 = idInitializeQuot (h1,h2,h1IsStb,&addOnlyOne,&kmax);
  2185. hom = (tHomog)idHomModule(s_h4,currQuotient,&weights1);
  2186. ring orig_ring=currRing;
  2187. ring syz_ring=rCurrRingAssure_SyzComp();
  2188. rSetSyzComp(kmax-1);
  2189. if (orig_ring!=syz_ring)
  2190. // s_h4 = idrMoveR_NoSort(s_h4,orig_ring);
  2191. s_h4 = idrMoveR(s_h4,orig_ring);
  2192. idTest(s_h4);
  2193. #if 0
  2194. void ipPrint_MA0(matrix m, const char *name);
  2195. matrix m=idModule2Matrix(idCopy(s_h4));
  2196. PrintS("start:\n");
  2197. ipPrint_MA0(m,"Q");
  2198. idDelete((ideal *)&m);
  2199. PrintS("last elem:");wrp(s_h4->m[IDELEMS(s_h4)-1]);PrintLn();
  2200. #endif
  2201. ideal s_h3;
  2202. if (addOnlyOne)
  2203. {
  2204. s_h3 = kStd(s_h4,currQuotient,hom,&weights1,NULL,0/*kmax-1*/,IDELEMS(s_h4)-1);
  2205. }
  2206. else
  2207. {
  2208. s_h3 = kStd(s_h4,currQuotient,hom,&weights1,NULL,kmax-1);
  2209. }
  2210. test = old_test;
  2211. #if 0
  2212. // only together with the above debug stuff
  2213. idSkipZeroes(s_h3);
  2214. m=idModule2Matrix(idCopy(s_h3));
  2215. Print("result, kmax=%d:\n",kmax);
  2216. ipPrint_MA0(m,"S");
  2217. idDelete((ideal *)&m);
  2218. #endif
  2219. idTest(s_h3);
  2220. if (weights1!=NULL) delete weights1;
  2221. idDelete(&s_h4);
  2222. for (i=0;i<IDELEMS(s_h3);i++)
  2223. {
  2224. if ((s_h3->m[i]!=NULL) && (pGetComp(s_h3->m[i])>=kmax))
  2225. {
  2226. if (resultIsIdeal)
  2227. pShift(&s_h3->m[i],-kmax);
  2228. else
  2229. pShift(&s_h3->m[i],-kmax+1);
  2230. }
  2231. else
  2232. pDelete(&s_h3->m[i]);
  2233. }
  2234. if (resultIsIdeal)
  2235. s_h3->rank = 1;
  2236. else
  2237. s_h3->rank = h1->rank;
  2238. if(syz_ring!=orig_ring)
  2239. {
  2240. rChangeCurrRing(orig_ring);
  2241. s_h3 = idrMoveR_NoSort(s_h3, syz_ring);
  2242. rKill(syz_ring);
  2243. }
  2244. idSkipZeroes(s_h3);
  2245. idTest(s_h3);
  2246. return s_h3;
  2247. }
  2248. /*2
  2249. *computes recursively all monomials of a certain degree
  2250. *in every step the actvar-th entry in the exponential
  2251. *vector is incremented and the other variables are
  2252. *computed by recursive calls of makemonoms
  2253. *if the last variable is reached, the difference to the
  2254. *degree is computed directly
  2255. *vars is the number variables
  2256. *actvar is the actual variable to handle
  2257. *deg is the degree of the monomials to compute
  2258. *monomdeg is the actual degree of the monomial in consideration
  2259. */
  2260. static void makemonoms(int vars,int actvar,int deg,int monomdeg)
  2261. {
  2262. poly p;
  2263. int i=0;
  2264. if ((idpowerpoint == 0) && (actvar ==1))
  2265. {
  2266. idpower[idpowerpoint] = pOne();
  2267. monomdeg = 0;
  2268. }
  2269. while (i<=deg)
  2270. {
  2271. if (deg == monomdeg)
  2272. {
  2273. pSetm(idpower[idpowerpoint]);

Large files files are truncated, but you can click here to view the full file