UNPKG

@woosh/meep-engine

Version:

Pure JavaScript game engine. Fully featured and production ready.

92 lines (69 loc) 2.16 kB
const EPSILON = 1e-10; /** * NxN matrix Householder reduction * Return subfunction to upper Hessenberg matrix by Householder transformation * @see http://www-in.aut.ac.jp/~minemura/pub/Csimu/C/QRmethod.html * @param {number[]} a * @param {number} n */ export function matrix_householder_in_place(a, n) { const u = new Float64Array(n); const d = new Float64Array(n); const ds = new Float64Array(n); let i, j, k; let sum; for (k = 0; k <= n - 3; k++) { for (i = 0; i <= k; i++) { u[i] = 0; } for (i = k + 1; i < n; i++) { u[i] = a[n * i + k]; } // Build transformation matrix H sum = 0.0; for (i = k + 1; i < n; i++) { sum = sum + u[i] * u[i]; } const u_k_1 = u[k + 1]; const u_k_1_abs = Math.abs(u_k_1); if (u_k_1_abs < EPSILON) { continue; } const sigma = Math.sqrt(sum) * u_k_1 / u_k_1_abs; u[k + 1] += sigma; const v_norm = Math.sqrt(2.0 * sigma * u[k + 1]); for (i = k + 1; i < n; i++) { u[i] /= v_norm; } // Similarity transformation for (i = 0; i < n; i++) { d[i] = 0.0; ds[i] = 0.0; for (j = k + 1; j <= n - 1; j++) { const u_j = u[j]; d[i] += a[n * i + j] * u_j; ds[i] += a[n * j + i] * u_j; } } let ud = 0.0; let uds = 0.0; for (i = k + 1; i < n; i++) { const u_i = u[i]; ud += u_i * d[i]; uds += u_i * ds[i]; } for (i = 0; i < n; i++) { const u_i = u[i]; d[i] = 2.0 * (d[i] - ud * u_i); ds[i] = 2.0 * (ds[i] - uds * u_i); } for (i = 0; i < n; i++) { const u_i = u[i]; const d_i = d[i]; const n_i = n * i; for (j = 0; j < n; j++) { a[n_i + j] -= u_i * ds[j] + d_i * u[j]; } } } }