import { EPS } from "./api.js";
import { safeDiv } from "./safe-div.js";
const derivative = (f, eps = EPS) => (x) => (f(x + eps) - f(x)) / eps;
const solveLinear = (a, b) => safeDiv(-b, a);
const solveQuadratic = (a, b, c, eps = 1e-9) => {
  const d = 2 * a;
  let r = b * b - 4 * a * c;
  return r < 0 ? [] : r < eps ? [-b / d] : (r = Math.sqrt(r), [(-b - r) / d, (-b + r) / d]);
};
const solveCubic = (a, b, c, d, eps = 1e-9) => {
  const aa = a * a;
  const bb = b * b;
  const ba3 = b / (3 * a);
  const p = (3 * a * c - bb) / (3 * aa);
  const q = (2 * bb * b - 9 * a * b * c + 27 * aa * d) / (27 * aa * a);
  if (Math.abs(p) < eps) {
    return [Math.cbrt(-q) - ba3];
  } else if (Math.abs(q) < eps) {
    return p < 0 ? [-Math.sqrt(-p) - ba3, -ba3, Math.sqrt(-p) - ba3] : [-ba3];
  } else {
    const denom = q * q / 4 + p * p * p / 27;
    if (Math.abs(denom) < eps) {
      return [-1.5 * q / p - ba3, 3 * q / p - ba3];
    } else if (denom > 0) {
      const u = Math.cbrt(-q / 2 - Math.sqrt(denom));
      return [u - p / (3 * u) - ba3];
    } else {
      const u = 2 * Math.sqrt(-p / 3), t = Math.acos(3 * q / p / u) / 3, k = 2 * Math.PI / 3;
      return [
        u * Math.cos(t) - ba3,
        u * Math.cos(t - k) - ba3,
        u * Math.cos(t - 2 * k) - ba3
      ];
    }
  }
};
const solveTridiagonal = (a, b, c, d) => {
  const n = d.length - 1;
  const tmp = new Array(n + 1);
  tmp[0] = c[0] / b[0];
  d[0] = d[0] / b[0];
  for (let i = 1; i <= n; i++) {
    const ai = a[i];
    const bi = b[i];
    const denom = 1 / (bi - ai * tmp[i - 1]);
    tmp[i] = c[i] * denom;
    d[i] = (d[i] - ai * d[i - 1]) * denom;
  }
  for (let i = n; i-- > 0; ) {
    d[i] -= tmp[i] * d[i + 1];
  }
  return d;
};
export {
  derivative,
  solveCubic,
  solveLinear,
  solveQuadratic,
  solveTridiagonal
};
