In [106]:
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 clock
%matplotlib inline

In [46]:
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':
        try:
            U = sla.cholesky(A.T.dot(A))
        except:
            ATA = A.T.dot(A)
            ATA[np.abs(ATA) < 10 ** -14] = 0.
            U = sla.cholesky(ATA)
        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 [50]:
A, b = example(100, 27)
x = solve_lsq(A, b, method='normal')
np.isclose(A.dot(x), b)


                          0
0        (13646.4023137+0j)
1        (4191.07369663+0j)
2        (8709.20233718+0j)
3        (574.256033149+0j)
4        (1595.41379715+0j)
5        (55.8347984041+0j)
6        (176.178705531+0j)
7        (4.18885768137+0j)
8        (14.5633111608+0j)
9       (0.247192749914+0j)
10      (0.933653754871+0j)
11     (0.0115373486403+0j)
12     (0.0468931927835+0j)
13      (0.001843854543+0j)
14   (0.000424538413196+0j)
15   (1.21781617689e-05+0j)
16   (5.62113610424e-05+0j)
17   (2.66712279129e-07+0j)
18   (1.30256310758e-06+0j)
19   (2.21727328984e-08+0j)
20   (4.30644951798e-09+0j)
21   (2.61516595462e-10+0j)
22   (4.84160739891e-11+0j)
23   (1.99621820427e-12+0j)
24   (5.23259487344e-13+0j)
25  (-7.07892475149e-14+0j)
26  (-3.09112330824e-13+0j)
Out[50]:
array([ True,  True,  True,  True,  True,  True,  True,  True,  True,
        True,  True,  True,  True,  True,  True,  True,  True,  True,
        True,  True,  True,  True,  True,  True,  True,  True,  True,
        True,  True,  True,  True,  True,  True,  True,  True,  True,
        True,  True,  True,  True,  True,  True,  True,  True,  True,
        True,  True,  True,  True,  True,  True,  True,  True,  True,
        True,  True,  True,  True,  True,  True,  True,  True,  True,
        True,  True,  True,  True,  True,  True,  True,  True,  True,
        True,  True,  True,  True,  True,  True,  True,  True,  True,
        True,  True,  True,  True,  True,  True,  True,  True,  True,
        True,  True,  True,  True,  True,  True,  True,  True,  True,  True], dtype=bool)

In [119]:
m = 100
times = np.zeros(m)
for mode in ['qr', 'svd']:
    for n in range(1, m):
        A, b = example(m, n)

        t_start = clock()
        x = solve_lsq(A, b, method=mode)
        times[n] = clock() - t_start
    plt.plot(times, label=mode)
    
times = np.zeros(m)

for n in range(1, 26):
    A, b = example(m, n)
    t_start = clock()
    x = solve_lsq(A, b, method='normal')
    times[n] = clock() - t_start
plt.plot(times[:26])


Out[119]:
[<matplotlib.lines.Line2D at 0x7fe20ccd1630>]

In [109]:
for n in range(1, 26):
    A, b = example(m, n)


Out[109]:
[<matplotlib.lines.Line2D at 0x7fe20cd3fda0>]

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]:
False

In [81]:
U, s, V = sla.svd(A, full_matrices=False)
V.dot(np.diag(1 / s).dot(U.T.dot(b)))


Out[81]:
array([ 0.87888801,  0.73738623,  1.2775084 , -0.94054901,  1.30438628,
        1.13090557,  0.91060691,  1.13696161,  0.25475408])

In [82]:
b


Out[82]:
array([ 1.        ,  0.62108984,  0.64609802,  0.7500381 ,  0.9       ,
        1.125     ,  1.49992379,  2.23865695,  4.03128129,  9.        ])

In [26]:
1e-15


Out[26]:
1e-15

In [99]:
A, b = example(m, 10)
U,s,V = LA.svd(A)

In [84]:
U.shape, s.shape, V.shape


Out[84]:
((100, 100), (10,), (10, 10))

In [85]:
N = np.diag(1 /s)
W = np.zeros((10, 90))

v = np.hstack((W, N))

In [90]:
dot(,U.T)

In [100]:
c = np.dot(U.T,b) # c = U^t*b
w = LA.solve(np.diag(s),c) # w = V^t*c
xSVD = np.dot(V.T,w)


---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-100-9655b27d352f> in <module>()
      1 c = np.dot(U.T,b) # c = U^t*b
----> 2 w = LA.solve(np.diag(s),c) # w = V^t*c
      3 xSVD = np.dot(V.T,w)

/home/lorenzo/anaconda3/lib/python3.6/site-packages/numpy/linalg/linalg.py in solve(a, b)
    382     signature = 'DD->D' if isComplexType(t) else 'dd->d'
    383     extobj = get_linalg_error_extobj(_raise_linalgerror_singular)
--> 384     r = gufunc(a, b, signature=signature, extobj=extobj)
    385 
    386     return wrap(r.astype(result_t, copy=False))

ValueError: solve1: Input operand 1 has a mismatch in its core dimension 0, with gufunc signature (m,m),(m)->(m) (size 100 is different from 10)

In [89]:
A.shape, x.shape


Out[89]:
((100, 10), (99,))

In [93]:
x


Out[93]:
array([  8.20162737e-14,  -3.49909847e-15,   5.16286509e-14,
        -1.16356463e-15,  -1.98281883e-14,   4.93364231e-15,
         4.89890411e-15,  -2.85116867e-15,  -9.47755318e-16,
        -5.79780533e-16])

In [ ]: