矩陣的行列式
只有方陣才能使用行列式,行列式可以告訴我們變換時對象被拉伸的程度
det(
[
a b
c d
]
)
= ad * cb
// 多階的行列式拆成系數 * matrix(2x2)的形式進行計算
det(
[
a b c
d e f
g h i
]
) =
a * det(
[
e f
h i
]
)
-
b * det(
[
d f
g i
]
)
+
c * det(
[
d e
g h
]
)
class Matrix {
constructor(...components) {
this.rows = components
}
sum(arr) {
return arr.reduce((el, next) => el + next, 0)
}
columns() {
// (M * N)^T = matirx(N * M)
return this.rows[0].map((_, i) => this.rows.map(row => row[i]))
}
mult(other) {
if (this.rows[0].length !== other.rows.length) {
throw new Error('該矩陣的列數不等於給定矩陣的行數')
}
const sum = this.sum
// 將矩陣轉置
const columns = other.columns()
const newRows = this.rows.map(row => (
columns.map(column => (
sum(row.map((element, i) => element * column[i]))
))
))
return new Matrix(...newRows)
}
transpose() {
return new Matrix(...this.columns())
}
scaleMult(number) {
const newRows = this.rows.map(row => (
row.map(element => element * number)
))
return new Matrix(...newRows)
}
determinant() {
if (this.rows[0].length !== this.rows.length) {
throw new Error('該矩陣的列數不等於給定矩陣的行數')
}
// 二階行列式使用交叉相乘
if (this.rows.length === 2) {
return this.rows[0][0] * this.rows[1][1] - this.rows[0][1] * this.rows[1][0]
}
const sum = this.sum
// n階行列式,拆成a * det(Matrix[2x2])的形式進行計算
const parts = this.rows[0].map((coef,index) => {
const MatrixRows = this.rows.slice(1).map(row => {
return [...row.slice(0, index), ...row.slice(index + 1)]
})
const matrix = new Matrix(...MatrixRows)
const result = coef * matrix.determinant()
return index % 2 === 0 ? result : -result
})
return sum(parts)
}
}
const log = console.log
const one = new Matrix(
[2, -3, 1],
[2, 0, -1],
[1, 4, 5]
)
log(one.determinant())
矩陣的逆
M^-1
MM^-1 = M^-1M = I
奇異矩陣
行列式為0的矩陣為奇異矩陣,不可以求矩陣的逆
1. 奇異矩陣(不可逆矩陣)
2. 奇異矩陣的行列式為0
3. 非奇異矩陣(可逆矩陣)
4. 非奇異矩陣的行列式不為0
標准伴隨矩陣
M = [
-4 -3 3
0 2 -2
1 4 -1
]
adj M = [
C(11) C(12) C(13)
C(21) C(22) C(23)
C(31) C(32) C(33)
]^T
= [
6 -2 -2
9 1 13
0 -8 -8
]^T
= [
6 9 0
-2 1 -8
-2 13 -8
]
代數余子式矩陣
C(11) = det([
2 -2
4 -1
]) = 6
C(12) = -det([
0 -2
1 -1
]) = -2
C(13) = det([
0 2
1 4
]) = -2
C(21) = -det([
-3 3
4 -1
]) = 9
C(22) = det([
-4 3
1 -1
]) = 1
C(23) = -det([
-1 -3
1 4
]) = 13
C(31) = det([
3 -3
2 -2
]) = 0
C(32) = -det([
-4 3
0 -2
]) = -8
C(33) = det([
-4 -3
0 2
]) = -8
矩陣的逆
作用撤銷變換
M^-1 = adj M / |M| (標准伴隨矩陣 / 矩陣的行列式)
(M^1)^1 = M
I^-1 = I
(M^T)^-1 = (M^-1)^T
(AB)^-1 = B^-1A^-1
(M1M2..Mn)^-1 = Mn^-1Mn-1^-1M2^-1M1^-1
|M^-1| = 1 / |M|
(vM)M^-1 = v(MM^-1) = vI = v
class Matrix {
constructor(...components) {
this.rows = components
}
sum(arr) {
return arr.reduce((el, next) => el + next, 0)
}
columns() {
// (M * N)^T = matirx(N * M)
return this.rows[0].map((_, i) => this.rows.map(row => row[i]))
}
mult(other) {
if (this.rows[0].length !== other.rows.length) {
throw new Error('該矩陣的列數不等於給定矩陣的行數')
}
const sum = this.sum
// 將矩陣轉置
const columns = other.columns()
const newRows = this.rows.map(row => (
columns.map(column => (
sum(row.map((element, i) => element * column[i]))
))
))
return new Matrix(...newRows)
}
transpose() {
return new Matrix(...this.columns())
}
scaleMult(number) {
const newRows = this.rows.map(row => (
row.map(element => element * number)
))
return new Matrix(...newRows)
}
determinant() {
if (this.rows[0].length !== this.rows.length) {
throw new Error('該矩陣的列數不等於給定矩陣的行數')
}
// 二階行列式使用交叉相乘
if (this.rows.length === 2) {
return this.rows[0][0] * this.rows[1][1] - this.rows[0][1] * this.rows[1][0]
}
const sum = this.sum
// n階行列式,拆成a * det(Matrix[2x2])的形式進行計算
const parts = this.rows[0].map((coef, index) => {
const MatrixRows = this.rows.slice(1).map(row => {
return [...row.slice(0, index), ...row.slice(index + 1)]
})
const matrix = new Matrix(...MatrixRows)
const result = coef * matrix.determinant()
return index % 2 === 0 ? result : -result
})
return sum(parts)
}
withoutElementAtIndex(arr, index) {
return [...arr.slice(0, index), ...arr.slice(index + 1)]
}
minor(i, j) {
// 根據給定i,j行列,去除該行列元素,返回一個去除該行列的矩陣
const withoutElementAtIndex = this.withoutElementAtIndex
const newRows = withoutElementAtIndex(this.rows, i)
.map(row => withoutElementAtIndex(row, j))
// 余子式輔助矩陣
const matrix = new Matrix(...newRows)
// 返回余子式輔助計算結果
return matrix.determinant()
}
// 求代數余子式
cofactor(i, j) {
// 余子式符號 sign(aij) = (-1)^i+j
const sign = (-1) ** (i + j)
const minor = this.minor(i, j)
return sign * minor
}
map(func) {
return new Matrix(
...this.rows.map((row, i) => (
row.map((element, j) => (
func(element, i, j)
))
))
)
}
// 求伴隨矩陣
adjugate() {
// 將余子式矩陣結果進行轉置得到伴隨矩陣
return this.map((_, i, j) => this.cofactor(i, j)).transpose()
}
// 求矩陣的逆
inverse() {
const determinant = this.determinant()
if (determinant === 0) {
throw new Error('奇異矩陣不能求矩陣的逆')
}
const adjugate = this.adjugate()
return adjugate.scaleMult(1 / determinant)
}
}
const log = console.log
const matrix = new Matrix(
[2, 3, 1],
[4, 7, 2],
[3, 1, 1]
)
log(matrix.inverse())
// const matrix = new Matrix(
// [1, 2, 3],
// [4, 5, 6],
// [7, 8, 9]
// )
// log(matrix.cofactor(0, 1))
// const one = new Matrix(
// [3, -2, 0],
// [1, 4, -3],
// [-1, 0, 2]
// )
// log(one.determinant())