一、矩陣運算
1.1 矩陣相乘
- 、
function multiply(a, b) {
// 相乘約束
if (a[0].length !== b.length) {
throw new Error();
}
let m = a.length;
let p = a[0].length;
let n = b[0].length;
// 初始化 m*n 全 0 二維數組
let c = new Array(m).fill(0).map(arr => new Array(n).fill(0));
for (let i = 0; i < m; i++) {
for (let j = 0; j < n; j++) {
for (let k = 0; k < p; k++) {
c[i][j] += a[i][k] * b[k][j];
}
}
}
return c;
}
1.2 行列式
-
1 階:
-
2 階:
-
3 階:
-
n 階:任意某行(或某列)的各元素與其對應的代數餘子式乘積之和
3 階行列式:對應行平移後公式也可認爲『主對角線元素積與副對角線元素積之差
代數餘子式:『 』乘以『去掉方陣第 i 行第 j 列的元素後構成的方陣的行列式』的值
n 階行列式可取第 1 行的各元素與其對應的代數餘子式乘積之和,如:
function det(square) {
// 方陣約束
if (square.length !== square[0].length) {
throw new Error();
}
// 方陣階數
let n = square.length;
let result = 0;
if (n > 3) {
// n 階
for (let column = 0; column < n; column++) {
// 去掉第 0 行第 column 列的矩陣
let matrix = new Array(n - 1).fill(0).map(arr => new Array(n - 1).fill(0));
for (let i = 0; i < n - 1; i++) {
for (let j = 0; j < n - 1; j++) {
if (j < column) {
matrix[i][j] = square[i + 1][j];
} else {
matrix[i][j] = square[i + 1][j + 1];
}
}
}
result += square[0][column] * Math.pow(-1, 0 + column) * det(matrix);
}
} else if (n === 3) {
// 3 階
result = square[0][0] * square[1][1] * square[2][2] +
square[0][1] * square[1][2] * square[2][0] +
square[0][2] * square[1][0] * square[2][1] -
square[0][2] * square[1][1] * square[2][0] -
square[0][1] * square[1][0] * square[2][2] -
square[0][0] * square[1][2] * square[2][1];
} else if (n === 2) {
// 2 階
result = square[0][0] * square[1][1] - square[0][1] * square[1][0];
} else if (n === 1) {
// 1 階
result = square[0][0];
}
return result;
}
1.2 轉置矩陣
function transpose(matrix) {
let result = new Array(matrix.length).fill(0).map(arr => new Array(matrix[0].length).fill(0));
for (let i = 0; i < result.length; i++) {
for (let j = 0; j < result[0].length; j++) {
result[i][j] = matrix[j][i];
}
}
return result;
}
1.3 伴隨矩陣
- 伴隨矩陣:矩陣中每個元素對應的代數餘子式所構成矩陣的轉置矩陣
function adjoint(square) {
// 方陣約束
if (square[0].length !== square.length) {
throw new Error();
}
let n = square.length;
let result = new Array(n).fill(0).map(arr => new Array(n).fill(0));
for (let row = 0; row < n; row++) {
for (let column = 0; column < n; column++) {
// 去掉第 row 行第 column 列的矩陣
let matrix = [];
for (let i = 0; i < square.length; i++) {
if (i !== row) {
let arr = [];
for (let j = 0; j < square.length; j++) {
if (j !== column) {
arr.push(square[i][j]);
}
}
matrix.push(arr);
}
}
result[row][column] = Math.pow(-1, row + column) * det(matrix);
}
}
return transpose(result);
}
PS
和
det()
函數裏求『去掉第 0 行第 column 列矩陣』的複製方法相比較,求『去掉第 row 行第 column 列矩陣』裏採用尾插法相對更加簡潔可讀一些。不過還是太 low …
1.4 逆矩陣
function inv(square) {
if (square[0].length !== square.length) {
throw new Error();
}
let detValue = det(square);
let result = adjoint(square);
for (let i = 0; i < result.length; i++) {
for (let j = 0; j < result.length; j++) {
result[i][j] /= detValue;
}
}
return result;
}
1.5 秩
// TODO