zoukankan      html  css  js  c++  java
  • 矩阵的行列式与矩阵的逆

    矩阵的行列式

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

    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())
    
    
    
  • 相关阅读:
    [usaco]Cow Pedigrees
    组合数取模
    [usaco]Controlling Companies
    ubuntu g++ 升级
    膜拜
    Node.js权威指南 (2)
    Vue.js 开发环境的搭建
    src路径问题:./ 与 ../
    vscode vue代码提示错误
    H5 localStorage sessionStorage
  • 原文地址:https://www.cnblogs.com/pluslius/p/13828976.html
Copyright © 2011-2022 走看看