In [1]:
from __future__ import print_function, division
import thinkstats2
import thinkplot
import pandas as pd
import numpy as np
from fractions import Fraction
%matplotlib inline
In [2]:
def scalar_product(x, y):
x = np.asarray(x)
y = np.asarray(y)
return np.sum(x * y)
In [3]:
scalar_product([1,2,3], (4,5,6))
Out[3]:
In [4]:
scalar_product([1,2,3], 2)
Out[4]:
In [5]:
scalar_product([1,2,3], [2])
Out[5]:
In [6]:
try:
scalar_product([1,2,3], (4,5,6,7))
except ValueError as e:
print(e)
In [7]:
class ArrayWrapper:
def __init__(self, array):
self.array = np.asarray(array)
def __eq__(self, other):
return np.array_equal(self.array, other.array)
def __add__(self, other):
return self.__class__(self.array + other.array)
def __sub__(self, other):
return self.__class__(self.array - other.array)
def __str__(self):
return str(self.array)
def __repr__(self):
return '%s(\n%s)' % (self.__class__.__name__, str(self.array))
def __len__(self):
return len(self.array)
def __getitem__(self, index):
return self.array[index]
def __setitem__(self, index, elt):
self.array[index] = elt
@property
def t(self):
return self.__class__(self.array.transpose())
class Vector(ArrayWrapper):
def __mul__(self, other):
return scalar_product(self.array, other.array)
In [8]:
def random_array(*shape):
return np.random.randint(1, 10, shape)
In [9]:
x = Vector(random_array(3))
x
Out[9]:
In [10]:
x[0], x[1], x[2]
Out[10]:
In [11]:
x[1] += 1
In [12]:
for elt in x:
print(elt)
In [13]:
y = Vector(x.array)
y
Out[13]:
In [14]:
x == y
Out[14]:
In [15]:
x.t
Out[15]:
In [16]:
x == x.t
Out[16]:
In [17]:
y = Vector(random_array(3))
y
Out[17]:
In [18]:
x == y
Out[18]:
In [19]:
x+y
Out[19]:
In [20]:
x-y
Out[20]:
In [21]:
x*y
Out[21]:
In [31]:
def mm_product(array1, array2):
dtype = np.result_type(array1, array2)
array = np.zeros((len(array1), len(array2)), dtype=dtype)
for i, row1 in enumerate(array1):
for j, row2 in enumerate(array2):
array[i][j] = scalar_product(row1, row2)
return array
In [32]:
class Matrix(ArrayWrapper):
def __mul__(self, other):
return self.__class__(mm_product(self.array, other.t.array))
def __truediv__(self, other):
return self.__class__(np.linalg.solve(self.array, other.array.flat))
In [33]:
A = Matrix(random_array(3, 3))
A
Out[33]:
In [34]:
len(A)
Out[34]:
In [35]:
for row in A:
print(row)
In [36]:
B = Matrix(random_array(3, 3))
B
Out[36]:
In [37]:
A+B
Out[37]:
In [38]:
A-B
Out[38]:
In [39]:
A*B
Out[39]:
In [40]:
A.array.dot(B.array)
Out[40]:
In [41]:
x = Vector(random_array(3))
x
Out[41]:
In [42]:
A*x
Out[42]:
In [45]:
def mv_product(A, x):
dtype = np.result_type(A, x)
array = np.zeros(len(A), dtype=dtype)
for i, row in enumerate(A):
array[i] = scalar_product(row, x)
return Vector(array)
In [46]:
mv_product(A.array, x.array)
Out[46]:
In [47]:
A.array.dot(x.array)
Out[47]:
In [48]:
x = Matrix(random_array(3, 1))
x
Out[48]:
In [49]:
x == x.t
Out[49]:
In [50]:
x.t * x
Out[50]:
In [51]:
x * x.t
Out[51]:
In [52]:
x * x
Out[52]:
In [53]:
A * x
Out[53]:
In [54]:
A.array.dot(x.array)
Out[54]:
In [55]:
scalar = Matrix([[2]])
scalar
Out[55]:
In [56]:
scalar == scalar.t
Out[56]:
In [57]:
scalar * scalar
Out[57]:
In [58]:
x * scalar
Out[58]:
In [59]:
A * scalar
Out[59]:
In [60]:
b = A * x
b
Out[60]:
In [61]:
b.array
Out[61]:
In [62]:
np.linalg.solve(A.array, b.array)
Out[62]:
In [63]:
print(A / b)
In [64]:
A.array.shape
Out[64]:
In [65]:
b.array.shape
Out[65]:
In [66]:
m = np.hstack([A.array, b.array]).astype(Fraction)
print(m)
In [67]:
m[1] -= m[0]
print(m)
In [68]:
m[:, :-1]
Out[68]:
In [69]:
m[:, -1]
Out[69]:
In [70]:
def solve_augmented(m):
m = m.astype(float)
return np.linalg.solve(m[:, :-1], m[:,-1])
In [71]:
print(solve_augmented(m))
In [72]:
row1 = 0
row2 = 1
col = 0
pivot = m[row1, col]
victim = m[row2, col]
m[row1], pivot, victim, m[row1] * Fraction(victim, pivot)
Out[72]:
In [73]:
m[row2] -= m[row1] * Fraction(victim, pivot)
print(m)
In [74]:
def clobber(m, row1, row2, col):
pivot = m[row1, col]
victim = m[row2, col]
m[row2] -= m[row1] * Fraction(victim, pivot)
In [75]:
clobber(m, 0, 2, 0)
print(m)
In [76]:
clobber(m, 1, 2, 1)
print(m)
In [77]:
m[2] /= m[2,2]
print(m)
In [ ]: