In [1]:
from scipy import linalg

import numpy as np

In [2]:
A = np.array([[1, 2], [3, 4]])

In [3]:
# Matrix Multiplication
A.dot(A)


Out[3]:
array([[ 7, 10],
       [15, 22]])

In [4]:
# Matrix Norm
linalg.norm(A)


Out[4]:
5.477225575051661

In [5]:
# CHECK: Matrix Norm
np.sqrt(sum([x**2 for x in range(1, 5)]))


Out[5]:
5.477225575051661

In [8]:
# Calc determinant
# For 2x2 matrix is a*d - b*c
linalg.det(A)


Out[8]:
-2.0

In [9]:
print(A)


[[1 2]
 [3 4]]

In [10]:
# Calc Matrix Inverse
A_inv = linalg.inv(A)

In [11]:
print(A_inv)


[[-2.   1. ]
 [ 1.5 -0.5]]

In [12]:
# CHECK: Inverse X original = identity matrix
A_inv.dot(A)


Out[12]:
array([[1.00000000e+00, 0.00000000e+00],
       [1.11022302e-16, 1.00000000e+00]])

In [13]:
# Compute Eigenvalues

In [14]:
# Decomposes A into a
# diagonal matrix x and invertible matrix y such that y * x * y^-1
x, y = linalg.eig(A)

x0, x1 = x[0], x[1]

y0, y1 = y[:, 0], y[:, 1]

In [25]:
y


Out[25]:
array([[-0.82456484, -0.41597356],
       [ 0.56576746, -0.90937671]])

In [26]:
# Verify normal equation #1
print(A.dot(y0))


[ 0.30697009 -0.21062466]

In [27]:
print(x0 * y0)


[ 0.30697009-0.j -0.21062466+0.j]

In [28]:
# Verify normal equation #2

print(A.dot(y1))


[-2.23472698 -4.88542751]

In [29]:
print(x1 * y1)


[-2.23472698+0.j -4.88542751+0.j]

In [30]:
# verify eigenvalue decomposition
y.dot(np.diag(x).dot(linalg.inv(y)))


Out[30]:
array([[1.+0.j, 2.+0.j],
       [3.+0.j, 4.+0.j]])

In [31]:
# Calc singular value decomposition
# Extension to eigenvalues for non-invertible or non-square matrices
# product of an orthogonal matrix * diagonal matrix * another orthogonal matrix
u, s, v = linalg.svd(A)

In [32]:
# U is symmetric & orthogonal
print(u)

print(u.dot(u.T))


[[-0.40455358 -0.9145143 ]
 [-0.9145143   0.40455358]]
[[1. 0.]
 [0. 1.]]

In [18]:
# Sigma is a diagonal matrix (if A is invertible)
print(np.diag(s))


[[5.4649857  0.        ]
 [0.         0.36596619]]

In [19]:
# V is symmetric
print(v)

# V is orthogonal
print(v.dot(v.T))


[[-0.57604844 -0.81741556]
 [ 0.81741556 -0.57604844]]
[[1. 0.]
 [0. 1.]]

In [20]:
# CHECK: singular value decomposition recovers A
u.dot(np.diag(s).dot(v))


Out[20]:
array([[1., 2.],
       [3., 4.]])

In [ ]: