source: git/libpolys/polys/matpol.cc @ 845729b

spielwiese
Last change on this file since 845729b was 845729b, checked in by Oleksandr Motsak <motsak@…>, 13 years ago
Removed linear algebra stuff (Bareiss/Det etc) from matpol.cc TODO: matpol -> simplematrices?
  • Property mode set to 100644
File size: 15.0 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/* $Id$ */
5
6/*
7* ABSTRACT:
8*/
9
10#include <stdio.h>
11#include <math.h>
12
13#include "config.h"
14#include <misc/auxiliary.h>
15
16#include <omalloc/omalloc.h>
17#include <misc/mylimits.h>
18
19
20// #include <kernel/structs.h>
21// #include <kernel/kstd1.h>
22// #include <kernel/polys.h>
23
24#include <misc/intvec.h>
25#include <coeffs/numbers.h>
26
27#include <reporter/reporter.h>
28
29
30#include "monomials/ring.h"
31#include "monomials/p_polys.h"
32
33#include "coeffrings.h"
34#include "simpleideals.h"
35#include "matpol.h"
36#include "prCopy.h"
37
38// #include "sparsmat.h"
39   
40//omBin ip_smatrix_bin = omGetSpecBin(sizeof(ip_smatrix));
41#define ip_smatrix_bin sip_sideal_bin
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  if (r<=0) r=1;
51  if ( (((int)(INT_MAX/sizeof(poly))) / r) <= c)
52  {
53    Werror("internal error: creating matrix[%d][%d]",r,c);
54    return NULL;
55  }
56  matrix rc = (matrix)omAllocBin(ip_smatrix_bin);
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)
74matrix 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
95matrix 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
123matrix 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
139matrix 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
145matrix 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
158matrix 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*/
175matrix 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
189matrix 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
206matrix 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
223matrix 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
267matrix 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*/
288poly 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*/
302poly 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*/
326matrix 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*/
376void   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
413matrix 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 
432  if (rHasLocalOrMixedOrdering(R))
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*/
495static 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
515void 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
578BOOLEAN mp_Equal(matrix a, matrix b, const ring R)
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
612static poly minuscopy (poly p, const ring R)
613{
614  poly w;
615  number  e;
616  e = n_Init(-1, R);
617  w = p_Copy(p, R);
618  p_Mult_nn(w, e, R);
619  n_Delete(&e, R);
620  return w;
621}
622
623/*2
624* insert a monomial into a list, avoid duplicates
625* arguments are destroyed
626*/
627static poly p_Insert(poly p1, poly p2, const ring R)
628{
629  poly a1, p, a2, a;
630  int c;
631
632  if (p1==NULL) return p2;
633  if (p2==NULL) return p1;
634  a1 = p1;
635  a2 = p2;
636  a = p  = p_One(R);
637  loop
638  {
639    c = p_Cmp(a1, a2, R);
640    if (c == 1)
641    {
642      a = pNext(a) = a1;
643      pIter(a1);
644      if (a1==NULL)
645      {
646        pNext(a) = a2;
647        break;
648      }
649    }
650    else if (c == -1)
651    {
652      a = pNext(a) = a2;
653      pIter(a2);
654      if (a2==NULL)
655      {
656        pNext(a) = a1;
657        break;
658      }
659    }
660    else
661    {
662      p_LmDelete(&a2, R);
663      a = pNext(a) = a1;
664      pIter(a1);
665      if (a1==NULL)
666      {
667        pNext(a) = a2;
668        break;
669      }
670      else if (a2==NULL)
671      {
672        pNext(a) = a1;
673        break;
674      }
675    }
676  }
677  p_LmDelete(&p, R);
678  return p;
679}
680
681/*2
682*if what == xy the result is the list of all different power products
683*    x^i*y^j (i, j >= 0) that appear in fro
684*/
685static poly mp_Select (poly fro, poly what, const ring R)
686{
687  int i;
688  poly h, res;
689  res = NULL;
690  while (fro!=NULL)
691  {
692    h = p_One(R);
693    for (i=1; i<=rVar(R); i++)
694      p_SetExp(h,i, p_GetExp(fro,i, R) * p_GetExp(what, i, R), R);
695    p_SetComp(h, p_GetComp(fro, R), R);
696    p_Setm(h, R);
697    res = p_Insert(h, res, R);
698    fro = fro->next;
699  }
700  return res;
701}
702
703/*
704*static void ppp(matrix a)
705*{
706*  int j,i,r=a->nrows,c=a->ncols;
707*  for(j=1;j<=r;j++)
708*  {
709*    for(i=1;i<=c;i++)
710*    {
711*      if(MATELEM(a,j,i)!=NULL) Print("X");
712*      else Print("0");
713*    }
714*    Print("\n");
715*  }
716*}
717*/
718
719static void mp_PartClean(matrix a, int lr, int lc, const ring R)
720{
721  poly *q1;
722  int i,j;
723
724  for (i=lr-1;i>=0;i--)
725  {
726    q1 = &(a->m)[i*a->ncols];
727    for (j=lc-1;j>=0;j--) if(q1[j]) p_Delete(&q1[j], R);
728  }
729}
730
731static void mp_FinalClean(matrix a, const ring R)
732{
733  omFreeSize((ADDRESS)a->m,a->nrows*a->ncols*sizeof(poly));
734  omFreeBin((ADDRESS)a, ip_smatrix_bin);
735}
736
737BOOLEAN mp_IsDiagUnit(matrix U, const ring R)
738{
739  if(MATROWS(U)!=MATCOLS(U))
740    return FALSE;
741  for(int i=MATCOLS(U);i>=1;i--)
742  {
743    for(int j=MATCOLS(U); j>=1; j--)
744    {
745      if (i==j)
746      {
747        if (!p_IsUnit(MATELEM(U,i,i), R)) return FALSE;
748      }
749      else if (MATELEM(U,i,j)!=NULL) return FALSE;
750    }
751  }
752  return TRUE;
753}
754
755void iiWriteMatrix(matrix im, const char *n, int dim, const ring r, int spaces)
756{
757  int i,ii = MATROWS(im)-1;
758  int j,jj = MATCOLS(im)-1;
759  poly *pp = im->m;
760
761  for (i=0; i<=ii; i++)
762  {
763    for (j=0; j<=jj; j++)
764    {
765      if (spaces>0)
766        Print("%-*.*s",spaces,spaces," ");
767      if (dim == 2) Print("%s[%u,%u]=",n,i+1,j+1);
768      else if (dim == 1) Print("%s[%u]=",n,j+1);
769      else if (dim == 0) Print("%s=",n);
770      if ((i<ii)||(j<jj)) p_Write(*pp++, r);
771      else                p_Write0(*pp, r);
772    }
773  }
774}
775
776char * iiStringMatrix(matrix im, int dim, const ring r, char ch)
777{
778  int i,ii = MATROWS(im);
779  int j,jj = MATCOLS(im);
780  poly *pp = im->m;
781  char *s=StringSetS("");
782
783  for (i=0; i<ii; i++)
784  {
785    for (j=0; j<jj; j++)
786    {
787      p_String0(*pp++, r);
788      s=StringAppend("%c",ch);
789      if (dim > 1) s = StringAppendS("\n");
790    }
791  }
792  s[strlen(s)- (dim > 1 ? 2 : 1)]='\0';
793  return s;
794}
795
796void   mp_Delete(matrix* a, const ring r)
797{
798  id_Delete((ideal *) a, r);
799}
Note: See TracBrowser for help on using the repository browser.