blob: 14833da627094c0894bf2d62db252d8fb22ee54b [file] [log] [blame]
diff -ru src/src/basemath/alglin1.c b/src/basemath/alglin1.c
--- src/src/basemath/alglin1.c 2012-09-25 23:10:46.000000000 +0200
+++ b/src/basemath/alglin1.c 2013-01-03 13:56:55.487513420 +0100
@@ -2969,6 +2969,21 @@
return NULL; /* not reached */
}
+/* A a 2x2 matrix
+ returns the determinant of A computed by the simple formula
+*/
+static GEN
+det2x2(GEN A)
+{
+ pari_sp av = avma;
+ GEN a = gcoeff(A, 1, 1),
+ b = gcoeff(A, 1, 2),
+ c = gcoeff(A, 2, 1),
+ d = gcoeff(A, 2, 2);
+ return gerepileupto(av, gsub(gmul(a, d), gmul(b, c)));
+}
+
+
static GEN
det_simple_gauss(GEN a, GEN data, pivot_fun pivot)
{
@@ -3021,6 +3036,7 @@
if (typ(a)!=t_MAT) pari_err(mattype1,"det2");
if (!nbco) return gen_1;
if (nbco != lg(a[1])-1) pari_err(mattype1,"det2");
+ if (nbco == 2) return det2x2 (a);
pivot = get_pivot_fun(a, &data);
return det_simple_gauss(a, data, pivot);
}
@@ -3158,11 +3174,7 @@
{
case 0: return gen_1;
case 1: return gcopy(gcoeff(M,1,1));
- case 2: {
- GEN a = gcoeff(M,1,1), b = gcoeff(M,1,2);
- GEN c = gcoeff(M,2,1), d = gcoeff(M,2,2);
- return gerepileupto(av, gsub(gmul(a,d), gmul(b,c)));
- }
+ case 2: return det2x2(M);
}
if (max > ((n+2)>>1)) max = (n+2)>>1;
for (j = 1; j <= n; j++)
@@ -3193,9 +3205,10 @@
}
if (best_row)
{
+ double d = lbest-1;
GEN s = NULL;
long k;
- bound /= (lbest-1);
+ bound /= d*d*d;
for (k = 1; k < lbest; k++)
{
GEN c = coeff_det(M, best_row, best[k], max, bound);
@@ -3205,9 +3218,10 @@
}
if (best_col)
{
+ double d = lbest-1;
GEN s = NULL;
long k;
- bound /= (lbest-1);
+ bound /= d*d*d;
for (k = 1; k < lbest; k++)
{
GEN c = coeff_det(M, best[k], best_col, max, bound);
@@ -3230,15 +3244,24 @@
if (!n) return gen_1;
if (n != lg(a[1])-1) pari_err(mattype1,"det");
if (n == 1) return gcopy(gcoeff(a,1,1));
- if (RgM_is_FpM(a, &p) && p)
+ if (RgM_is_FpM(a, &p))
{
- pari_sp av = avma;
- return gerepilecopy(av, Fp_to_mod(FpM_det(RgM_to_FpM(a, p), p), p));
+ pari_sp av;
+ if (!p)
+ { /* ZM */
+ return det_simple_gauss(a, NULL, &gauss_get_pivot_NZ);
+ }
+ else
+ { /* FpM */
+ av = avma;
+ return gerepilecopy(av, Fp_to_mod(FpM_det(RgM_to_FpM(a, p), p), p));
+ }
}
+ if (n == 2) return det2x2 (a);
pivot = get_pivot_fun(a, &data);
if (pivot != gauss_get_pivot_NZ) return det_simple_gauss(a, data, pivot);
- B = (double)n; B = B*B; B = B*B;
- return det_develop(a, 7, B);
+ B = (double)n;
+ return det_develop(a, 7, B*B*B);
}