| 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); |
| } |
| |
| |