mirror of
https://gitlab.com/scemama/qp_plugins_scemama.git
synced 2024-11-07 22:53:42 +01:00
69 lines
2.1 KiB
Python
69 lines
2.1 KiB
Python
# !!!
|
|
import numpy as np
|
|
from QR import QR_fact
|
|
from RSVD import powit_RSVD
|
|
# !!!
|
|
def R3SVD_AMMAR(A, t, delta_t, npow, nb_oversamp, err_thr, maxit, tol):
|
|
# !!!
|
|
# build initial QB decomposition
|
|
# !!!
|
|
n = A.shape[1]
|
|
G = np.random.randn(n, t)
|
|
normA = np.linalg.norm(A, ord='fro')**2
|
|
i_it = 0
|
|
rank = 0
|
|
Y = np.dot(A,G)
|
|
# The power scheme
|
|
for j in range(npow):
|
|
Q = QR_fact(Y)
|
|
Q = QR_fact( np.dot(A.T,Q) )
|
|
Y = np.dot(A,Q)
|
|
# orthogonalization process
|
|
Q_old = QR_fact(Y)
|
|
B = np.dot(Q_old.T,A)
|
|
normB = np.linalg.norm(B, ord='fro')**2
|
|
# error percentage
|
|
errpr = abs( normA - normB ) / normA
|
|
rank += t
|
|
i_it += 1
|
|
print("iteration = {}, rank = {}, error = {}".format(i_it, rank, errpr))
|
|
# !!!
|
|
# incrementally build up QB decomposition
|
|
# !!!
|
|
while ( (errpr>err_thr) and (i_it<maxit) and (rank<=min(A.shape)-delta_t) ): #
|
|
G = np.random.randn(n, delta_t)
|
|
Y = np.dot(A,G)
|
|
#Y = Y - np.dot(Q_old, np.dot(Q_old.T,Y) ) # orthogonalization with Q
|
|
# power scheme
|
|
for j in range(npow):
|
|
Q = QR_fact(Y)
|
|
Q = QR_fact( np.dot(A.T,Q) )
|
|
Y = np.dot(A,Q)
|
|
Y = Y - np.dot(Q_old, np.dot(Q_old.T,Y) ) # orthogonalization with Q
|
|
Q_new = QR_fact(Y)
|
|
B_new = np.dot(Q_new.T,A)
|
|
# build up approximate basis
|
|
Q_old = np.append(Q_new, Q_old, axis=1)
|
|
#B = np.append(B_new, B, axis=0)
|
|
normB += np.linalg.norm(B_new, ord='fro')**2
|
|
errpr = abs( normA - normB ) / normA
|
|
rank += delta_t
|
|
i_it += 1
|
|
print("iteration = {}, rank = {}, error = {}".format(i_it, rank, errpr))
|
|
# !!!
|
|
#UL, SL, VLT = np.linalg.svd(B, full_matrices=0)
|
|
#UL = np.dot(Q_old,UL)
|
|
# !!!
|
|
print("iteration = {}, rank = {}, error = {}".format(i_it, rank, errpr))
|
|
UL, SL, VLT = powit_RSVD(A, rank, npow, nb_oversamp)
|
|
#return UL, SL, VLT
|
|
# !!!
|
|
rank = SL.shape[0]
|
|
new_r = rank
|
|
for i in range(rank):
|
|
if( SL[i] <= tol ):
|
|
new_r = i
|
|
break
|
|
return UL[:,:(new_r)], SL[:(new_r)], VLT[:(new_r),:]
|
|
# !!!
|