source: git/kernel/tgbgauss.cc @ 47e836b

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