## rd_GL(n,F) : random invertible matrix of order n with entries in F

from PyECC import *


def rd_GL(n,F=Zn(2)):
    a = rd_nonzero(F)[0]  
    A = matrix([a])
    for _ in range(2,n+1):
        A = rd_extend(A)
    return A

def rd_extend(A):
    n = ncols(A); K = K_(A)
    v = rd_nonzero_vector(K,n+1)
    r = 0
    for j in range(n+1):
        if v[j]!=0: 
            r = j
            break
    A = rd_insert(A,r)
    x = v[r]
    for j in range(r+1,n+1):
        A[:,j] = A[:,j]+ A[:,r]*v[j]
    A[:,r] = x*A[:,r]
    return A

def rd_insert(A,r):
    n = ncols(A)
    if r<0 or r>n: return "r has to be in 0..n"
    K = K_(A)
    B = matrix(K,n+1,n+1)
    B[0,r] = 1
    for j in range(1,n+1):
        B[j,r] = rd(K)
    if r==0:
        B[1:,1:] = A[:,:]
    elif r==n:
        B[1:,0:n] = A[:,:] 
    else:
       B[1:,0:r] = A[:,0:r] 
       B[1:,r+1:n+1] = A[:,r:n] 
    return B

show(rd_GL(7))

show(rd_GL(7,Zn(83)))