source: git/kernel/tgbgauss.cc @ a82c308

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