矩阵的行列式与矩阵的逆

矩阵的行列式

只有方阵才能使用行列式,行列式可以告诉我们变换时对象被拉伸的程度

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())


posted @ 2020-10-16 22:02  pluscat  阅读(2236)  评论(0编辑  收藏  举报