JSFiddle - React, Tailwind, and code Playground
by Josh Pullen
JavaScript
const neg = a => [-a[0], -a[1]];
const add = (...nums) => nums.reduce((a, b) => [a[0] + b[0], a[1] + b[1]], [0, 0]);
const sub = (a, b) => add(a, neg(b));
const scale = (scalar, num) => [scalar * num[0], scalar * num[1]];
const inverse = a => [a[0] / (a[0] ** 2 + a[1] ** 2), -a[1] / (a[0] ** 2 + a[1] ** 2)];
const mult = (...nums) => nums.reduce((a, b) => [a[0] * b[0] - a[1] * b[1], a[1] * b[0] + a[0] * b[1]], [1, 0]);
const div = (a, b) => mult(a, inverse(b));
const pow = (a, power) => {
let result = [1, 0];
for (let i = 0; i < power; i++) {
result = mult(result, a);
}
return result;
}
function combinations(arr, size = null) {
const getAllCombinations = (arr) => {
if (arr.length === 0) return [[]];
const allSubCombos = getAllCombinations(arr.slice(1))
return [
...allSubCombos,
...allSubCombos.map(b => [arr[0], ...b])
];
}
const allCombos = getAllCombinations(arr);
if (size === null) {
return allCombos;
}
return allCombos.filter(combo => combo.length === size);
}
function rootsToCoefficients(roots) {
const n = roots.length;
let coeffs = [];
for (let k = 0; k <= roots.length; k++) {
coeffs.push(
scale(
(-1) ** (n - k),
add(...combinations(roots, n - k).map((values) => mult(...values)))
)
);
}
return coeffs;
}
function evalPoly(coeffs, x) {
return add(...coeffs.map((value, i) => mult(value, pow(x, i))));
}
function evalDPoly(coeffs, x) {
return add(...coeffs.map((value, i) => i === 0 ? [0, 0] : mult(scale(i, value), pow(x, i - 1))));
}
function polynomialDegree(coeffs) {
let deg = coeffs.length - 1;
while (deg > -1 && coeffs[deg][0] === 0 && coeffs[deg][1] === 0) {
deg--;
}
return deg;
}
// Based on python code at
// https://rosettacode.org/wiki/Polynomial_long_division#Python
function polynomialDivision(N, D) {
let dD = polynomialDegree(D);
let dN = polynomialDegree(N);
if (dD < 0) {
throw new Error("Polynomial division:...