- 原文地址:Linear Algebra: Basic Matrix Operations
- 原文做者:Rodion Chachura
- 译文出自:掘金翻译计划
- 本文永久连接:github.com/xitu/gold-m…
- 译者:lsvih
- 校对者:JackEggie, shixi-li
本文是“JavaScript 线性代数”教程的一部分。javascript
在本文中,咱们将介绍矩阵的大部分基本运算,依次是矩阵的加减法、矩阵的标量乘法、矩阵与矩阵的乘法、求转置矩阵,以及深刻了解矩阵的行列式运算。本文将不会涉及逆矩阵、矩阵的秩等概念,未来再探讨它们。前端
矩阵的加法与减法运算将接收两个矩阵做为输入,并输出一个新的矩阵。矩阵的加法和减法都是在份量级别上进行的,所以要进行加减的矩阵必须有着相同的维数。java
为了不重复编写加减法的代码,咱们先建立一个能够接收运算函数的方法,这个方法将对两个矩阵的份量分别执行传入的某种运算。而后在加法、减法或者其它运算中直接调用它就好了:android
class Matrix {
// ...
componentWiseOperation(func, { rows }) {
const newRows = rows.map((row, i) =>
row.map((element, j) => func(this.rows[i][j], element))
)
return new Matrix(...newRows)
}
add(other) {
return this.componentWiseOperation((a, b) => a + b, other)
}
subtract(other) {
return this.componentWiseOperation((a, b) => a - b, other)
}
}
const one = new Matrix(
[1, 2],
[3, 4]
)
const other = new Matrix(
[5, 6],
[7, 8]
)
console.log(one.add(other))
// Matrix { rows: [ [ 6, 8 ], [ 10, 12 ] ] }
console.log(other.subtract(one))
// Matrix { rows: [ [ 4, 4 ], [ 4, 4 ] ] }
复制代码
矩阵的标量乘法与向量的缩放相似,就是将矩阵中的每一个元素都乘上标量:ios
class Matrix {
// ...
scaleBy(number) {
const newRows = this.rows.map(row =>
row.map(element => element * number)
)
return new Matrix(...newRows)
}
}
const matrix = new Matrix(
[2, 3],
[4, 5]
)
console.log(matrix.scaleBy(2))
// Matrix { rows: [ [ 4, 6 ], [ 8, 10 ] ] }
复制代码
当 A、B 两个矩阵的维数是兼容的时候,就能对这两个矩阵进行矩阵乘法。所谓维数兼容,指的是 A 的列数与 B 的行数相同。矩阵的乘积 AB 是经过对 A 的每一行与矩阵 B 的每一列计算点积获得:git
class Matrix {
// ...
multiply(other) {
if (this.rows[0].length !== other.rows.length) {
throw new Error('The number of columns of this matrix is not equal to the number of rows of the given matrix.')
}
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)
}
}
const one = new Matrix(
[3, -4],
[0, -3],
[6, -2],
[-1, 1]
)
const other = new Matrix(
[3, 2, -4],
[4, -3, 5]
)
console.log(one.multiply(other))
// Matrix {
// rows:
// [ [ -7, 18, -32 ],
// [ -12, 9, -15 ],
// [ 10, 18, -34 ],
// [ 1, -5, 9 ] ]}
复制代码
咱们能够把矩阵乘法 AB 视为前后应用 A 和 B 两个线性变换矩阵。为了更好地理解这种概念,能够看一看咱们的 linear-algebra-demo。github
下图中黄色的部分就是对红色方块应用线性变换 C 的结果。而线性变换 C 就是矩阵乘法 AB 的结果,其中 A 是作相对于 y 轴进行反射的变换矩阵,B 是作剪切变换的矩阵。后端
若是在矩阵乘法中调换 A 和 B 的顺序,咱们会获得一个不一样的结果,由于至关于先应用了 B 的剪切变换,再应用 A 的反射变换:函数
转置矩阵 由公式
定义。换句话说,咱们经过关于矩阵的对角线对其进行翻转来获得转置矩阵。须要注意的是,矩阵对角线上的元素不受转置运算影响。区块链
class Matrix {
// ...
transpose() {
return new Matrix(...this.columns())
}
}
const matrix = new Matrix(
[0, 1, 2],
[3, 4, 5],
[6, 7, 8],
[9, 10, 11]
)
console.log(matrix.transpose())
// Matrix {
// rows: [
// [ 0, 3, 6, 9 ],
// [ 1, 4, 7, 10 ],
// [ 2, 5, 8, 11 ]
// ]
// }
复制代码
矩阵的行列式运算将计算矩阵中的全部系数,最后输出一个数字。准确地说,行列式能够描述一个由矩阵行构成的向量的相对几何指标(好比在欧式空间中的有向面积、体积等空间概念)。更准确地说,矩阵 A 的行列式至关于告诉你由 A 的行定义的方块的体积。 矩阵的行列式运算以下所示:
矩阵的行列式运算以下所示:
咱们的方法能够计算任意大小矩阵(只要其行列的数量相同)的行列式:
class Matrix {
// ...
determinant() {
if (this.rows.length !== this.rows[0].length) {
throw new Error('Only matrices with the same number of rows and columns are supported.')
}
if (this.rows.length === 2) {
return this.rows[0][0] * this.rows[1][1] - this.rows[0][1] * this.rows[1][0]
}
const parts = this.rows[0].map((coef, index) => {
const matrixRows = this.rows.slice(1).map(row => [ ...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 matrix2 = new Matrix(
[ 0, 3],
[-2, 1]
)
console.log(matrix2.determinant())
// 6
const matrix3 = new Matrix(
[2, -3, 1],
[2, 0, -1],
[1, 4, 5]
)
console.log(matrix3.determinant())
// 49
const matrix4 = new Matrix(
[3, 0, 2, -1],
[1, 2, 0, -2],
[4, 0, 6, -3],
[5, 0, 2, 0]
)
console.log(matrix4.determinant())
// 20
复制代码
行列式能够告诉咱们变换时对象被拉伸的程度。所以咱们能够将其视为线性变换改变面积的因子。为了更好地理解这个概念,请参考 linear-algebra-demo:
在下图中,咱们能够看到对红色的 1×1 方形进行线性变换后获得了一个 3×2 的长方形,面积从 1 变为了 6,这个数字与线性变换矩阵的行列式值相同。
若是咱们应用一个剪切变换,能够看到方形会变成一个面积不变的平行四边形。所以,剪切变换矩阵的行列式值等于 1:
若是行列式的值是负数,则说明应用线性变换后,空间被反转了。好比在下图中,咱们能够看到变换前 在
的左边,而变换后
在
的右边。
若是变换的行列式为 0,则表示它会将全部空间都压缩到一条线或一个点上。也就是说,计算一个给定矩阵的行列式是否为 0,能够判断这个矩阵对应的线性变换是否会将对象压缩到更小的维度去。
在三维空间里,行列式能够告诉你体积缩放了多少:
变换行列式等于 0,意味着原来的空间会被彻底压缩成体积为 0 的空间。如前文所说,若是在 2 维空间中变换的行列式为 0,则意味着变换的结果将空间压缩成了一条线或一个点;而在 3 维空间中变换的行列式为 0 意味着一个物体会被压扁成一个平面,以下图所示:
若是发现译文存在错误或其余须要改进的地方,欢迎到 掘金翻译计划 对译文进行修改并 PR,也可得到相应奖励积分。文章开头的 本文永久连接 即为本文在 GitHub 上的 MarkDown 连接。
掘金翻译计划 是一个翻译优质互联网技术文章的社区,文章来源为 掘金 上的英文分享文章。内容覆盖 Android、iOS、前端、后端、区块链、产品、设计、人工智能等领域,想要查看更多优质译文请持续关注 掘金翻译计划、官方微博、知乎专栏。