Skip to content

Instantly share code, notes, and snippets.

@jiqiujia
Last active November 17, 2017 08:06
Show Gist options
  • Save jiqiujia/7d80a27e06e81b36ce54be2de5bc283e to your computer and use it in GitHub Desktop.
Save jiqiujia/7d80a27e06e81b36ce54be2de5bc283e to your computer and use it in GitHub Desktop.
numerical linear algebra
#from https://rosettacode.org/wiki/LU_decomposition#Python
from pprint import pprint
def matrixMul(A, B):
TB = zip(*B)
return [[sum(ea*eb for ea,eb in zip(a,b)) for b in TB] for a in A]
def pivotize(m):
"""Creates the pivoting matrix for m."""
n = len(m)
ID = [[float(i == j) for i in xrange(n)] for j in xrange(n)]
for j in xrange(n):
row = max(xrange(j, n), key=lambda i: abs(m[i][j]))
if j != row:
ID[j], ID[row] = ID[row], ID[j]
return ID
def lu(A):
"""Decomposes a nxn matrix A by PA=LU and returns L, U and P."""
n = len(A)
L = [[0.0] * n for i in xrange(n)]
U = [[0.0] * n for i in xrange(n)]
P = pivotize(A)
A2 = matrixMul(P, A)
for j in xrange(n):
L[j][j] = 1.0
for i in xrange(j+1):
s1 = sum(U[k][j] * L[i][k] for k in xrange(i))
U[i][j] = A2[i][j] - s1
for i in xrange(j, n):
s2 = sum(U[k][j] * L[i][k] for k in xrange(j))
L[i][j] = (A2[i][j] - s2) / U[j][j]
return (L, U, P)
a = [[1, 3, 5], [2, 4, 7], [1, 1, 0]]
for part in lu(a):
pprint(part, width=19)
print
print
b = [[11,9,24,2],[1,5,2,6],[3,17,18,1],[2,5,7,1]]
for part in lu(b):
pprint(part)
print
################
#could be changed to inplace calculation
def LU(A):
U = np.copy(A)
m, n = A.shape
L = np.eye(n)
for k in range(n-1):
for j in range(k+1,n):
L[j,k] = U[j,k]/U[k,k]
U[j,k:n] -= L[j,k] * U[k,k:n]
return L, U
#from https://github.com/fastai/numerical-linear-algebra
#refer to: Randomized Matrix Decompositions using R
# computes an orthonormal matrix whose range approximates the range of A
# power_iteration_normalizer can be safe_sparse_dot (fast but unstable), LU (imbetween), or QR (slow but most accurate)
def randomized_range_finder(A, size, n_iter=5):
Q = np.random.normal(size=(A.shape[1], size))
for i in range(n_iter):
Q, _ = linalg.lu(A @ Q, permute_l=True)
Q, _ = linalg.lu(A.T @ Q, permute_l=True)
Q, _ = linalg.qr(A @ Q, mode='economic')
return Q
def randomized_svd(M, n_components, n_oversamples=10, n_iter=4):
n_random = n_components + n_oversamples
Q = randomized_range_finder(M, n_random, n_iter)
# project M to the (k + p) dimensional space using the basis vectors
B = Q.T @ M
# compute the SVD on the thin matrix: (k + p) wide
Uhat, s, V = linalg.svd(B, full_matrices=False)
del B
U = Q @ Uhat
return U[:, :n_components], s[:n_components], V[:n_components, :]
u, s, v = randomized_svd(vectors, 5)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment