implement triangularisation (triangcheck) feature

This commit is contained in:
Lukasz M 2022-08-25 12:47:23 +02:00
parent 70851add1d
commit efcc4abf0a

View File

@ -67,6 +67,31 @@ def eigcheck(a, b, rowcol, intmax):
def diagcheck(a, b, rowcol, intmax):
return (a.diagonalize()[1] == inmat(rowcol))
# pascalmat function to generate pascal matrices (used for generating unimodular matrices)
def pascalmat(n) :
mat = []
# generate rows of binomial coefficients
for i in range(n) :
mat.append(sp.binomial_coefficients_list(i) + [0]*(n-1-i))
mat = sp.Matrix(mat)
# make a lower triangular pascal matrix
lmat = mat.transpose()
rand = random.random()
# randomly pick either lower or upper triangular pascal matrix
if rand <= 1/2 :
mat = lmat
return mat
def triangcheck(a, b, rowcol, intmax) :
print("Input triangularised matrix,")
T = inmat(rowcol)
print("Input basis change matrix (from standard basis)")
P_inv = inmat(rowcol)
# check if P_inv is invertible
if P_inv.det() == 0 : return False
# return false if T is not upper triangular and not similar to the original matrix
return (T.is_upper and a == P_inv.inv()*T*P_inv)
# practice function
def practice(t) :
count = 0
@ -82,6 +107,8 @@ def practice(t) :
f = eigcheck
elif t == "diag" :
f = diagcheck
elif t == "triang" :
f = triangcheck
else :
exit()
@ -101,6 +128,23 @@ def practice(t) :
while True :
a = genmatrix(rowcol, intmax, dif)
b = genmatrix(rowcol, intmax, dif)
if t == "triang" :
while True :
# generate matrices with smaller integers
a = genmatrix(rowcol, intmax//rowcol, dif)
# ensure a is invertible
if a.det() == 0 : continue
# find a non-fractional upper trianagular matrix (ensures triangularisability)
c = a.LUdecompositionFF()[3]
croots = {k: k for k in sp.roots(c.charpoly()) if k not in sp.roots(c.charpoly(), filter='Z')}
# make sure only integer roots and c is not diagonalisable
if not (len(croots) != 0 and c.is_diagonalizable) :
a = c
pmat = pascalmat(rowcol)
# multiply by a pascal matrix to get a similar matrix with nice numbers
a = pmat.inv()*a*pmat
if a.is_upper: continue
break
# infinite loop until user succeeds
while True :
@ -128,5 +172,5 @@ def practice(t) :
continue
# take input from user on the type of practice they want to do
t = input("What do you want to practice? (mult, det, inv, eig, diag) ")
t = input("What do you want to practice? (mult, det, inv, eig, diag, triang) ")
practice(t)