@woosh/meep-engine
Version:
Pure JavaScript game engine. Fully featured and production ready.
58 lines (41 loc) • 1.94 kB
JavaScript
import { assert } from "../../assert.js";
import { lu_factor_linear_system } from "./lu_factor_linear_system.js";
import { lu_solve_linear_system } from "./lu_solve_linear_system.js";
import { solve_linear_system_GEPP_2x2 } from "./solve_linear_system_GEPP_2x2.js";
const SCRATCH_SIZE = 16;
const scratch = new Uint32Array(SCRATCH_SIZE);
/**
* Solve linear equations Ax = b using Crout's method. Input is square matrix A and load vector b.
* Solution x is written over load vector.
* The dimension of the matrix is specified in size. If error is found, method returns a 0.
*
* @see https://github.com/Kitware/VTK/blob/af928016f4041ad8a6a193d032355b909721fc95/Common/Core/vtkMath.cxx
*
* @param {number[]|Float32Array|Float64Array} A Matrix of coefficients
* @param {number[]|Float32Array|Float64Array} x Vector of right-hand constants for each equation, resulting solution for variables will also be written here
* @param {number} size size of the system. Size 1 means a single variable and a single equation, 2 means a 2 variable equation system etc
* @returns {boolean} true if solution found, false if factorization fails
*/
export function solve_linear_system(A, x, size) {
assert.isNonNegativeInteger(size, 'size');
assert.defined(A, 'A');
assert.defined(x, 'x');
if (size === 1) {
if (A[0] === 0) {
// Unable to solve linear system
return false;
}
x[0] /= A[0];
return true;
} else if (size === 2) {
// special fast path for 2 variable systems
return solve_linear_system_GEPP_2x2(A, x, x);
}
const index = size <= SCRATCH_SIZE ? scratch : new Uint32Array(size);
if (lu_factor_linear_system(A, index, size) === false) {
// can not factorize system
return false;
}
lu_solve_linear_system(A, index, x, size);
return true;
}