@woosh/meep-engine 2.135.0 → 2.138.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/core/geom/2d/aabb/aabb2_intersects_ray.d.ts.map +1 -1
- package/src/core/geom/2d/aabb/aabb2_intersects_ray.js +5 -7
- package/src/core/geom/2d/hash-grid/shg_query_elements_circle.d.ts.map +1 -1
- package/src/core/geom/2d/hash-grid/shg_query_elements_circle.js +2 -3
- package/src/core/geom/3d/aabb/aabb3_intersects_line_segment.d.ts.map +1 -1
- package/src/core/geom/3d/aabb/aabb3_intersects_line_segment.js +9 -11
- package/src/core/geom/3d/tetrahedra/tetrahedron_compute_circumsphere.d.ts.map +1 -1
- package/src/core/geom/3d/tetrahedra/tetrahedron_compute_circumsphere.js +6 -4
- package/src/core/geom/3d/topology/simplify/quadratic/Quadric3.d.ts.map +1 -1
- package/src/core/geom/3d/topology/simplify/quadratic/Quadric3.js +1 -2
- package/src/core/geom/Quaternion.d.ts +26 -39
- package/src/core/geom/Quaternion.d.ts.map +1 -1
- package/src/core/geom/Quaternion.js +124 -136
- package/src/core/geom/Vector2.d.ts +28 -14
- package/src/core/geom/Vector2.d.ts.map +1 -1
- package/src/core/geom/Vector2.js +114 -97
- package/src/core/geom/Vector3.d.ts +21 -34
- package/src/core/geom/Vector3.d.ts.map +1 -1
- package/src/core/geom/Vector3.js +131 -142
- package/src/core/geom/Vector4.d.ts +21 -30
- package/src/core/geom/Vector4.d.ts.map +1 -1
- package/src/core/geom/Vector4.js +80 -93
- package/src/core/geom/packing/computeBoundingSphereOfSpheres.d.ts.map +1 -1
- package/src/core/geom/packing/computeBoundingSphereOfSpheres.js +23 -6
- package/src/core/geom/packing/miniball/Miniball.d.ts.map +1 -1
- package/src/core/geom/packing/miniball/Miniball.js +4 -11
- package/src/core/geom/packing/miniball/Subspan.d.ts +14 -39
- package/src/core/geom/packing/miniball/Subspan.d.ts.map +1 -1
- package/src/core/geom/packing/miniball/Subspan.js +105 -158
- package/src/core/geom/packing/miniball/miniball_compute_quality.d.ts.map +1 -1
- package/src/core/geom/packing/miniball/miniball_compute_quality.js +2 -6
- package/src/core/geom/vec/vector_axpy.d.ts +12 -0
- package/src/core/geom/vec/vector_axpy.d.ts.map +1 -0
- package/src/core/geom/vec/vector_axpy.js +15 -0
- package/src/core/geom/vec/vector_axpy_offset.d.ts +17 -0
- package/src/core/geom/vec/vector_axpy_offset.d.ts.map +1 -0
- package/src/core/geom/vec/vector_axpy_offset.js +20 -0
- package/src/core/geom/vec/vector_dot_offset.d.ts +18 -0
- package/src/core/geom/vec/vector_dot_offset.d.ts.map +1 -0
- package/src/core/geom/vec/vector_dot_offset.js +25 -0
- package/src/core/math/complex/complex_horner_eval.d.ts +16 -0
- package/src/core/math/complex/complex_horner_eval.d.ts.map +1 -0
- package/src/core/math/complex/complex_horner_eval.js +31 -0
- package/src/core/math/fabsf.d.ts +2 -3
- package/src/core/math/fabsf.d.ts.map +1 -1
- package/src/core/math/fabsf.js +3 -5
- package/src/core/math/linalg/cubic_residual_times_derivative_accumulate.d.ts +26 -0
- package/src/core/math/linalg/cubic_residual_times_derivative_accumulate.d.ts.map +1 -0
- package/src/core/math/linalg/cubic_residual_times_derivative_accumulate.js +43 -0
- package/src/core/math/linalg/eigen/matrix_eigenvalues_in_place.d.ts +2 -1
- package/src/core/math/linalg/eigen/matrix_eigenvalues_in_place.d.ts.map +1 -1
- package/src/core/math/linalg/eigen/matrix_eigenvalues_in_place.js +2 -1
- package/src/core/math/linalg/eigen/matrix_householder_in_place.d.ts +10 -4
- package/src/core/math/linalg/eigen/matrix_householder_in_place.d.ts.map +1 -1
- package/src/core/math/linalg/eigen/matrix_householder_in_place.js +122 -98
- package/src/core/math/linalg/eigen/matrix_qr_in_place.d.ts +2 -2
- package/src/core/math/linalg/eigen/matrix_qr_in_place.d.ts.map +1 -1
- package/src/core/math/linalg/eigen/matrix_qr_in_place.js +144 -124
- package/src/core/math/linalg/givens/givens_apply_rows.d.ts +22 -0
- package/src/core/math/linalg/givens/givens_apply_rows.d.ts.map +1 -0
- package/src/core/math/linalg/givens/givens_apply_rows.js +28 -0
- package/src/core/math/linalg/givens/givens_apply_rows_offset.d.ts +24 -0
- package/src/core/math/linalg/givens/givens_apply_rows_offset.d.ts.map +1 -0
- package/src/core/math/linalg/givens/givens_apply_rows_offset.js +30 -0
- package/src/core/math/linalg/givens/givens_rotation_coefficients.d.ts +25 -0
- package/src/core/math/linalg/givens/givens_rotation_coefficients.d.ts.map +1 -0
- package/src/core/math/linalg/givens/givens_rotation_coefficients.js +39 -0
- package/src/core/math/linalg/lu_factor_linear_system.d.ts +1 -1
- package/src/core/math/linalg/lu_factor_linear_system.d.ts.map +1 -1
- package/src/core/math/linalg/lu_factor_linear_system.js +108 -117
- package/src/core/math/linalg/lu_solve_linear_system.d.ts +1 -1
- package/src/core/math/linalg/lu_solve_linear_system.js +53 -53
- package/src/core/math/linalg/polynomial_add_into.d.ts +18 -0
- package/src/core/math/linalg/polynomial_add_into.d.ts.map +1 -0
- package/src/core/math/linalg/polynomial_add_into.js +29 -0
- package/src/core/math/linalg/polynomial_complex_roots_aberth_ehrlich.d.ts +6 -1
- package/src/core/math/linalg/polynomial_complex_roots_aberth_ehrlich.d.ts.map +1 -1
- package/src/core/math/linalg/polynomial_complex_roots_aberth_ehrlich.js +48 -50
- package/src/core/math/linalg/polynomial_cubic_derivative_eval.d.ts +15 -0
- package/src/core/math/linalg/polynomial_cubic_derivative_eval.d.ts.map +1 -0
- package/src/core/math/linalg/polynomial_cubic_derivative_eval.js +16 -0
- package/src/core/math/linalg/polynomial_cubic_horner_eval.d.ts +18 -0
- package/src/core/math/linalg/polynomial_cubic_horner_eval.d.ts.map +1 -0
- package/src/core/math/linalg/polynomial_cubic_horner_eval.js +19 -0
- package/src/core/math/linalg/polynomial_cubic_second_derivative_eval.d.ts +13 -0
- package/src/core/math/linalg/polynomial_cubic_second_derivative_eval.d.ts.map +1 -0
- package/src/core/math/linalg/polynomial_cubic_second_derivative_eval.js +14 -0
- package/src/core/math/linalg/polynomial_multiply.d.ts +21 -0
- package/src/core/math/linalg/polynomial_multiply.d.ts.map +1 -0
- package/src/core/math/linalg/polynomial_multiply.js +41 -0
- package/src/core/math/linalg/polynomial_real_roots_in_interval.d.ts +6 -1
- package/src/core/math/linalg/polynomial_real_roots_in_interval.d.ts.map +1 -1
- package/src/core/math/linalg/polynomial_real_roots_in_interval.js +29 -18
- package/src/core/math/linalg/polynomial_root_bound_cauchy.d.ts +17 -0
- package/src/core/math/linalg/polynomial_root_bound_cauchy.d.ts.map +1 -0
- package/src/core/math/linalg/polynomial_root_bound_cauchy.js +30 -0
- package/src/core/math/linalg/polynomial_scale_into.d.ts +14 -0
- package/src/core/math/linalg/polynomial_scale_into.d.ts.map +1 -0
- package/src/core/math/linalg/polynomial_scale_into.js +17 -0
- package/src/core/math/linalg/polynomial_sub_into.d.ts +18 -0
- package/src/core/math/linalg/polynomial_sub_into.d.ts.map +1 -0
- package/src/core/math/linalg/polynomial_sub_into.js +29 -0
- package/src/core/math/linalg/solve_linear_system.d.ts +1 -1
- package/src/core/math/linalg/solve_linear_system.js +1 -1
- package/src/core/math/linalg/solve_linear_system_GEPP_2x2.d.ts +4 -4
- package/src/core/math/linalg/solve_linear_system_GEPP_2x2.d.ts.map +1 -1
- package/src/core/math/linalg/solve_linear_system_GEPP_2x2.js +96 -91
- package/src/core/math/solveQuadratic.d.ts +2 -2
- package/src/core/math/solveQuadratic.d.ts.map +1 -1
- package/src/core/math/solveQuadratic.js +1 -1
- package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite.d.ts +18 -10
- package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite.d.ts.map +1 -1
- package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite.js +18 -10
- package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite_1d.d.ts +13 -6
- package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite_1d.d.ts.map +1 -1
- package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite_1d.js +16 -11
- package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite_2d.d.ts +25 -3
- package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite_2d.d.ts.map +1 -1
- package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite_2d.js +97 -142
- package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite_nd.d.ts +30 -4
- package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite_nd.d.ts.map +1 -1
- package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite_nd.js +188 -132
- package/src/core/math/spline/spline3_hermite_intersects_spline3_hermite.d.ts +7 -3
- package/src/core/math/spline/spline3_hermite_intersects_spline3_hermite.d.ts.map +1 -1
- package/src/core/math/spline/spline3_hermite_intersects_spline3_hermite.js +35 -6
- package/src/core/science/units/MEASUREMENT_UNITS_SCIENTIFIC.d.ts +17 -0
- package/src/core/science/units/MEASUREMENT_UNITS_SCIENTIFIC.d.ts.map +1 -0
- package/src/core/science/units/MEASUREMENT_UNITS_SCIENTIFIC.js +87 -0
- package/src/core/science/units/MEASUREMENT_UNITS_SI.d.ts +13 -0
- package/src/core/science/units/MEASUREMENT_UNITS_SI.d.ts.map +1 -0
- package/src/core/science/units/MEASUREMENT_UNITS_SI.js +28 -0
- package/src/core/science/units/NamedUnit.d.ts +38 -0
- package/src/core/science/units/NamedUnit.d.ts.map +1 -0
- package/src/core/science/units/NamedUnit.js +48 -0
- package/src/core/science/units/UNIT_DIMENSION_MAPPING.d.ts +14 -0
- package/src/core/science/units/UNIT_DIMENSION_MAPPING.d.ts.map +1 -0
- package/src/core/science/units/UNIT_DIMENSION_MAPPING.js +29 -0
- package/src/core/science/units/UnitDimension.d.ts +26 -0
- package/src/core/science/units/UnitDimension.d.ts.map +1 -0
- package/src/core/science/units/UnitDimension.js +28 -0
- package/src/core/science/units/UnitMatrix.d.ts +117 -0
- package/src/core/science/units/UnitMatrix.d.ts.map +1 -0
- package/src/core/science/units/UnitMatrix.js +251 -0
- package/src/core/science/units/format_quantity.d.ts +25 -0
- package/src/core/science/units/format_quantity.d.ts.map +1 -0
- package/src/core/science/units/format_quantity.js +74 -0
- package/src/core/science/units/magnitude_prefix.d.ts +57 -0
- package/src/core/science/units/magnitude_prefix.d.ts.map +1 -0
- package/src/core/science/units/magnitude_prefix.js +127 -0
- package/src/core/science/units/si/AMPERE.d.ts +7 -0
- package/src/core/science/units/si/AMPERE.d.ts.map +1 -0
- package/src/core/science/units/si/AMPERE.js +13 -0
- package/src/core/science/units/si/CANDELA.d.ts +7 -0
- package/src/core/science/units/si/CANDELA.d.ts.map +1 -0
- package/src/core/science/units/si/CANDELA.js +13 -0
- package/src/core/science/units/si/DIMENSIONLESS.d.ts +8 -0
- package/src/core/science/units/si/DIMENSIONLESS.d.ts.map +1 -0
- package/src/core/science/units/si/DIMENSIONLESS.js +14 -0
- package/src/core/science/units/si/KELVIN.d.ts +7 -0
- package/src/core/science/units/si/KELVIN.d.ts.map +1 -0
- package/src/core/science/units/si/KELVIN.js +13 -0
- package/src/core/science/units/si/KILOGRAM.d.ts +7 -0
- package/src/core/science/units/si/KILOGRAM.d.ts.map +1 -0
- package/src/core/science/units/si/KILOGRAM.js +13 -0
- package/src/core/science/units/si/METER.d.ts +7 -0
- package/src/core/science/units/si/METER.d.ts.map +1 -0
- package/src/core/science/units/si/METER.js +13 -0
- package/src/core/science/units/si/MOLE.d.ts +7 -0
- package/src/core/science/units/si/MOLE.d.ts.map +1 -0
- package/src/core/science/units/si/MOLE.js +13 -0
- package/src/core/science/units/si/SECOND.d.ts +7 -0
- package/src/core/science/units/si/SECOND.d.ts.map +1 -0
- package/src/core/science/units/si/SECOND.js +13 -0
- package/src/core/science/units/si/derived/BECQUEREL.d.ts +10 -0
- package/src/core/science/units/si/derived/BECQUEREL.d.ts.map +1 -0
- package/src/core/science/units/si/derived/BECQUEREL.js +16 -0
- package/src/core/science/units/si/derived/COULOMB.d.ts +7 -0
- package/src/core/science/units/si/derived/COULOMB.d.ts.map +1 -0
- package/src/core/science/units/si/derived/COULOMB.js +13 -0
- package/src/core/science/units/si/derived/FARAD.d.ts +7 -0
- package/src/core/science/units/si/derived/FARAD.d.ts.map +1 -0
- package/src/core/science/units/si/derived/FARAD.js +13 -0
- package/src/core/science/units/si/derived/GRAY.d.ts +10 -0
- package/src/core/science/units/si/derived/GRAY.d.ts.map +1 -0
- package/src/core/science/units/si/derived/GRAY.js +16 -0
- package/src/core/science/units/si/derived/HENRY.d.ts +7 -0
- package/src/core/science/units/si/derived/HENRY.d.ts.map +1 -0
- package/src/core/science/units/si/derived/HENRY.js +13 -0
- package/src/core/science/units/si/derived/HERTZ.d.ts +10 -0
- package/src/core/science/units/si/derived/HERTZ.d.ts.map +1 -0
- package/src/core/science/units/si/derived/HERTZ.js +16 -0
- package/src/core/science/units/si/derived/JOULE.d.ts +7 -0
- package/src/core/science/units/si/derived/JOULE.d.ts.map +1 -0
- package/src/core/science/units/si/derived/JOULE.js +13 -0
- package/src/core/science/units/si/derived/KATAL.d.ts +7 -0
- package/src/core/science/units/si/derived/KATAL.d.ts.map +1 -0
- package/src/core/science/units/si/derived/KATAL.js +13 -0
- package/src/core/science/units/si/derived/LUMEN.d.ts +8 -0
- package/src/core/science/units/si/derived/LUMEN.d.ts.map +1 -0
- package/src/core/science/units/si/derived/LUMEN.js +14 -0
- package/src/core/science/units/si/derived/LUX.d.ts +7 -0
- package/src/core/science/units/si/derived/LUX.d.ts.map +1 -0
- package/src/core/science/units/si/derived/LUX.js +13 -0
- package/src/core/science/units/si/derived/NEWTON.d.ts +7 -0
- package/src/core/science/units/si/derived/NEWTON.d.ts.map +1 -0
- package/src/core/science/units/si/derived/NEWTON.js +13 -0
- package/src/core/science/units/si/derived/OHM.d.ts +7 -0
- package/src/core/science/units/si/derived/OHM.d.ts.map +1 -0
- package/src/core/science/units/si/derived/OHM.js +13 -0
- package/src/core/science/units/si/derived/PASCAL.d.ts +7 -0
- package/src/core/science/units/si/derived/PASCAL.d.ts.map +1 -0
- package/src/core/science/units/si/derived/PASCAL.js +13 -0
- package/src/core/science/units/si/derived/SIEMENS.d.ts +7 -0
- package/src/core/science/units/si/derived/SIEMENS.d.ts.map +1 -0
- package/src/core/science/units/si/derived/SIEMENS.js +13 -0
- package/src/core/science/units/si/derived/SIEVERT.d.ts +10 -0
- package/src/core/science/units/si/derived/SIEVERT.d.ts.map +1 -0
- package/src/core/science/units/si/derived/SIEVERT.js +16 -0
- package/src/core/science/units/si/derived/TESLA.d.ts +7 -0
- package/src/core/science/units/si/derived/TESLA.d.ts.map +1 -0
- package/src/core/science/units/si/derived/TESLA.js +13 -0
- package/src/core/science/units/si/derived/VOLT.d.ts +7 -0
- package/src/core/science/units/si/derived/VOLT.d.ts.map +1 -0
- package/src/core/science/units/si/derived/VOLT.js +13 -0
- package/src/core/science/units/si/derived/WATT.d.ts +7 -0
- package/src/core/science/units/si/derived/WATT.d.ts.map +1 -0
- package/src/core/science/units/si/derived/WATT.js +13 -0
- package/src/core/science/units/si/derived/WEBER.d.ts +7 -0
- package/src/core/science/units/si/derived/WEBER.d.ts.map +1 -0
- package/src/core/science/units/si/derived/WEBER.js +13 -0
- package/src/core/science/units/unit_matrix_to_string.d.ts +29 -0
- package/src/core/science/units/unit_matrix_to_string.d.ts.map +1 -0
- package/src/core/science/units/unit_matrix_to_string.js +403 -0
- package/src/engine/graphics/geometry/MikkT/CalcTexArea.d.ts.map +1 -1
- package/src/engine/graphics/geometry/MikkT/CalcTexArea.js +1 -2
- package/src/engine/graphics/geometry/MikkT/InitTriInfo.d.ts.map +1 -1
- package/src/engine/graphics/geometry/MikkT/InitTriInfo.js +6 -7
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { assert } from "../../assert.js";
|
|
2
|
+
import { complex_horner_eval } from "../complex/complex_horner_eval.js";
|
|
3
|
+
import { polynomial_root_bound_cauchy } from "./polynomial_root_bound_cauchy.js";
|
|
2
4
|
|
|
3
5
|
/*
|
|
4
6
|
Find all roots of a univariate polynomial in the complex plane via
|
|
@@ -21,43 +23,10 @@ import { assert } from "../../assert.js";
|
|
|
21
23
|
const MAX_SUPPORTED_DEGREE = 64;
|
|
22
24
|
|
|
23
25
|
const ABERTH_MAX_ITERATIONS = 80;
|
|
24
|
-
const
|
|
26
|
+
const ABERTH_CONVERGENCE_TOLERANCE_SQR = 1e-28;
|
|
25
27
|
|
|
26
28
|
const _DERIV = new Float64Array(MAX_SUPPORTED_DEGREE);
|
|
27
|
-
const
|
|
28
|
-
const _DP_EVAL = new Float64Array(2);
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Horner evaluation of polynomial p(z) at a complex z = (zr, zi).
|
|
32
|
-
* Writes [p(z).re, p(z).im] into `out`.
|
|
33
|
-
*/
|
|
34
|
-
function poly_eval_complex(coeffs, degree, zr, zi, out) {
|
|
35
|
-
let pr = coeffs[degree];
|
|
36
|
-
let pi = 0;
|
|
37
|
-
|
|
38
|
-
for (let i = degree - 1; i >= 0; i--) {
|
|
39
|
-
const new_pr = pr * zr - pi * zi + coeffs[i];
|
|
40
|
-
const new_pi = pr * zi + pi * zr;
|
|
41
|
-
pr = new_pr;
|
|
42
|
-
pi = new_pi;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
out[0] = pr;
|
|
46
|
-
out[1] = pi;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* Cauchy bound: every root z of `coeffs` satisfies |z| ≤ this value.
|
|
51
|
-
*/
|
|
52
|
-
function cauchy_root_magnitude_bound(coeffs, degree) {
|
|
53
|
-
const lead = Math.abs(coeffs[degree]);
|
|
54
|
-
let m = 0;
|
|
55
|
-
for (let i = 0; i < degree; i++) {
|
|
56
|
-
const a = Math.abs(coeffs[i]);
|
|
57
|
-
if (a > m) m = a;
|
|
58
|
-
}
|
|
59
|
-
return 1 + m / lead;
|
|
60
|
-
}
|
|
29
|
+
const scratch_v2 = new Float64Array(2);
|
|
61
30
|
|
|
62
31
|
/**
|
|
63
32
|
* Find all complex roots of a univariate polynomial via Aberth–Ehrlich.
|
|
@@ -75,10 +44,16 @@ function cauchy_root_magnitude_bound(coeffs, degree) {
|
|
|
75
44
|
* @param {Float64Array|number[]} roots_re real parts, length ≥ offset + degree
|
|
76
45
|
* @param {Float64Array|number[]} roots_im imaginary parts, length ≥ offset + degree
|
|
77
46
|
* @param {number} offset
|
|
47
|
+
* @param {number} [max_iterations=80] outer iteration cap. Lower values
|
|
48
|
+
* trade worst-case convergence accuracy for speed; the per-iteration
|
|
49
|
+
* convergence check still fires early in the common case. A low cap
|
|
50
|
+
* (~24-32) is appropriate for well-conditioned low-degree polynomials
|
|
51
|
+
* where Aberth typically converges in 15-25 iterations.
|
|
78
52
|
*/
|
|
79
53
|
export function polynomial_complex_roots_aberth_ehrlich(
|
|
80
54
|
coeffs, degree,
|
|
81
|
-
roots_re, roots_im, offset
|
|
55
|
+
roots_re, roots_im, offset,
|
|
56
|
+
max_iterations = ABERTH_MAX_ITERATIONS
|
|
82
57
|
) {
|
|
83
58
|
assert.greaterThanOrEqual(degree, 1, 'degree');
|
|
84
59
|
assert.greaterThanOrEqual(MAX_SUPPORTED_DEGREE, degree, 'degree exceeds MAX_SUPPORTED_DEGREE');
|
|
@@ -89,36 +64,42 @@ export function polynomial_complex_roots_aberth_ehrlich(
|
|
|
89
64
|
_DERIV[i] = (i + 1) * coeffs[i + 1];
|
|
90
65
|
}
|
|
91
66
|
|
|
92
|
-
const radius =
|
|
67
|
+
const radius = polynomial_root_bound_cauchy(coeffs, degree);
|
|
93
68
|
|
|
94
69
|
// Initial points around a circle, with a small phase offset to avoid
|
|
95
70
|
// landing exactly on a real root at iteration zero.
|
|
96
71
|
const phase_offset = 0.5;
|
|
97
72
|
const two_pi_over_n = (2 * Math.PI) / degree;
|
|
73
|
+
|
|
98
74
|
for (let k = 0; k < degree; k++) {
|
|
99
75
|
const angle = k * two_pi_over_n + phase_offset;
|
|
100
76
|
roots_re[offset + k] = radius * Math.cos(angle);
|
|
101
77
|
roots_im[offset + k] = radius * Math.sin(angle);
|
|
102
78
|
}
|
|
103
79
|
|
|
104
|
-
for (let iter = 0; iter <
|
|
80
|
+
for (let iter = 0; iter < max_iterations; iter++) {
|
|
105
81
|
let max_correction_sq = 0;
|
|
106
82
|
|
|
107
83
|
for (let k = 0; k < degree; k++) {
|
|
108
84
|
const zr = roots_re[offset + k];
|
|
109
85
|
const zi = roots_im[offset + k];
|
|
110
86
|
|
|
111
|
-
|
|
112
|
-
const pr =
|
|
113
|
-
const pi =
|
|
87
|
+
complex_horner_eval(scratch_v2, coeffs, degree, zr, zi);
|
|
88
|
+
const pr = scratch_v2[0];
|
|
89
|
+
const pi = scratch_v2[1];
|
|
114
90
|
|
|
115
|
-
|
|
116
|
-
const dpr =
|
|
117
|
-
const dpi =
|
|
91
|
+
complex_horner_eval(scratch_v2, _DERIV, degree - 1, zr, zi);
|
|
92
|
+
const dpr = scratch_v2[0];
|
|
93
|
+
const dpi = scratch_v2[1];
|
|
118
94
|
|
|
119
95
|
// w = p / p'
|
|
120
96
|
const dp_norm_sq = dpr * dpr + dpi * dpi;
|
|
121
|
-
|
|
97
|
+
|
|
98
|
+
if (dp_norm_sq === 0) {
|
|
99
|
+
// division by 0 guard
|
|
100
|
+
continue;
|
|
101
|
+
}
|
|
102
|
+
|
|
122
103
|
const inv_dp_sq = 1 / dp_norm_sq;
|
|
123
104
|
const wr = (pr * dpr + pi * dpi) * inv_dp_sq;
|
|
124
105
|
const wi = (pi * dpr - pr * dpi) * inv_dp_sq;
|
|
@@ -126,11 +107,18 @@ export function polynomial_complex_roots_aberth_ehrlich(
|
|
|
126
107
|
// S = Σ_{j≠k} 1/(z_k − z_j) in complex
|
|
127
108
|
let sr = 0, si = 0;
|
|
128
109
|
for (let j = 0; j < degree; j++) {
|
|
129
|
-
|
|
110
|
+
|
|
111
|
+
if (j === k) {
|
|
112
|
+
continue;
|
|
113
|
+
}
|
|
114
|
+
|
|
130
115
|
const dr = zr - roots_re[offset + j];
|
|
131
116
|
const di = zi - roots_im[offset + j];
|
|
132
117
|
const denom_sq = dr * dr + di * di;
|
|
133
|
-
|
|
118
|
+
|
|
119
|
+
if (denom_sq === 0) {
|
|
120
|
+
continue;
|
|
121
|
+
}
|
|
134
122
|
const inv_d_sq = 1 / denom_sq;
|
|
135
123
|
sr += dr * inv_d_sq;
|
|
136
124
|
si += -di * inv_d_sq;
|
|
@@ -139,10 +127,17 @@ export function polynomial_complex_roots_aberth_ehrlich(
|
|
|
139
127
|
// correction = w / (1 − w·S)
|
|
140
128
|
const ws_r = wr * sr - wi * si;
|
|
141
129
|
const ws_i = wr * si + wi * sr;
|
|
130
|
+
|
|
142
131
|
const denom_r = 1 - ws_r;
|
|
143
132
|
const denom_i = -ws_i;
|
|
133
|
+
|
|
144
134
|
const denom_sq2 = denom_r * denom_r + denom_i * denom_i;
|
|
145
|
-
|
|
135
|
+
|
|
136
|
+
if (denom_sq2 === 0){
|
|
137
|
+
// division by 0 guard
|
|
138
|
+
continue;
|
|
139
|
+
}
|
|
140
|
+
|
|
146
141
|
const inv_denom_sq2 = 1 / denom_sq2;
|
|
147
142
|
const corr_r = (wr * denom_r + wi * denom_i) * inv_denom_sq2;
|
|
148
143
|
const corr_i = (wi * denom_r - wr * denom_i) * inv_denom_sq2;
|
|
@@ -151,10 +146,13 @@ export function polynomial_complex_roots_aberth_ehrlich(
|
|
|
151
146
|
roots_im[offset + k] = zi - corr_i;
|
|
152
147
|
|
|
153
148
|
const corr_sq = corr_r * corr_r + corr_i * corr_i;
|
|
154
|
-
|
|
149
|
+
|
|
150
|
+
if (corr_sq > max_correction_sq){
|
|
151
|
+
max_correction_sq = corr_sq;
|
|
152
|
+
}
|
|
155
153
|
}
|
|
156
154
|
|
|
157
|
-
if (max_correction_sq <
|
|
155
|
+
if (max_correction_sq < ABERTH_CONVERGENCE_TOLERANCE_SQR) {
|
|
158
156
|
break;
|
|
159
157
|
}
|
|
160
158
|
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Evaluates p'(x), the first derivative of the cubic stored at
|
|
3
|
+
* coeffs[base..base+3]:
|
|
4
|
+
*
|
|
5
|
+
* p'(x) = coeffs[base+1]
|
|
6
|
+
* + 2 * coeffs[base+2] * x
|
|
7
|
+
* + 3 * coeffs[base+3] * x^2
|
|
8
|
+
*
|
|
9
|
+
* @param {number[]|Float32Array|Float64Array} coeffs
|
|
10
|
+
* @param {number} base index of the constant term (coefficient of x^0)
|
|
11
|
+
* @param {number} x
|
|
12
|
+
* @returns {number}
|
|
13
|
+
*/
|
|
14
|
+
export function polynomial_cubic_derivative_eval(coeffs: number[] | Float32Array | Float64Array, base: number, x: number): number;
|
|
15
|
+
//# sourceMappingURL=polynomial_cubic_derivative_eval.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"polynomial_cubic_derivative_eval.d.ts","sourceRoot":"","sources":["../../../../../src/core/math/linalg/polynomial_cubic_derivative_eval.js"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,yDALW,MAAM,EAAE,GAAC,YAAY,GAAC,YAAY,QAClC,MAAM,KACN,MAAM,GACJ,MAAM,CAIlB"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Evaluates p'(x), the first derivative of the cubic stored at
|
|
3
|
+
* coeffs[base..base+3]:
|
|
4
|
+
*
|
|
5
|
+
* p'(x) = coeffs[base+1]
|
|
6
|
+
* + 2 * coeffs[base+2] * x
|
|
7
|
+
* + 3 * coeffs[base+3] * x^2
|
|
8
|
+
*
|
|
9
|
+
* @param {number[]|Float32Array|Float64Array} coeffs
|
|
10
|
+
* @param {number} base index of the constant term (coefficient of x^0)
|
|
11
|
+
* @param {number} x
|
|
12
|
+
* @returns {number}
|
|
13
|
+
*/
|
|
14
|
+
export function polynomial_cubic_derivative_eval(coeffs, base, x) {
|
|
15
|
+
return coeffs[base + 1] + x * (2 * coeffs[base + 2] + x * 3 * coeffs[base + 3]);
|
|
16
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Horner evaluation of a cubic polynomial stored at coeffs[base..base+3]:
|
|
3
|
+
*
|
|
4
|
+
* p(x) = coeffs[base]
|
|
5
|
+
* + coeffs[base+1] * x
|
|
6
|
+
* + coeffs[base+2] * x^2
|
|
7
|
+
* + coeffs[base+3] * x^3
|
|
8
|
+
*
|
|
9
|
+
* The `base` offset lets callers pack many cubics into one flat buffer
|
|
10
|
+
* (e.g. one cubic per dimension at base = 4*d).
|
|
11
|
+
*
|
|
12
|
+
* @param {number[]|Float32Array|Float64Array} coeffs
|
|
13
|
+
* @param {number} base index of the constant term (coefficient of x^0)
|
|
14
|
+
* @param {number} x
|
|
15
|
+
* @returns {number}
|
|
16
|
+
*/
|
|
17
|
+
export function polynomial_cubic_horner_eval(coeffs: number[] | Float32Array | Float64Array, base: number, x: number): number;
|
|
18
|
+
//# sourceMappingURL=polynomial_cubic_horner_eval.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"polynomial_cubic_horner_eval.d.ts","sourceRoot":"","sources":["../../../../../src/core/math/linalg/polynomial_cubic_horner_eval.js"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,qDALW,MAAM,EAAE,GAAC,YAAY,GAAC,YAAY,QAClC,MAAM,KACN,MAAM,GACJ,MAAM,CAIlB"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Horner evaluation of a cubic polynomial stored at coeffs[base..base+3]:
|
|
3
|
+
*
|
|
4
|
+
* p(x) = coeffs[base]
|
|
5
|
+
* + coeffs[base+1] * x
|
|
6
|
+
* + coeffs[base+2] * x^2
|
|
7
|
+
* + coeffs[base+3] * x^3
|
|
8
|
+
*
|
|
9
|
+
* The `base` offset lets callers pack many cubics into one flat buffer
|
|
10
|
+
* (e.g. one cubic per dimension at base = 4*d).
|
|
11
|
+
*
|
|
12
|
+
* @param {number[]|Float32Array|Float64Array} coeffs
|
|
13
|
+
* @param {number} base index of the constant term (coefficient of x^0)
|
|
14
|
+
* @param {number} x
|
|
15
|
+
* @returns {number}
|
|
16
|
+
*/
|
|
17
|
+
export function polynomial_cubic_horner_eval(coeffs, base, x) {
|
|
18
|
+
return coeffs[base] + x * (coeffs[base + 1] + x * (coeffs[base + 2] + x * coeffs[base + 3]));
|
|
19
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Evaluates p''(x), the second derivative of the cubic stored at
|
|
3
|
+
* coeffs[base..base+3]:
|
|
4
|
+
*
|
|
5
|
+
* p''(x) = 2 * coeffs[base+2] + 6 * coeffs[base+3] * x
|
|
6
|
+
*
|
|
7
|
+
* @param {number[]|Float32Array|Float64Array} coeffs
|
|
8
|
+
* @param {number} base index of the constant term (coefficient of x^0)
|
|
9
|
+
* @param {number} x
|
|
10
|
+
* @returns {number}
|
|
11
|
+
*/
|
|
12
|
+
export function polynomial_cubic_second_derivative_eval(coeffs: number[] | Float32Array | Float64Array, base: number, x: number): number;
|
|
13
|
+
//# sourceMappingURL=polynomial_cubic_second_derivative_eval.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"polynomial_cubic_second_derivative_eval.d.ts","sourceRoot":"","sources":["../../../../../src/core/math/linalg/polynomial_cubic_second_derivative_eval.js"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,gEALW,MAAM,EAAE,GAAC,YAAY,GAAC,YAAY,QAClC,MAAM,KACN,MAAM,GACJ,MAAM,CAIlB"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Evaluates p''(x), the second derivative of the cubic stored at
|
|
3
|
+
* coeffs[base..base+3]:
|
|
4
|
+
*
|
|
5
|
+
* p''(x) = 2 * coeffs[base+2] + 6 * coeffs[base+3] * x
|
|
6
|
+
*
|
|
7
|
+
* @param {number[]|Float32Array|Float64Array} coeffs
|
|
8
|
+
* @param {number} base index of the constant term (coefficient of x^0)
|
|
9
|
+
* @param {number} x
|
|
10
|
+
* @returns {number}
|
|
11
|
+
*/
|
|
12
|
+
export function polynomial_cubic_second_derivative_eval(coeffs, base, x) {
|
|
13
|
+
return 2 * coeffs[base + 2] + 6 * coeffs[base + 3] * x;
|
|
14
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Multiplies two polynomials given in coefficient-array form.
|
|
3
|
+
*
|
|
4
|
+
* out(x) = a(x) * b(x)
|
|
5
|
+
*
|
|
6
|
+
* Coefficient layout: index i is the coefficient of x^i (ascending). The
|
|
7
|
+
* result has length `a_len + b_len - 1`. The first `out_len` entries of
|
|
8
|
+
* `out` are written; entries beyond that are not touched.
|
|
9
|
+
*
|
|
10
|
+
* `out` must not alias `a` or `b` — the routine writes into `out` while it
|
|
11
|
+
* still reads from the inputs.
|
|
12
|
+
*
|
|
13
|
+
* @param {number[]|Float64Array|Float32Array} out destination, length >= a_len + b_len - 1
|
|
14
|
+
* @param {number[]|Float64Array|Float32Array} a
|
|
15
|
+
* @param {number} a_len number of coefficients in a
|
|
16
|
+
* @param {number[]|Float64Array|Float32Array} b
|
|
17
|
+
* @param {number} b_len number of coefficients in b
|
|
18
|
+
* @returns {number} number of coefficients written into `out` (a_len + b_len - 1)
|
|
19
|
+
*/
|
|
20
|
+
export function polynomial_multiply(out: number[] | Float64Array | Float32Array, a: number[] | Float64Array | Float32Array, a_len: number, b: number[] | Float64Array | Float32Array, b_len: number): number;
|
|
21
|
+
//# sourceMappingURL=polynomial_multiply.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"polynomial_multiply.d.ts","sourceRoot":"","sources":["../../../../../src/core/math/linalg/polynomial_multiply.js"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AACH,yCAPW,MAAM,EAAE,GAAC,YAAY,GAAC,YAAY,KAClC,MAAM,EAAE,GAAC,YAAY,GAAC,YAAY,SAClC,MAAM,KACN,MAAM,EAAE,GAAC,YAAY,GAAC,YAAY,SAClC,MAAM,GACJ,MAAM,CAuBlB"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Multiplies two polynomials given in coefficient-array form.
|
|
3
|
+
*
|
|
4
|
+
* out(x) = a(x) * b(x)
|
|
5
|
+
*
|
|
6
|
+
* Coefficient layout: index i is the coefficient of x^i (ascending). The
|
|
7
|
+
* result has length `a_len + b_len - 1`. The first `out_len` entries of
|
|
8
|
+
* `out` are written; entries beyond that are not touched.
|
|
9
|
+
*
|
|
10
|
+
* `out` must not alias `a` or `b` — the routine writes into `out` while it
|
|
11
|
+
* still reads from the inputs.
|
|
12
|
+
*
|
|
13
|
+
* @param {number[]|Float64Array|Float32Array} out destination, length >= a_len + b_len - 1
|
|
14
|
+
* @param {number[]|Float64Array|Float32Array} a
|
|
15
|
+
* @param {number} a_len number of coefficients in a
|
|
16
|
+
* @param {number[]|Float64Array|Float32Array} b
|
|
17
|
+
* @param {number} b_len number of coefficients in b
|
|
18
|
+
* @returns {number} number of coefficients written into `out` (a_len + b_len - 1)
|
|
19
|
+
*/
|
|
20
|
+
export function polynomial_multiply(out, a, a_len, b, b_len) {
|
|
21
|
+
const out_len = a_len + b_len - 1;
|
|
22
|
+
|
|
23
|
+
for (let i = 0; i < out_len; i++) {
|
|
24
|
+
out[i] = 0;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
for (let i = 0; i < a_len; i++) {
|
|
28
|
+
const ai = a[i];
|
|
29
|
+
|
|
30
|
+
if (ai === 0) {
|
|
31
|
+
// short-circuit, 0*X == 0
|
|
32
|
+
continue;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
for (let j = 0; j < b_len; j++) {
|
|
36
|
+
out[i + j] += ai * b[j];
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return out_len;
|
|
41
|
+
}
|
|
@@ -9,7 +9,12 @@
|
|
|
9
9
|
* @param {number} hi
|
|
10
10
|
* @param {Float64Array|number[]} out
|
|
11
11
|
* @param {number} out_offset
|
|
12
|
+
* @param {number} [aberth_max_iterations] optional outer-iteration cap for the
|
|
13
|
+
* Aberth root finder used at degree ≥ 3. Defaults to the routine's own
|
|
14
|
+
* internal cap (80). Lower the cap when the caller knows the polynomial is
|
|
15
|
+
* well-conditioned and convergence is typically quick — e.g. degree-5
|
|
16
|
+
* well-behaved polys converge in 15-25 iterations.
|
|
12
17
|
* @returns {number} number of roots written
|
|
13
18
|
*/
|
|
14
|
-
export function polynomial_real_roots_in_interval(coeffs: Float64Array | number[], degree: number, lo: number, hi: number, out: Float64Array | number[], out_offset: number): number;
|
|
19
|
+
export function polynomial_real_roots_in_interval(coeffs: Float64Array | number[], degree: number, lo: number, hi: number, out: Float64Array | number[], out_offset: number, aberth_max_iterations?: number): number;
|
|
15
20
|
//# sourceMappingURL=polynomial_real_roots_in_interval.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"polynomial_real_roots_in_interval.d.ts","sourceRoot":"","sources":["../../../../../src/core/math/linalg/polynomial_real_roots_in_interval.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"polynomial_real_roots_in_interval.d.ts","sourceRoot":"","sources":["../../../../../src/core/math/linalg/polynomial_real_roots_in_interval.js"],"names":[],"mappings":"AA6FA;;;;;;;;;;;;;;;;;GAiBG;AACH,0DAbW,YAAY,GAAC,MAAM,EAAE,UACrB,MAAM,MACN,MAAM,MACN,MAAM,OACN,YAAY,GAAC,MAAM,EAAE,cACrB,MAAM,0BACN,MAAM,GAKJ,MAAM,CAqGlB"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { assert } from "../../assert.js";
|
|
2
2
|
import { solveQuadratic } from "../solveQuadratic.js";
|
|
3
3
|
import { polynomial_complex_roots_aberth_ehrlich } from "./polynomial_complex_roots_aberth_ehrlich.js";
|
|
4
|
+
import { polynomial_root_bound_cauchy } from "./polynomial_root_bound_cauchy.js";
|
|
4
5
|
|
|
5
6
|
/*
|
|
6
7
|
Find all real roots of a univariate polynomial that lie inside a closed interval [lo, hi].
|
|
@@ -58,16 +59,6 @@ function max_abs_coefficient(coeffs, degree) {
|
|
|
58
59
|
return m;
|
|
59
60
|
}
|
|
60
61
|
|
|
61
|
-
function root_scale_estimate(coeffs, degree) {
|
|
62
|
-
const lead = Math.abs(coeffs[degree]);
|
|
63
|
-
let m = 0;
|
|
64
|
-
for (let i = 0; i < degree; i++) {
|
|
65
|
-
const a = Math.abs(coeffs[i]);
|
|
66
|
-
if (a > m) m = a;
|
|
67
|
-
}
|
|
68
|
-
return 1 + m / lead;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
62
|
function newton_polish_real(coeffs, degree, x_init) {
|
|
72
63
|
let x = x_init;
|
|
73
64
|
|
|
@@ -111,13 +102,19 @@ function insert_sorted_unique(roots, count, value, dedupe_tolerance) {
|
|
|
111
102
|
* @param {number} hi
|
|
112
103
|
* @param {Float64Array|number[]} out
|
|
113
104
|
* @param {number} out_offset
|
|
105
|
+
* @param {number} [aberth_max_iterations] optional outer-iteration cap for the
|
|
106
|
+
* Aberth root finder used at degree ≥ 3. Defaults to the routine's own
|
|
107
|
+
* internal cap (80). Lower the cap when the caller knows the polynomial is
|
|
108
|
+
* well-conditioned and convergence is typically quick — e.g. degree-5
|
|
109
|
+
* well-behaved polys converge in 15-25 iterations.
|
|
114
110
|
* @returns {number} number of roots written
|
|
115
111
|
*/
|
|
116
112
|
export function polynomial_real_roots_in_interval(
|
|
117
113
|
coeffs,
|
|
118
114
|
degree,
|
|
119
115
|
lo, hi,
|
|
120
|
-
out, out_offset
|
|
116
|
+
out, out_offset,
|
|
117
|
+
aberth_max_iterations
|
|
121
118
|
) {
|
|
122
119
|
assert.isNonNegativeInteger(degree, 'degree');
|
|
123
120
|
assert.isNonNegativeInteger(out_offset, 'out_offset');
|
|
@@ -147,14 +144,17 @@ export function polynomial_real_roots_in_interval(
|
|
|
147
144
|
if (effective_degree === 2) {
|
|
148
145
|
const root_count = solveQuadratic(SCRATCH_QUADRATIC, 0, coeffs[2], coeffs[1], coeffs[0]);
|
|
149
146
|
let written = 0;
|
|
147
|
+
|
|
150
148
|
for (let i = 0; i < root_count; i++) {
|
|
151
149
|
const r = SCRATCH_QUADRATIC[i];
|
|
150
|
+
|
|
152
151
|
if (r >= lo && r <= hi) {
|
|
153
152
|
if (written === 0 || Math.abs(out[out_offset + written - 1] - r) > 0) {
|
|
154
153
|
out[out_offset + written] = r;
|
|
155
154
|
written++;
|
|
156
155
|
}
|
|
157
156
|
}
|
|
157
|
+
|
|
158
158
|
}
|
|
159
159
|
return written;
|
|
160
160
|
}
|
|
@@ -163,10 +163,11 @@ export function polynomial_real_roots_in_interval(
|
|
|
163
163
|
|
|
164
164
|
polynomial_complex_roots_aberth_ehrlich(
|
|
165
165
|
SCRATCH_COEFF, effective_degree,
|
|
166
|
-
SCRATCH_ROOTS_RE, SCRATCH_ROOTS_IM, 0
|
|
166
|
+
SCRATCH_ROOTS_RE, SCRATCH_ROOTS_IM, 0,
|
|
167
|
+
aberth_max_iterations
|
|
167
168
|
);
|
|
168
169
|
|
|
169
|
-
const root_scale =
|
|
170
|
+
const root_scale = polynomial_root_bound_cauchy(SCRATCH_COEFF, effective_degree);
|
|
170
171
|
const imag_threshold = IMAG_PART_REAL_THRESHOLD * Math.max(1, root_scale);
|
|
171
172
|
const residual_tolerance = NEWTON_RELATIVE_RESIDUAL_TOLERANCE * coeff_norm;
|
|
172
173
|
const dedupe_tolerance = DEDUPE_RELATIVE_TOLERANCE * Math.max(1, Math.max(Math.abs(lo), Math.abs(hi)));
|
|
@@ -177,17 +178,27 @@ export function polynomial_real_roots_in_interval(
|
|
|
177
178
|
const re = SCRATCH_ROOTS_RE[i];
|
|
178
179
|
const im = SCRATCH_ROOTS_IM[i];
|
|
179
180
|
|
|
180
|
-
if (!Number.isFinite(re) || !Number.isFinite(im))
|
|
181
|
+
if (!Number.isFinite(re) || !Number.isFinite(im)){
|
|
182
|
+
continue;
|
|
183
|
+
}
|
|
181
184
|
|
|
182
|
-
if (Math.abs(im) > imag_threshold)
|
|
185
|
+
if (Math.abs(im) > imag_threshold){
|
|
186
|
+
continue;
|
|
187
|
+
}
|
|
183
188
|
|
|
184
189
|
const polished = newton_polish_real(SCRATCH_COEFF, effective_degree, re);
|
|
185
|
-
if (!Number.isFinite(polished))
|
|
190
|
+
if (!Number.isFinite(polished)){
|
|
191
|
+
continue;
|
|
192
|
+
}
|
|
186
193
|
|
|
187
194
|
poly_eval_with_derivative(SCRATCH_COEFF, effective_degree, polished, SCRATCH_EVAL);
|
|
188
|
-
if (Math.abs(SCRATCH_EVAL[0]) > residual_tolerance)
|
|
195
|
+
if (Math.abs(SCRATCH_EVAL[0]) > residual_tolerance){
|
|
196
|
+
continue;
|
|
197
|
+
}
|
|
189
198
|
|
|
190
|
-
if (polished < lo || polished > hi)
|
|
199
|
+
if (polished < lo || polished > hi){
|
|
200
|
+
continue;
|
|
201
|
+
}
|
|
191
202
|
|
|
192
203
|
unique_count = insert_sorted_unique(SCRATCH_OUT_REAL, unique_count, polished, dedupe_tolerance);
|
|
193
204
|
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cauchy's bound on the magnitude of polynomial roots.
|
|
3
|
+
*
|
|
4
|
+
* For a polynomial `p(x) = c[0] + c[1]·x + ... + c[degree]·x^degree` with
|
|
5
|
+
* `c[degree] ≠ 0`, every (real or complex) root `z` satisfies
|
|
6
|
+
*
|
|
7
|
+
* |z| ≤ 1 + max(|c[0]|, |c[1]|, ..., |c[degree − 1]|) / |c[degree]|
|
|
8
|
+
*
|
|
9
|
+
* The bound is loose for general polynomials but cheap to compute and serves
|
|
10
|
+
* as a good initial radius for iterative root-finders such as Aberth–Ehrlich.
|
|
11
|
+
*
|
|
12
|
+
* @param {number[]|Float32Array|Float64Array} coeffs ascending-power, length ≥ degree + 1
|
|
13
|
+
* @param {number} degree polynomial degree, ≥ 1; the leading coefficient `coeffs[degree]` must be nonzero
|
|
14
|
+
* @returns {number}
|
|
15
|
+
*/
|
|
16
|
+
export function polynomial_root_bound_cauchy(coeffs: number[] | Float32Array | Float64Array, degree: number): number;
|
|
17
|
+
//# sourceMappingURL=polynomial_root_bound_cauchy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"polynomial_root_bound_cauchy.d.ts","sourceRoot":"","sources":["../../../../../src/core/math/linalg/polynomial_root_bound_cauchy.js"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,qDAJW,MAAM,EAAE,GAAC,YAAY,GAAC,YAAY,UAClC,MAAM,GACJ,MAAM,CAgBlB"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cauchy's bound on the magnitude of polynomial roots.
|
|
3
|
+
*
|
|
4
|
+
* For a polynomial `p(x) = c[0] + c[1]·x + ... + c[degree]·x^degree` with
|
|
5
|
+
* `c[degree] ≠ 0`, every (real or complex) root `z` satisfies
|
|
6
|
+
*
|
|
7
|
+
* |z| ≤ 1 + max(|c[0]|, |c[1]|, ..., |c[degree − 1]|) / |c[degree]|
|
|
8
|
+
*
|
|
9
|
+
* The bound is loose for general polynomials but cheap to compute and serves
|
|
10
|
+
* as a good initial radius for iterative root-finders such as Aberth–Ehrlich.
|
|
11
|
+
*
|
|
12
|
+
* @param {number[]|Float32Array|Float64Array} coeffs ascending-power, length ≥ degree + 1
|
|
13
|
+
* @param {number} degree polynomial degree, ≥ 1; the leading coefficient `coeffs[degree]` must be nonzero
|
|
14
|
+
* @returns {number}
|
|
15
|
+
*/
|
|
16
|
+
export function polynomial_root_bound_cauchy(coeffs, degree) {
|
|
17
|
+
const lead = Math.abs(coeffs[degree]);
|
|
18
|
+
|
|
19
|
+
let m = 0;
|
|
20
|
+
|
|
21
|
+
for (let i = 0; i < degree; i++) {
|
|
22
|
+
const a = Math.abs(coeffs[i]);
|
|
23
|
+
|
|
24
|
+
if (a > m) {
|
|
25
|
+
m = a;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
return 1 + m / lead;
|
|
30
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Scales polynomial `target` in place by a scalar.
|
|
3
|
+
*
|
|
4
|
+
* target(x) := scalar * target(x)
|
|
5
|
+
*
|
|
6
|
+
* Coefficient layout: index i is the coefficient of x^i (ascending). Only
|
|
7
|
+
* the first `target_len` coefficients are touched.
|
|
8
|
+
*
|
|
9
|
+
* @param {number[]|Float64Array|Float32Array} target modified in place
|
|
10
|
+
* @param {number} target_len number of coefficients to scale
|
|
11
|
+
* @param {number} scalar
|
|
12
|
+
*/
|
|
13
|
+
export function polynomial_scale_into(target: number[] | Float64Array | Float32Array, target_len: number, scalar: number): void;
|
|
14
|
+
//# sourceMappingURL=polynomial_scale_into.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"polynomial_scale_into.d.ts","sourceRoot":"","sources":["../../../../../src/core/math/linalg/polynomial_scale_into.js"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,8CAJW,MAAM,EAAE,GAAC,YAAY,GAAC,YAAY,cAClC,MAAM,UACN,MAAM,QAMhB"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Scales polynomial `target` in place by a scalar.
|
|
3
|
+
*
|
|
4
|
+
* target(x) := scalar * target(x)
|
|
5
|
+
*
|
|
6
|
+
* Coefficient layout: index i is the coefficient of x^i (ascending). Only
|
|
7
|
+
* the first `target_len` coefficients are touched.
|
|
8
|
+
*
|
|
9
|
+
* @param {number[]|Float64Array|Float32Array} target modified in place
|
|
10
|
+
* @param {number} target_len number of coefficients to scale
|
|
11
|
+
* @param {number} scalar
|
|
12
|
+
*/
|
|
13
|
+
export function polynomial_scale_into(target, target_len, scalar) {
|
|
14
|
+
for (let i = 0; i < target_len; i++) {
|
|
15
|
+
target[i] *= scalar;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Subtracts polynomial `a` from `target` in place.
|
|
3
|
+
*
|
|
4
|
+
* target(x) := target(x) - a(x)
|
|
5
|
+
*
|
|
6
|
+
* Coefficient layout: index i is the coefficient of x^i (ascending). If
|
|
7
|
+
* `a_len > target_len`, the excess coefficients in `target` at indices
|
|
8
|
+
* [target_len, a_len) are first cleared to zero, so the returned length
|
|
9
|
+
* (max of the two input lengths) reflects valid coefficients.
|
|
10
|
+
*
|
|
11
|
+
* @param {number[]|Float64Array|Float32Array} target receives the difference, length >= max(target_len, a_len)
|
|
12
|
+
* @param {number} target_len current number of coefficients in target
|
|
13
|
+
* @param {number[]|Float64Array|Float32Array} a
|
|
14
|
+
* @param {number} a_len number of coefficients in a
|
|
15
|
+
* @returns {number} new logical length of target = max(target_len, a_len)
|
|
16
|
+
*/
|
|
17
|
+
export function polynomial_sub_into(target: number[] | Float64Array | Float32Array, target_len: number, a: number[] | Float64Array | Float32Array, a_len: number): number;
|
|
18
|
+
//# sourceMappingURL=polynomial_sub_into.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"polynomial_sub_into.d.ts","sourceRoot":"","sources":["../../../../../src/core/math/linalg/polynomial_sub_into.js"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,4CANW,MAAM,EAAE,GAAC,YAAY,GAAC,YAAY,cAClC,MAAM,KACN,MAAM,EAAE,GAAC,YAAY,GAAC,YAAY,SAClC,MAAM,GACJ,MAAM,CAclB"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Subtracts polynomial `a` from `target` in place.
|
|
3
|
+
*
|
|
4
|
+
* target(x) := target(x) - a(x)
|
|
5
|
+
*
|
|
6
|
+
* Coefficient layout: index i is the coefficient of x^i (ascending). If
|
|
7
|
+
* `a_len > target_len`, the excess coefficients in `target` at indices
|
|
8
|
+
* [target_len, a_len) are first cleared to zero, so the returned length
|
|
9
|
+
* (max of the two input lengths) reflects valid coefficients.
|
|
10
|
+
*
|
|
11
|
+
* @param {number[]|Float64Array|Float32Array} target receives the difference, length >= max(target_len, a_len)
|
|
12
|
+
* @param {number} target_len current number of coefficients in target
|
|
13
|
+
* @param {number[]|Float64Array|Float32Array} a
|
|
14
|
+
* @param {number} a_len number of coefficients in a
|
|
15
|
+
* @returns {number} new logical length of target = max(target_len, a_len)
|
|
16
|
+
*/
|
|
17
|
+
export function polynomial_sub_into(target, target_len, a, a_len) {
|
|
18
|
+
const n = a_len > target_len ? a_len : target_len;
|
|
19
|
+
|
|
20
|
+
for (let i = target_len; i < n; i++) {
|
|
21
|
+
target[i] = 0;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
for (let i = 0; i < a_len; i++) {
|
|
25
|
+
target[i] -= a[i];
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
return n;
|
|
29
|
+
}
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
*
|
|
6
6
|
* @see https://github.com/Kitware/VTK/blob/af928016f4041ad8a6a193d032355b909721fc95/Common/Core/vtkMath.cxx
|
|
7
7
|
*
|
|
8
|
-
* @param {number[]|Float32Array|Float64Array} A Matrix of coefficients
|
|
8
|
+
* @param {number[]|Float32Array|Float64Array} A Matrix of coefficients, column-major flat layout (A[j*size + i] = element at row i, col j)
|
|
9
9
|
* @param {number[]|Float32Array|Float64Array} x Vector of right-hand constants for each equation, resulting solution for variables will also be written here
|
|
10
10
|
* @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
|
|
11
11
|
* @returns {boolean} true if solution found, false if factorization fails
|
|
@@ -13,7 +13,7 @@ const scratch = new Uint32Array(SCRATCH_SIZE);
|
|
|
13
13
|
*
|
|
14
14
|
* @see https://github.com/Kitware/VTK/blob/af928016f4041ad8a6a193d032355b909721fc95/Common/Core/vtkMath.cxx
|
|
15
15
|
*
|
|
16
|
-
* @param {number[]|Float32Array|Float64Array} A Matrix of coefficients
|
|
16
|
+
* @param {number[]|Float32Array|Float64Array} A Matrix of coefficients, column-major flat layout (A[j*size + i] = element at row i, col j)
|
|
17
17
|
* @param {number[]|Float32Array|Float64Array} x Vector of right-hand constants for each equation, resulting solution for variables will also be written here
|
|
18
18
|
* @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
|
|
19
19
|
* @returns {boolean} true if solution found, false if factorization fails
|