source: git/kernel/tgbgauss.cc @ b055de9

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