source: git/kernel/tgbgauss.cc @ 81306a

spielwiese
Last change on this file since 81306a was 81306a, checked in by Michael Brickenstein <bricken@…>, 18 years ago
*bricken: moved mac_poly things to tgbgauss git-svn-id: file:///usr/local/Singular/svn/trunk@8102 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 16.6 KB
Line 
1#include "mod2.h"
2#include "tgbgauss.h"
3
4static const int bundle_size=100;
5
6mac_poly mac_p_add_ff_qq(mac_poly a, number f,mac_poly b){
7  mac_poly erg;
8  mac_poly* set_this;
9  set_this=&erg;
10  while((a!=NULL) &&(b!=NULL)){
11    if (a->exp<b->exp){
12      (*set_this)=a;
13      a=a->next;
14      set_this= &((*set_this)->next);
15    } 
16    else{
17      if (a->exp>b->exp){
18        mac_poly in =new mac_poly_r();
19        in->exp=b->exp;
20        in->coef=nMult(b->coef,f);
21        (*set_this)=in;
22        b=b->next;
23        set_this= &((*set_this)->next);
24      }
25      else {
26        //a->exp==b->ecp
27        number n=nMult(b->coef,f);
28        number n2=nAdd(a->coef,n);
29        nDelete(&n);
30        nDelete(&(a->coef));
31        if (nIsZero(n2)){
32          nDelete(&n2);
33          mac_poly ao=a;
34          a=a->next;
35          delete ao;
36          b=b->next;
37         
38        } else {
39          a->coef=n2;
40          b=b->next;
41          (*set_this)=a;
42          a=a->next;
43          set_this= &((*set_this)->next);
44        }
45 
46      }
47   
48    }
49  }
50  if((a==NULL)&&(b==NULL)){
51    (*set_this)=NULL;
52    return erg;
53  }
54  if (b==NULL) {
55    (*set_this=a);
56    return erg;
57  }
58 
59  //a==NULL
60  while(b!=NULL){
61    mac_poly mp= new mac_poly_r();
62    mp->exp=b->exp;
63    mp->coef=nMult(f,b->coef);
64    (*set_this)=mp;
65    set_this=&(mp->next);
66    b=b->next;
67  }
68  (*set_this)=NULL;
69  return erg;
70 
71}
72void mac_mult_cons(mac_poly p,number c){
73  while(p){
74    number m=nMult(p->coef,c);
75    nDelete(&(p->coef));
76    p->coef=m;
77    p=p->next;
78  }
79 
80}
81int mac_length(mac_poly p){
82  int l=0;
83  while(p){
84    l++;
85    p=p->next;
86  }
87  return l;
88}
89//contrary to delete on the mac_poly_r, the coefficients are also destroyed here
90void mac_destroy(mac_poly p){
91  mac_poly iter=p;
92  while(iter)
93  {
94    mac_poly next=iter->next;
95    nDelete(&iter->coef);
96    delete iter;
97    iter=next;
98  }
99}
100
101void simple_gauss(tgb_sparse_matrix* mat, calc_dat* c){
102  int col, row;
103  int* row_cache=(int*) omalloc(mat->get_rows()*sizeof(int));
104  col=0;
105  row=0;
106  int i;
107  int pn=mat->get_rows();
108  int matcol=mat->get_columns();
109  int* area=(int*) omalloc(sizeof(int)*((matcol-1)/bundle_size+1));
110  const int max_area_index=(matcol-1)/bundle_size;
111    //rows are divided in areas
112  //if row begins with columns col, it is located in [area[col/bundle_size],area[col/bundle_size+1]-1]
113  assume(pn>0);
114  //first clear zeroes
115  for(i=0;i<pn;i++)
116  {
117    if(mat->zero_row(i))
118    {
119      mat->perm_rows(i,pn-1);
120      pn--;
121      if(i!=pn){i--;}
122    }
123 
124  }
125  mat->sort_rows();
126  for(i=0;i<pn;i++)
127  {
128      row_cache[i]=mat->min_col_not_zero_in_row(i);
129      // Print("row_cache:%d\n",row_cache[i]);
130  }
131  int last_area=-1;
132  for(i=0;i<pn;i++)
133  {
134    int this_area=row_cache[i]/bundle_size;
135    assume(this_area>=last_area);
136    if(this_area>last_area)
137    {
138      int j;
139      for(j=last_area+1;j<=this_area;j++)
140        area[j]=i;
141      last_area=this_area;
142    }
143  }
144  for(i=last_area+1;i<=max_area_index;i++)
145  {
146    area[i]=pn;
147  }
148  while(row<pn-1){
149    //row is the row where pivot should be
150    // row== pn-1 means we have only to act on one row so no red nec.
151    //we assume further all rows till the pn-1 row are non-zero
152   
153    //select column
154   
155    //col=mat->min_col_not_zero_in_row(row);
156    int max_in_area;
157    {
158      int tai=row_cache[row]/bundle_size;
159      assume(tai<=max_area_index);
160      if(tai==max_area_index)
161        max_in_area=pn-1;
162      else
163        max_in_area=area[tai+1]-1;
164    }
165    assume(row_cache[row]==mat->min_col_not_zero_in_row(row));
166    col=row_cache[row];
167
168   
169    assume(col!=matcol);
170    int found_in_row;
171   
172    found_in_row=row;
173    BOOLEAN must_reduce=FALSE;
174    assume(pn<=mat->get_rows());
175    for(i=row+1;i<=max_in_area;i++){
176      int first;//=mat->min_col_not_zero_in_row(i);
177      assume(row_cache[i]==mat->min_col_not_zero_in_row(i));
178      first=row_cache[i];
179      assume(first!=matcol);
180      if(first<col)
181      {
182        col=first;
183        found_in_row=i;
184        must_reduce=FALSE;
185      }
186      else {
187        if(first==col)
188          must_reduce=TRUE;
189      }
190    }
191    //select pivot
192    int act_l=nSize(mat->get(found_in_row,col))*mat->non_zero_entries(found_in_row);
193    if(must_reduce)
194    {
195      for(i=found_in_row+1;i<=max_in_area;i++){
196        assume(mat->min_col_not_zero_in_row(i)>=col);
197        int first;
198        assume(row_cache[i]==mat->min_col_not_zero_in_row(i));
199        first=row_cache[i];
200        assume(first!=matcol);
201        //      if((!(mat->is_zero_entry(i,col)))&&(mat->non_zero_entries(i)<act_l))
202        int nz;
203        if((row_cache[i]==col)&&((nz=nSize(mat->get(i,col))*mat->non_zero_entries(i))<act_l))
204        {
205          found_in_row=i;
206        act_l=nz;
207        }
208       
209      }
210    }
211    mat->perm_rows(row,found_in_row);
212    int h=row_cache[row];
213    row_cache[row]=row_cache[found_in_row];
214    row_cache[found_in_row]=h;
215
216
217
218    if(!must_reduce){
219      row++;
220      continue;
221    }
222    //reduction
223    //must extract content and normalize here
224    mat->row_content(row);
225    mat->row_normalize(row);
226
227    //for(i=row+1;i<pn;i++){
228    for(i=max_in_area;i>row;i--)
229    {
230      int col_area_index=col/bundle_size;
231      assume(col_area_index<=max_area_index);
232      assume(mat->min_col_not_zero_in_row(i)>=col);
233      int first;
234      assume(row_cache[i]==mat->min_col_not_zero_in_row(i));
235      first=row_cache[i];
236      assume(first!=matcol);
237      if(row_cache[i]==col)
238      {
239       
240        number c1=mat->get(i,col);
241        number c2=mat->get(row,col);
242        number n1=c1;
243        number n2=c2;
244
245        ksCheckCoeff(&n1,&n2);
246        //nDelete(&c1);
247        n1=nNeg(n1);
248        mat->mult_row(i,n2);
249        mat->add_lambda_times_row(i,row,n1);
250        nDelete(&n1);
251        nDelete(&n2);
252        assume(mat->is_zero_entry(i,col));
253        row_cache[i]=mat->min_col_not_zero_in_row(i);
254        assume(mat->min_col_not_zero_in_row(i)>col);
255        if(row_cache[i]==matcol)
256        {
257          int index;
258          index=i;
259          int last_in_area;
260          int this_cai=col_area_index;
261          while(this_cai<max_area_index)
262          {
263            last_in_area=area[this_cai+1]-1;
264            int h_c=row_cache[last_in_area];
265            row_cache[last_in_area]=row_cache[index];
266            row_cache[index]=h_c;
267            mat->perm_rows(index,last_in_area);
268            index=last_in_area;
269            this_cai++;
270            area[this_cai]--;
271          }
272          mat->perm_rows(index,pn-1);
273          row_cache[index]=row_cache[pn-1];
274          row_cache[pn-1]=matcol;
275          pn--;
276        }
277        else 
278        {
279          int index;
280          index=i;
281          int last_in_area;
282          int this_cai=col_area_index;
283          int final_cai=row_cache[index]/bundle_size;
284          assume(final_cai<=max_area_index);
285          while(this_cai<final_cai)
286          {
287            last_in_area=area[this_cai+1]-1;
288            int h_c=row_cache[last_in_area];
289            row_cache[last_in_area]=row_cache[index];
290            row_cache[index]=h_c;
291            mat->perm_rows(index,last_in_area);
292            index=last_in_area;
293            this_cai++;
294            area[this_cai]--;
295          }
296        }
297      }
298      else
299        assume(mat->min_col_not_zero_in_row(i)>col);
300    }
301
302//     for(i=row+1;i<pn;i++)
303//     {
304//       assume(mat->min_col_not_zero_in_row(i)==row_cache[i]);
305//       // if(mat->zero_row(i))
306//       assume(matcol==mat->get_columns());
307//       if(row_cache[i]==matcol)
308//       {
309//      assume(mat->zero_row(i));
310//      mat->perm_rows(i,pn-1);
311//      row_cache[i]=row_cache[pn-1];
312//      row_cache[pn-1]=matcol;
313//      pn--;
314//      if(i!=pn){i--;}
315//       }
316//     }
317#ifdef TGB_DEBUG
318  {
319  int last=-1;
320  for(i=0;i<pn;i++)
321  {
322    int act=mat->min_col_not_zero_in_row(i);
323    assume(act>last);
324   
325  }
326  for(i=pn;i<mat->get_rows();i++)
327  {
328    assume(mat->zero_row(i));
329   
330  }
331 
332
333  }
334#endif
335    row++;
336  }
337  omfree(area);
338  omfree(row_cache);
339}
340void simple_gauss2(tgb_matrix* mat){
341  int col, row;
342  col=0;
343  row=0;
344  int i;
345  int pn=mat->get_rows();
346  assume(pn>0);
347  //first clear zeroes
348//   for(i=0;i<pn;i++)
349//   {
350//     if(mat->zero_row(i))
351//     {
352//       mat->perm_rows(i,pn-1);
353//       pn--;
354//       if(i!=pn){i--;}
355//     }
356//   }
357  while((row<pn-1)&&(col<mat->get_columns())){
358    //row is the row where pivot should be
359    // row== pn-1 means we have only to act on one row so no red nec.
360    //we assume further all rows till the pn-1 row are non-zero
361   
362    //select column
363   
364    //    col=mat->min_col_not_zero_in_row(row);
365    assume(col!=mat->get_columns());
366    int found_in_row=-1;
367   
368    //    found_in_row=row;
369    assume(pn<=mat->get_rows());
370    for(i=row;i<pn;i++)
371    {
372      //    int first=mat->min_col_not_zero_in_row(i);
373      //  if(first<col)
374      if(!(mat->is_zero_entry(i,col))){
375       
376        found_in_row=i;
377        break;
378      }
379    }
380    if(found_in_row!=-1)
381    {
382    //select pivot
383      int act_l=mat->non_zero_entries(found_in_row);
384      for(i=i+1;i<pn;i++)
385      {
386        int vgl;
387        assume(mat->min_col_not_zero_in_row(i)>=col);
388        if((!(mat->is_zero_entry(i,col)))&&((vgl=mat->non_zero_entries(i))<act_l))
389        {
390          found_in_row=i;
391          act_l=vgl;
392        }
393       
394      }
395      mat->perm_rows(row,found_in_row);
396     
397     
398      //reduction
399      for(i=row+1;i<pn;i++){
400        assume(mat->min_col_not_zero_in_row(i)>=col);
401        if(!(mat->is_zero_entry(i,col)))
402        {
403         
404          number c1=nNeg(nCopy(mat->get(i,col)));
405          number c2=mat->get(row,col);
406          number n1=c1;
407          number n2=c2;
408         
409          ksCheckCoeff(&n1,&n2);
410          nDelete(&c1);
411          mat->mult_row(i,n2);
412          mat->add_lambda_times_row(i,row,n1);
413          assume(mat->is_zero_entry(i,col));
414         
415        } 
416        assume(mat->min_col_not_zero_in_row(i)>col);
417      }
418      row++;
419    }
420    col++;
421    // for(i=row+1;i<pn;i++)
422//     {
423//       if(mat->zero_row(i))
424//       {
425//      mat->perm_rows(i,pn-1);
426//      pn--;
427//      if(i!=pn){i--;}
428//       }
429//     }
430
431  }
432}
433
434tgb_matrix::tgb_matrix(int i, int j){
435  n=(number**) omalloc(i*sizeof (number*));;
436  int z;
437  int z2;
438  for(z=0;z<i;z++)
439  {
440    n[z]=(number*)omalloc(j*sizeof(number));
441    for(z2=0;z2<j;z2++)
442    {
443      n[z][z2]=nInit(0);
444    }
445  }
446  this->columns=j;
447  this->rows=i;
448  free_numbers=FALSE;
449}
450tgb_matrix::~tgb_matrix(){
451  int z;
452  for(z=0;z<rows;z++)
453  {
454    if(n[z])
455    {
456      if(free_numbers)
457      {
458        int z2;
459        for(z2=0;z2<columns;z2++)
460        {
461          nDelete(&(n[z][z2]));
462        }
463      }
464      omfree(n[z]);
465    }
466  }
467  omfree(n);
468}
469void tgb_matrix::print(){
470  int i;
471  int j;
472  Print("\n");
473  for(i=0;i<rows;i++)
474  {
475    Print("(");
476    for(j=0;j<columns;j++)
477    {
478      StringSetS("");
479      n_Write(n[i][j],currRing);
480      Print(StringAppendS(""));
481      Print("\t");
482    }
483    Print(")\n");
484  }
485}
486//transfers ownership of n to the matrix
487void tgb_matrix::set(int i, int j, number n){
488  assume(i<rows);
489  assume(j<columns);
490  this->n[i][j]=n;
491}
492int tgb_matrix::get_rows(){
493  return rows;
494}
495int tgb_matrix::get_columns(){
496  return columns;
497}
498number tgb_matrix::get(int i, int j){
499  assume(i<rows);
500  assume(j<columns);
501  return n[i][j];
502}
503BOOLEAN tgb_matrix::is_zero_entry(int i, int j){
504  return (nIsZero(n[i][j]));
505}
506void tgb_matrix::perm_rows(int i, int j){
507  number* h;
508  h=n[i];
509  n[i]=n[j];
510  n[j]=h;
511}
512int tgb_matrix::min_col_not_zero_in_row(int row){
513  int i;
514  for(i=0;i<columns;i++)
515  {
516    if(!(nIsZero(n[row][i])))
517      return i;
518  }
519  return columns;//error code
520}
521int tgb_matrix::next_col_not_zero(int row,int pre){
522  int i;
523  for(i=pre+1;i<columns;i++)
524  {
525    if(!(nIsZero(n[row][i])))
526      return i;
527  }
528  return columns;//error code
529}
530BOOLEAN tgb_matrix::zero_row(int row){
531  int i;
532  for(i=0;i<columns;i++)
533  {
534    if(!(nIsZero(n[row][i])))
535      return FALSE;
536  }
537  return TRUE;
538}
539int tgb_matrix::non_zero_entries(int row){
540  int i;
541  int z=0;
542  for(i=0;i<columns;i++)
543  {
544    if(!(nIsZero(n[row][i])))
545      z++;
546  }
547  return z;
548}
549//row add_to=row add_to +row summand*factor
550void tgb_matrix::add_lambda_times_row(int add_to,int summand,number factor){
551  int i;
552  for(i=0;i<columns;i++){
553    if(!(nIsZero(n[summand][i])))
554    {
555      number n1=n[add_to][i];
556      number n2=nMult(factor,n[summand][i]);
557      n[add_to][i]=nAdd(n1,n2);
558      nDelete(&n1);
559      nDelete(&n2);
560    }
561  }
562}
563void tgb_matrix::mult_row(int row,number factor){
564  if (nIsOne(factor))
565    return;
566  int i;
567  for(i=0;i<columns;i++){
568    if(!(nIsZero(n[row][i])))
569    {
570      number n1=n[row][i];
571      n[row][i]=nMult(n1,factor);
572      nDelete(&n1);
573    }
574  }
575}
576void tgb_matrix::free_row(int row, BOOLEAN free_non_zeros){
577  int i;
578  for(i=0;i<columns;i++)
579    if((free_non_zeros)||(!(nIsZero(n[row][i]))))
580      nDelete(&(n[row][i]));
581  omfree(n[row]);
582  n[row]=NULL;
583}
584
585
586tgb_sparse_matrix::tgb_sparse_matrix(int i, int j, ring rarg){
587  mp=(mac_poly*) omalloc(i*sizeof (mac_poly));;
588  int z;
589  int z2;
590  for(z=0;z<i;z++)
591  {
592    mp[z]=NULL;
593  }
594  this->columns=j;
595  this->rows=i;
596  free_numbers=FALSE;
597  r=rarg;
598}
599tgb_sparse_matrix::~tgb_sparse_matrix(){
600  int z;
601  for(z=0;z<rows;z++)
602  {
603    if(mp[z])
604    {
605      if(free_numbers)
606      {
607        mac_destroy(mp[z]);
608      }
609      else {
610        while(mp[z])
611        {
612         
613          mac_poly next=mp[z]->next;
614          delete mp[z];
615          mp[z]=next;
616        }
617      }
618    }
619  }
620  omfree(mp);
621}
622static int row_cmp_gen(const void* a, const void* b){
623  const mac_poly ap= *((mac_poly*) a);
624  const mac_poly bp=*((mac_poly*) b);
625  if (ap==NULL) return 1;
626  if (bp==NULL) return -1;
627  if (ap->exp<bp->exp) return -1;
628  return 1;
629}
630void tgb_sparse_matrix::sort_rows(){
631  qsort(mp,rows,sizeof(mac_poly),row_cmp_gen);
632}
633void tgb_sparse_matrix::print(){
634  int i;
635  int j;
636  Print("\n");
637  for(i=0;i<rows;i++)
638  {
639    Print("(");
640    for(j=0;j<columns;j++)
641    {
642      StringSetS("");
643      number n=get(i,j);
644      n_Write(n,currRing);
645      Print(StringAppendS(""));
646      Print("\t");
647    }
648    Print(")\n");
649  }
650}
651//transfers ownership of n to the matrix
652void tgb_sparse_matrix::set(int i, int j, number n){
653  assume(i<rows);
654  assume(j<columns);
655  mac_poly* set_this=&mp[i];
656  //  while(((*set_this)!=NULL)&&((*set_this)­>exp<j))
657  while(((*set_this)!=NULL) && ((*set_this)->exp<j))
658    set_this=&((*set_this)->next);
659
660  if (((*set_this)==NULL)||((*set_this)->exp>j))
661  {
662    if (nIsZero(n)) return;
663    mac_poly old=(*set_this);
664    (*set_this)=new mac_poly_r();
665    (*set_this)->exp=j;
666    (*set_this)->coef=n;
667    (*set_this)->next=old;
668    return;
669  }
670  assume((*set_this)->exp==j);
671  if(!nIsZero(n))
672  {
673    nDelete(&(*set_this)->coef);
674    (*set_this)->coef=n;
675  }
676  else
677  {
678    nDelete(&(*set_this)->coef);
679    mac_poly dt=(*set_this);
680    (*set_this)=dt->next;
681    delete dt;
682   
683   
684  }
685  return;
686}
687
688
689
690int tgb_sparse_matrix::get_rows(){
691  return rows;
692}
693int tgb_sparse_matrix::get_columns(){
694  return columns;
695}
696number tgb_sparse_matrix::get(int i, int j){
697  assume(i<rows);
698  assume(j<columns);
699  mac_poly r=mp[i];
700  while((r!=NULL)&&(r->exp<j))
701    r=r->next;
702  if ((r==NULL)||(r->exp>j))
703  {
704    number n=nInit(0);
705    return n;
706  }
707  assume(r->exp==j);
708  return r->coef;
709}
710BOOLEAN tgb_sparse_matrix::is_zero_entry(int i, int j){
711  assume(i<rows);
712  assume(j<columns);
713  mac_poly r=mp[i];
714  while((r!=NULL)&&(r->exp<j))
715    r=r->next;
716  if ((r==NULL)||(r->exp>j))
717  {
718    return TRUE;
719  }
720  assume(!nIsZero(r->coef));
721  assume(r->exp==j);
722  return FALSE;
723 
724}
725
726int tgb_sparse_matrix::min_col_not_zero_in_row(int row){
727  if(mp[row]!=NULL)
728  {
729    assume(!nIsZero(mp[row]->coef));
730    return mp[row]->exp;
731  }
732  else
733
734 
735  return columns;//error code
736}
737int tgb_sparse_matrix::next_col_not_zero(int row,int pre){ 
738  mac_poly r=mp[row];
739  while((r!=NULL)&&(r->exp<=pre))
740    r=r->next;
741  if(r!=NULL)
742  {
743    assume(!nIsZero(r->coef));
744    return r->exp;
745  }
746  return columns;//error code
747}
748BOOLEAN tgb_sparse_matrix::zero_row(int row){
749  assume((mp[row]==NULL)||(!nIsZero(mp[row]->coef)));
750  if (mp[row]==NULL)
751    return TRUE;
752  else
753    return FALSE;
754}
755void tgb_sparse_matrix::row_normalize(int row){
756  if (!rField_has_simple_inverse(r))  /* Z/p, GF(p,n), R, long R/C */
757  {
758    mac_poly m=mp[row];
759        while (m!=NULL)
760        {
761          if (currRing==r) {nTest(m->coef);}
762          n_Normalize(m->coef,r);
763          m=m->next;
764        }
765  }
766}
767void tgb_sparse_matrix::row_content(int row){
768 
769  mac_poly ph=mp[row];
770  number h,d;
771  mac_poly p;
772
773  if(TEST_OPT_CONTENTSB) return;
774  if(ph->next==NULL)
775  {
776    nDelete(&ph->coef);
777    ph->coef=nInit(1);
778  }
779  else
780  {
781    nNormalize(ph->coef);
782    if(!nGreaterZero(ph->coef)) {
783      //ph = pNeg(ph);
784      p=ph;
785      while(p)
786      {
787        p->coef=nNeg(p->coef);
788        p=p->next;
789      }
790    }
791   
792    h=nCopy(ph->coef);
793    p = ph->next;
794   
795    while (p!=NULL)
796    {
797      nNormalize(p->coef);
798      d=nGcd(h,p->coef,currRing);
799      nDelete(&h);
800      h = d;
801      if(nIsOne(h))
802      {
803        break;
804      }
805      p=p->next;
806    }
807    p = ph;
808    //number tmp;
809    if(!nIsOne(h))
810    {
811      while (p!=NULL)
812      {
813   
814        d = nIntDiv(pGetCoeff(p),h);
815        nDelete(&p->coef);
816        p->coef=d;
817        p=p->next;
818      }
819    }
820    nDelete(&h);
821
822  }
823}
824int tgb_sparse_matrix::non_zero_entries(int row){
825
826  return mac_length(mp[row]);
827}
828//row add_to=row add_to +row summand*factor
829void tgb_sparse_matrix::add_lambda_times_row(int add_to,int summand,number factor){
830  mp[add_to]= mac_p_add_ff_qq(mp[add_to], factor,mp[summand]);
831
832}
833void tgb_sparse_matrix::mult_row(int row,number factor){
834  if (nIsZero(factor))
835  {
836    mac_destroy(mp[row]);
837    mp[row]=NULL;
838   
839    return;
840  }
841  if(nIsOne(factor))
842    return;
843  mac_mult_cons(mp[row],factor);
844}
845void tgb_sparse_matrix::free_row(int row, BOOLEAN free_non_zeros){
846  if(free_non_zeros)
847    mac_destroy(mp[row]);
848  else
849  {
850    while(mp[row])
851    {
852     
853      mac_poly next=mp[row]->next;
854      delete mp[row];
855      mp[row]=next;
856    }
857  }
858  mp[row]=NULL;
859}
Note: See TracBrowser for help on using the repository browser.