import { assert } from "../assert.js";

const q = 0.7172491568;
const p0 = 0.6312725339;
const ps0 = 0.4308049446;
const p1 = 0.3500347951;
const ps1 = 0.4678202347;
const p2 = -0.06207747907;
const ps2 = 0.04253832927;
// const lamb4 = (lamb * lamb) * (lamb * lamb);
const lamb4 = 0.559840650625;

/**
 * Bessel first order function of zeroth order
 * @see https://link.springer.com/article/10.1007/s40314-020-01238-z
 * @see https://www.shadertoy.com/view/Wt3czM
 * @param {number} x
 * @return {number}
 */
export function bessel_j0(x) {
    assert.notNaN(x, 'x');

    const xx = x * x;

    const t0 = Math.sqrt(1.0 + lamb4 * xx);
    const t1 = Math.sqrt(t0);

    return xx === 0.0 ? 1.0 : 1.0 / (t1 * (1.0 + q * xx)) * ((p0 + p1 * xx + p2 * t0) * Math.cos(x) + ((ps0 + ps1 * xx) * t0 + ps2 * xx) * (Math.sin(x) / x));

}
