- Linear Algebra: Linear Transformation, Matrix
- Rodion Chachura
- The Nuggets translation Project
- Permanent link to this article: github.com/xitu/gold-m…
- Translator: lsvih
- Proofread by: Mcskiller, Baddyo
JavaScript Linear algebra: Linear transformations and matrices
This article is part of the “JavaScript Linear Algebra” tutorial.
A matrix is a “rectangular” array of m rows and n columns of real numbers. For example, a 3×2 matrix looks like this:
The constructor of the Matrix class takes several rows of elements as arguments. We can retrieve a row in a matrix by specifying a row number, and then retrieve a specific element by specifying a column number. Let’s get straight to the code:
class Matrix {
constructor(. rows) {
this.rows = rows
}
}
const matrix = new Matrix(
[0.1],
[2.3],
[4.5])console.log(matrix)
// Matrix { rows: [ [ 0, 1 ], [ 2, 3 ], [ 4, 5 ] ] }
console.log(matrix.rows[1])
// [2, 3]
console.log(matrix.rows[1] [1])
/ / 3
Copy the code
Matrix vector product
Matrix vector multiplication — Ax⃗A\vec{x}Ax will combine the columns of matrix AAA with coefficients x⃗\vec{x}x. For example, the product of A 3×23\times 23×2 matrix A and A 2D vector x⃗\vec{x}x will yield A 3D vector. The calculation is written as :y⃗ :y⃗=Ax⃗\vec{y} : \vec{y} =A \vec{x}y :y =Ax.
Suppose you have a set of vector {e ⃗ 1, 2} e ⃗ \ {\ vec {e} _1, \ vec _2 \} {e} {e 1, 2} e, another vector y ⃗ \ vec is {} y y e ⃗ 1 \ vec {e} _1e 1 and 2 \ vec ⃗ e {e} _2e linear combination of 2: Y ⃗ = alpha beta e ⃗ e ⃗ 1 + 2 \ vec {} y = \ alpha \ vec + \ beta \ {e} _1 vec {e} _2y = alpha beta e e 1 + 2. Where, α,β∈R\alpha, \beta \in \mathbb{R}α,β∈R is the coefficient of this linear combination.
In order to better learn linear combinations, we specifically define matrix vector multiplication for this purpose. We can write the previous linear combination in the form of matrix vector multiplication: y⃗=Ex⃗\vec{y} =E \vec{x}y =Ex. The matrix EEE has two columns e⃗1\vec{e}_1e 1 and e⃗2\vec{e}_2e 2. The dimension of the matrix is n×2n \times 2n×2, where NNN is the dimension of the vectors e⃗1\vec{e}_1e 1, e⃗2\vec{e}_2e 2 and y⃗\vec{y}y.
The following figure shows the linear combination of vector v⃗\vec{v}v as vector ı⃗\vec{\imath} and vector ȷ⃗\vec{\jmath} ⃗.
const i = new Vector(1.0)
const j = new Vector(0.1)
const firstCoeff = 2
const secondCoeff = 5
const linearCombination = i.scaleBy(firstCoeff).add(j.scaleBy(secondCoeff))
console.log(linearCombination)
// Vector { components: [ 2, 5 ] }
Copy the code
Linear transformation
Matrix and vector multiplication is an abstract concept of linear transformation, which is one of the key concepts in learning linear algebra. The multiplication of a vector with a matrix can be thought of as a linear transformation of a vector: take an n-dimensional vector as input and output an m-dimensional vector. In other words, a matrix is some well-defined transformation of space.
We can understand linear transformations more clearly with an example. We first need to add a method to the Matrix class that returns the columns of the Matrix:
class Matrix {
constructor(. rows) {
this.rows = rows
}
columns() {
return this.rows[0].map((_, i) = > this.rows.map(r= > r[i]))
}
}
const matrix = new Matrix(
[1.2.3],
[4.5.6],
[7.8.9])console.log(matrix.columns())
// [[1, 4, 7], [2, 5, 8], [3, 6, 9]]
Copy the code
The dimension of the vector will be the same as the number of rows of the matrix. If we multiply a 2D vector by a 3×2 matrix, we get a 3D vector; If you multiply a 3D vector by a 2×3 matrix, you get a 2D vector; An error will be reported if the number of columns of the matrix and the dimension of the vector are not the same when multiplying. In the following code, you can see several different forms of a vector multiplied by a matrix:
const sum = arr= > arr.reduce((acc, value) = > acc + value, 0)
class Vector {
// ...
transform(matrix) {
const columns = matrix.columns()
if(columns.length ! = =this.components.length) {
throw new Error('Matrix columns length should be equal to vector components length.')}const multiplied = columns
.map((column, i) = > column.map(c= > c * this.components[i]))
const newComponents = multiplied[0].map((_, i) = > sum(multiplied.map(column= > column[i])))
return newVector(... newComponents) } }const vector2D = new Vector(3.5)
const vector3D = new Vector(3.5.2)
const matrix2x2D = new Matrix(
[1.2],
[3.4])const matrix2x3D = new Matrix(
[1.2.3],
[4.5.6])const matrix3x2D = new Matrix(
[1.2],
[3.4],
[5.6])// 2D => 2D
console.log(vector2D.transform(matrix2x2D))
// Vector { components: [ 13, 29 ] }
// 3D => 2D
console.log(vector3D.transform(matrix2x3D))
// Vector { components: [ 19, 49 ] }
// 2D => 3D
console.log(vector2D.transform(matrix3x2D))
// Vector { components: [ 13, 29, 45 ] }
console.log(vector2D.transform(matrix2x3D))
// Error: Matrix columns length should be equal to vector components length.
Copy the code
The sample
Now, we’re going to try to apply a linear transformation to a two-dimensional object. First, we need to create a new Contour class that receives a set of vectors (forming an Contour in a 2D plane) from constructor, transforms all vector coordinates in the Contour using a unique method called Transform, and returns a new Contour.
class Contour {
constructor(vectors) {
this.vectors = vectors
}
transform(matrix) {
const newVectors = this.vectors.map(v= > v.transform(matrix))
return new Contour(newVectors)
}
}
const contour = new Contour([
new Vector(0.0),
new Vector(0.4),
new Vector(4.4),
new Vector(4.0)])Copy the code
Now, try out the various transformation matrices in the Linear-Opencoursed-demo project. The red square is the initialized contour, and the blue shape is the contour after applying the transformation matrix.
In the following way, we can construct a matrix that will be used to rotate a given vector by a specified Angle.
const angle = toRadians(45)
const matrix = new Matrix(
[Math.cos(angle), -Math.sin(angle)],
[Math.sin(angle), Math.cos(angle)]
)
Copy the code
The same is true for transforming objects in 3D space. You can see an animation of a red square transforming into a blue parallelogram in the image below.
If you find any mistakes in your translation or other areas that need to be improved, you are welcome to the Nuggets Translation Program to revise and PR your translation, and you can also get the corresponding reward points. The permanent link to this article at the beginning of this article is the MarkDown link to this article on GitHub.
The Nuggets Translation Project is a community that translates quality Internet technical articles from English sharing articles on nuggets. The content covers Android, iOS, front-end, back-end, blockchain, products, design, artificial intelligence and other fields. If you want to see more high-quality translation, please continue to pay attention to the Translation plan of Digging Gold, the official Weibo, Zhihu column.