source: git/kernel/tgbgauss.cc @ 1e579c6

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