In [1]:
# 巫術
%run magic.ipynb
assert 'np' in locals()
print("巫術準備完成")
In [4]:
A=Matrix([0, 2, 4],[2, 4, 2],[3,3,1])
A
Out[4]:
In [8]:
A[2,0]
Out[8]:
In [9]:
b = Vector(2,3,1)
b
Out[9]:
In [10]:
S = np.hstack([A,b])
S
Out[10]:
In [17]:
show_equations(S)
Out[17]:
In [11]:
def T(i,j):
def op(M):
R = M.copy()
R[[i,j]]=R[[j,i]]
return R
return op
T(0,1)(S)
Out[11]:
因為有巫術,可以寫成矩陣乘法 @ 的形式
不然括號太多不容易對齊
In [12]:
T(0,1) @ S
Out[12]:
In [15]:
def D(i, m):
assert m!=0
def op(M):
R= M.copy()
R[i] = m * R[i]
return R
return op
D(2, 1/5)(S)
Out[15]:
In [16]:
def L(i, j, m):
def op(M):
R = M.copy()
R[i] = R[i] + m*R[j]
return R
return op
L(0, 1, 1)(S)
Out[16]:
再看一下 $S$
In [18]:
S
Out[18]:
In [19]:
show_equations(S)
Out[19]:
先讓第二列首項變成 1
In [20]:
D(1, 1/2) @ S
Out[20]:
然後消去第三列
In [21]:
L(2,1,-3) @ _
Out[21]:
最後再交換第二列和第一列,紀錄起來,叫做 S1
In [22]:
S1 = T(0,1) @ _
S1
Out[22]:
In [23]:
show_equations(S1)
Out[23]:
再來處理第二行,一樣,把第二列的首項變成 $1$,然後去消第一列和第三列的第二行
In [24]:
D(1, 1/2) @ S1
Out[24]:
In [25]:
L(2,1,3) @ _
Out[25]:
In [26]:
L(0,1,-2) @ _
Out[26]:
In [27]:
S2 = _ # 用 S2 紀錄第二步驟
In [28]:
show_equations(S2)
Out[28]:
In [29]:
S2
Out[29]:
最後處理第三行
In [30]:
D(2, 1/4) @ S2
Out[30]:
In [31]:
L(1,2, -2) @ _
Out[31]:
In [32]:
L(0,2,3) @ _
Out[32]:
In [33]:
S3 = _ # 用 S3 紀錄第二步驟
In [34]:
show_equations(S3)
Out[34]:
In [37]:
S3
Out[37]:
In [46]:
Vector(S3[:,-1])
Out[46]:
In [47]:
x = Vector(S3[:, -1])
x
Out[47]:
In [48]:
# 或者這樣也行
x = S3[:, [-1]]
x
Out[48]:
代入原來方程式
In [49]:
A @ x
Out[49]:
In [50]:
b
Out[50]:
檢查是不是每一列都相等
In [51]:
A @ x == b
Out[51]:
In [53]:
np.all((A @ x == b))
Out[53]:
In [59]:
np.any([False,False, False])
Out[59]:
In [103]:
def generate_A_b(n=4):
while True:
A = Matrix(np.random.randint(-10, 10, size=(n,n)))
if True or np.linalg.matrix_rank(A)==n:
x = Vector(np.random.randint(-5,5, size=n))
x /= Vector(np.random.randint(1,5, size=n))
b = A@x
display(Latex("$A=$"), A)
display(Latex("$b=$"), b)
return A, b
A, b = generate_A_b()
S = np.hstack([A,b])
show_equations(S)
Out[103]:
In [104]:
S
Out[104]:
In [105]:
D(0, -1/5) @ S
Out[105]:
In [106]:
L(1, 0, -1) @ _
Out[106]:
In [107]:
L(2, 0, 7) @ _
Out[107]:
In [108]:
L(3, 0, -4) @ _
Out[108]:
In [109]:
S0 = _
S0
Out[109]:
In [110]:
S1 = L(3,1, 76/5) @ L(2, 1, -88/5) @ L(0, 1, -9/5) @ D(1, -5/59) @ S0
S1
Out[110]:
In [111]:
L(3, 2, -796/59) @ L(1, 2, -12/59) @ L(0, 2, 116/59) @ D(2, -59/1344) @ S1
Out[111]:
In [112]:
S2 = _
S2
Out[112]:
In [113]:
S3 = L(2,3,89/336)@L(1,3,17/28)@L(0,3, -73/84) @ D(3, -84/863) @ S2
S3
Out[113]:
In [114]:
show_equations(S3)
Out[114]:
In [115]:
x = S3[:, [-1]]
x
Out[115]:
In [116]:
# 檢查答案
check_answer(A @ x == b)
Out[116]:
In [ ]: