source: git/libpolys/polys/matpol.cc @ dd930e5

spielwiese
Last change on this file since dd930e5 was dd930e5, checked in by Hans Schoenemann <hannes@…>, 8 years ago
add: mp_Compare
  • Property mode set to 100644
File size: 32.2 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4
5/*
6* ABSTRACT:
7*/
8
9#include <stdio.h>
10#include <math.h>
11
12
13
14
15#include <misc/auxiliary.h>
16
17#include <omalloc/omalloc.h>
18#include <misc/mylimits.h>
19
20
21// #include <kernel/structs.h>
22// #include <kernel/GBEngine/kstd1.h>
23// #include <kernel/polys.h>
24
25#include <misc/intvec.h>
26#include <coeffs/numbers.h>
27
28#include <reporter/reporter.h>
29
30
31#include "monomials/ring.h"
32#include "monomials/p_polys.h"
33
34#include "coeffrings.h"
35#include "simpleideals.h"
36#include "matpol.h"
37#include "prCopy.h"
38
39#include "sparsmat.h"
40
41//omBin sip_sideal_bin = omGetSpecBin(sizeof(ip_smatrix));
42/*0 implementation*/
43
44static poly mp_Exdiv ( poly m, poly d, poly vars, const ring);
45static poly mp_Select (poly fro, poly what, const ring);
46
47/// create a r x c zero-matrix
48matrix mpNew(int r, int c)
49{
50  int rr=r;
51  if (rr<=0) rr=1;
52  if ( (((int)(MAX_INT_VAL/sizeof(poly))) / rr) <= c)
53  {
54    Werror("internal error: creating matrix[%d][%d]",r,c);
55    return NULL;
56  }
57  matrix rc = (matrix)omAllocBin(sip_sideal_bin);
58  rc->nrows = r;
59  rc->ncols = c;
60  rc->rank = r;
61  if ((c != 0)&&(r!=0))
62  {
63    int s=r*c*sizeof(poly);
64    rc->m = (poly*)omAlloc0(s);
65    //if (rc->m==NULL)
66    //{
67    //  Werror("internal error: creating matrix[%d][%d]",r,c);
68    //  return NULL;
69    //}
70  }
71  return rc;
72}
73
74/// copies matrix a (from ring r to r)
75matrix mp_Copy (matrix a, const ring r)
76{
77  id_Test((ideal)a, r);
78  poly t;
79  int i, m=MATROWS(a), n=MATCOLS(a);
80  matrix b = mpNew(m, n);
81
82  for (i=m*n-1; i>=0; i--)
83  {
84    t = a->m[i];
85    if (t!=NULL)
86    {
87      p_Normalize(t, r);
88      b->m[i] = p_Copy(t, r);
89    }
90  }
91  b->rank=a->rank;
92  return b;
93}
94
95/// copies matrix a from rSrc into rDst
96matrix mp_Copy(const matrix a, const ring rSrc, const ring rDst)
97{
98  id_Test((ideal)a, rSrc);
99
100  poly t;
101  int i, m=MATROWS(a), n=MATCOLS(a);
102
103  matrix b = mpNew(m, n);
104
105  for (i=m*n-1; i>=0; i--)
106  {
107    t = a->m[i];
108    if (t!=NULL)
109    {
110      b->m[i] = prCopyR_NoSort(t, rSrc, rDst);
111      p_Normalize(b->m[i], rDst);
112    }
113  }
114  b->rank=a->rank;
115
116  id_Test((ideal)b, rDst);
117
118  return b;
119}
120
121
122
123/// make it a p * unit matrix
124matrix mp_InitP(int r, int c, poly p, const ring R)
125{
126  matrix rc = mpNew(r,c);
127  int i=si_min(r,c), n = c*(i-1)+i-1, inc = c+1;
128
129  p_Normalize(p, R);
130  while (n>0)
131  {
132    rc->m[n] = p_Copy(p, R);
133    n -= inc;
134  }
135  rc->m[0]=p;
136  return rc;
137}
138
139/// make it a v * unit matrix
140matrix mp_InitI(int r, int c, int v, const ring R)
141{
142  return mp_InitP(r, c, p_ISet(v, R), R);
143}
144
145/// c = f*a
146matrix mp_MultI(matrix a, int f, const ring R)
147{
148  int k, n = a->nrows, m = a->ncols;
149  poly p = p_ISet(f, R);
150  matrix c = mpNew(n,m);
151
152  for (k=m*n-1; k>0; k--)
153    c->m[k] = pp_Mult_qq(a->m[k], p, R);
154  c->m[0] = p_Mult_q(p_Copy(a->m[0], R), p, R);
155  return c;
156}
157
158/// multiply a matrix 'a' by a poly 'p', destroy the args
159matrix mp_MultP(matrix a, poly p, const ring R)
160{
161  int k, n = a->nrows, m = a->ncols;
162
163  p_Normalize(p, R);
164  for (k=m*n-1; k>0; k--)
165  {
166    if (a->m[k]!=NULL)
167      a->m[k] = p_Mult_q(a->m[k], p_Copy(p, R), R);
168  }
169  a->m[0] = p_Mult_q(a->m[0], p, R);
170  return a;
171}
172
173/*2
174* multiply a poly 'p' by a matrix 'a', destroy the args
175*/
176matrix pMultMp(poly p, matrix a, const ring R)
177{
178  int k, n = a->nrows, m = a->ncols;
179
180  p_Normalize(p, R);
181  for (k=m*n-1; k>0; k--)
182  {
183    if (a->m[k]!=NULL)
184      a->m[k] = p_Mult_q(p_Copy(p, R), a->m[k], R);
185  }
186  a->m[0] = p_Mult_q(p, a->m[0], R);
187  return a;
188}
189
190matrix mp_Add(matrix a, matrix b, const ring R)
191{
192  int k, n = a->nrows, m = a->ncols;
193  if ((n != b->nrows) || (m != b->ncols))
194  {
195/*
196*    Werror("cannot add %dx%d matrix and %dx%d matrix",
197*      m,n,b->cols(),b->rows());
198*/
199    return NULL;
200  }
201  matrix c = mpNew(n,m);
202  for (k=m*n-1; k>=0; k--)
203    c->m[k] = p_Add_q(p_Copy(a->m[k], R), p_Copy(b->m[k], R), R);
204  return c;
205}
206
207matrix mp_Sub(matrix a, matrix b, const ring R)
208{
209  int k, n = a->nrows, m = a->ncols;
210  if ((n != b->nrows) || (m != b->ncols))
211  {
212/*
213*    Werror("cannot sub %dx%d matrix and %dx%d matrix",
214*      m,n,b->cols(),b->rows());
215*/
216    return NULL;
217  }
218  matrix c = mpNew(n,m);
219  for (k=m*n-1; k>=0; k--)
220    c->m[k] = p_Sub(p_Copy(a->m[k], R), p_Copy(b->m[k], R), R);
221  return c;
222}
223
224matrix mp_Mult(matrix a, matrix b, const ring R)
225{
226  int i, j, k;
227  int m = MATROWS(a);
228  int p = MATCOLS(a);
229  int q = MATCOLS(b);
230
231  if (p!=MATROWS(b))
232  {
233/*
234*   Werror("cannot multiply %dx%d matrix and %dx%d matrix",
235*     m,p,b->rows(),q);
236*/
237    return NULL;
238  }
239  matrix c = mpNew(m,q);
240
241  for (i=1; i<=m; i++)
242  {
243    for (k=1; k<=p; k++)
244    {
245      poly aik;
246      if ((aik=MATELEM(a,i,k))!=NULL)
247      {
248        for (j=1; j<=q; j++)
249        {
250          poly bkj;
251          if ((bkj=MATELEM(b,k,j))!=NULL)
252          {
253            poly *cij=&(MATELEM(c,i,j));
254            poly s = pp_Mult_qq(aik /*MATELEM(a,i,k)*/, bkj/*MATELEM(b,k,j)*/, R);
255            if (/*MATELEM(c,i,j)*/ (*cij)==NULL) (*cij)=s;
256            else (*cij) = p_Add_q((*cij) /*MATELEM(c,i,j)*/ ,s, R);
257          }
258        }
259      }
260    //  pNormalize(t);
261    //  MATELEM(c,i,j) = t;
262    }
263  }
264  for(i=m*q-1;i>=0;i--) p_Normalize(c->m[i], R);
265  return c;
266}
267
268matrix mp_Transp(matrix a, const ring R)
269{
270  int    i, j, r = MATROWS(a), c = MATCOLS(a);
271  poly *p;
272  matrix b =  mpNew(c,r);
273
274  p = b->m;
275  for (i=0; i<c; i++)
276  {
277    for (j=0; j<r; j++)
278    {
279      if (a->m[j*c+i]!=NULL) *p = p_Copy(a->m[j*c+i], R);
280      p++;
281    }
282  }
283  return b;
284}
285
286/*2
287*returns the trace of matrix a
288*/
289poly mp_Trace ( matrix a, const ring R)
290{
291  int i;
292  int n = (MATCOLS(a)<MATROWS(a)) ? MATCOLS(a) : MATROWS(a);
293  poly  t = NULL;
294
295  for (i=1; i<=n; i++)
296    t = p_Add_q(t, p_Copy(MATELEM(a,i,i), R), R);
297  return t;
298}
299
300/*2
301*returns the trace of the product of a and b
302*/
303poly TraceOfProd ( matrix a, matrix b, int n, const ring R)
304{
305  int i, j;
306  poly  p, t = NULL;
307
308  for (i=1; i<=n; i++)
309  {
310    for (j=1; j<=n; j++)
311    {
312      p = pp_Mult_qq(MATELEM(a,i,j), MATELEM(b,j,i), R);
313      t = p_Add_q(t, p, R);
314    }
315  }
316  return t;
317}
318
319// #ifndef SIZE_OF_SYSTEM_PAGE
320// #define SIZE_OF_SYSTEM_PAGE 4096
321// #endif
322
323/*2
324* corresponds to Maple's coeffs:
325* var has to be the number of a variable
326*/
327matrix mp_Coeffs (ideal I, int var, const ring R)
328{
329  poly h,f;
330  int l, i, c, m=0;
331  matrix co;
332  /* look for maximal power m of x_var in I */
333  for (i=IDELEMS(I)-1; i>=0; i--)
334  {
335    f=I->m[i];
336    while (f!=NULL)
337    {
338      l=p_GetExp(f,var, R);
339      if (l>m) m=l;
340      pIter(f);
341    }
342  }
343  co=mpNew((m+1)*I->rank,IDELEMS(I));
344  /* divide each monomial by a power of x_var,
345  * remember the power in l and the component in c*/
346  for (i=IDELEMS(I)-1; i>=0; i--)
347  {
348    f=I->m[i];
349    I->m[i]=NULL;
350    while (f!=NULL)
351    {
352      l=p_GetExp(f,var, R);
353      p_SetExp(f,var,0, R);
354      c=si_max((int)p_GetComp(f, R),1);
355      p_SetComp(f,0, R);
356      p_Setm(f, R);
357      /* now add the resulting monomial to co*/
358      h=pNext(f);
359      pNext(f)=NULL;
360      //MATELEM(co,c*(m+1)-l,i+1)
361      //  =p_Add_q(MATELEM(co,c*(m+1)-l,i+1),f, R);
362      MATELEM(co,(c-1)*(m+1)+l+1,i+1)
363        =p_Add_q(MATELEM(co,(c-1)*(m+1)+l+1,i+1),f, R);
364      /* iterate f*/
365      f=h;
366    }
367  }
368  id_Delete(&I, R);
369  return co;
370}
371
372/*2
373* given the result c of mpCoeffs(ideal/module i, var)
374* i of rank r
375* build the matrix of the corresponding monomials in m
376*/
377void   mp_Monomials(matrix c, int r, int var, matrix m, const ring R)
378{
379  /* clear contents of m*/
380  int k,l;
381  for (k=MATROWS(m);k>0;k--)
382  {
383    for(l=MATCOLS(m);l>0;l--)
384    {
385      p_Delete(&MATELEM(m,k,l), R);
386    }
387  }
388  omfreeSize((ADDRESS)m->m,MATROWS(m)*MATCOLS(m)*sizeof(poly));
389  /* allocate monoms in the right size r x MATROWS(c)*/
390  m->m=(poly*)omAlloc0(r*MATROWS(c)*sizeof(poly));
391  MATROWS(m)=r;
392  MATCOLS(m)=MATROWS(c);
393  m->rank=r;
394  /* the maximal power p of x_var: MATCOLS(m)=r*(p+1) */
395  int p=MATCOLS(m)/r-1;
396  /* fill in the powers of x_var=h*/
397  poly h=p_One(R);
398  for(k=r;k>0; k--)
399  {
400    MATELEM(m,k,k*(p+1))=p_One(R);
401  }
402  for(l=p;l>=0; l--)
403  {
404    p_SetExp(h,var,p-l, R);
405    p_Setm(h, R);
406    for(k=r;k>0; k--)
407    {
408      MATELEM(m,k,k*(p+1)-l)=p_Copy(h, R);
409    }
410  }
411  p_Delete(&h, R);
412}
413
414matrix mp_CoeffProc (poly f, poly vars, const ring R)
415{
416  assume(vars!=NULL);
417  poly sel, h;
418  int l, i;
419  int pos_of_1 = -1;
420  matrix co;
421
422  if (f==NULL)
423  {
424    co = mpNew(2, 1);
425    MATELEM(co,1,1) = p_One(R);
426    MATELEM(co,2,1) = NULL;
427    return co;
428  }
429  sel = mp_Select(f, vars, R);
430  l = pLength(sel);
431  co = mpNew(2, l);
432
433  if (rHasLocalOrMixedOrdering(R))
434  {
435    for (i=l; i>=1; i--)
436    {
437      h = sel;
438      pIter(sel);
439      pNext(h)=NULL;
440      MATELEM(co,1,i) = h;
441      MATELEM(co,2,i) = NULL;
442      if (p_IsConstant(h, R)) pos_of_1 = i;
443    }
444  }
445  else
446  {
447    for (i=1; i<=l; i++)
448    {
449      h = sel;
450      pIter(sel);
451      pNext(h)=NULL;
452      MATELEM(co,1,i) = h;
453      MATELEM(co,2,i) = NULL;
454      if (p_IsConstant(h, R)) pos_of_1 = i;
455    }
456  }
457  while (f!=NULL)
458  {
459    i = 1;
460    loop
461    {
462      if (i!=pos_of_1)
463      {
464        h = mp_Exdiv(f, MATELEM(co,1,i),vars, R);
465        if (h!=NULL)
466        {
467          MATELEM(co,2,i) = p_Add_q(MATELEM(co,2,i), h, R);
468          break;
469        }
470      }
471      if (i == l)
472      {
473        // check monom 1 last:
474        if (pos_of_1 != -1)
475        {
476          h = mp_Exdiv(f, MATELEM(co,1,pos_of_1),vars, R);
477          if (h!=NULL)
478          {
479            MATELEM(co,2,pos_of_1) = p_Add_q(MATELEM(co,2,pos_of_1), h, R);
480          }
481        }
482        break;
483      }
484      i ++;
485    }
486    pIter(f);
487  }
488  return co;
489}
490
491/*2
492*exact divisor: let d  == x^i*y^j, m is thought to have only one term;
493*    return m/d iff d divides m, and no x^k*y^l (k>i or l>j) divides m
494* consider all variables in vars
495*/
496static poly mp_Exdiv ( poly m, poly d, poly vars, const ring R)
497{
498  int i;
499  poly h = p_Head(m, R);
500  for (i=1; i<=rVar(R); i++)
501  {
502    if (p_GetExp(vars,i, R) > 0)
503    {
504      if (p_GetExp(d,i, R) != p_GetExp(h,i, R))
505      {
506        p_Delete(&h, R);
507        return NULL;
508      }
509      p_SetExp(h,i,0, R);
510    }
511  }
512  p_Setm(h, R);
513  return h;
514}
515
516void mp_Coef2(poly v, poly mon, matrix *c, matrix *m, const ring R)
517{
518  poly* s;
519  poly p;
520  int sl,i,j;
521  int l=0;
522  poly sel=mp_Select(v,mon, R);
523
524  p_Vec2Polys(sel,&s,&sl, R);
525  for (i=0; i<sl; i++)
526    l=si_max(l,pLength(s[i]));
527  *c=mpNew(sl,l);
528  *m=mpNew(sl,l);
529  poly h;
530  int isConst;
531  for (j=1; j<=sl;j++)
532  {
533    p=s[j-1];
534    if (p_IsConstant(p, R)) /*p != NULL */
535    {
536      isConst=-1;
537      i=l;
538    }
539    else
540    {
541      isConst=1;
542      i=1;
543    }
544    while(p!=NULL)
545    {
546      h = p_Head(p, R);
547      MATELEM(*m,j,i) = h;
548      i+=isConst;
549      p = p->next;
550    }
551  }
552  while (v!=NULL)
553  {
554    i = 1;
555    j = p_GetComp(v, R);
556    loop
557    {
558      poly mp=MATELEM(*m,j,i);
559      if (mp!=NULL)
560      {
561        h = mp_Exdiv(v, mp /*MATELEM(*m,j,i)*/, mp, R);
562        if (h!=NULL)
563        {
564          p_SetComp(h,0, R);
565          MATELEM(*c,j,i) = p_Add_q(MATELEM(*c,j,i), h, R);
566          break;
567        }
568      }
569      if (i < l)
570        i++;
571      else
572        break;
573    }
574    v = v->next;
575  }
576}
577
578/*2
579* insert a monomial into a list, avoid duplicates
580* arguments are destroyed
581*/
582static poly p_Insert(poly p1, poly p2, const ring R)
583{
584  poly a1, p, a2, a;
585  int c;
586
587  if (p1==NULL) return p2;
588  if (p2==NULL) return p1;
589  a1 = p1;
590  a2 = p2;
591  a = p  = p_One(R);
592  loop
593  {
594    c = p_Cmp(a1, a2, R);
595    if (c == 1)
596    {
597      a = pNext(a) = a1;
598      pIter(a1);
599      if (a1==NULL)
600      {
601        pNext(a) = a2;
602        break;
603      }
604    }
605    else if (c == -1)
606    {
607      a = pNext(a) = a2;
608      pIter(a2);
609      if (a2==NULL)
610      {
611        pNext(a) = a1;
612        break;
613      }
614    }
615    else
616    {
617      p_LmDelete(&a2, R);
618      a = pNext(a) = a1;
619      pIter(a1);
620      if (a1==NULL)
621      {
622        pNext(a) = a2;
623        break;
624      }
625      else if (a2==NULL)
626      {
627        pNext(a) = a1;
628        break;
629      }
630    }
631  }
632  p_LmDelete(&p, R);
633  return p;
634}
635
636/*2
637*if what == xy the result is the list of all different power products
638*    x^i*y^j (i, j >= 0) that appear in fro
639*/
640static poly mp_Select (poly fro, poly what, const ring R)
641{
642  int i;
643  poly h, res;
644  res = NULL;
645  while (fro!=NULL)
646  {
647    h = p_One(R);
648    for (i=1; i<=rVar(R); i++)
649      p_SetExp(h,i, p_GetExp(fro,i, R) * p_GetExp(what, i, R), R);
650    p_SetComp(h, p_GetComp(fro, R), R);
651    p_Setm(h, R);
652    res = p_Insert(h, res, R);
653    fro = fro->next;
654  }
655  return res;
656}
657
658/*
659*static void ppp(matrix a)
660*{
661*  int j,i,r=a->nrows,c=a->ncols;
662*  for(j=1;j<=r;j++)
663*  {
664*    for(i=1;i<=c;i++)
665*    {
666*      if(MATELEM(a,j,i)!=NULL) PrintS("X");
667*      else PrintS("0");
668*    }
669*    PrintLn();
670*  }
671*}
672*/
673
674static void mp_PartClean(matrix a, int lr, int lc, const ring R)
675{
676  poly *q1;
677  int i,j;
678
679  for (i=lr-1;i>=0;i--)
680  {
681    q1 = &(a->m)[i*a->ncols];
682    for (j=lc-1;j>=0;j--) if(q1[j]) p_Delete(&q1[j], R);
683  }
684}
685
686BOOLEAN mp_IsDiagUnit(matrix U, const ring R)
687{
688  if(MATROWS(U)!=MATCOLS(U))
689    return FALSE;
690  for(int i=MATCOLS(U);i>=1;i--)
691  {
692    for(int j=MATCOLS(U); j>=1; j--)
693    {
694      if (i==j)
695      {
696        if (!p_IsUnit(MATELEM(U,i,i), R)) return FALSE;
697      }
698      else if (MATELEM(U,i,j)!=NULL) return FALSE;
699    }
700  }
701  return TRUE;
702}
703
704void iiWriteMatrix(matrix im, const char *n, int dim, const ring r, int spaces)
705{
706  int i,ii = MATROWS(im)-1;
707  int j,jj = MATCOLS(im)-1;
708  poly *pp = im->m;
709
710  for (i=0; i<=ii; i++)
711  {
712    for (j=0; j<=jj; j++)
713    {
714      if (spaces>0)
715        Print("%-*.*s",spaces,spaces," ");
716      if (dim == 2) Print("%s[%u,%u]=",n,i+1,j+1);
717      else if (dim == 1) Print("%s[%u]=",n,j+1);
718      else if (dim == 0) Print("%s=",n);
719      if ((i<ii)||(j<jj)) p_Write(*pp++, r);
720      else                p_Write0(*pp, r);
721    }
722  }
723}
724
725char * iiStringMatrix(matrix im, int dim, const ring r, char ch)
726{
727  int i,ii = MATROWS(im);
728  int j,jj = MATCOLS(im);
729  poly *pp = im->m;
730  char ch_s[2];
731  ch_s[0]=ch;
732  ch_s[1]='\0';
733
734  StringSetS("");
735
736  for (i=0; i<ii; i++)
737  {
738    for (j=0; j<jj; j++)
739    {
740      p_String0(*pp++, r);
741      StringAppendS(ch_s);
742      if (dim > 1) StringAppendS("\n");
743    }
744  }
745  char *s=StringEndS();
746  s[strlen(s)- (dim > 1 ? 2 : 1)]='\0';
747  return s;
748}
749
750void   mp_Delete(matrix* a, const ring r)
751{
752  id_Delete((ideal *) a, r);
753}
754
755/*
756* C++ classes for Bareiss algorithm
757*/
758class row_col_weight
759{
760  private:
761  int ym, yn;
762  public:
763  float *wrow, *wcol;
764  row_col_weight() : ym(0) {}
765  row_col_weight(int, int);
766  ~row_col_weight();
767};
768
769row_col_weight::row_col_weight(int i, int j)
770{
771  ym = i;
772  yn = j;
773  wrow = (float *)omAlloc(i*sizeof(float));
774  wcol = (float *)omAlloc(j*sizeof(float));
775}
776row_col_weight::~row_col_weight()
777{
778  if (ym!=0)
779  {
780    omFreeSize((ADDRESS)wcol, yn*sizeof(float));
781    omFreeSize((ADDRESS)wrow, ym*sizeof(float));
782  }
783}
784
785/*2
786*  a submatrix M of a matrix X[m,n]:
787*    0 <= i < s_m <= a_m
788*    0 <= j < s_n <= a_n
789*    M = ( Xarray[qrow[i],qcol[j]] )
790*    if a_m = a_n and s_m = s_n
791*      det(X) = sign*div^(s_m-1)*det(M)
792*    resticted pivot for elimination
793*      0 <= j < piv_s
794*/
795class mp_permmatrix
796{
797  private:
798  int       a_m, a_n, s_m, s_n, sign, piv_s;
799  int       *qrow, *qcol;
800  poly      *Xarray;
801  ring _R;
802  void mpInitMat();
803  poly * mpRowAdr(int r)
804  { return &(Xarray[a_n*qrow[r]]); }
805  poly * mpColAdr(int c)
806  { return &(Xarray[qcol[c]]); }
807  void mpRowWeight(float *);
808  void mpColWeight(float *);
809  void mpRowSwap(int, int);
810  void mpColSwap(int, int);
811  public:
812  mp_permmatrix() : a_m(0) {}
813  mp_permmatrix(matrix, ring);
814  mp_permmatrix(mp_permmatrix *);
815  ~mp_permmatrix();
816  int mpGetRow();
817  int mpGetCol();
818  int mpGetRdim() { return s_m; }
819  int mpGetCdim() { return s_n; }
820  int mpGetSign() { return sign; }
821  void mpSetSearch(int s);
822  void mpSaveArray() { Xarray = NULL; }
823  poly mpGetElem(int, int);
824  void mpSetElem(poly, int, int);
825  void mpDelElem(int, int);
826  void mpElimBareiss(poly);
827  int mpPivotBareiss(row_col_weight *);
828  int mpPivotRow(row_col_weight *, int);
829  void mpToIntvec(intvec *);
830  void mpRowReorder();
831  void mpColReorder();
832};
833mp_permmatrix::mp_permmatrix(matrix A, ring R) : sign(1)
834{
835  a_m = A->nrows;
836  a_n = A->ncols;
837  this->mpInitMat();
838  Xarray = A->m;
839  _R=R;
840}
841
842mp_permmatrix::mp_permmatrix(mp_permmatrix *M)
843{
844  poly p, *athis, *aM;
845  int i, j;
846
847  _R=M->_R;
848  a_m = M->s_m;
849  a_n = M->s_n;
850  sign = M->sign;
851  this->mpInitMat();
852  Xarray = (poly *)omAlloc0(a_m*a_n*sizeof(poly));
853  for (i=a_m-1; i>=0; i--)
854  {
855    athis = this->mpRowAdr(i);
856    aM = M->mpRowAdr(i);
857    for (j=a_n-1; j>=0; j--)
858    {
859      p = aM[M->qcol[j]];
860      if (p)
861      {
862        athis[j] = p_Copy(p,_R);
863      }
864    }
865  }
866}
867
868mp_permmatrix::~mp_permmatrix()
869{
870  int k;
871
872  if (a_m != 0)
873  {
874    omFreeSize((ADDRESS)qrow,a_m*sizeof(int));
875    omFreeSize((ADDRESS)qcol,a_n*sizeof(int));
876    if (Xarray != NULL)
877    {
878      for (k=a_m*a_n-1; k>=0; k--)
879        p_Delete(&Xarray[k],_R);
880      omFreeSize((ADDRESS)Xarray,a_m*a_n*sizeof(poly));
881    }
882  }
883}
884
885
886static float mp_PolyWeight(poly p, const ring r);
887void mp_permmatrix::mpColWeight(float *wcol)
888{
889  poly p, *a;
890  int i, j;
891  float count;
892
893  for (j=s_n; j>=0; j--)
894  {
895    a = this->mpColAdr(j);
896    count = 0.0;
897    for(i=s_m; i>=0; i--)
898    {
899      p = a[a_n*qrow[i]];
900      if (p)
901        count += mp_PolyWeight(p,_R);
902    }
903    wcol[j] = count;
904  }
905}
906void mp_permmatrix::mpRowWeight(float *wrow)
907{
908  poly p, *a;
909  int i, j;
910  float count;
911
912  for (i=s_m; i>=0; i--)
913  {
914    a = this->mpRowAdr(i);
915    count = 0.0;
916    for(j=s_n; j>=0; j--)
917    {
918      p = a[qcol[j]];
919      if (p)
920        count += mp_PolyWeight(p,_R);
921    }
922    wrow[i] = count;
923  }
924}
925
926void mp_permmatrix::mpRowSwap(int i1, int i2)
927{
928   poly p, *a1, *a2;
929   int j;
930
931   a1 = &(Xarray[a_n*i1]);
932   a2 = &(Xarray[a_n*i2]);
933   for (j=a_n-1; j>= 0; j--)
934   {
935     p = a1[j];
936     a1[j] = a2[j];
937     a2[j] = p;
938   }
939}
940
941void mp_permmatrix::mpColSwap(int j1, int j2)
942{
943   poly p, *a1, *a2;
944   int i, k = a_n*a_m;
945
946   a1 = &(Xarray[j1]);
947   a2 = &(Xarray[j2]);
948   for (i=0; i< k; i+=a_n)
949   {
950     p = a1[i];
951     a1[i] = a2[i];
952     a2[i] = p;
953   }
954}
955void mp_permmatrix::mpInitMat()
956{
957  int k;
958
959  s_m = a_m;
960  s_n = a_n;
961  piv_s = 0;
962  qrow = (int *)omAlloc(a_m*sizeof(int));
963  qcol = (int *)omAlloc(a_n*sizeof(int));
964  for (k=a_m-1; k>=0; k--) qrow[k] = k;
965  for (k=a_n-1; k>=0; k--) qcol[k] = k;
966}
967
968void mp_permmatrix::mpColReorder()
969{
970  int k, j, j1, j2;
971
972  if (a_n > a_m)
973    k = a_n - a_m;
974  else
975    k = 0;
976  for (j=a_n-1; j>=k; j--)
977  {
978    j1 = qcol[j];
979    if (j1 != j)
980    {
981      this->mpColSwap(j1, j);
982      j2 = 0;
983      while (qcol[j2] != j) j2++;
984      qcol[j2] = j1;
985    }
986  }
987}
988
989void mp_permmatrix::mpRowReorder()
990{
991  int k, i, i1, i2;
992
993  if (a_m > a_n)
994    k = a_m - a_n;
995  else
996    k = 0;
997  for (i=a_m-1; i>=k; i--)
998  {
999    i1 = qrow[i];
1000    if (i1 != i)
1001    {
1002      this->mpRowSwap(i1, i);
1003      i2 = 0;
1004      while (qrow[i2] != i) i2++;
1005      qrow[i2] = i1;
1006    }
1007  }
1008}
1009
1010/*
1011* perform replacement for pivot strategy in Bareiss algorithm
1012* change sign of determinant
1013*/
1014static void mpReplace(int j, int n, int &sign, int *perm)
1015{
1016  int k;
1017
1018  if (j != n)
1019  {
1020    k = perm[n];
1021    perm[n] = perm[j];
1022    perm[j] = k;
1023    sign = -sign;
1024  }
1025}
1026/*2
1027* pivot strategy for Bareiss algorithm
1028*/
1029int mp_permmatrix::mpPivotBareiss(row_col_weight *C)
1030{
1031  poly p, *a;
1032  int i, j, iopt, jopt;
1033  float sum, f1, f2, fo, r, ro, lp;
1034  float *dr = C->wrow, *dc = C->wcol;
1035
1036  fo = 1.0e20;
1037  ro = 0.0;
1038  iopt = jopt = -1;
1039
1040  s_n--;
1041  s_m--;
1042  if (s_m == 0)
1043    return 0;
1044  if (s_n == 0)
1045  {
1046    for(i=s_m; i>=0; i--)
1047    {
1048      p = this->mpRowAdr(i)[qcol[0]];
1049      if (p)
1050      {
1051        f1 = mp_PolyWeight(p,_R);
1052        if (f1 < fo)
1053        {
1054          fo = f1;
1055          if (iopt >= 0)
1056            p_Delete(&(this->mpRowAdr(iopt)[qcol[0]]),_R);
1057          iopt = i;
1058        }
1059        else
1060          p_Delete(&(this->mpRowAdr(i)[qcol[0]]),_R);
1061      }
1062    }
1063    if (iopt >= 0)
1064      mpReplace(iopt, s_m, sign, qrow);
1065    return 0;
1066  }
1067  this->mpRowWeight(dr);
1068  this->mpColWeight(dc);
1069  sum = 0.0;
1070  for(i=s_m; i>=0; i--)
1071    sum += dr[i];
1072  for(i=s_m; i>=0; i--)
1073  {
1074    r = dr[i];
1075    a = this->mpRowAdr(i);
1076    for(j=s_n; j>=0; j--)
1077    {
1078      p = a[qcol[j]];
1079      if (p)
1080      {
1081        lp = mp_PolyWeight(p,_R);
1082        ro = r - lp;
1083        f1 = ro * (dc[j]-lp);
1084        if (f1 != 0.0)
1085        {
1086          f2 = lp * (sum - ro - dc[j]);
1087          f2 += f1;
1088        }
1089        else
1090          f2 = lp-r-dc[j];
1091        if (f2 < fo)
1092        {
1093          fo = f2;
1094          iopt = i;
1095          jopt = j;
1096        }
1097      }
1098    }
1099  }
1100  if (iopt < 0)
1101    return 0;
1102  mpReplace(iopt, s_m, sign, qrow);
1103  mpReplace(jopt, s_n, sign, qcol);
1104  return 1;
1105}
1106poly mp_permmatrix::mpGetElem(int r, int c)
1107{
1108  return Xarray[a_n*qrow[r]+qcol[c]];
1109}
1110
1111/*
1112* the Bareiss-type elimination with division by div (div != NULL)
1113*/
1114void mp_permmatrix::mpElimBareiss(poly div)
1115{
1116  poly piv, elim, q1, q2, *ap, *a;
1117  int i, j, jj;
1118
1119  ap = this->mpRowAdr(s_m);
1120  piv = ap[qcol[s_n]];
1121  for(i=s_m-1; i>=0; i--)
1122  {
1123    a = this->mpRowAdr(i);
1124    elim = a[qcol[s_n]];
1125    if (elim != NULL)
1126    {
1127      elim = p_Neg(elim,_R);
1128      for (j=s_n-1; j>=0; j--)
1129      {
1130        q2 = NULL;
1131        jj = qcol[j];
1132        if (ap[jj] != NULL)
1133        {
1134          q2 = SM_MULT(ap[jj], elim, div,_R);
1135          if (a[jj] != NULL)
1136          {
1137            q1 = SM_MULT(a[jj], piv, div,_R);
1138            p_Delete(&a[jj],_R);
1139            q2 = p_Add_q(q2, q1, _R);
1140          }
1141        }
1142        else if (a[jj] != NULL)
1143        {
1144          q2 = SM_MULT(a[jj], piv, div, _R);
1145        }
1146        if ((q2!=NULL) && div)
1147          SM_DIV(q2, div, _R);
1148        a[jj] = q2;
1149      }
1150      p_Delete(&a[qcol[s_n]], _R);
1151    }
1152    else
1153    {
1154      for (j=s_n-1; j>=0; j--)
1155      {
1156        jj = qcol[j];
1157        if (a[jj] != NULL)
1158        {
1159          q2 = SM_MULT(a[jj], piv, div, _R);
1160          p_Delete(&a[jj], _R);
1161          if (div)
1162            SM_DIV(q2, div, _R);
1163          a[jj] = q2;
1164        }
1165      }
1166    }
1167  }
1168}
1169/*
1170* weigth of a polynomial, for pivot strategy
1171*/
1172static float mp_PolyWeight(poly p, const ring r)
1173{
1174  int i;
1175  float res;
1176
1177  if (pNext(p) == NULL)
1178  {
1179    res = (float)n_Size(pGetCoeff(p),r->cf);
1180    for (i=rVar(r);i>0;i--)
1181    {
1182      if(p_GetExp(p,i,r)!=0)
1183      {
1184        res += 2.0;
1185        break;
1186      }
1187    }
1188  }
1189  else
1190  {
1191    res = 0.0;
1192    do
1193    {
1194      res += (float)n_Size(pGetCoeff(p),r->cf)+2.0;
1195      pIter(p);
1196    }
1197    while (p);
1198  }
1199  return res;
1200}
1201/*
1202* find best row
1203*/
1204static int mp_PivBar(matrix a, int lr, int lc, const ring r)
1205{
1206  float f1, f2;
1207  poly *q1;
1208  int i,j,io;
1209
1210  io = -1;
1211  f1 = 1.0e30;
1212  for (i=lr-1;i>=0;i--)
1213  {
1214    q1 = &(a->m)[i*a->ncols];
1215    f2 = 0.0;
1216    for (j=lc-1;j>=0;j--)
1217    {
1218      if (q1[j]!=NULL)
1219        f2 += mp_PolyWeight(q1[j],r);
1220    }
1221    if ((f2!=0.0) && (f2<f1))
1222    {
1223      f1 = f2;
1224      io = i;
1225    }
1226  }
1227  if (io<0) return 0;
1228  else return io+1;
1229}
1230
1231static void mpSwapRow(matrix a, int pos, int lr, int lc)
1232{
1233  poly sw;
1234  int j;
1235  poly* a2 = a->m;
1236  poly* a1 = &a2[a->ncols*(pos-1)];
1237
1238  a2 = &a2[a->ncols*(lr-1)];
1239  for (j=lc-1; j>=0; j--)
1240  {
1241    sw = a1[j];
1242    a1[j] = a2[j];
1243    a2[j] = sw;
1244  }
1245}
1246
1247/*2
1248*  prepare one step of 'Bareiss' algorithm
1249*  for application in minor
1250*/
1251static int mp_PrepareRow (matrix a, int lr, int lc, const ring R)
1252{
1253  int r;
1254
1255  r = mp_PivBar(a,lr,lc,R);
1256  if(r==0) return 0;
1257  if(r<lr) mpSwapRow(a, r, lr, lc);
1258  return 1;
1259}
1260
1261/*
1262* find pivot in the last row
1263*/
1264static int mp_PivRow(matrix a, int lr, int lc, const ring r)
1265{
1266  float f1, f2;
1267  poly *q1;
1268  int j,jo;
1269
1270  jo = -1;
1271  f1 = 1.0e30;
1272  q1 = &(a->m)[(lr-1)*a->ncols];
1273  for (j=lc-1;j>=0;j--)
1274  {
1275    if (q1[j]!=NULL)
1276    {
1277      f2 = mp_PolyWeight(q1[j],r);
1278      if (f2<f1)
1279      {
1280        f1 = f2;
1281        jo = j;
1282      }
1283    }
1284  }
1285  if (jo<0) return 0;
1286  else return jo+1;
1287}
1288
1289static void mpSwapCol(matrix a, int pos, int lr, int lc)
1290{
1291  poly sw;
1292  int j;
1293  poly* a2 = a->m;
1294  poly* a1 = &a2[pos-1];
1295
1296  a2 = &a2[lc-1];
1297  for (j=a->ncols*(lr-1); j>=0; j-=a->ncols)
1298  {
1299    sw = a1[j];
1300    a1[j] = a2[j];
1301    a2[j] = sw;
1302  }
1303}
1304
1305/*2
1306*  prepare one step of 'Bareiss' algorithm
1307*  for application in minor
1308*/
1309static int mp_PreparePiv (matrix a, int lr, int lc,const ring r)
1310{
1311  int c;
1312
1313  c = mp_PivRow(a, lr, lc,r);
1314  if(c==0) return 0;
1315  if(c<lc) mpSwapCol(a, c, lr, lc);
1316  return 1;
1317}
1318
1319static void mp_ElimBar(matrix a0, matrix re, poly div, int lr, int lc, const ring R)
1320{
1321  int r=lr-1, c=lc-1;
1322  poly *b = a0->m, *x = re->m;
1323  poly piv, elim, q1, q2, *ap, *a, *q;
1324  int i, j;
1325
1326  ap = &b[r*a0->ncols];
1327  piv = ap[c];
1328  for(j=c-1; j>=0; j--)
1329    if (ap[j] != NULL) ap[j] = p_Neg(ap[j],R);
1330  for(i=r-1; i>=0; i--)
1331  {
1332    a = &b[i*a0->ncols];
1333    q = &x[i*re->ncols];
1334    if (a[c] != NULL)
1335    {
1336      elim = a[c];
1337      for (j=c-1; j>=0; j--)
1338      {
1339        q1 = NULL;
1340        if (a[j] != NULL)
1341        {
1342          q1 = sm_MultDiv(a[j], piv, div,R);
1343          if (ap[j] != NULL)
1344          {
1345            q2 = sm_MultDiv(ap[j], elim, div, R);
1346            q1 = p_Add_q(q1,q2,R);
1347          }
1348        }
1349        else if (ap[j] != NULL)
1350          q1 = sm_MultDiv(ap[j], elim, div, R);
1351        if (q1 != NULL)
1352        {
1353          if (div)
1354            sm_SpecialPolyDiv(q1, div,R);
1355          q[j] = q1;
1356        }
1357      }
1358    }
1359    else
1360    {
1361      for (j=c-1; j>=0; j--)
1362      {
1363        if (a[j] != NULL)
1364        {
1365          q1 = sm_MultDiv(a[j], piv, div, R);
1366          if (div)
1367            sm_SpecialPolyDiv(q1, div, R);
1368          q[j] = q1;
1369        }
1370      }
1371    }
1372  }
1373}
1374
1375/*2*/
1376/// entries of a are minors and go to result (only if not in R)
1377void mp_MinorToResult(ideal result, int &elems, matrix a, int r, int c,
1378                     ideal R, const ring)
1379{
1380  poly *q1;
1381  int e=IDELEMS(result);
1382  int i,j;
1383
1384  if (R != NULL)
1385  {
1386    for (i=r-1;i>=0;i--)
1387    {
1388      q1 = &(a->m)[i*a->ncols];
1389      //for (j=c-1;j>=0;j--)
1390      //{
1391      //  if (q1[j]!=NULL) q1[j] = kNF(R,currRing->qideal,q1[j]);
1392      //}
1393    }
1394  }
1395  for (i=r-1;i>=0;i--)
1396  {
1397    q1 = &(a->m)[i*a->ncols];
1398    for (j=c-1;j>=0;j--)
1399    {
1400      if (q1[j]!=NULL)
1401      {
1402        if (elems>=e)
1403        {
1404          pEnlargeSet(&(result->m),e,e);
1405          e += e;
1406          IDELEMS(result) =e;
1407        }
1408        result->m[elems] = q1[j];
1409        q1[j] = NULL;
1410        elems++;
1411      }
1412    }
1413  }
1414}
1415/*
1416// from  linalg_from_matpol.cc: TODO: compare with above & remove...
1417void mp_MinorToResult(ideal result, int &elems, matrix a, int r, int c,
1418                     ideal R, const ring R)
1419{
1420  poly *q1;
1421  int e=IDELEMS(result);
1422  int i,j;
1423
1424  if (R != NULL)
1425  {
1426    for (i=r-1;i>=0;i--)
1427    {
1428      q1 = &(a->m)[i*a->ncols];
1429      for (j=c-1;j>=0;j--)
1430      {
1431        if (q1[j]!=NULL) q1[j] = kNF(R,currRing->qideal,q1[j]);
1432      }
1433    }
1434  }
1435  for (i=r-1;i>=0;i--)
1436  {
1437    q1 = &(a->m)[i*a->ncols];
1438    for (j=c-1;j>=0;j--)
1439    {
1440      if (q1[j]!=NULL)
1441      {
1442        if (elems>=e)
1443        {
1444          if(e<SIZE_OF_SYSTEM_PAGE)
1445          {
1446            pEnlargeSet(&(result->m),e,e);
1447            e += e;
1448          }
1449          else
1450          {
1451            pEnlargeSet(&(result->m),e,SIZE_OF_SYSTEM_PAGE);
1452            e += SIZE_OF_SYSTEM_PAGE;
1453          }
1454          IDELEMS(result) =e;
1455        }
1456        result->m[elems] = q1[j];
1457        q1[j] = NULL;
1458        elems++;
1459      }
1460    }
1461  }
1462}
1463*/
1464
1465static void mpFinalClean(matrix a)
1466{
1467  omFreeSize((ADDRESS)a->m,a->nrows*a->ncols*sizeof(poly));
1468  omFreeBin((ADDRESS)a, sip_sideal_bin);
1469}
1470
1471/*2*/
1472/// produces recursively the ideal of all arxar-minors of a
1473void mp_RecMin(int ar,ideal result,int &elems,matrix a,int lr,int lc,
1474              poly barDiv, ideal R, const ring r)
1475{
1476  int k;
1477  int kr=lr-1,kc=lc-1;
1478  matrix nextLevel=mpNew(kr,kc);
1479
1480  loop
1481  {
1482/*--- look for an optimal row and bring it to last position ------------*/
1483    if(mp_PrepareRow(a,lr,lc,r)==0) break;
1484/*--- now take all pivots from the last row ------------*/
1485    k = lc;
1486    loop
1487    {
1488      if(mp_PreparePiv(a,lr,k,r)==0) break;
1489      mp_ElimBar(a,nextLevel,barDiv,lr,k,r);
1490      k--;
1491      if (ar>1)
1492      {
1493        mp_RecMin(ar-1,result,elems,nextLevel,kr,k,a->m[kr*a->ncols+k],R,r);
1494        mp_PartClean(nextLevel,kr,k, r);
1495      }
1496      else mp_MinorToResult(result,elems,nextLevel,kr,k,R,r);
1497      if (ar>k-1) break;
1498    }
1499    if (ar>=kr) break;
1500/*--- now we have to take out the last row...------------*/
1501    lr = kr;
1502    kr--;
1503  }
1504  mpFinalClean(nextLevel);
1505}
1506/*
1507// from  linalg_from_matpol.cc: TODO: compare with above & remove...
1508void mp_RecMin(int ar,ideal result,int &elems,matrix a,int lr,int lc,
1509              poly barDiv, ideal R, const ring R)
1510{
1511  int k;
1512  int kr=lr-1,kc=lc-1;
1513  matrix nextLevel=mpNew(kr,kc);
1514
1515  loop
1516  {
1517// --- look for an optimal row and bring it to last position ------------
1518    if(mpPrepareRow(a,lr,lc)==0) break;
1519// --- now take all pivots from the last row ------------
1520    k = lc;
1521    loop
1522    {
1523      if(mpPreparePiv(a,lr,k)==0) break;
1524      mpElimBar(a,nextLevel,barDiv,lr,k);
1525      k--;
1526      if (ar>1)
1527      {
1528        mpRecMin(ar-1,result,elems,nextLevel,kr,k,a->m[kr*a->ncols+k],R);
1529        mpPartClean(nextLevel,kr,k);
1530      }
1531      else mpMinorToResult(result,elems,nextLevel,kr,k,R);
1532      if (ar>k-1) break;
1533    }
1534    if (ar>=kr) break;
1535// --- now we have to take out the last row...------------
1536    lr = kr;
1537    kr--;
1538  }
1539  mpFinalClean(nextLevel);
1540}
1541*/
1542
1543/*2*/
1544/// returns the determinant of the matrix m;
1545/// uses Bareiss algorithm
1546poly mp_DetBareiss (matrix a, const ring r)
1547{
1548  int s;
1549  poly div, res;
1550  if (MATROWS(a) != MATCOLS(a))
1551  {
1552    Werror("det of %d x %d matrix",MATROWS(a),MATCOLS(a));
1553    return NULL;
1554  }
1555  matrix c = mp_Copy(a,r);
1556  mp_permmatrix *Bareiss = new mp_permmatrix(c,r);
1557  row_col_weight w(Bareiss->mpGetRdim(), Bareiss->mpGetCdim());
1558
1559  /* Bareiss */
1560  div = NULL;
1561  while(Bareiss->mpPivotBareiss(&w))
1562  {
1563    Bareiss->mpElimBareiss(div);
1564    div = Bareiss->mpGetElem(Bareiss->mpGetRdim(), Bareiss->mpGetCdim());
1565  }
1566  Bareiss->mpRowReorder();
1567  Bareiss->mpColReorder();
1568  Bareiss->mpSaveArray();
1569  s = Bareiss->mpGetSign();
1570  delete Bareiss;
1571
1572  /* result */
1573  res = MATELEM(c,1,1);
1574  MATELEM(c,1,1) = NULL;
1575  id_Delete((ideal *)&c,r);
1576  if (s < 0)
1577    res = p_Neg(res,r);
1578  return res;
1579}
1580/*
1581// from  linalg_from_matpol.cc: TODO: compare with above & remove...
1582poly mp_DetBareiss (matrix a, const ring R)
1583{
1584  int s;
1585  poly div, res;
1586  if (MATROWS(a) != MATCOLS(a))
1587  {
1588    Werror("det of %d x %d matrix",MATROWS(a),MATCOLS(a));
1589    return NULL;
1590  }
1591  matrix c = mp_Copy(a, R);
1592  mp_permmatrix *Bareiss = new mp_permmatrix(c, R);
1593  row_col_weight w(Bareiss->mpGetRdim(), Bareiss->mpGetCdim());
1594
1595  // Bareiss
1596  div = NULL;
1597  while(Bareiss->mpPivotBareiss(&w))
1598  {
1599    Bareiss->mpElimBareiss(div);
1600    div = Bareiss->mpGetElem(Bareiss->mpGetRdim(), Bareiss->mpGetCdim());
1601  }
1602  Bareiss->mpRowReorder();
1603  Bareiss->mpColReorder();
1604  Bareiss->mpSaveArray();
1605  s = Bareiss->mpGetSign();
1606  delete Bareiss;
1607
1608  // result
1609  res = MATELEM(c,1,1);
1610  MATELEM(c,1,1) = NULL;
1611  id_Delete((ideal *)&c, R);
1612  if (s < 0)
1613    res = p_Neg(res, R);
1614  return res;
1615}
1616*/
1617
1618/*2
1619* compute all ar-minors of the matrix a
1620*/
1621matrix mp_Wedge(matrix a, int ar, const ring R)
1622{
1623  int     i,j,k,l;
1624  int *rowchoise,*colchoise;
1625  BOOLEAN rowch,colch;
1626  matrix result;
1627  matrix tmp;
1628  poly p;
1629
1630  i = binom(a->nrows,ar);
1631  j = binom(a->ncols,ar);
1632
1633  rowchoise=(int *)omAlloc(ar*sizeof(int));
1634  colchoise=(int *)omAlloc(ar*sizeof(int));
1635  result = mpNew(i,j);
1636  tmp    = mpNew(ar,ar);
1637  l = 1; /* k,l:the index in result*/
1638  idInitChoise(ar,1,a->nrows,&rowch,rowchoise);
1639  while (!rowch)
1640  {
1641    k=1;
1642    idInitChoise(ar,1,a->ncols,&colch,colchoise);
1643    while (!colch)
1644    {
1645      for (i=1; i<=ar; i++)
1646      {
1647        for (j=1; j<=ar; j++)
1648        {
1649          MATELEM(tmp,i,j) = MATELEM(a,rowchoise[i-1],colchoise[j-1]);
1650        }
1651      }
1652      p = mp_DetBareiss(tmp, R);
1653      if ((k+l) & 1) p=p_Neg(p, R);
1654      MATELEM(result,l,k) = p;
1655      k++;
1656      idGetNextChoise(ar,a->ncols,&colch,colchoise);
1657    }
1658    idGetNextChoise(ar,a->nrows,&rowch,rowchoise);
1659    l++;
1660  }
1661
1662  /*delete the matrix tmp*/
1663  for (i=1; i<=ar; i++)
1664  {
1665    for (j=1; j<=ar; j++) MATELEM(tmp,i,j) = NULL;
1666  }
1667  id_Delete((ideal *) &tmp, R);
1668  return (result);
1669}
1670int mp_Compare(matrix a, matrix b, const ring R)
1671{
1672  if (MATCOLS(a)<MATCOLS(b)) return -1;
1673  else if (MATCOLS(a)>MATCOLS(b)) return 1;
1674  if (MATROWS(a)<MATROWS(b)) return -1;
1675  else if (MATROWS(a)<MATROWS(b)) return 1;
1676
1677  int i=MATCOLS(a)*MATROWS(b)-1;
1678  int c;
1679  while (i>=0)
1680  {
1681    if (a->m[i]==NULL)
1682    {
1683      if (b->m[i]!=NULL) return -1;
1684    }
1685    else
1686      if (b->m[i]==NULL) return 1;
1687      else if ((c=p_Cmp(a->m[i],b->m[i], R))!=0) return c;
1688    i--;
1689  }
1690  unsigned ii=MATCOLS(a)*MATROWS(b)-1;
1691  unsigned j=0;
1692  int r=0;
1693  while (j<=ii)
1694  {
1695    r=p_Compare(a->m[j],b->m[j],R);
1696    if (r!=0) return r;
1697    j++;
1698  }
1699  return r;
1700}
1701
1702BOOLEAN mp_Equal(matrix a, matrix b, const ring R)
1703{
1704  int r=mp_Compare(a,b,R);
1705  return (r==0);
1706}
1707
Note: See TracBrowser for help on using the repository browser.