source: git/kernel/tgbgauss.cc @ f3a8c2e

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