@antv/g2
Version:
the Grammar of Graphics in Javascript
72 lines (62 loc) • 1.68 kB
text/typescript
/**
* Gaussian elimination
* @param array a matrix
* @return array x solution vector
*/
export function gauss(a: number[][]): number[] {
const row = a.length;
const col = a[0].length;
const m = row; // 方程的个数
const n = col - 1; // 变量的个数(最后一列是常量)
/**
* 先对 a 进行排序,排序规则为:
* - 第 i 列对应从 i 行到最后一行的最大值,放到当前行
*/
for (let i = 0; i < n; i++) {
// 1. 找到这一列的最大值、已经行索引
let max = Number.MIN_SAFE_INTEGER;
let maxRow;
// 找到这一列的最大值、已经行索引
for (let j = i; j < m; j++) {
if (Math.abs(a[j][i]) > max) {
max = Math.abs(a[j][i]);
maxRow = j;
}
}
// 2. 找到这一列的最大值之后,交换行
const tmp = a[maxRow];
a[maxRow] = a[i];
a[i] = tmp;
// 3. 这一行下面,在这一列上的数据全部为 0
for (let j = i + 1; j < m; j++) {
// 配平系数
const c = -a[j][i] / a[i][i];
// 这一行的元素全部处理
for (let k = i; k < n + 1; k++) {
a[j][k] += c * a[i][k];
}
}
}
/**
* 反向迭代,计算变量值
*/
const b = new Array(n).fill(0);
// 只有 n 个变量(n 后的方程直接忽略)
for (let i = n - 1; i >= 0; i--) {
b[i] = a[i][n] / a[i][i];
// 向上带入归零
for (let j = i - 1; j >= 0; j--) {
const c = -a[j][i] / a[i][i];
a[j][i] += a[i][i] * c;
a[j][n] += a[i][n] * c;
}
}
return b;
}
/**
* 乘法
* @param v
*/
export function multiply(v: number[]) {
return v.reduce((r, c) => r * c, 1);
}