source: git/kernel/syz.cc @ 57bfa2

spielwiese
Last change on this file since 57bfa2 was 57bfa2, checked in by Motsak Oleksandr <motsak@…>, 15 years ago
*motsak: better extension-testing switches git-svn-id: file:///usr/local/Singular/svn/trunk@11698 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 29.6 KB
RevLine 
[35aab3]1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
[57bfa2]4/* $Id: syz.cc,v 1.21 2009-04-14 12:40:46 motsak Exp $ */
[35aab3]5
6/*
7* ABSTRACT: resolutions
8*/
9
10
11#include "mod2.h"
12#include "structs.h"
13#include "omalloc.h"
14#include "polys.h"
15#include "febase.h"
16#include "kstd1.h"
17#include "kutil.h"
18#include "stairc.h"
19#include "intvec.h"
20#include "numbers.h"
21#include "ideals.h"
22#include "intvec.h"
23#include "ring.h"
24#include "syz.h"
25#include "prCopy.h"
26
[90adb6a]27#ifdef HAVE_PLURAL
28#include "sca.h"
29#endif // HAVE_PLURAL
[35aab3]30
31void syDeleteRes(resolvente * res,int length)
32{
33  for (int i=0;i<length;i++)
34  {
35    if (!idIs0((*res)[i]))
36      idDelete(&((*res)[i]));
37  }
38  omFreeSize((ADDRESS)res,length*sizeof(ideal));
39  *res = NULL;
40}
41
42static intvec * syPrepareModComp(ideal arg,intvec ** w)
43{
44  intvec *w1 = NULL;
45  int i;
46  BOOLEAN isIdeal=FALSE;
47
48  if ((w==NULL) || (*w==NULL)) return w1;
49  int maxxx = (*w)->length();
50  if (maxxx==1)
51  {
52    maxxx = 2;
53    isIdeal = TRUE;
54  }
55  w1 = new intvec(maxxx+IDELEMS(arg));
56  if (!isIdeal)
57  {
58    for (i=0;i<maxxx;i++)
59    {
60      (*w1)[i] = (**w)[i];
61    }
62  }
63  for (i=maxxx;i<maxxx+IDELEMS(arg);i++)
64  {
65    if (arg->m[i-maxxx]!=NULL)
66    {
[b130fb]67      (*w1)[i] = pFDeg(arg->m[i-maxxx],currRing);
[35aab3]68      if (pGetComp(arg->m[i-maxxx])!=0)
69      {
70        (*w1)[i]+=(**w)[pGetComp(arg->m[i-maxxx])-1];
71      }
72    }
73  }
74  delete (*w);
75  *w = new intvec(IDELEMS(arg)+1);
76  for (i=0;i<IDELEMS(arg);i++)
77  {
78     (**w)[i+1] = (*w1)[i+maxxx];
79  }
80  return w1;
81}
82
83static void syDeleteAbove(ideal up, int k)
84{
85  if (up!=NULL)
86  {
87    for (int i=0;i<IDELEMS(up);i++)
88    {
89      if (up->m[i]!=NULL)
90        pDeleteComp(&(up->m[i]),k+1);
91    }
92  }
93}
94
95/*2
96*minimizes the module mod and cancel superfluous syzygies
97*from syz
98*/
99static void syMinStep(ideal mod,ideal syz,BOOLEAN final=FALSE,ideal up=NULL,
100                      tHomog h=isNotHomog)
101{
102  ideal deg0=NULL;
103  poly Unit1,Unit2,actWith;
104  int len,i,j,ModComp,m,k,l;
105  BOOLEAN searchUnit,existsUnit;
106
107  if (TEST_OPT_PROT) PrintS("m");
108  if ((final) && (h==isHomog))
109  /*minim is TRUE, we are in the module: maxlength, maxlength <>0*/
110  {
111    deg0=idJet(syz,0);
112    idSkipZeroes(deg0);
113    syz=deg0;
114  }
115/*--cancels empty entees and their related components above--*/
116  j = IDELEMS(syz);
117  while ((j>0) && (!syz->m[j-1])) j--;
118  k = 0;
119  while (k<j)
120  {
121    if (syz->m[k]!=NULL)
122      k++;
123    else
124    {
125      if (TEST_OPT_PROT) PrintS(".");
126      for (l=k;l<j-1;l++) syz->m[l] = syz->m[l+1];
127      syz->m[j-1] = NULL;
128      syDeleteAbove(up,k);
129      j--;
130    }
131  }
132/*--searches for syzygies coming from superfluous elements
133* in the module below--*/
134  searchUnit = TRUE;
135  int curr_syz_limit = rGetCurrSyzLimit();
136  while (searchUnit)
137  {
138    i=0;
139    j=IDELEMS(syz);
140    while ((j>0) && (syz->m[j-1]==NULL)) j--;
141    existsUnit = FALSE;
[753f9d2]142    if (rHasGlobalOrdering_currRing())
[35aab3]143    {
144      while ((i<j) && (!existsUnit))
145      {
146        existsUnit = pVectorHasUnitB(syz->m[i],&ModComp);
147        i++;
148      }
149    }
150    else
151    {
152      int I=0;
153      l = 0;
154      len=0;
155      for (i=0;i<IDELEMS(syz);i++)
156      {
157        if (syz->m[i]!=NULL)
158        {
159          pVectorHasUnit(syz->m[i],&m, &l);
160          if ((len==0) ||((l>0) && (l<len)))
161          {
162            len = l;
163            ModComp = m;
164            I = i;
165          }
166        }
167      }
168//Print("Laenge ist: %d\n",len);
169      if (len>0) existsUnit = TRUE;
170      i = I+1;
171    }
172    if (existsUnit)
173    {
174      i--;
175//--takes out the founded syzygy--
176      if (TEST_OPT_PROT) PrintS("f");
177      actWith = syz->m[i];
178      if (!rField_has_simple_inverse()) pCleardenom(actWith);
179//Print("actWith: ");pWrite(actWith);
180      syz->m[i] = NULL;
181      for (k=i;k<j-1;k++)  syz->m[k] = syz->m[k+1];
182      syz->m[j-1] = NULL;
183      syDeleteAbove(up,i);
184      j--;
185//--makes Gauss alg. for the column ModComp--
186      Unit1 = pTakeOutComp(&(actWith), ModComp);
187//PrintS("actWith now: ");pWrite(actWith);
188//Print("Unit1: ");pWrite(Unit1);
189      k=0;
190//Print("j= %d",j);
191      while (k<j)
192      {
193        if (syz->m[k]!=NULL)
194        {
195          Unit2 = pTakeOutComp(&(syz->m[k]), ModComp);
196//Print("element %d: ",k);pWrite(syz->m[k]);
197//PrintS("Unit2: ");pWrite(Unit2);
[8049ad]198          syz->m[k] = pMult(pCopy(Unit1),syz->m[k]);
[35aab3]199          syz->m[k] = pSub(syz->m[k],
200            pMult(Unit2,pCopy(actWith)));
201          if (syz->m[k]==NULL)
202          {
203            for (l=k;l<j-1;l++)
204              syz->m[l] = syz->m[l+1];
205            syz->m[j-1] = NULL;
206            j--;
207            syDeleteAbove(up,k);
208            k--;
209          }
210        }
211        k++;
212      }
213      pDelete(&actWith);
214      pDelete(&Unit1);
215//--deletes superfluous elements from the module below---
216      pDelete(&(mod->m[ModComp-1 - curr_syz_limit]));
217      for (k=ModComp-1 - curr_syz_limit;k<IDELEMS(mod)-1;k++)
218        mod->m[k] = mod->m[k+1];
219      mod->m[IDELEMS(mod)-1] = NULL;
220    }
221    else
222      searchUnit = FALSE;
223  }
224  if (TEST_OPT_PROT) PrintLn();
225  idSkipZeroes(mod);
226  idSkipZeroes(syz);
227  if (deg0!=NULL)
228    idDelete(&deg0);
229}
230
231/*2
232* make Gauss with the element elnum in the module component ModComp
233* for the generators from - till
234*/
235void syGaussForOne(ideal syz, int elnum, int ModComp,int from,int till)
236{
237  int k,j,i,lu;
238  poly unit1,unit2;
239  poly actWith=syz->m[elnum];
240
241  if (from<0) from = 0;
242  if ((till<=0) || (till>IDELEMS(syz))) till = IDELEMS(syz);
243  syz->m[elnum] = NULL;
244  if (!rField_has_simple_inverse()) pCleardenom(actWith);
245/*--makes Gauss alg. for the column ModComp--*/
246  pTakeOutComp(&(actWith), ModComp, &unit1, &lu);
247  while (from<till)
248  {
[3705d5c]249    poly tmp=syz->m[from];
250    if (/*syz->m[from]*/ tmp!=NULL)
[35aab3]251    {
[3705d5c]252      pTakeOutComp(&(tmp), ModComp, &unit2, &lu);
253      tmp = pMult(pCopy(unit1),tmp);
254      syz->m[from] = pSub(tmp,
[b6201e]255        pMult(unit2,pCopy(actWith)));
[35aab3]256    }
257    from++;
258  }
259  pDelete(&actWith);
260  pDelete(&unit1);
261}
262static void syDeleteAbove1(ideal up, int k)
263{
264  poly p,pp;
265  if (up!=NULL)
266  {
267    for (int i=0;i<IDELEMS(up);i++)
268    {
269      p = up->m[i];
270      while ((p!=NULL) && (pGetComp(p)==k))
271      {
[fe3266]272        /*
[35aab3]273        pp = pNext(p);
274        pNext(p) = NULL;
275        pDelete(&p);
276        p = pp;
[fe3266]277        */
278        pLmDelete(&p);
[35aab3]279      }
280      up->m[i] = p;
281      if (p!=NULL)
282      {
283        while (pNext(p)!=NULL)
284        {
285          if (pGetComp(pNext(p))==k)
286          {
[fe3266]287            /*
[35aab3]288            pp = pNext(pNext(p));
289            pNext(pNext(p)) = NULL;
290            pDelete(&pNext(p));
291            pNext(p) = pp;
[fe3266]292            */
293            pLmDelete(&pNext(p));
[35aab3]294          }
295          else
296            pIter(p);
297        }
298      }
299    }
300  }
301}
302/*2
303*minimizes the resolution res
304*assumes homogeneous or local case
305*/
306static void syMinStep1(resolvente res, int length)
307{
308  int i,j,k,l,index=0;
309  poly p;
310  ideal deg0=NULL,reddeg0=NULL;
311  intvec *have_del=NULL,*to_del=NULL;
312
313  while ((index<length) && (res[index]!=NULL))
314  {
315/*---we take out dependend elements from syz---------------------*/
316    if (res[index+1]!=NULL)
317    {
318      deg0 = idJet(res[index+1],0);
[e7c6b22]319      reddeg0 = kInterRedOld(deg0);
[35aab3]320      idDelete(&deg0);
321      have_del = new intvec(IDELEMS(res[index]));
322      for (i=0;i<IDELEMS(reddeg0);i++)
323      {
324        if (reddeg0->m[i]!=NULL)
325        {
326          j = pGetComp(reddeg0->m[i]);
327          pDelete(&(res[index]->m[j-1]));
[fe3266]328          /*res[index]->m[j-1] = NULL;*/
[35aab3]329          (*have_del)[j-1] = 1;
330        }
331      }
332      idDelete(&reddeg0);
333    }
334    if (index>0)
335    {
336/*--- we search for units and perform Gaussian elimination------*/
337      j = to_del->length();
338      while (j>0)
339      {
340        if ((*to_del)[j-1]==1)
341        {
342          k = 0;
343          while (k<IDELEMS(res[index]))
344          {
345            p = res[index]->m[k];
346            while ((p!=NULL) && ((!pLmIsConstantComp(p)) || (pGetComp(p)!=j)))
347              pIter(p);
348            if ((p!=NULL) && (pLmIsConstantComp(p)) && (pGetComp(p)==j)) break;
349            k++;
350          }
351          if (k>=IDELEMS(res[index]))
352          {
353            PrintS("out of range\n");
354          }
355          syGaussForOne(res[index],k,j);
356          if (res[index+1]!=NULL)
357            syDeleteAbove1(res[index+1],k+1);
358          (*to_del)[j-1] = 0;
359        }
360        j--;
361      }
362    }
363    if (to_del!=NULL) delete to_del;
364    to_del = have_del;
365    have_del = NULL;
366    index++;
367  }
368  if (TEST_OPT_PROT) PrintLn();
369  syKillEmptyEntres(res,length);
370}
371
372void syMinimizeResolvente(resolvente res, int length, int first)
373{
374  int syzIndex=first;
375  intvec *dummy;
376
377  if (syzIndex<1) syzIndex=1;
378  if ((syzIndex==1) && (idHomModule(res[0],currQuotient,&dummy)) && (!rIsPluralRing(currRing)))
379  {
380    syMinStep1(res,length);
381    delete dummy;
382    return;
383  }
384  while ((syzIndex<length-1) && (res[syzIndex]!=NULL) && (res[syzIndex+1]!=NULL))
385  {
386    syMinStep(res[syzIndex-1],res[syzIndex],FALSE,res[syzIndex+1]);
387    syzIndex++;
388  }
389  if (res[syzIndex]!=NULL)
390    syMinStep(res[syzIndex-1],res[syzIndex]);
391  if (!idIs0(res[0]))
392    idMinEmbedding(res[0],TRUE);
393}
394
395/*2
396* resolution of ideal/module arg, <=maxlength steps, (r[0..maxlength])
397*   no limitation in length if maxlength==0
398* input:arg
399*       minim: TRUE means mres cmd, FALSE nres cmd.
400*       if *len!=0: module weights: weights[0]
401*          (and weights is defined:weights[0..len-1]
402*
403* output:resolvente r[0..length-1],
404*        module weights: weights[0..length-1]
405*/
406resolvente syResolvente(ideal arg, int maxlength, int * length,
407                        intvec *** weights, BOOLEAN minim)
408{
409  resolvente res;
410  resolvente newres;
411  tHomog hom=isNotHomog;
412  ideal temp=NULL;
413  intvec *w = NULL,**tempW;
[62dd9b]414  int i,k,syzIndex = 0,j,rk_arg=si_max(1,(int)idRankFreeModule(arg));
[35aab3]415  int Kstd1_OldDeg=Kstd1_deg;
416  BOOLEAN completeMinim;
417  BOOLEAN oldDegBound=TEST_OPT_DEGBOUND;
418  BOOLEAN setRegularity=TRUE;
419  int wlength=*length;
420
421  if (maxlength!=-1) *length = maxlength+1;
422  else              *length = 5;
423  if ((wlength!=0) && (*length!=wlength))
424  {
425    intvec **wtmp = (intvec**)omAlloc0((*length)*sizeof(intvec*));
426    wtmp[0]=(*weights)[0];
427    omFreeSize((ADDRESS)*weights,wlength*sizeof(intvec*));
428    *weights=wtmp;
429  }
430  res = (resolvente)omAlloc0((*length)*sizeof(ideal));
431
432/*--- initialize the syzygy-ring -----------------------------*/
433  ring origR = currRing;
434  ring syz_ring = rCurrRingAssure_SyzComp();
435  rSetSyzComp(rk_arg);
436
437  if (syz_ring != origR)
438  {
439    res[0] = idrCopyR_NoSort(arg, origR);
440  }
441  else
442  {
443    res[0] = idCopy(arg);
444  }
445
446/*--- creating weights for the module components ---------------*/
[a63c24]447  if ((weights!=NULL) && (*weights!=NULL)&& ((*weights)[0]!=NULL))
448  {
449    if (!idTestHomModule(res[0],currQuotient,(*weights)[0]))
450    {
[e6a019]451      WarnS("wrong weights given(1):"); (*weights)[0]->show();PrintLn();
[a63c24]452      idHomModule(res[0],currQuotient,&w);
453      w->show();PrintLn();
454      *weights=NULL;
455    }
456  }
457
[35aab3]458  if ((weights==NULL) || (*weights==NULL) || ((*weights)[0]==NULL))
459  {
460    hom=(tHomog)idHomModule(res[0],currQuotient,&w);
461    if (hom==isHomog)
462    {
463      *weights = (intvec**)omAlloc0((*length)*sizeof(intvec*));
464      if (w!=NULL) (*weights)[0] = ivCopy(w);
465    }
466  }
467  else
468  {
469    if ((weights!=NULL) && (*weights!=NULL)&& ((*weights)[0]!=NULL))
470    {
471      w = ivCopy((*weights)[0]);
472      hom = isHomog;
473    }
474  }
475  if (hom==isHomog)
476  {
477    intvec *w1 = syPrepareModComp(res[0],&w);
478    if (w!=NULL) { delete w;w=NULL; }
479    w = w1;
480    j = 0;
481    while ((j<IDELEMS(res[0])) && (res[0]->m[j]==NULL)) j++;
482    if (j<IDELEMS(res[0]))
483    {
[b130fb]484      if (pFDeg(res[0]->m[j],currRing)!=pTotaldegree(res[0]->m[j]))
[35aab3]485        setRegularity = FALSE;
486    }
487  }
488  else
489  {
490    setRegularity = FALSE;
491  }
492
493/*--- the main loop --------------------------------------*/
494  while ((!idIs0(res[syzIndex])) &&
495         ((maxlength==-1) || (syzIndex<=maxlength)))
496   // (syzIndex<maxlength+(int)minim)))
497/*--- compute one step more for minimizing-----------------*/
498  {
499    if (Kstd1_deg!=0) Kstd1_deg++;
500    if (syzIndex+1==*length)
501    {
502      newres = (resolvente)omAlloc0((*length+5)*sizeof(ideal));
503      tempW = (intvec**)omAlloc0((*length+5)*sizeof(intvec*));
504      for (j=0;j<*length;j++)
505      {
506        newres[j] = res[j];
507        if (*weights!=NULL) tempW[j] = (*weights)[j];
508        /*else              tempW[j] = NULL;*/
509      }
510      omFreeSize((ADDRESS)res,*length*sizeof(ideal));
511      if (*weights != NULL) omFreeSize((ADDRESS)*weights,*length*sizeof(intvec*));
512      *length += 5;
513      res=newres;
514      *weights = tempW;
515    }
516/*--- interreducing first -----------------------------------*/
517    if (syzIndex>0)
518    {
519      int rkI=idRankFreeModule(res[syzIndex]);
520      rSetSyzComp(rkI);
521    }
522    if (minim || (syzIndex!=0))
523    {
[e7c6b22]524      temp = kInterRedOld(res[syzIndex],currQuotient);
[35aab3]525      idDelete(&res[syzIndex]);
526      idSkipZeroes(temp);
527      res[syzIndex] = temp;
528    }
529    temp = NULL;
530/*--- computing the syzygy modules --------------------------------*/
531    if ((currQuotient==NULL)&&(syzIndex==0)&& (!TEST_OPT_DEGBOUND))
532    {
533      res[/*syzIndex+*/1] = idSyzygies(res[0/*syzIndex*/],hom,&w,FALSE,setRegularity,&Kstd1_deg);
534      if ((!TEST_OPT_NOTREGULARITY) && (Kstd1_deg>0)) test |= Sy_bit(OPT_DEGBOUND);
535    }
536    else
537    {
538        res[syzIndex+1] = idSyzygies(res[syzIndex],hom,&w,FALSE);
539    }
540    completeMinim=(syzIndex!=maxlength) || (maxlength ==-1) || (hom!=isHomog);
541    syzIndex++;
542    if (TEST_OPT_PROT) Print("[%d]\n",syzIndex);
543    if ((minim)||(syzIndex>1))
544      syMinStep(res[syzIndex-1],res[syzIndex],!completeMinim,NULL,hom);
545    if (!completeMinim)
546    /*minim is TRUE, we are in the module: maxlength, maxlength <>0*/
547    {
548      idDelete(&res[syzIndex]);
549    }
550/*---creating the iterated weights for module components ---------*/
551    if ((hom == isHomog) && (!idIs0(res[syzIndex])))
552    {
553//Print("die %d Modulegewichte sind:\n",w1->length());
554//w1->show();
555//PrintLn();
556      int max_comp = idRankFreeModule(res[syzIndex]);
557      k = max_comp - rGetCurrSyzLimit();
558      assume(w != NULL);
559      if (w != NULL)
560        w->resize(max_comp+IDELEMS(res[syzIndex]));
561      else
562        w = new intvec(max_comp+IDELEMS(res[syzIndex]));
563      (*weights)[syzIndex] = new intvec(k);
564      for (i=0;i<k;i++)
565      {
566        if (res[syzIndex-1]->m[i]!=NULL) // hs
567        {
[b130fb]568          (*w)[i + rGetCurrSyzLimit()] = pFDeg(res[syzIndex-1]->m[i],currRing);
[35aab3]569          if (pGetComp(res[syzIndex-1]->m[i])>0)
570            (*w)[i + rGetCurrSyzLimit()]
571              += (*w)[pGetComp(res[syzIndex-1]->m[i])-1];
572          (*((*weights)[syzIndex]))[i] = (*w)[i+rGetCurrSyzLimit()];
573        }
574      }
575      for (i=k;i<k+IDELEMS(res[syzIndex]);i++)
576      {
577        if (res[syzIndex]->m[i-k]!=NULL)
[b130fb]578          (*w)[i+rGetCurrSyzLimit()] = pFDeg(res[syzIndex]->m[i-k],currRing)
[35aab3]579                    +(*w)[pGetComp(res[syzIndex]->m[i-k])-1];
580      }
581    }
582  }
583/*--- end of the main loop --------------------------------------*/
584/*--- deleting the temporare data structures --------------------*/
585  if ((syzIndex!=0) && (res[syzIndex]!=NULL) && (idIs0(res[syzIndex])))
586    idDelete(&res[syzIndex]);
587  if (w !=NULL) delete w;
588
589  Kstd1_deg=Kstd1_OldDeg;
590  if (!oldDegBound)
591    test &= ~Sy_bit(OPT_DEGBOUND);
592
593  for (i=1; i<=syzIndex; i++)
594  {
595    if (! idIs0(res[i]))
596    {
597      for (j=0; j<IDELEMS(res[i]); j++)
598      {
599        pShift(&res[i]->m[j], -rGetMaxSyzComp(i));
600      }
601    }
602  }
603/*--- going back to the original ring -------------------------*/
604  if (origR != syz_ring)
605  {
606    rChangeCurrRing(origR);
607    for (i=0; i<=syzIndex; i++)
608    {
609      res[i] = idrMoveR_NoSort(res[i], syz_ring);
610    }
611    rKill(syz_ring);
612  }
613  return res;
614}
615
616syStrategy syResolution(ideal arg, int maxlength,intvec * w, BOOLEAN minim)
617{
[8b09ef]618
[90adb6a]619#ifdef HAVE_PLURAL
[8b09ef]620
[57bfa2]621  const ideal idSaveCurrQuotient = currQuotient;
622  const ideal idSaveCurrRingQuotient = currRing->qideal;
[8b09ef]623
[90adb6a]624  if( rIsSCA(currRing) )
625  {
[e65ce5]626
627#ifdef RDEBUG
628//    rWrite(currRing);
629//    rDebugPrint(currRing);
630#endif
[8b09ef]631
[57bfa2]632    if( ncExtensions(TESTSYZSCAMASK) )
633    {
634      currQuotient = SCAQuotient(currRing);
635      currRing->qideal = currQuotient;
636    }
[90adb6a]637
638    const unsigned int m_iFirstAltVar = scaFirstAltVar(currRing);
639    const unsigned int m_iLastAltVar  = scaLastAltVar(currRing);
640   
[e2efe91]641    arg = id_KillSquares(arg, m_iFirstAltVar, m_iLastAltVar, currRing, false); // kill suares in input!
[90adb6a]642  }
643#endif
644 
[35aab3]645  int typ0;
646  syStrategy result=(syStrategy)omAlloc0(sizeof(ssyStrategy));
647
[90adb6a]648  if ((w!=NULL) && (!idTestHomModule(arg,currQuotient,w))) // is this right in SCA case???
[a63c24]649  {
[e6a019]650    WarnS("wrong weights given(2):");w->show();PrintLn();
[a63c24]651    idHomModule(arg,currQuotient,&w);
652    w->show();PrintLn();
653    w=NULL;
654  }
[35aab3]655  if (w!=NULL)
656  {
657    result->weights = (intvec**)omAlloc0Bin(void_ptr_bin);
658    (result->weights)[0] = ivCopy(w);
659    result->length = 1;
660  }
661  resolvente fr = syResolvente(arg,maxlength,&(result->length),&(result->weights),minim),fr1;
662  if (minim)
663  {
664    result->minres = (resolvente)omAlloc0((result->length+1)*sizeof(ideal));
665    fr1 =  result->minres;
666  }
667  else
668  {
669    result->fullres = (resolvente)omAlloc0((result->length+1)*sizeof(ideal));
670    fr1 =  result->fullres;
671  }
672  for (int i=result->length-1;i>=0;i--)
673  {
674    if (fr[i]!=NULL)
675      fr1[i] = fr[i];
676    fr[i] = NULL;
677  }
678  omFreeSize((ADDRESS)fr,(result->length)*sizeof(ideal));
[90adb6a]679
680
681#ifdef HAVE_PLURAL
682  if( rIsSCA(currRing) )
683  {
[8b09ef]684
[57bfa2]685    if( ncExtensions(TESTSYZSCAMASK) )
686    {
687      currQuotient     = idSaveCurrQuotient; 
688      currRing->qideal = idSaveCurrRingQuotient;
689    }
[90adb6a]690
691    id_Delete(&arg, currRing);
692  }
693#endif
694
695
[35aab3]696  return result;
697}
698
699static poly sypCopyConstant(poly inp)
700{
701  poly outp=NULL,q;
702
703  while (inp!=NULL)
704  {
705    if (pLmIsConstantComp(inp))
706    {
707      if (outp==NULL)
708      {
709        q = outp = pHead(inp);
710      }
711      else
712      {
713        pNext(q) = pHead(inp);
714        pIter(q);
715      }
716    }
717    pIter(inp);
718  }
719  return outp;
720}
721int syDetect(ideal id,int index,BOOLEAN homog,int * degrees,int * tocancel)
722{
723  int i, j, k, ModComp,subFromRank=0, lu;
724  poly p, q, qq, Unit1, Unit2;
725  ideal temp;
726
727  if (idIs0(id)) return 0;
728  temp = idInit(IDELEMS(id),id->rank);
729  for (i=0;i<IDELEMS(id);i++)
730  {
731    temp->m[i] = sypCopyConstant(id->m[i]);
732  }
733  i = IDELEMS(id);
734  while ((i>0) && (temp->m[i-1]==NULL)) i--;
735  if (i==0)
736  {
737    idDelete(&temp);
738    return 0;
739  }
740  j = 0;
741  p = NULL;
742  while ((j<i) && (temp->m[j]==NULL)) j++;
743  while (j<i)
744  {
745    if (homog)
746    {
[b130fb]747      if (index==0) k = pFDeg(temp->m[j],currRing)+degrees[pGetComp(temp->m[j])];
748      else          k = degrees[pGetComp(temp->m[j])];
[35aab3]749      if (k>=index) tocancel[k-index]++;
750      if ((k>=0) && (index==0)) subFromRank++;
751    }
752    else
753    {
754      tocancel[0]--;
755    }
756    syGaussForOne(temp,j,pGetComp(temp->m[j]),j+1,i);
757    j++;
758    while ((j<i) && (temp->m[j]==NULL)) j++;
759  }
760  idDelete(&temp);
761  return subFromRank;
762}
763
764void syDetect(ideal id,int index,int rsmin, BOOLEAN homog,
765              intvec * degrees,intvec * tocancel)
766{
767  int * deg=NULL;
768  int * tocan=(int*) omAlloc0(tocancel->length()*sizeof(int));
769  int i;
770
771  if (homog)
772  {
773    deg = (int*) omAlloc0(degrees->length()*sizeof(int));
774    for (i=degrees->length();i>0;i--)
775      deg[i-1] = (*degrees)[i-1]-rsmin;
776  }
777  int dummy=syDetect(id,index,homog,deg,tocan);
778  for (i=tocancel->length();i>0;i--)
779    (*tocancel)[i-1] = tocan[i-1];
780  if (homog)
781    omFreeSize((ADDRESS)deg,degrees->length()*sizeof(int));
782  omFreeSize((ADDRESS)tocan,tocancel->length()*sizeof(int));
783}
784
785/*2
786* computes the betti numbers from a given resolution
787* of length 'length' (0..length-1), not necessairily minimal,
788* (if weights are given, they are used)
789* returns the int matrix of betti numbers
790* and the regularity
791*/
792intvec * syBetti(resolvente res,int length, int * regularity,
793                 intvec* weights,BOOLEAN tomin,int * row_shift)
794{
795//#define BETTI_WITH_ZEROS
796  //tomin = FALSE;
797  int i,j=0,k=0,l,rows,cols,mr;
798  int *temp1,*temp2,*temp3;/*used to compute degrees*/
799  int *tocancel; /*(BOOLEAN)tocancel[i]=element is superfluous*/
800  int r0_len;
801
802  /*------ compute size --------------*/
803  *regularity = -1;
804  cols = length;
805  while ((cols>0)
806  && ((res[cols-1]==NULL)
807    || (idIs0(res[cols-1]))))
808  {
809    cols--;
810  }
811  intvec * result;
812  if (idIs0(res[0]))
813  {
814    if (res[0]==NULL)
815      result = new intvec(1,1,1);
816    else
817      result = new intvec(1,1,res[0]->rank);
818    return result;
819  }
820  intvec *w=NULL;
[a63c24]821  if (weights!=NULL)
822  {
823    if (!idTestHomModule(res[0],currQuotient,weights))
824    {
[e6a019]825      WarnS("wrong weights given(3):");weights->show();PrintLn();
[a63c24]826      idHomModule(res[0],currQuotient,&w);
827      if (w!=NULL) { w->show();PrintLn();}
828      weights=NULL;
829    }
830  }
[8ebd1a0]831#if 0
832  if (idHomModule(res[0],currQuotient,&w)!=isHomog)
833  {
834    Warn("betti-command: Input is not homogeneous!");
835    weights=NULL;
836  }
837#endif
[a63c24]838  if (weights==NULL) weights=w;
839  else delete w;
840  r0_len=IDELEMS(res[0]);
841  while ((r0_len>0) && (res[0]->m[r0_len-1]==NULL)) r0_len--;
842  #ifdef SHOW_W
[192b522]843  PrintS("weights:");if (weights!=NULL) weights->show(); else Print("NULL"); PrintLn();
[a63c24]844  #endif
[35aab3]845  int rkl=l = si_max(idRankFreeModule(res[0]),res[0]->rank);
846  i = 0;
847  while ((i<length) && (res[i]!=NULL))
848  {
849    if (IDELEMS(res[i])>l) l = IDELEMS(res[i]);
850    i++;
851  }
852  temp1 = (int*)omAlloc0((l+1)*sizeof(int));
853  temp2 = (int*)omAlloc((l+1)*sizeof(int));
854  rows = 1;
855  mr = 1;
856  cols++;
857  for (i=0;i<cols-1;i++)
858  {
859    if ((i==0) && (weights!=NULL)) pSetModDeg(weights);
860    memset(temp2,0,(l+1)*sizeof(int));
861    for (j=0;j<IDELEMS(res[i]);j++)
862    {
863      if (res[i]->m[j]!=NULL)
864      {
865        if ((pGetComp(res[i]->m[j])>l)
866        || ((i>1) && (res[i-1]->m[pGetComp(res[i]->m[j])-1]==NULL)))
867        {
868          WerrorS("input not a resolvent");
869          omFreeSize((ADDRESS)temp1,(l+1)*sizeof(int));
870          omFreeSize((ADDRESS)temp2,(l+1)*sizeof(int));
871          return NULL;
872        }
[b130fb]873        temp2[j+1] = pFDeg(res[i]->m[j],currRing)+temp1[pGetComp(res[i]->m[j])];
[35aab3]874        if (temp2[j+1]-i>rows) rows = temp2[j+1]-i;
875        if (temp2[j+1]-i<mr) mr = temp2[j+1]-i;
876      }
877    }
878    if ((i==0) && (weights!=NULL)) pSetModDeg(NULL);
879    temp3 = temp1;
880    temp1 = temp2;
881    temp2 = temp3;
882  }
883  mr--;
[3e1bc9]884  if (weights!=NULL)
885  {
886    for(j=0;j<weights->length();j++)
887    {
888      if (rows <(*weights)[j]+1) rows=(-mr)+(*weights)[j]+1;
889    }
890  }
[35aab3]891  /*------ computation betti numbers --------------*/
892  rows -= mr;
[a63c24]893  result = new intvec(rows+1,cols,0);
894  if (weights!=NULL)
895  {
896    for(j=0;j<weights->length();j++)
897    {
898      IMATELEM((*result),(-mr)+(*weights)[j]+1,1) ++;
[192b522]899      //Print("imat(%d,%d)++ -> %d\n",(-mr)+(*weights)[j]+1, 1, IMATELEM((*result),(-mr)+(*weights)[j]+1,1));
[a63c24]900    }
901  }
902  else
903  {
904    (*result)[(-mr)*cols] = /*idRankFreeModule(res[0])*/ rkl;
905    if ((!idIs0(res[0])) && ((*result)[(-mr)*cols]==0))
906      (*result)[(-mr)*cols] = 1;
907  }
[35aab3]908  tocancel = (int*)omAlloc0((rows+1)*sizeof(int));
909  memset(temp1,0,(l+1)*sizeof(int));
[a63c24]910  if (weights!=NULL)
911  {
912    memset(temp2,0,l*sizeof(int));
913    pSetModDeg(weights);
914  }
915  else
916    memset(temp2,0,l*sizeof(int));
[35aab3]917  int dummy = syDetect(res[0],0,TRUE,temp2,tocancel);
[a63c24]918  if (weights!=NULL) pSetModDeg(NULL);
[35aab3]919  if (tomin)
[a63c24]920  {
921    //(*result)[(-mr)*cols] -= dummy;
922    for(j=0;j<=rows+mr;j++)
923    {
[192b522]924      //Print("tocancel[%d]=%d imat(%d,%d)=%d\n",j,tocancel[j],(-mr)+j+1,1,IMATELEM((*result),(-mr)+j+1,1));
[a63c24]925      IMATELEM((*result),(-mr)+j+1,1) -= tocancel[j];
926    }
927  }
[35aab3]928  for (i=0;i<cols-1;i++)
929  {
930    if ((i==0) && (weights!=NULL)) pSetModDeg(weights);
931    memset(temp2,0,l*sizeof(int));
932    for (j=0;j<IDELEMS(res[i]);j++)
933    {
934      if (res[i]->m[j]!=NULL)
935      {
[b130fb]936        temp2[j+1] = pFDeg(res[i]->m[j],currRing)+temp1[pGetComp(res[i]->m[j])];
[35aab3]937        //(*result)[i+1+(temp2[j+1]-i-1)*cols]++;
938        //if (temp2[j+1]>i) IMATELEM((*result),temp2[j+1]-i-mr,i+2)++;
939        IMATELEM((*result),temp2[j+1]-i-mr,i+2)++;
940      }
941      else if (i==0)
942      {
943        if (j<r0_len) IMATELEM((*result),-mr,2)++;
944      }
945    }
946  /*------ computation betti numbers, if res not minimal --------------*/
947    if (tomin)
948    {
949      for (j=mr;j<rows+mr;j++)
950      {
951        //(*result)[i+1+j*cols] -= tocancel[j+1];
952        IMATELEM((*result),j+1-mr,i+2) -= tocancel[j+1];
953      }
954      if ((i<length-1) && (res[i+1]!=NULL))
955      {
956        memset(tocancel,0,(rows+1)*sizeof(int));
957        dummy = syDetect(res[i+1],i+1,TRUE,temp2,tocancel);
958        for (j=0;j<rows;j++)
959        {
960          //(*result)[i+1+j*cols] -= tocancel[j];
961          IMATELEM((*result),j+1,i+2) -= tocancel[j];
962        }
963      }
964    }
965    temp3 = temp1;
966    temp1 = temp2;
967    temp2 = temp3;
[a63c24]968    for (j=0;j<=rows;j++)
[35aab3]969    {
970    //  if (((*result)[i+1+j*cols]!=0) && (j>*regularity)) *regularity = j;
971      if ((IMATELEM((*result),j+1,i+2)!=0) && (j>*regularity)) *regularity = j;
972    }
973    if ((i==0) && (weights!=NULL)) pSetModDeg(NULL);
974  }
[a63c24]975  // Print("nach minim:\n"); result->show(); PrintLn();
[35aab3]976  /*------ clean up --------------*/
977  omFreeSize((ADDRESS)tocancel,(rows+1)*sizeof(int));
978  omFreeSize((ADDRESS)temp1,(l+1)*sizeof(int));
979  omFreeSize((ADDRESS)temp2,(l+1)*sizeof(int));
980  if ((tomin) && (mr<0))  // deletes the first (zero) line
981  {
[a63c24]982    for (j=1;j<=rows+mr+1;j++)
[35aab3]983    {
984      for (k=1;k<=cols;k++)
985      {
986        IMATELEM((*result),j,k) = IMATELEM((*result),j-mr,k);
987      }
988    }
[a63c24]989    for (j=rows+mr+1;j<=rows+1;j++)
[35aab3]990    {
991      for (k=1;k<=cols;k++)
992      {
993        IMATELEM((*result),j,k) = 0;
994      }
995    }
996  }
997  j = 0;
998  k = 0;
[a63c24]999  for (i=1;i<=result->rows();i++)
[35aab3]1000  {
[a63c24]1001    for(l=1;l<=result->cols();l++)
1002    if (IMATELEM((*result),i,l) != 0)
[35aab3]1003    {
[a63c24]1004      j = si_max(j, i-1);
1005      k = si_max(k, l-1);
[35aab3]1006    }
1007  }
1008  intvec * exactresult=new intvec(j+1,k+1,0);
1009  for (i=0;i<exactresult->rows();i++)
1010  {
1011    for (j=0;j<exactresult->cols();j++)
1012    {
1013      IMATELEM(*exactresult,i+1,j+1) = IMATELEM(*result,i+1,j+1);
1014    }
1015  }
1016  if (row_shift!=NULL) *row_shift = mr;
1017  delete result;
1018  return exactresult;
1019}
1020
1021/*2
1022* minbare via syzygies
1023*/
1024ideal syMinBase(ideal arg)
1025{
1026  intvec ** weights=NULL;
1027  int leng;
1028  if (idIs0(arg)) return idInit(1,arg->rank);
1029  resolvente res=syResolvente(arg,1,&leng,&weights,TRUE);
1030  ideal result=res[0];
1031  omFreeSize((ADDRESS)res,leng*sizeof(ideal));
1032  if (weights!=NULL)
1033  {
1034    if (*weights!=NULL)
1035    {
1036      delete (*weights);
1037      *weights=NULL;
1038    }
1039    if ((leng>=1) && (*(weights+1)!=NULL))
1040    {
1041      delete *(weights+1);
1042      *(weights+1)=NULL;
1043    }
1044  }
1045  idSkipZeroes(result);
1046  return result;
1047}
1048
1049/*2
1050* computes Betti-numbers from a resolvente of
1051* (non-)homogeneous objects
1052* the numbers of entrees !=NULL in res and weights must be equal
1053* and < length
1054*/
1055intvec * syNewBetti(resolvente res, intvec ** weights, int length)
1056{
1057  intvec * result,*tocancel;
1058  int i,j,k,rsmin=0,rsmax=0,rs=0;
1059  BOOLEAN homog=TRUE;
1060
1061  if (weights!=NULL)           //---homogeneous Betti numbers
1062  {
1063/*--------------computes size of the field----------------------*/
1064    for (i=1;i<length;i++)
1065    {
1066      if (weights[i] != NULL)
1067      {
1068        for (j=1;j<(weights[i])->length();j++)
1069        {
1070          if ((*(weights[i]))[j]-i<rsmin) rsmin = (*(weights[i]))[j]-i;
1071          if ((*(weights[i]))[j]-i>rsmax) rsmax = (*(weights[i]))[j]-i;
1072        }
1073      }
1074    }
1075    i = 0;
1076    while (weights[i] != NULL) i++;
1077    i--;
1078    for (j=0;j<IDELEMS(res[i]);j++)
1079    {
1080      if (res[i]->m[j]!=NULL)
1081      {
[b130fb]1082        k = pFDeg(res[i]->m[j],currRing)+(*(weights[i]))[pGetComp(res[i]->m[j])]-i-1;
[35aab3]1083        if (k>rsmax) rsmax = k;
1084        if (k<rsmin) rsmin = k;
1085      }
1086    }
1087    for (j=1;j<(weights[0])->length();j++)
1088    {
1089      if ((*weights[0])[j]>rsmax) rsmax = (*weights[0])[j];
1090      if ((*weights[0])[j]<rsmin) rsmin = (*weights[0])[j];
1091    }
1092//Print("rsmax = %d\n",rsmax);
1093//Print("rsmin = %d\n",rsmin);
1094    rs = rsmax-rsmin+1;
1095    result = new intvec(rs,i+2,0);
1096    tocancel = new intvec(rs);
1097/*-----------enter the Betti numbers-------------------------------*/
1098    if (/*idRankFreeModule(res[0])*/ res[0]->rank==0)
1099    {
1100      IMATELEM(*result,1-rsmin,1)=1;
1101    }
1102    else
1103    {
1104      for (i=1;i<(weights[0])->length();i++)
1105        IMATELEM(*result,(*weights[0])[i]+1-rsmin,1)++;
1106    }
1107    i = 1;
1108    while (weights[i]!=NULL)
1109    {
1110      for (j=1;j<(weights[i])->length();j++)
1111      {
1112        IMATELEM(*result,(*(weights[i]))[j]-i+1-rsmin,i+1)++;
1113      }
1114      i++;
1115    }
1116    i--;
1117    for (j=0;j<IDELEMS(res[i]);j++)
1118    {
1119      if (res[i]->m[j]!=NULL)
1120      {
[b130fb]1121        k = pFDeg(res[i]->m[j],currRing)+(*(weights[i]))[pGetComp(res[i]->m[j])]-i;
[35aab3]1122        IMATELEM(*result,k-rsmin,i+2)++;
1123      }
1124    }
1125  }
1126  else                //-----the non-homgeneous case
1127  {
1128    homog = FALSE;
1129    tocancel = new intvec(1);
1130    k = length;
1131    while ((k>0) && (idIs0(res[k-1]))) k--;
1132    result = new intvec(1,k+1,0);
1133    (*result)[0] = res[0]->rank;
1134    for (i=0;i<length;i++)
1135    {
1136      if (res[i]!=NULL)
1137      {
1138        for (j=0;j<IDELEMS(res[i]);j++)
1139        {
1140          if (res[i]->m[j]!=NULL) (*result)[i+1]++;
1141        }
1142      }
1143    }
1144  }
1145/*--------computes the Betti numbers for the minimized reolvente----*/
1146
1147  i = 1;
1148  while ((res[i]!=NULL) && (weights[i]!=NULL))
1149  {
1150    syDetect(res[i],i,rsmin,homog,weights[i],tocancel);
1151    if (homog)
1152    {
1153      for (j=0;j<rs-1;j++)
1154      {
1155        IMATELEM((*result),j+1,i+1) -= (*tocancel)[j];
1156        IMATELEM((*result),j+1,i+2) -= (*tocancel)[j+1];
1157      }
1158      IMATELEM((*result),rs,i+1) -= (*tocancel)[rs-1];
1159    }
1160    else
1161    {
1162      (*result)[i+1] -= (*tocancel)[0];
1163      (*result)[i+2] -= (*tocancel)[0];
1164    }
1165    i++;
1166  }
1167
1168/*--------print Betti numbers for control---------------------------*/
1169  for(i=rsmin;i<=rsmax;i++)
1170  {
1171    Print("%2d:",i);
1172    for(j=1;j<=result->cols();j++)
1173    {
1174      Print(" %5d",IMATELEM(*result,i-rsmin+1,j));
1175    }
1176    PrintLn();
1177  }
1178  return result;
1179}
1180
1181/*2
1182* is looking for the minimal minimized module of a resolvente
1183* i.e. returns 0 if res comes from a mres-command and 1 in the
1184* case of res-commands
1185*/
1186int syIsMinimizedFrom(resolvente res,int length)
1187{
1188  poly p;
1189  int i,j=length;
1190
1191  while ((j>0) && (res[j-1]==NULL)) j--;
1192  while (j>0)
1193  {
1194    for (i=0;i<IDELEMS(res[j-1]);i++)
1195    {
1196      p = res[j-1]->m[i];
1197      while (p!=NULL)
1198      {
1199        if (pLmIsConstantComp(p)) return j;
1200        p = pNext(p);
1201      }
1202    }
1203    j--;
1204  }
1205  return j;
1206}
Note: See TracBrowser for help on using the repository browser.