Karim BELABAS on Thu, 23 Jul 1998 18:20:57 +0200 (MET DST)


[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]

Re: bug report/techn. question: incorrect type in ...


[Maximilian Pitschi:]
> I'm trying to do some matix computations, e.g., matdet(...), with
> identical matrices M1 and M2, which depend on a parameter p.  See log
> below. To me, the matrices differ only in the way they were defined.

The following patch should get rid of _some_ of the problems linked to bad
guesses in the linear algebra package: the ones connected with polynomials
or rational functions (in particular your example with matdet/matsolve now
works ok).

[Note: I also changed slightly the maximal pivot strategy, comparing
exponents, instead of the numbers themselves. Hence this breaks the
`linear' bench, producing a different (in fact, slightly more precise)
result for 1/(1. * mathilbert(7))]

Cheers, Karim.

*** src/basemath/alglin1.c.orig	Thu Jul 23 15:40:23 1998
--- src/basemath/alglin1.c	Thu Jul 23 17:52:19 1998
***************
*** 608,613 ****
--- 608,648 ----
  /*                       Solve A*X=B (Gauss pivot)                 */
  /*                                                                 */
  /*******************************************************************/
+ 
+ /* Assume x is a non-empty matrix. Return 0 if maximal pivot should not be
+  * used, and the matrix precision (min real precision of coeffs) otherwise.
+  */
+ static long 
+ matprec(GEN x)
+ {
+   long tx,i,j,l, k = VERYBIGINT, lx = lg(x), ly = lg(x[1]);
+   GEN p1;
+   for (i=1; i<lx; i++)
+     for (j=1; j<ly; j++) 
+     {
+       p1 = gmael(x,i,j); tx = typ(p1);
+       if (!is_scalar_t(tx)) return 0;
+       l = precision(p1); if (l && l<k) k = l;
+     }
+   return (k==VERYBIGINT)? 0: k;
+ }
+ 
+ /* As above, returning 1 if the precision would be non-zero, 0 otherwise */
+ static long
+ use_maximal_pivot(GEN x)
+ {
+   long tx,i,j, lx = lg(x), ly = lg(x[1]);
+   GEN p1;
+   for (i=1; i<lx; i++)
+     for (j=1; j<ly; j++) 
+     {
+       p1 = gmael(x,i,j); tx = typ(p1);
+       if (!is_scalar_t(tx)) return 0;
+       if (precision(p1)) return 1;
+     }
+   return 0;
+ }
+ 
  static GEN
  check_b(GEN b, long nbli)
  {
***************
*** 645,651 ****
  GEN
  gauss(GEN a, GEN b)
  {
!   long inexact,ismat,nbli,nbco,i,j,k,av,av1,tetpil,lim;
    GEN p,m,u;
    /* nbli: nb lines of b = nb columns of a */
    /* nbco: nb columns of b (if matrix) */
--- 680,686 ----
  GEN
  gauss(GEN a, GEN b)
  {
!   long inexact,ismat,nbli,nbco,i,j,k,av,tetpil,lim;
    GEN p,m,u;
    /* nbli: nb lines of b = nb columns of a */
    /* nbco: nb columns of b (if matrix) */
***************
*** 664,706 ****
    a = dummycopy(a);
    b = check_b(b,nbli);
    nbco = lg(b)-1;
!   inexact = isinexactreal(a);
    ismat   = (typ(b)==t_MAT);
    if(DEBUGLEVEL>4)
      fprintferr("Entering gauss with inexact=%ld ismat=%ld\n",inexact,ismat);
  
    for (i=1; i<nbli; i++)
    {
-     long exchange;
- 
      /* k is the line where we find the pivot */
      p=gcoeff(a,i,i); k=i;
      if (inexact) /* maximal pivot */
      {
!       GEN p1, p2;
!       av1 = avma;
!       p2 = gabs(p,DEFAULTPREC);
        for (j=i+1; j<=nbli; j++)
        {
!         p1 = gabs(gcoeff(a,j,i),DEFAULTPREC);
!         if (gcmp(p1,p2)>0) { p2=p1; k=j; }
        }
!       if (gcmp0(p2)) err(matinv1);
!       exchange = (k > i);
!       avma = av1;
      }
!     else /* first non-zero pivot */
      {
!       exchange = gcmp0(p);
!       if (exchange)
!       {
!         do k++; while (k<=nbli && gcmp0(gcoeff(a,k,i)));
!         if (k>nbli) err(matinv1);
!       }
      }
  
!     /* exchange==1 if k<>i, we exchange the lines s.t. k=i */
!     if (exchange)
      {
        for (j=i; j<=nbli; j++)
        {
--- 699,731 ----
    a = dummycopy(a);
    b = check_b(b,nbli);
    nbco = lg(b)-1;
!   inexact = use_maximal_pivot(a);
    ismat   = (typ(b)==t_MAT);
    if(DEBUGLEVEL>4)
      fprintferr("Entering gauss with inexact=%ld ismat=%ld\n",inexact,ismat);
  
    for (i=1; i<nbli; i++)
    {
      /* k is the line where we find the pivot */
      p=gcoeff(a,i,i); k=i;
      if (inexact) /* maximal pivot */
      {
!       long e, ex = gexpo(p);
        for (j=i+1; j<=nbli; j++)
        {
!         e = gexpo(gcoeff(a,j,i));
!         if (e > ex) { ex=e; k=j; }
        }
!       if (gcmp0(gcoeff(a,k,i))) err(matinv1);
      }
!     else if (gcmp0(p)) /* first non-zero pivot */
      {
!       do k++; while (k<=nbli && gcmp0(gcoeff(a,k,i)));
!       if (k>nbli) err(matinv1);
      }
  
!     /* if (k!=i), exchange the lines s.t. k = i */
!     if (k != i)
      {
        for (j=i; j<=nbli; j++)
        {
***************
*** 1043,1057 ****
  static void
  gauss_get_prec(GEN x, long prec)
  {
!   long pr;
  
!   gauss_is_zero = &gcmp0;
!   if (!prec)
!   {
!     if (!isinexactreal(x)) return;
!     prec = DEFAULTPREC;
!   }
!   pr = gprecision(x); if (!pr) return;
    if (pr > prec) prec = pr;
  
    gauss_ex = BITS_IN_LONG - bit_accuracy(prec);
--- 1068,1076 ----
  static void
  gauss_get_prec(GEN x, long prec)
  {
!   long pr = matprec(x); 
  
!   if (!pr) { gauss_is_zero = &gcmp0; return; }
    if (pr > prec) prec = pr;
  
    gauss_ex = BITS_IN_LONG - bit_accuracy(prec);
***************
*** 1489,1501 ****
  static GEN
  det_simple_gauss(GEN a, long inexact)
  {
!   long nbco,i,j,k,av,av1,s,exchange;
    GEN x,p,m;
  
-   if (typ(a)!=t_MAT) err(mattype1,"det2");
-   nbco=lg(a)-1; if (!nbco) return gun;
-   if (nbco != lg(a[1])-1) err(mattype1,"det2");
- 
    av=avma; s=1; x=gun; a=dummycopy(a);
    for (i=1; i<nbco; i++)
    {
--- 1508,1516 ----
  static GEN
  det_simple_gauss(GEN a, long inexact)
  {
!   long i,j,k,av,av1,s, nbco = lg(a)-1;
    GEN x,p,m;
  
    av=avma; s=1; x=gun; a=dummycopy(a);
    for (i=1; i<nbco; i++)
    {
***************
*** 1512,1529 ****
        }
        p1 = gcoeff(a,i,k);
        if (gcmp0(p1)) { av1=avma; return gerepile(av,av1,gcopy(p1)); }
-       exchange = (k > i);
      }
!     else
      {
!       exchange = gcmp0(p);
!       if (exchange)
!       {
!         do k++; while(k<=nbco && gcmp0(gcoeff(a,i,k)));
!         if (k>nbco) { avma=av; return gzero; }
!       }
      }
!     if (exchange)
      {
        j=a[k]; a[k]=a[i]; a[i]=j;
        s = -s; p = gcoeff(a,i,i); 
--- 1527,1539 ----
        }
        p1 = gcoeff(a,i,k);
        if (gcmp0(p1)) { av1=avma; return gerepile(av,av1,gcopy(p1)); }
      }
!     else if (gcmp0(p))
      {
!       do k++; while(k<=nbco && gcmp0(gcoeff(a,i,k)));
!       if (k>nbco) { avma=av; return gzero; }
      }
!     if (k != i)
      {
        j=a[k]; a[k]=a[i]; a[i]=j;
        s = -s; p = gcoeff(a,i,i); 
***************
*** 1546,1554 ****
  }
  
  GEN
! det2(GEN x)
  {
!   return det_simple_gauss(x,isinexactreal(x));
  }
  
  /* determinant in a ring A: all computations are done within A
--- 1556,1568 ----
  }
  
  GEN
! det2(GEN a)
  {
!   long nbco = lg(a)-1;
!   if (typ(a)!=t_MAT) err(mattype1,"det2");
!   if (!nbco) return gun;
!   if (nbco != lg(a[1])-1) err(mattype1,"det2");
!   return det_simple_gauss(a,use_maximal_pivot(a));
  }
  
  /* determinant in a ring A: all computations are done within A
***************
*** 1557,1569 ****
  GEN
  det(GEN a)
  {
!   long nbco,i,j,k,av,av1,s;
    GEN p1,p,m,pprec;
  
-   if (isinexactreal(a)) return det_simple_gauss(a,1);
    if (typ(a)!=t_MAT) err(mattype1,"det");
!   nbco=lg(a)-1; if (!nbco) return gun;
    if (nbco != lg(a[1])-1) err(mattype1,"det");
  
    av=avma; a=dummycopy(a);
    pprec=gun; s=1;
--- 1571,1583 ----
  GEN
  det(GEN a)
  {
!   long nbco = lg(a)-1,i,j,k,av,av1,s;
    GEN p1,p,m,pprec;
  
    if (typ(a)!=t_MAT) err(mattype1,"det");
!   if (!nbco) return gun;
    if (nbco != lg(a[1])-1) err(mattype1,"det");
+   if (use_maximal_pivot(a)) return det_simple_gauss(a,1);
  
    av=avma; a=dummycopy(a);
    pprec=gun; s=1;
--
Karim Belabas                    email: Karim.Belabas@math.u-psud.fr
Dep. de Mathematiques, Bat. 425
Universite Paris-Sud             Tel: (00 33) 1 69 15 57 48
F-91405 Orsay (France)           Fax: (00 33) 1 69 15 60 19
--
PARI/GP Home Page: http://pari.home.ml.org