In [1]:
import numpy as np
import matplotlib.pyplot as plt
import scipy.linalg as sla
import numpy.linalg as LA
import pandas as pd
from time import process_time
%matplotlib inline
In [74]:
def example(m, n):
A = np.vander(np.linspace(-1., 1., m), n)
b = A.dot(np.ones(n))
return A, b
def solve_lsq(A, b, method='qr'):
if method=='normal':
U = sla.cholesky(A.T.dot(A))
y = sla.solve_triangular(U.T, A.T.dot(b), lower=True)
return sla.solve_triangular(U, y)
if method=='qr':
Q, R = sla.qr(A, mode='economic')
return sla.solve_triangular(R, Q.T.dot(b)[:R.shape[0]])
if method=='svd':
U, s, V = sla.svd(A, full_matrices=False)
return V.dot(np.diag(1 / s).dot(U.T.dot(b)))
def test_lsq():
A = np.random.random((4, 4))
b = np.random.random(4)
x = solve_lsq(A, b, 'normal')
print(A.T.dot(b) - A.T.dot(A).dot(x))
In [42]:
A, b = example(4, 4)
In [80]:
m = 100
times = np.zeros(m)
for n in range(m, m):
A, b = example(m, n)
print(n)
t_start = process_time()
x = solve_lsq(A, b, method='normal')
times[n] = process_time() - t_start
In [111]:
plt.plot(times)
Out[111]:
In [79]:
m = 10
n = 9
A, b = example(m, n)
t_start = process_time()
x = solve_lsq(A, b, method='svd')
np.allclose(A.dot(x), b)
Out[79]:
In [81]:
U, s, V = sla.svd(A, full_matrices=False)
V.dot(np.diag(1 / s).dot(U.T.dot(b)))
Out[81]:
In [82]:
b
Out[82]:
In [ ]: