implement triangularisation (triangcheck) feature
This commit is contained in:
parent
70851add1d
commit
efcc4abf0a
@ -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)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user