内容
Chió算法Chió‘s method,是一种计算行列式的方法,也叫Chió Pivotal Condensation,后面这个英文,不太好翻译。还有个说法叫Chio展开法,英文为Chio’s Expansion。这个算法,给我的第一印象是,性能不是很高。它是一种递归算法,是把一个
n
×
n
n\times n
n×n的矩阵缩成一个
(
n
−
1
)
×
(
n
−
1
)
(n-1)\times (n-1)
(n−1)×(n−1)的矩阵,直到缩小为
2
×
2
2\times 2
2×2的矩阵。
2
×
2
2\times 2
2×2的矩阵计算它的行列式就不需要什么算法了,直接公式就完事了,另一个不能递归到
1
×
1
1\times 1
1×1的矩阵的原因是它的缩小过程大量运用了
2
×
2
2\times 2
2×2矩阵的行列式。
Chió算法的原理如下:
A
=
(
a
11
⋯
a
1
n
⋮
⋱
⋮
a
n
1
⋯
a
n
n
)
∣
A
∣
=
1
a
11
n
−
2
∣
∣
a
11
a
12
a
21
a
22
∣
∣
a
11
a
13
a
21
a
23
∣
⋯
∣
a
11
a
1
n
a
21
a
2
n
∣
∣
a
11
a
12
a
31
a
32
∣
∣
a
11
a
13
a
31
a
33
∣
⋯
∣
a
11
a
1
n
a
31
a
3
n
∣
⋮
⋮
⋱
⋮
∣
a
11
a
12
a
n
1
a
32
∣
∣
a
11
a
13
a
n
1
a
33
∣
⋯
∣
a
11
a
1
n
a
n
1
a
3
n
∣
∣
A=\begin{pmatrix} a_{11}& \cdots & a_{1n}\\ \vdots & \ddots & \vdots \\ a_{n1}& \cdots & a_{nn} \end{pmatrix}\\ |A|=\frac{1}{a_{11}^{n-2}}\begin{vmatrix} \begin{vmatrix} a_{11} & a_{12}\\ a_{21} & a_{22} \end{vmatrix} & \begin{vmatrix} a_{11} & a_{13}\\ a_{21} & a_{23} \end{vmatrix} & \cdots & \begin{vmatrix} a_{11} & a_{1n}\\ a_{21} & a_{2n} \end{vmatrix}\\\\ \begin{vmatrix} a_{11} & a_{12}\\ a_{31} & a_{32} \end{vmatrix} & \begin{vmatrix} a_{11} & a_{13}\\ a_{31} & a_{33} \end{vmatrix} & \cdots & \begin{vmatrix} a_{11} & a_{1n}\\ a_{31} & a_{3n} \end{vmatrix}\\\\ \vdots & \vdots & \ddots & \vdots \\\\ \begin{vmatrix} a_{11} & a_{12}\\ a_{n1} & a_{32} \end{vmatrix} & \begin{vmatrix} a_{11} & a_{13}\\ a_{n1} & a_{33} \end{vmatrix} & \cdots & \begin{vmatrix} a_{11} & a_{1n}\\ a_{n1} & a_{3n} \end{vmatrix}\\ \end{vmatrix}
A=
a11⋮an1⋯⋱⋯a1n⋮ann
∣A∣=a11n−21
a11a21a12a22
a11a31a12a32
⋮
a11an1a12a32
a11a21a13a23
a11a31a13a33
⋮
a11an1a13a33
⋯⋯⋱⋯
a11a21a1na2n
a11a31a1na3n
⋮
a11an1a1na3n
规律是什么呢?缩小后的矩阵,每个元素是
2
×
2
2\times 2
2×2矩阵的行列式,这个
2
×
2
2\times 2
2×2矩阵,左上角永远是
a
11
a_{11}
a11,右下角其实是原矩阵除去第一行第一列后剩余的矩阵,右上角是原矩阵第一行的元素,左下角是原矩阵第一列的元素。其实这个结构很优雅的,很容易记住。不过看到了这个结构后,也能立马明白为啥性能差了吧,计算量太大了。
举例
emsp;以一个实际的矩阵为例子:
A
=
(
1
−
1
−
2
−
3
3
−
2
−
1
−
2
2
1
1
1
6
5
4
3
)
∣
A
∣
=
1
1
2
∣
∣
1
−
1
3
−
2
∣
∣
1
−
2
3
−
1
∣
∣
1
−
3
3
−
2
∣
∣
1
−
1
2
1
∣
∣
1
−
2
2
1
∣
∣
1
−
3
2
1
∣
∣
1
−
1
6
5
∣
∣
1
−
2
6
4
∣
∣
1
−
3
6
3
∣
∣
=
∣
1
5
7
3
5
7
11
16
21
∣
=
1
1
1
∣
∣
1
5
3
5
∣
∣
1
7
3
7
∣
∣
1
5
11
16
∣
∣
1
7
11
21
∣
∣
=
∣
−
10
−
14
−
39
−
56
∣
=
14
A= \begin{pmatrix}1 & -1 & -2 & -3\\ 3 & -2 & -1 & -2\\ 2 & 1 & 1 & 1\\ 6 & 5 & 4 & 3\\ \end{pmatrix}\\ |A|=\frac{1}{1^{2}} \begin{vmatrix} \begin{vmatrix}1 & -1\\ 3&-2\end{vmatrix} & \begin{vmatrix}1 & -2\\ 3&-1\end{vmatrix} & \begin{vmatrix}1 & -3\\ 3&-2\end{vmatrix}\\\\ \begin{vmatrix}1 & -1\\ 2&1\end{vmatrix} & \begin{vmatrix}1 & -2\\ 2&1\end{vmatrix} & \begin{vmatrix}1 & -3\\ 2&1\end{vmatrix}\\\\ \begin{vmatrix}1 & -1\\ 6&5\end{vmatrix} & \begin{vmatrix}1 & -2\\ 6&4\end{vmatrix} & \begin{vmatrix}1 & -3\\ 6&3\end{vmatrix}\\ \end{vmatrix}\\ \\= \begin{vmatrix}1 & 5 & 7\\ 3 & 5 & 7\\ 11 & 16 & 21\\ \end{vmatrix}\\=\frac{1}{ 1 ^{ 1 }} \begin{vmatrix}\begin{vmatrix}1 & 5\\ 3&5\end{vmatrix} & \begin{vmatrix}1 & 7\\ 3&7\end{vmatrix}\\\\ \begin{vmatrix}1 & 5\\ 11&16\end{vmatrix} & \begin{vmatrix}1 & 7\\ 11&21\end{vmatrix}\\ \end{vmatrix}\\ \\= \begin{vmatrix}-10 & -14\\ -39 & -56\\ \end{vmatrix}\\=14
A=
1326−1−215−2−114−3−213
∣A∣=121
13−1−2
12−11
16−15
13−2−1
12−21
16−24
13−3−2
12−31
16−33
=
131155167721
=111
1355
111516
1377
111721
=
−10−39−14−56
=14
Python实现
def chio(self):
n = len(self.__lines)
if len(self.__lines) == 2:
return self.__lines[0][0] * self.__lines[1][1] - self.__lines[0][1] * self.__lines[1][0]
remain = [[0 for _ in range(0, n - 1)] for _ in range(0, n - 1)]
# i 代表行
for i in range(0, n - 1):
# j 代表列
for j in range(0, n - 1):
tl = self.__lines[0][0]
tr = self.__lines[j + 1][0]
bl = self.__lines[0][i + 1]
br = self.__lines[j + 1][i + 1]
remain[i][j] = tl * br - tr * bl
return Matrix(remain).chio() / self.__lines[0][0] ** (n - 2)
测试代码:
class MyTestCase(unittest.TestCase):
def test(self):
a = Matrix([[1, 3, 2, 6],
[-1, -2, 1, 5],
[-2, -1, 1, 4],
[-3, -2, 1, 3]])
print("A=", a.to_latex(), ",det(A)= ", a.chio(), "|A|=", a.determinant())
if __name__ == '__main__':
if __name__ == '__main__':
unittest.main()