# Input: a matrix, which is assumed to have integer entries. # Output: the determinant MyDet := proc(A::Matrix) local n,m,i,B,p,np,d,AA; # This gives the number of rows and columns n,m := LinearAlgebra[Dimension](A); if n<>m then error "expecting a square matrix" fi; # B is an upper bound for the determinant. I multiplied the "2-norm" (i.e. the length) # of every column, and then rounded up to get an integer: B := ceil(mul(LinearAlgebra[VectorNorm](LinearAlgebra[Column](A,i), 2), i=1..n)); # np = number of primes so far, m = product of primes so far np := 0; m := 1; while m < 2*B + 1 do np := np + 1; if np = 1 then p[np] := 33554393 else p[np] := prevprime(p[np-1]) fi; # Compute Det mod p using Maple's LinearAlgebra:-Modular package: # AA := LinearAlgebra:-Modular:-Mod(p[np], A, float[8]); d[np] := LinearAlgebra:-Modular:-Determinant(p[np], AA, inplaceRET); m := m*p[np]; lprint(np, "primes completed") od; d := chrem( [seq(d[i], i=1..np)], [seq(p[i], i=1..np)] ); mods(d, m) end: # This creates a procedure whose output is a random integer in the range -10^10 .. 10^10 rnd := rand(-10^10 .. 10^10): # This creates a random 200 by 200 matrix whose entries are randomly # chosen in the range -10^10 .. 10^10: N := 400; A := Matrix(N, N, [seq(seq(rnd(), i=1..N), j=1..N)]): tt := time(): MyDet(A); time() - tt; # Maple command for computing the determinant: LinearAlgebra:-Determinant(A); # is faster. I searched through the help pages to find out why it is faster, and found out # that it computes determinants by solving a linear system, which in turn is done by: # "The default method is to solve the system modulo a machine-sized prime and construct rational solutions using p-adic lifting". # We will cover p-adic lifting in a different context later in this course.