def HausQR(a): #another qr decomposition, but now using Hausholder reflections c = mh.MatrixTrans(a) q = HausholderRef(c[0]) c = mh.MatrixTrans(mh.MatrixMinor(mh.MatrixMulti(q, a), 0, 0)) for _ in range(1, min(len(a) - 1, len(a[0]))): t = fill(len(a), HausholderRef(c[0])) q = mh.MatrixMulti(t, q) c = mh.MatrixTrans(mh.MatrixMinor(mh.MatrixMulti(q, a), 0, 0)) r = mh.MatrixMulti(q, a) q = mh.MatrixTrans(q) return q, r
def QR(a): #Gram-Schmidt's proccess c = mh.MatrixTrans(a) #easy acces to columns u = [c[0].copy() ] #first iteration eliminates problem of none return of vecSigma e = [list(map(lambda k: k / magn(u[0]), u[0]))] for i in range(1, len(a[0])): #print(vecSigma( lambda k: ortProj(u[k],c[i]),0,i-1 )) u.append( vecSub(c[i], vecSigma(lambda k: ortProj(u[k], c[i]), 0, i - 1))) e.append(list(map(lambda k: k / magn(u[i]), u[i]))) q = mh.MatrixTrans(e) r = mh.MatrixMulti(e, a) #QR = A => (Q^-1)QR = (Q^-1)A => R = (Qt)A return q, r
def SVD(a): aat = mh.MatrixMulti(a, mh.MatrixTrans(a)) ata = mh.MatrixMulti(mh.MatrixTrans(a), a) mh.MatrixPrint(aat, "aat") mh.MatrixPrint(ata, "ata") eigenvalues_aat = list(map(lambda x: round(x, ndigits=6), Francis(aat))) singularvalues_aat = list(map(sqrt, eigenvalues_aat)) mh.MatrixPrint([eigenvalues_aat], "eigen aat") mh.MatrixPrint([singularvalues_aat], "singular aat") eigenvalues_ata = list(map(lambda x: round(x, ndigits=6), Francis(ata))) singularvalues_ata = list(map(sqrt, eigenvalues_ata)) mh.MatrixPrint([eigenvalues_ata], "eigen ata") mh.MatrixPrint([singularvalues_ata], "singular ata") S = mh.MatrixMake(len(a), len(a[0])) for i in range(min(len(a), len(a[0]))): S[i][i] = singularvalues_aat[i] mh.MatrixPrint(S, msg="Σ")
def HausholderRef( a ): #funtion for returning matrics that makes hauholder refletion based on a vector v = a.copy() v[0] -= magn(a) I = mh.MatrixIdentity(len(a)) return mh.MatrixAdd( I, mh.MatrixScale(mh.MatrixMulti(mh.MatrixTrans([v]), [v]), -2 / dotProd(v, v)))
def Francis(a, bl=0.00000000001, c=1000): ''' Francis algorithm of finding eigenvalues using Hausholder reflections. bl = computational squared error, c = abort counter - after c iterations func just returns currently computed values ''' i = 0 while not (triU(a, bl) | triU(mh.MatrixTrans(a), bl) | (i == c)): #print("i =",i) q, r = HausQR(a) i += 1 a = mh.MatrixMulti(r, q) #mh.MatrixPrint(a) #print("end of algorithm after",i,"iterations") return list(map(lambda x: a[x][x], range(len(a))))
mh.MatrixPrint(aat, "aat") mh.MatrixPrint(ata, "ata") eigenvalues_aat = list(map(lambda x: round(x, ndigits=6), Francis(aat))) singularvalues_aat = list(map(sqrt, eigenvalues_aat)) mh.MatrixPrint([eigenvalues_aat], "eigen aat") mh.MatrixPrint([singularvalues_aat], "singular aat") eigenvalues_ata = list(map(lambda x: round(x, ndigits=6), Francis(ata))) singularvalues_ata = list(map(sqrt, eigenvalues_ata)) mh.MatrixPrint([eigenvalues_ata], "eigen ata") mh.MatrixPrint([singularvalues_ata], "singular ata") S = mh.MatrixMake(len(a), len(a[0])) for i in range(min(len(a), len(a[0]))): S[i][i] = singularvalues_aat[i] mh.MatrixPrint(S, msg="Σ") A = [[3, 2, 2], [2, 3, -2]] C = [[2, 4], [1, 3], [0, 0], [0, 0]] cU = [[0.82, -0.58, 0, 0], [0.58, 0.82, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]] cS = [[5.47, 0], [0, 0.37], [0, 0], [0, 0]] cV = [[0.40, -0.91], [0.91, 0.40]] mh.MatrixPrint(mh.MatrixMulti(C, mh.MatrixTrans(C))) mh.MatrixPrint(mh.MatrixMulti(mh.MatrixTrans(C), C)) SVD(A) mh.MatrixPrint(mh.MatrixMulti(mh.MatrixMulti(cU, cS), mh.MatrixTrans(cV)), msg="USVt")