(Relatively) Efficient Generation of Invertible 3x3 Matrices
-
The following code generates a matrix by creating two non-zero random vectors, forcing them to be linearly independent, and then taking the cross product to calculate a third vector. It then finds a random permutation of these three vectors within a matrix, and may also transpose the matrix at random.
nonZeroVec := overload( [ proc(v::Vector) option overload; local dim:=LinearAlgebra:-Dimension(v); if LinearAlgebra:-Equal(v,LinearAlgebra:-ZeroVector(dim)) then v(rand(1..dim)()):=rand(1..4)()*(-1)^rand(0..1)():fi: end, proc(l::list) option overload; local i; for i from 1 to numelems(l) do nonZeroVec(l[i]) od: end ] ): nonSing3 := proc() local a,b,num1,num2,c,trans,M: #Generate Random Column Vectors: a:=LinearAlgebra:-RandomVector(3, generator = -4..4): b:=LinearAlgebra:-RandomVector(3, generator = -4..4): #Check for zero vectors: nonZeroVec([a,b]): #Ensure Linear Independance: while LinearAlgebra:-Equal(abs(a/norm(a)),abs(b/norm(b))) do num1:=rand(0..1)(): num2:=rand(0..1)(): b(1):=(-1)^num1 *rand(1..2)()+b(1): b(2):=(-1)^(num2*(1-num1)) *rand(1..2)()+b(2): b(3):=(-1)^((1-num2)*(1-num1)) *rand(1..2)() +b(3): nonZeroVec([a,b]): od: c:=LinearAlgebra:-CrossProduct(a,b): c:=c/max(igcd(c(1),c(2),c(3)),1): M:=Matrix( combinat:-permute(convert([a,b,c],list))[rand(1..6)()] ): trans:=rand(0..1)(): M:=M*(1-trans) + LinearAlgebra:-Transpose(M)*trans: return M; end proc: