(Relatively) Efficient Generation of Invertible 3x3 Matrices


  • TA School Banned

    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: