source: git/libpolys/coeffs/bigintmat.cc @ 0acf3e

spielwiese
Last change on this file since 0acf3e was ba5e9e, checked in by Oleksandr Motsak <motsak@…>, 11 years ago
Changed configure-scripts to generate individual public config files for each package: resources, libpolys, singular (main) fix: sources should include correct corresponding config headers.
  • Property mode set to 100644
File size: 18.0 KB
RevLine 
[9127cc]1/*****************************************
[fe02b1]2 *  Computer Algebra System SINGULAR      *
3 *****************************************/
[9127cc]4/*
[fe02b1]5 * ABSTRACT: class bigintmat: matrizes of big integers
6 */
[83192d]7
8#ifdef HAVE_CONFIG_H
[ba5e9e]9#include "libpolysconfig.h"
[83192d]10#endif /* HAVE_CONFIG_H */
11
[84fc1f]12#include "bigintmat.h"
[fe02b1]13
[9127cc]14#include <misc/intvec.h>
[fe02b1]15
16//#include <kernel/mod2.h>
17//#include <kernel/options.h>
18
[9127cc]19#include <math.h>
20#include <string.h>
21
[6caad65]22// Ungetestet
23static void bimRowContent(bigintmat *bimat, int rowpos, int colpos);
24static void bimReduce(bigintmat *bimat, int rpiv, int colpos,
25                      int ready, int all);
26
27
28
[bca341]29//#define BIMATELEM(M,I,J) (M)[ (M).index(I,J) ]
[9127cc]30
[510dbc]31bigintmat * bigintmat::transpose()
32{
33  bigintmat * t = new bigintmat(col, row, basecoeffs());
34  for (int i=1; i<=row; i++)
35  {
36    for (int j=1; j<=col; j++)
37    {
[eea50a]38      t->set(j, i, BIMATELEM(*this,i,j));
[510dbc]39    }
40  }
41  return t;
42}
[9127cc]43
44// Beginnt bei [0]
[fe02b1]45void bigintmat::set(int i, number n, const coeffs C)
[9127cc]46{
[fe02b1]47  assume (C == NULL || C == basecoeffs());
48
49  rawset(i, n_Copy(n, basecoeffs()), basecoeffs());
[9127cc]50}
51
[fe02b1]52// Beginnt bei [1,1]
53void bigintmat::set(int i, int j, number n, const coeffs C)
[9127cc]54{
[fe02b1]55  assume (C == NULL || C == basecoeffs());
[81384b]56  assume (i >= 0 && j >= 0);
[fe02b1]57  assume (i <= rows() && j <= cols());
[75f10d]58
[fe02b1]59  set(index(i, j), n, C);
[9127cc]60}
61
[fe02b1]62number bigintmat::get(int i) const
[9127cc]63{
[fe02b1]64  assume (i >= 0);
65  assume (i<rows()*cols());
[75f10d]66
[fe02b1]67  return n_Copy(v[i], basecoeffs());
[9127cc]68}
69
[fe02b1]70number bigintmat::get(int i, int j) const
[9127cc]71{
[81384b]72  assume (i >= 0 && j >= 0);
[fe02b1]73  assume (i <= rows() && j <= cols());
[75f10d]74
[fe02b1]75  return get(index(i, j));
[9127cc]76}
77
78// Überladener *=-Operator (fÃŒr int und bigint)
79// Frage hier: *= verwenden oder lieber = und * einzeln?
80void bigintmat::operator*=(int intop)
81{
[fe02b1]82  number iop = n_Init(intop, basecoeffs());
[75f10d]83
[fe02b1]84  inpMult(iop, basecoeffs());
[75f10d]85
[fe02b1]86  n_Delete(&iop, basecoeffs());
[9127cc]87}
88
[fe02b1]89void bigintmat::inpMult(number bintop, const coeffs C)
[9127cc]90{
[fe02b1]91  assume (C == NULL || C == basecoeffs());
[75f10d]92
[fe02b1]93  const int l = rows() * cols();
94
95  for (int i=0; i < l; i++)
96    n_InpMult(v[i], bintop, basecoeffs());
[9127cc]97}
98
99// Stimmen Parameter?
100// Welche der beiden Methoden?
101// Oder lieber eine comp-Funktion?
102
[fe02b1]103bool operator==(const bigintmat & lhr, const bigintmat & rhr)
[9127cc]104{
105  if (&lhr == &rhr) { return true; }
106  if (lhr.cols() != rhr.cols()) { return false; }
107  if (lhr.rows() != rhr.rows()) { return false; }
[fe02b1]108  if (lhr.basecoeffs() != rhr.basecoeffs()) { return false; }
109
110  const int l = (lhr.rows())*(lhr.cols());
[75f10d]111
[fe02b1]112  for (int i=0; i < l; i++)
[9127cc]113  {
[fe02b1]114    if (!n_Equal(lhr[i], rhr[i], lhr.basecoeffs())) { return false; }
[9127cc]115  }
[75f10d]116
[9127cc]117  return true;
118}
119
[fe02b1]120bool operator!=(const bigintmat & lhr, const bigintmat & rhr)
[9127cc]121{
122  return !(lhr==rhr);
123}
124
125// Matrix-Add/-Sub/-Mult so oder mit operator+/-/* ?
126bigintmat * bimAdd(bigintmat * a, bigintmat * b)
127{
128  if (a->cols() != b->cols()) return NULL;
[eea50a]129  if (a->rows() != b->rows()) return NULL;
[fe02b1]130  if (a->basecoeffs() != b->basecoeffs()) { return NULL; }
[75f10d]131
[fe02b1]132  const coeffs basecoeffs = a->basecoeffs();
[75f10d]133
[fe02b1]134  int i;
135
[eea50a]136  bigintmat * bim = new bigintmat(a->rows(), a->cols(), basecoeffs);
[75f10d]137
[eea50a]138  for (i=a->rows()*a->cols()-1;i>=0; i--)
[fe02b1]139    bim->rawset(i, n_Add((*a)[i], (*b)[i], basecoeffs), basecoeffs);
[75f10d]140
141  return bim;
142}
143bigintmat * bimAdd(bigintmat * a, int b)
144{
145
146  const int mn = a->rows()*a->cols();
147
148  const coeffs basecoeffs = a->basecoeffs();
149  number bb=n_Init(b,basecoeffs);
150
151  int i;
152
153  bigintmat * bim = new bigintmat(a->rows(),a->cols() , basecoeffs);
154
155  for (i=0; i<mn; i++)
156    bim->rawset(i, n_Add((*a)[i], bb, basecoeffs), basecoeffs);
157
158  n_Delete(&bb,basecoeffs);
[9127cc]159  return bim;
160}
161
162bigintmat * bimSub(bigintmat * a, bigintmat * b)
163{
164  if (a->cols() != b->cols()) return NULL;
[eea50a]165  if (a->rows() != b->rows()) return NULL;
[fe02b1]166  if (a->basecoeffs() != b->basecoeffs()) { return NULL; }
167
168  const coeffs basecoeffs = a->basecoeffs();
169
170  int i;
171
[eea50a]172  bigintmat * bim = new bigintmat(a->rows(), a->cols(), basecoeffs);
[75f10d]173
[eea50a]174  for (i=a->rows()*a->cols()-1;i>=0; i--)
[fe02b1]175    bim->rawset(i, n_Sub((*a)[i], (*b)[i], basecoeffs), basecoeffs);
[75f10d]176
177  return bim;
178}
179
180bigintmat * bimSub(bigintmat * a, int b)
181{
182
183  const int mn = a->rows()*a->cols();
184
185  const coeffs basecoeffs = a->basecoeffs();
186  number bb=n_Init(b,basecoeffs);
187
188  int i;
189
190  bigintmat * bim = new bigintmat(a->rows(),a->cols() , basecoeffs);
191
192  for (i=0; i<mn; i++)
193    bim->rawset(i, n_Sub((*a)[i], bb, basecoeffs), basecoeffs);
194
195  n_Delete(&bb,basecoeffs);
[9127cc]196  return bim;
197}
198
199bigintmat * bimMult(bigintmat * a, bigintmat * b)
200{
[fe02b1]201  const int ca = a->cols();
202  const int cb = b->cols();
203
204  const int ra = a->rows();
205  const int rb = b->rows();
[75f10d]206
[fe02b1]207  if (ca != rb)
208  {
209#ifndef NDEBUG
210    Werror("wrong bigintmat sizes at multiplication a * b: acols: %d != brows: %d\n", ca, rb);
211#endif
212    return NULL;
213  }
[75f10d]214
[fe02b1]215  assume (ca == rb);
[75f10d]216
[fe02b1]217  if (a->basecoeffs() != b->basecoeffs()) { return NULL; }
[75f10d]218
[fe02b1]219  const coeffs basecoeffs = a->basecoeffs();
220
221  int i, j, k;
[75f10d]222
[9127cc]223  number sum;
[75f10d]224
[fe02b1]225  bigintmat * bim = new bigintmat(ra, cb, basecoeffs);
[75f10d]226
[510dbc]227  for (i=1; i<=ra; i++)
228    for (j=1; j<=cb; j++)
[9127cc]229    {
[fe02b1]230      sum = n_Init(0, basecoeffs);
[75f10d]231
[510dbc]232      for (k=1; k<=ca; k++)
[9127cc]233      {
[fe02b1]234        number prod = n_Mult( BIMATELEM(*a, i, k), BIMATELEM(*b, k, j), basecoeffs);
[75f10d]235
[fe02b1]236        number sum2 = n_Add(sum, prod, basecoeffs); // no inplace add :(
[75f10d]237
[fe02b1]238        n_Delete(&sum, basecoeffs); n_Delete(&prod, basecoeffs);
[75f10d]239
[9127cc]240        sum = sum2;
241      }
[510dbc]242      bim->rawset(i, j, sum, basecoeffs);
[9127cc]243    }
244  return bim;
245}
246
[75f10d]247bigintmat * bimMult(bigintmat * a, int b)
248{
249
250  const int mn = a->rows()*a->cols();
251
252  const coeffs basecoeffs = a->basecoeffs();
253  number bb=n_Init(b,basecoeffs);
254
255  int i;
256
257  bigintmat * bim = new bigintmat(a->rows(),a->cols() , basecoeffs);
258
259  for (i=0; i<mn; i++)
260    bim->rawset(i, n_Mult((*a)[i], bb, basecoeffs), basecoeffs);
261
262  n_Delete(&bb,basecoeffs);
263  return bim;
264}
265
266bigintmat * bimMult(bigintmat * a, number b, const coeffs cf)
267{
268  if (cf!=a->basecoeffs()) return NULL;
269
270  const int mn = a->rows()*a->cols();
271
272  const coeffs basecoeffs = a->basecoeffs();
273
274  int i;
275
276  bigintmat * bim = new bigintmat(a->rows(),a->cols() , basecoeffs);
277
278  for (i=0; i<mn; i++)
279    bim->rawset(i, n_Mult((*a)[i], b, basecoeffs), basecoeffs);
280
281  return bim;
282}
283
[fe02b1]284// ----------------------------------------------------------------- //
[9127cc]285// Korrekt?
286
287intvec * bim2iv(bigintmat * b)
288{
[fe02b1]289  intvec * iv = new intvec(b->rows(), b->cols(), 0);
290  for (int i=0; i<(b->rows())*(b->cols()); i++)
291    (*iv)[i] = n_Int((*b)[i], b->basecoeffs()); // Geht das so?
[9127cc]292  return iv;
293}
294
[fe02b1]295bigintmat * iv2bim(intvec * b, const coeffs C)
[9127cc]296{
[fe02b1]297  const int l = (b->rows())*(b->cols());
298  bigintmat * bim = new bigintmat(b->rows(), b->cols(), C);
[75f10d]299
[fe02b1]300  for (int i=0; i < l; i++)
301    bim->rawset(i, n_Init((*b)[i], C), C);
[75f10d]302
[9127cc]303  return bim;
304}
305
[fe02b1]306// ----------------------------------------------------------------- //
307
[9127cc]308int bigintmat::compare(const bigintmat* op) const
309{
[fe02b1]310  assume (basecoeffs() == op->basecoeffs() );
311
312#ifndef NDEBUG
313  if (basecoeffs() != op->basecoeffs() )
314    WerrorS("wrong bigintmat comparison: different basecoeffs!\n");
315#endif
316
[9127cc]317  if ((col!=1) ||(op->cols()!=1))
318  {
319    if((col!=op->cols())
[fe02b1]320       || (row!=op->rows()))
[9127cc]321      return -2;
322  }
[fe02b1]323
[9127cc]324  int i;
325  for (i=0; i<si_min(row*col,op->rows()*op->cols()); i++)
326  {
[fe02b1]327    if ( n_Greater(v[i], (*op)[i], basecoeffs()) )
[9127cc]328      return 1;
[fe02b1]329    else if (! n_Equal(v[i], (*op)[i], basecoeffs()))
[9127cc]330      return -1;
331  }
332
333  for (; i<row; i++)
334  {
[fe02b1]335    if ( n_GreaterZero(v[i], basecoeffs()) )
[9127cc]336      return 1;
[fe02b1]337    else if (! n_IsZero(v[i], basecoeffs()) )
[9127cc]338      return -1;
339  }
340  for (; i<op->rows(); i++)
341  {
[fe02b1]342    if ( n_GreaterZero((*op)[i], basecoeffs()) )
[9127cc]343      return -1;
[fe02b1]344    else if (! n_IsZero((*op)[i], basecoeffs()) )
[9127cc]345      return 1;
346  }
347  return 0;
348}
349
350
351bigintmat * bimCopy(const bigintmat * b)
352{
[fe02b1]353  if (b == NULL)
354    return NULL;
[75f10d]355
[fe02b1]356  return new bigintmat(b);
[9127cc]357}
358
359char* bigintmat::String()
360{
361  StringSetS("");
[fe02b1]362  const int l = cols()*rows();
363
364  n_Write(v[0], basecoeffs());
365  for (int i = 1; i < l; i++)
[9127cc]366  {
[fe02b1]367    StringAppendS(","); n_Write(v[i], basecoeffs());
[9127cc]368  }
[fe02b1]369  /* if (i != col*row-1)
370  {
371  StringAppendS(",");
372  if ((i+1)%col == 0)
373  StringAppendS("\n");
374  }   */
[538512]375  return StringEndS();
[9127cc]376}
377
[81384b]378char* bigintmat::StringAsPrinted()
379{
380  if ((col==0) || (row==0))
[3ee806]381    return NULL;
[81384b]382  else
383  {
384    int * colwid = getwid(80);
385    if (colwid == NULL)
386    {
387      WerrorS("not enough space to print bigintmat");
388      WerrorS("try string(...) for a unformatted output");
[3ee806]389      return NULL;
[81384b]390    }
[3ee806]391    char * ps;
[81384b]392    int slength = 0;
393    for (int j=0; j<col; j++)
394      slength += colwid[j]*row;
395    slength += col*row+row;
396    ps = (char*) omAlloc0(sizeof(char)*(slength));
397    int pos = 0;
398    for (int i=0; i<col*row; i++)
399    {
400      StringSetS("");
401      n_Write(v[i], basecoeffs());
402      char * ts = StringEndS();
403      const int _nl = strlen(ts);
404      int cj = i%col;
405      if (_nl > colwid[cj])
406      {
407        StringSetS("");
[008939]408        int ci = i/col;
[81384b]409        StringAppend("[%d,%d]", ci+1, cj+1);
410        char * ph = StringEndS();
411        int phl = strlen(ph);
412        if (phl > colwid[cj])
413        {
414          for (int j=0; j<colwid[cj]-1; j++)
415            ps[pos+j] = ' ';
416          ps[pos+colwid[cj]-1] = '*';
417        }
418        else
419        {
420          for (int j=0; j<colwid[cj]-phl; j++)
421            ps[pos+j] = ' ';
422          for (int j=0; j<phl; j++)
423            ps[pos+colwid[cj]-phl+j] = ph[j];
424        }
425        omFree(ph);
426      }
427      else  // Mit Leerzeichen auffÃŒllen und zahl reinschreiben
428      {
429        for (int j=0; j<colwid[cj]-_nl; j++)
430          ps[pos+j] = ' ';
431        for (int j=0; j<_nl; j++)
432          ps[pos+colwid[cj]-_nl+j] = ts[j];
433      }
434      // ", " und (evtl) "\n" einfÃŒgen
435      if ((i+1)%col == 0)
436      {
437        if (i != col*row-1)
438        {
439          ps[pos+colwid[cj]] = ',';
440          ps[pos+colwid[cj]+1] = '\n';
441          pos += colwid[cj]+2;
442        }
443      }
444      else
445      {
446        ps[pos+colwid[cj]] = ',';
447        pos += colwid[cj]+1;
448      }
449
450      omFree(ts);  // Hier ts zerstören
451    }
452    return(ps);
453    // omFree(ps);
454  }
455  // if ((col==0) || (row==0))
456  //   return 0;
457  // int * colwid = getwid(80);
458  // if (colwid == NULL)
459  // {
460  //   WerrorS("not enough space to print bigintmat");
461  //   WerrorS("try string(...) for a unformatted output");
462  //   return 0;
463  // }
464  // char * ps;
465  // int slength = 0;
466  // for (int j=0; j<col; j++)
467  //   slength += colwid[j]*row;
468  // slength += 2*(col-1)*row+2*row-1;
469  // ps = (char*) omAlloc0(sizeof(char)*(slength));
470  // int pos = 0;
471  // for (int i=0; i<col*row; i++)
472  // {
473  //   StringSetS("");
474  //   n_Write(v[i], basecoeffs());
475  //   char * temp = StringAppendS("");
476  //   char * ts = omStrDup(temp);
477  //   int nl = strlen(ts);
478  //   int cj = i%col;
479  //   if (nl > colwid[cj])
480  //   {
481  //     StringSetS("");
482  //     int ci = floor(i/col);
483  //     StringAppend("[%d,%d]", ci+1, cj+1);
484  //     char *tmp = StringAppendS("");
485  //     char * ph = omStrDup(tmp);
486  //     int phl = strlen(ph);
487  //     if (phl > colwid[cj])
488  //     {
489  //       for (int j=0; j<colwid[cj]; j++)
490  //         ps[pos+j] = '*';
491  //     }
492  //     else
493  //     {
494  //       for (int j=0; j<colwid[cj]-phl; j++)
495  //         ps[pos+j] = ' ';
496  //       for (int j=0; j<phl; j++)
497  //         ps[pos+colwid[cj]-phl+j] = ph[j];
498  //     }
499  //     omFree(ph);
500  //   }
501  //   else  // Mit Leerzeichen auffÃŒllen und Zahl reinschreiben
502  //   {
503  //     for (int j=0; j<colwid[cj]-nl; j++)
504  //       ps[pos+j] = ' ';
505  //     for (int j=0; j<nl; j++)
506  //       ps[pos+colwid[cj]-nl+j] = ts[j];
507  //   }
508  //   // ", " oder "\n" einfÃŒgen
509  //   if ((i+1)%col == 0)
510  //   {
511  //     if (i != col*row-1)
512  //     {
513  //       ps[pos+colwid[cj]] = ',';
514  //       ps[pos+colwid[cj]+1] = '\n';
515  //       pos += colwid[cj]+2;
516  //     }
517  //   }
518  //   else
519  //   {
520  //     ps[pos+colwid[cj]] = ',';
521  //     ps[pos+colwid[cj]+1] = ' ';
522  //     pos += colwid[cj]+2;
523  //   }
524  //   omFree(ts);
525  // }
526  // return ps;
527}
528
[510dbc]529int intArrSum(int * a, int length)
530{
531  int sum = 0;
532  for (int i=0; i<length; i++)
533    sum += a[i];
534  return sum;
535}
536
537int findLongest(int * a, int length)
[9127cc]538{
[510dbc]539  int l = 0;
540  int index;
541  for (int i=0; i<length; i++)
[9127cc]542  {
[510dbc]543    if (a[i] > l)
[9127cc]544    {
[510dbc]545      l = a[i];
546      index = i;
547    }
548  }
549  return index;
550}
551
552int getShorter (int * a, int l, int j, int cols, int rows)
553{
554  int sndlong = 0;
555  int min;
556  for (int i=0; i<rows; i++)
557  {
558    int index = cols*i+j;
559    if ((a[index] > sndlong) && (a[index] < l))
560    {
[008939]561      min = floor(log10((double)cols))+floor(log10((double)rows))+5;
[510dbc]562      if ((a[index] < min) && (min < l))
563        sndlong = min;
[9127cc]564      else
[510dbc]565        sndlong = a[index];
[9127cc]566    }
567  }
[510dbc]568  if (sndlong == 0)
569  {
[008939]570    min = floor(log10((double)cols))+floor(log10((double)rows))+5;
[510dbc]571    if (min < l)
572      sndlong = min;
573    else
574      sndlong = 1;
575  }
576  return sndlong;
577}
578
579
580int * bigintmat::getwid(int maxwid)
581{
582  int const c = /*2**/(col-1)+1;
583  if (col + c > maxwid-1) return NULL;
584  int * wv = (int*)omAlloc(sizeof(int)*col*row);
585  int * cwv = (int*)omAlloc(sizeof(int)*col);
586  for (int j=0; j<col; j++)
587  {
588    cwv[j] = 0;
589    for (int i=0; i<row; i++)
590    {
591      StringSetS("");
592      n_Write(v[col*i+j], basecoeffs());
[538512]593      char * tmp = StringEndS();
[510dbc]594      const int _nl = strlen(tmp);
595      wv[col*i+j] = _nl;
596      if (_nl > cwv[j])
597        cwv[j]=_nl;
[538512]598      omFree(tmp);
[510dbc]599    }
600  }
601
602  // Groesse verkleinern, bis < maxwid
603  while (intArrSum(cwv, col)+c > maxwid)
604  {
605    int j = findLongest(cwv, col);
606    cwv[j] = getShorter(wv, cwv[j], j, col, row);
607  }
608  omFree(wv);
609  return cwv;
[9127cc]610}
611
612void bigintmat::pprint(int maxwid)
613{
614  if ((col==0) || (row==0))
615    PrintS("");
616  else
617  {
[510dbc]618    int * colwid = getwid(maxwid);
619    if (colwid == NULL)
620    {
621      WerrorS("not enough space to print bigintmat");
622      return;
623    }
[9127cc]624    char * ps;
[510dbc]625    int slength = 0;
626    for (int j=0; j<col; j++)
627      slength += colwid[j]*row;
628    slength += col*row+row;
629    ps = (char*) omAlloc0(sizeof(char)*(slength));
[9127cc]630    int pos = 0;
631    for (int i=0; i<col*row; i++)
632    {
633      StringSetS("");
[fe02b1]634      n_Write(v[i], basecoeffs());
[538512]635      char * ts = StringEndS();
[fe02b1]636      const int _nl = strlen(ts);
[510dbc]637      int cj = i%col;
638      if (_nl > colwid[cj])
[9127cc]639      {
640        StringSetS("");
[008939]641        int ci = i/col;
[9127cc]642        StringAppend("[%d,%d]", ci+1, cj+1);
[538512]643        char * ph = StringEndS();
[9127cc]644        int phl = strlen(ph);
[510dbc]645        if (phl > colwid[cj])
[9127cc]646        {
[510dbc]647          for (int j=0; j<colwid[cj]-1; j++)
648            ps[pos+j] = ' ';
649          ps[pos+colwid[cj]-1] = '*';
[9127cc]650        }
651        else
652        {
[510dbc]653          for (int j=0; j<colwid[cj]-phl; j++)
[9127cc]654            ps[pos+j] = ' ';
655          for (int j=0; j<phl; j++)
[510dbc]656            ps[pos+colwid[cj]-phl+j] = ph[j];
[9127cc]657        }
658        omFree(ph);
659      }
660      else  // Mit Leerzeichen auffÃŒllen und zahl reinschreiben
661      {
[510dbc]662        for (int j=0; j<colwid[cj]-_nl; j++)
[9127cc]663          ps[pos+j] = ' ';
[fe02b1]664        for (int j=0; j<_nl; j++)
[510dbc]665          ps[pos+colwid[cj]-_nl+j] = ts[j];
[9127cc]666      }
[510dbc]667      // ", " und (evtl) "\n" einfÃŒgen
[9127cc]668      if ((i+1)%col == 0)
669      {
670        if (i != col*row-1)
671        {
[510dbc]672          ps[pos+colwid[cj]] = ',';
673          ps[pos+colwid[cj]+1] = '\n';
674          pos += colwid[cj]+2;
[9127cc]675        }
676      }
677      else
678      {
[510dbc]679        ps[pos+colwid[cj]] = ',';
680        pos += colwid[cj]+1;
[9127cc]681      }
[510dbc]682
683      omFree(ts);  // Hier ts zerstören
[9127cc]684    }
685    PrintS(ps);
[510dbc]686   // omFree(ps);
[9127cc]687  }
688}
689
690// Ungetestet
[e3f523]691// (According to C. Fieker) Seems to have a lot of memory leaks (pure adaptation of the
692// corresponding method for intmat) due to return statements
[9127cc]693static void bimRowContent(bigintmat *bimat, int rowpos, int colpos)
694{
[fe02b1]695  const coeffs basecoeffs = bimat->basecoeffs();
[75f10d]696
[9127cc]697  number tgcd, m;
698  int i=bimat->cols();
699
700  loop
701  {
[fe02b1]702    tgcd = n_Copy(BIMATELEM(*bimat,rowpos,i--), basecoeffs);
703    if (! n_IsZero(tgcd, basecoeffs)) break;
[9127cc]704    if (i<colpos) return;
705  }
[fe02b1]706  if ((! n_GreaterZero(tgcd, basecoeffs)) && (! n_IsZero(tgcd, basecoeffs))) tgcd = n_Neg(tgcd, basecoeffs);
707  if ( n_IsOne(tgcd,basecoeffs)) return;
[9127cc]708  loop
709  {
[fe02b1]710    m = n_Copy(BIMATELEM(*bimat,rowpos,i--), basecoeffs);
711    if (! n_IsZero(m,basecoeffs))
[9127cc]712    {
[fe02b1]713      number tp1 = n_Gcd(tgcd, m, basecoeffs);
714      n_Delete(&tgcd, basecoeffs);
[9127cc]715      tgcd = tp1;
716    }
[fe02b1]717    if ( n_IsOne(tgcd,basecoeffs)) return;
[9127cc]718    if (i<colpos) break;
719  }
720  for (i=bimat->cols();i>=colpos;i--)
721  {
[fe02b1]722    number tp2 = n_Div(BIMATELEM(*bimat,rowpos,i), tgcd,basecoeffs);
723    n_Delete(&BIMATELEM(*bimat,rowpos,i), basecoeffs);
[9127cc]724    BIMATELEM(*bimat,rowpos,i) = tp2;
725  }
[fe02b1]726  n_Delete(&tgcd, basecoeffs);
727  n_Delete(&m, basecoeffs);
[9127cc]728}
729
730static void bimReduce(bigintmat *bimat, int rpiv, int colpos,
[fe02b1]731                      int ready, int all)
[9127cc]732{
[fe02b1]733  const coeffs basecoeffs = bimat->basecoeffs();
734
[9127cc]735  number tgcd, ce, m1, m2;
736  int j, i;
737  number piv = BIMATELEM(*bimat,rpiv,colpos);
738
739  for (j=all;j>ready;j--)
740  {
[fe02b1]741    ce = n_Copy(BIMATELEM(*bimat,j,colpos),basecoeffs);
742    if (! n_IsZero(ce, basecoeffs))
[9127cc]743    {
[fe02b1]744      n_Delete(&BIMATELEM(*bimat,j,colpos), basecoeffs);
745      BIMATELEM(*bimat,j,colpos) = n_Init(0, basecoeffs);
746      m1 = n_Copy(piv,basecoeffs);
747      m2 = n_Copy(ce,basecoeffs);
748      tgcd = n_Gcd(m1, m2, basecoeffs);
749      if (! n_IsOne(tgcd,basecoeffs))
[9127cc]750      {
[fe02b1]751        number tp1 = n_Div(m1, tgcd,basecoeffs);
752        number tp2 = n_Div(m2, tgcd,basecoeffs);
753        n_Delete(&m1, basecoeffs);
754        n_Delete(&m2, basecoeffs);
[9127cc]755        m1 = tp1;
756        m2 = tp2;
757      }
758      for (i=bimat->cols();i>colpos;i--)
759      {
[fe02b1]760        n_Delete(&BIMATELEM(*bimat,j,i), basecoeffs);
761        number tp1 = n_Mult(BIMATELEM(*bimat,j,i), m1,basecoeffs);
762        number tp2 = n_Mult(BIMATELEM(*bimat,rpiv,i), m2,basecoeffs);
763        BIMATELEM(*bimat,j,i) = n_Sub(tp1, tp2,basecoeffs);
764        n_Delete(&tp1, basecoeffs);
765        n_Delete(&tp2, basecoeffs);
[9127cc]766      }
767      bimRowContent(bimat, j, colpos+1);
[fe02b1]768      n_Delete(&m1, basecoeffs);
769      n_Delete(&m2, basecoeffs);
[9127cc]770    }
[fe02b1]771    n_Delete(&ce, basecoeffs);
[9127cc]772  }
773}
774
[e9d581]775// columnwise concatination of two bigintmats
776bigintmat * bimConcat(bigintmat * a, bigintmat * b, const coeffs cf)
777{
778  int ac=a->cols();
779  int r=si_max(a->rows(),b->rows());
780  bigintmat * ab = new bigintmat(r,ac + b->cols(),cf);
[9127cc]781
[e9d581]782  int i,j;
783  for (i=1; i<=a->rows(); i++)
784  {
785    for (j=1; j<=ac; j++)
786    {
787      n_Delete(&(BIMATELEM(*ab,i,j)),cf);
788      BIMATELEM(*ab,i,j)=n_Copy(BIMATELEM(*a,i,j),cf);
789    }
790  }
[9127cc]791
[e9d581]792  for (i=1; i<=b->rows(); i++)
793  {
794    for (j=1; j<=b->cols(); j++)
795    {
796      n_Delete(&(BIMATELEM(*ab,i,j+ac)),cf);
797      BIMATELEM(*ab,i,j+ac)=n_Copy(BIMATELEM(*b,i,j),cf);
798    }
799  }
[9127cc]800
[e9d581]801  return ab;
802}
[9127cc]803
Note: See TracBrowser for help on using the repository browser.