iferr(Mat([1]) + matrix(0,1),E,E)
iferr(1/matrix(2,2,i,j,Mod(0, 2)),E,E)
test(n)=
{
  until(matrank(M)==n,M=matrix(n,n,i,j,random(Mod(1,2))));
  if(M^-1*M!=matid(n),error("F2m"));
}
test(200)
test(2)

matsize(matrix(0, 0) * matrix(0, 2))

default(realprecision,38);
h=mathilbert(40);
[Q,R] = matqr(h); vecmax(abs(h-Q*R)) < 1e-37
[q,R] = matqr(h,1); vecmax(abs(mathouseholder(q,h)-R)) < 1e-37
matqr([;])
matqr([;],1)
mathouseholder(1,1)
mathouseholder(q,1)
mathouseholder(q, vectorv(40,i,1))
Mat(List())
Mat(List([1]))
Mat([[1,2,3],[2,3,4]]~)
Mat(Qfb(1,2,5))
matdiagonal(matid(2))
iferr(matdiagonal([1,2;3,4]),E,E)
matpascal(4,1/2)
A=[1,2,3;4,5,6];B=[4,6;10,12]
matinverseimage(A,B)
matinverseimage(A*Mod(1,2),B)
matinverseimage(A*Mod(1,7),B)
matinverseimage(A*Mod(1,2^64+13),B)
matinverseimage(A*Mod(1,3037000507),B)
B=[4,10]~;
matinverseimage(A*Mod(1,2),B)
matinverseimage(A*Mod(1,7),B)
matinverseimage(A*Mod(1,2^64+13),B)
matinverseimage(A*Mod(1,3037000507),B)

test(f)=
{
  print(f,":");
  print(f(A*Mod(1,2)));
  print(f(A*Mod(1,7)));
  print(f(A*Mod(1,3037000507)));
  print(f(A*Mod(1,2^64+13)));
  print(f(A*(1+O(101^3))));
}
testall()=
{
  test(matdet);
  test(matrank);
  test(matadjoint);
  test(matimage);
  test(matimagecompl);
  test(matindexrank);
  test(matker);
  test(lindep);
  test(x->matsolve(x,vectorv(#x,i,i)));
  test(x->matsolve(x,matrix(#x,#x,i,j,i+j)));
  test(x->x^(-1));
  test(x->x^2);
  test(x->A*x);
}
A = [1,2,4;2,12,7;2,9,11];
testall();
A = [;]
testall();

A=[0,1,0;1,0,1;2,0,3];
matdet(A*Mod(1,3037000507))
matdet(A*Mod(1,2^64+13))
matsolve(A*Mod(1,2^64+13),[1,2,3]~)
matsolve([1,0;0,0]*Mod(1,2),[1,1]~)
matsolve([1,0;0,0]*Mod(1,3),[1,1]~)

matker([1.,I;I,-1.])
matkerint(Mat([1,1]))

trace(matid(3))
trace([;])
iferr(trace(Mat([1,2])),E,E)
matrixqz([1/3,1/4;1/2,1/3])
matrixqz(matrix(2,2),-1)
m=[1,-4,6,1;-13,14,-8,-3;0,0,0,0;0,0,0,0;7,-9,3,2;-7,9,7,4;0,0,0,0;0,0,0,0;10,-2,-2,0;0,0,-4,-4;0,0,0,0;0,0,0,0;-7,9,-7,-4;-4,-3,7,3;0,0,0,0;0,0,0,0;-5,1,9,4;1,-4,-10,-5;0,0,0,0;0,0,0,0;-13,14,-8,-5;-3,-7,7,4;0,0,0,0;0,0,0,0;-18,15,5,3;8,6,-6,-2;0,0,0,0;0,0,0,0;0,0,0,0;4,3,3,1;0,0,0,0;0,0,0,0;11,-6,4,3;-7,9,7,2;0,0,0,0;0,0,0,0;-5,1,7,4;4,3,1,1;0,0,0,0;0,0,0,0;-6,5,-9,-7;-9,-2,10,7;0,0,0,0;0,0,0,0;-1,4,-4,-1;-20,4,6,4;0,0,0,0;0,0,0,0;0,0,-8,-4;9,2,6,3;0,0,0,0;0,0,0,0;0,0,0,0;0,0,0,0;3,7,1,0;6,-5,-7,-5;0,0,0,0;0,0,0,0;-11,6,8,5;0,0,-6,-4;0,0,0,0;0,0,0,0;-12,10,10,6;0,0,-8,-4;0,0,0,0;0,0,0,0;-5,1,3,2;-6,5,-7,-3;0,0,0,0;0,0,0,0;10,-2,-6,-4;-4,-3,3,1;0,0,0,0;0,0,0,0;0,0,0,0;0,0,0,0;0,0,0,0;0,0,0,0;-2,8,0,-2;2,-8,-4,-2;0,0,0,0;0,0,0,0];
a=matrixqz(m,-2);matdet(a~*a)

A=[1,2,3;4,5,6;7,8,9];
test(lindep)
test(matsupplement)

default(parisize,10^6); \\ need to exercise gerepile in matker+matimage
p=2^64+13;
A=matrix(70,70,i,j, i+j);
Ap=Mod(A,p);
#matker(Ap)
#matimage(Ap)
#matker(A)
vecsum([])
vecsum([2])
vecsum(primes(4))
vecsum(1)
vecprod([])
vecprod([1,2,3])
1~

content([])
content([;])
content(matrix(0,2))

vectorsmall(3)
v=vectorsmall(3,i,3*i^2)
content(v)
content(vectorsmall(0))
v=vectorsmall(5,i,(3-i)*i)
content(v)
vectorsmall(3,i,i^100)

m=[1,0;0,0;0,1]; b=[1,2;0,0;3,4];
liftint(Mod(m,2)^(-1))
liftint(Mod(m,3)^(-1))
liftint(Mod(m,2^64+13)^(-1))
liftint(matsolve(Mod(m,2),b))
liftint(matsolve(Mod(m,3),b))
liftint(matsolve(Mod(m,2^64+13),b))
(m*ffgen(2^2)^0)^(-1)
(m*ffgen(3^2)^0)^(-1)
(m*ffgen((2^64+13)^2)^0)^(-1)

m=[1,2,3;4,5,6];
m[1,]=[1,2]
m[1,]=[1,2,3,4]
m[1,]=[1,2,3]~
m[2,]=[1,2,3]
m
m[1,]*=2
m

test(t) =
{
   N = [1, 2; -1, -2]*t^0;
   print(matinverseimage(N, N^0));
}
test(Mod(1, 3));
test(Mod(1, nextprime(2^64)));
test(ffgen(2^17));
test(ffgen(2017^3));
test(ffgen(nextprime(2^64)^3));

p = nextprime(2^63);
q = nextprime(p + 1);
{
   forvec(v = vector(8, i, [0, 2]),
          matker([p^v[1]*q^v[2], p^v[3]*q^v[4];
                  p^v[5]*q^v[6], p^v[7]*q^v[8]], 1));
}

test(x) =
{
   n = 22; r = 12;
   M = matrix(n, n, i, j, random(x));
   P = matrix(n, r, i, j, if(2*i >= 3*j + 8, random(x), 0*x));
   N = P*matrix(r, n, i, j, random(x));
   Q = N[,1..r];
   R = mattranspose(P);
   X = matsolve(M, N);
   K = matker(N);
   J = matimage(N);
   print(M*X == N);
   print(N*K == 0);
   print(N*lindep(N) == 0);
   print(R*lindep(R) == 0);
   print(matimage(J) == J);
   print(matrank(J) == r);
   print(matrank(K) == n - r);
   print(matrank(N) == r);
   print(J^-1 * J == matid(r));
   print(matdet(M^-1) == matdet(M)^-1);
   print(P*matinverseimage(P, Q) == Q);
   print(lindep(J));
   print(matker(K));
   print(matker(M));
   print(matinverseimage(N, M));
   print(matinverseimage(P, M));
   iferr(N^-1, e,, errname(e) == "e_INV");
   iferr(matsolve(N, M), e,, errname(e) == "e_INV");
}
test(Mod(1, 8161));
test(ffgen(2017^3));
