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