| 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