From 9be757e2cad72d8bc8ed285968a892ce125a33b6 Mon Sep 17 00:00:00 2001 From: Allen Goodman Date: Mon, 17 Jun 2024 14:14:11 -0400 Subject: [PATCH] polynomial operators --- docs/index.md | 257 +++++++++- docs/stylesheets/extra.css | 0 mkdocs.yml | 13 +- pyproject.toml | 2 + src/beignet/__init__.py | 466 ++++++++++++++++++ src/beignet/_add_chebyshev_polynomial.py | 55 +++ src/beignet/_add_laguerre_polynomial.py | 55 +++ src/beignet/_add_legendre_polynomial.py | 55 +++ .../_add_physicists_hermite_polynomial.py | 55 +++ src/beignet/_add_polynomial.py | 55 +++ .../_add_probabilists_hermite_polynomial.py | 55 +++ src/beignet/_chebyshev_extrema.py | 11 + src/beignet/_chebyshev_gauss_quadrature.py | 16 + src/beignet/_chebyshev_interpolation.py | 45 ++ .../_chebyshev_polynomial_companion.py | 47 ++ src/beignet/_chebyshev_polynomial_domain.py | 3 + .../_chebyshev_polynomial_from_roots.py | 86 ++++ src/beignet/_chebyshev_polynomial_one.py | 3 + src/beignet/_chebyshev_polynomial_power.py | 55 +++ src/beignet/_chebyshev_polynomial_roots.py | 25 + .../_chebyshev_polynomial_to_polynomial.py | 36 ++ .../_chebyshev_polynomial_vandermonde.py | 28 ++ .../_chebyshev_polynomial_vandermonde_2d.py | 49 ++ .../_chebyshev_polynomial_vandermonde_3d.py | 51 ++ src/beignet/_chebyshev_polynomial_weight.py | 6 + src/beignet/_chebyshev_polynomial_x.py | 3 + src/beignet/_chebyshev_polynomial_zero.py | 3 + src/beignet/_chebyshev_zeros.py | 11 + .../_differentiate_chebyshev_polynomial.py | 64 +++ .../_differentiate_laguerre_polynomial.py | 78 +++ .../_differentiate_legendre_polynomial.py | 81 +++ ...erentiate_physicists_hermite_polynomial.py | 60 +++ src/beignet/_differentiate_polynomial.py | 55 +++ ...entiate_probabilists_hermite_polynomial.py | 60 +++ src/beignet/_divide_chebyshev_polynomial.py | 149 ++++++ src/beignet/_divide_laguerre_polynomial.py | 149 ++++++ src/beignet/_divide_legendre_polynomial.py | 149 ++++++ .../_divide_physicists_hermite_polynomial.py | 151 ++++++ src/beignet/_divide_polynomial.py | 149 ++++++ ..._divide_probabilists_hermite_polynomial.py | 151 ++++++ src/beignet/_evaluate_chebyshev_polynomial.py | 35 ++ .../_evaluate_chebyshev_polynomial_2d.py | 36 ++ .../_evaluate_chebyshev_polynomial_3d.py | 37 ++ ...luate_chebyshev_polynomial_cartesian_2d.py | 13 + ...luate_chebyshev_polynomial_cartesian_3d.py | 14 + src/beignet/_evaluate_laguerre_polynomial.py | 38 ++ .../_evaluate_laguerre_polynomial_2d.py | 36 ++ .../_evaluate_laguerre_polynomial_3d.py | 37 ++ ...aluate_laguerre_polynomial_cartesian_2d.py | 13 + ...aluate_laguerre_polynomial_cartesian_3d.py | 14 + src/beignet/_evaluate_legendre_polynomial.py | 40 ++ .../_evaluate_legendre_polynomial_2d.py | 36 ++ .../_evaluate_legendre_polynomial_3d.py | 37 ++ ...aluate_legendre_polynomial_cartesian_2d.py | 13 + ...aluate_legendre_polynomial_cartesian_3d.py | 14 + ..._evaluate_physicists_hermite_polynomial.py | 40 ++ ...aluate_physicists_hermite_polynomial_2d.py | 38 ++ ...aluate_physicists_hermite_polynomial_3d.py | 39 ++ ...sicists_hermite_polynomial_cartesian_2d.py | 19 + ...sicists_hermite_polynomial_cartesian_3d.py | 16 + src/beignet/_evaluate_polynomial.py | 34 ++ src/beignet/_evaluate_polynomial_2d.py | 45 ++ src/beignet/_evaluate_polynomial_3d.py | 52 ++ .../_evaluate_polynomial_cartesian_2d.py | 25 + .../_evaluate_polynomial_cartesian_3d.py | 30 ++ .../_evaluate_polynomial_from_roots.py | 21 + ...valuate_probabilists_hermite_polynomial.py | 40 ++ ...uate_probabilists_hermite_polynomial_2d.py | 38 ++ ...uate_probabilists_hermite_polynomial_3d.py | 39 ++ ...ilists_hermite_polynomial_cartersian_2d.py | 15 + ...ilists_hermite_polynomial_cartersian_3d.py | 16 + src/beignet/_fit_chebyshev_polynomial.py | 84 ++++ src/beignet/_fit_laguerre_polynomial.py | 83 ++++ src/beignet/_fit_legendre_polynomial.py | 83 ++++ .../_fit_physicists_hermite_polynomial.py | 85 ++++ src/beignet/_fit_polynomial.py | 109 ++++ .../_fit_probabilists_hermite_polynomial.py | 85 ++++ src/beignet/_gauss_laguerre_quadrature.py | 30 ++ src/beignet/_gauss_legendre_quadrature.py | 38 ++ ...hysicists_hermite_polynomial_quadrature.py | 102 ++++ ...babilists_hermite_polynomial_quadrature.py | 98 ++++ .../_integrate_chebyshev_polynomial.py | 73 +++ src/beignet/_integrate_laguerre_polynomial.py | 60 +++ src/beignet/_integrate_legendre_polynomial.py | 65 +++ ...integrate_physicists_hermite_polynomial.py | 63 +++ src/beignet/_integrate_polynomial.py | 103 ++++ ...tegrate_probabilists_hermite_polynomial.py | 63 +++ src/beignet/_laguerre_polynomial_companion.py | 28 ++ src/beignet/_laguerre_polynomial_domain.py | 3 + .../_laguerre_polynomial_from_roots.py | 85 ++++ src/beignet/_laguerre_polynomial_one.py | 3 + src/beignet/_laguerre_polynomial_power.py | 61 +++ src/beignet/_laguerre_polynomial_roots.py | 25 + .../_laguerre_polynomial_to_polynomial.py | 55 +++ .../_laguerre_polynomial_vandermonde.py | 30 ++ .../_laguerre_polynomial_vandermonde_2d.py | 49 ++ .../_laguerre_polynomial_vandermonde_3d.py | 51 ++ src/beignet/_laguerre_polynomial_weight.py | 6 + src/beignet/_laguerre_polynomial_x.py | 3 + src/beignet/_laguerre_polynomial_zero.py | 3 + src/beignet/_legendre_polynomial_companion.py | 32 ++ src/beignet/_legendre_polynomial_domain.py | 3 + .../_legendre_polynomial_from_roots.py | 85 ++++ src/beignet/_legendre_polynomial_one.py | 3 + src/beignet/_legendre_polynomial_power.py | 61 +++ src/beignet/_legendre_polynomial_roots.py | 25 + .../_legendre_polynomial_to_polynomial.py | 47 ++ .../_legendre_polynomial_vandermonde.py | 30 ++ .../_legendre_polynomial_vandermonde_2d.py | 49 ++ .../_legendre_polynomial_vandermonde_3d.py | 51 ++ src/beignet/_legendre_polynomial_weight.py | 6 + src/beignet/_legendre_polynomial_x.py | 3 + src/beignet/_legendre_polynomial_zero.py | 3 + src/beignet/_linear_chebyshev_polynomial.py | 6 + src/beignet/_linear_laguerre_polynomial.py | 6 + src/beignet/_linear_legendre_polynomial.py | 6 + .../_linear_physicists_hermite_polynomial.py | 6 + src/beignet/_linear_polynomial.py | 6 + ..._linear_probabilists_hermite_polynomial.py | 6 + src/beignet/_multiply_chebyshev_polynomial.py | 60 +++ .../_multiply_chebyshev_polynomial_by_x.py | 25 + src/beignet/_multiply_laguerre_polynomial.py | 82 +++ .../_multiply_laguerre_polynomial_by_x.py | 29 ++ src/beignet/_multiply_legendre_polynomial.py | 80 +++ .../_multiply_legendre_polynomial_by_x.py | 24 + ..._multiply_physicists_hermite_polynomial.py | 85 ++++ ...iply_physicists_hermite_polynomial_by_x.py | 25 + src/beignet/_multiply_polynomial.py | 42 ++ src/beignet/_multiply_polynomial_by_x.py | 34 ++ ...ultiply_probabilists_hermite_polynomial.py | 84 ++++ ...ly_probabilists_hermite_polynomial_by_x.py | 25 + ...physicists_hermite_polynomial_companion.py | 40 ++ .../_physicists_hermite_polynomial_domain.py | 3 + ...hysicists_hermite_polynomial_from_roots.py | 87 ++++ .../_physicists_hermite_polynomial_one.py | 3 + .../_physicists_hermite_polynomial_power.py | 65 +++ .../_physicists_hermite_polynomial_roots.py | 27 + ...icists_hermite_polynomial_to_polynomial.py | 45 ++ ...ysicists_hermite_polynomial_vandermonde.py | 25 + ...cists_hermite_polynomial_vandermonde_2d.py | 51 ++ ...cists_hermite_polynomial_vandermonde_3d.py | 53 ++ .../_physicists_hermite_polynomial_weight.py | 6 + .../_physicists_hermite_polynomial_x.py | 3 + .../_physicists_hermite_polynomial_zero.py | 3 + src/beignet/_polynomial_companion.py | 35 ++ src/beignet/_polynomial_domain.py | 3 + src/beignet/_polynomial_from_roots.py | 97 ++++ src/beignet/_polynomial_one.py | 3 + src/beignet/_polynomial_power.py | 76 +++ src/beignet/_polynomial_roots.py | 48 ++ .../_polynomial_to_chebyshev_polynomial.py | 18 + .../_polynomial_to_laguerre_polynomial.py | 18 + .../_polynomial_to_legendre_polynomial.py | 18 + ...nomial_to_physicists_hermite_polynomial.py | 22 + ...mial_to_probabilists_hermite_polynomial.py | 22 + src/beignet/_polynomial_vandermonde.py | 33 ++ src/beignet/_polynomial_vandermonde_2d.py | 58 +++ src/beignet/_polynomial_vandermonde_3d.py | 63 +++ src/beignet/_polynomial_x.py | 3 + src/beignet/_polynomial_zero.py | 3 + ...obabilists_hermite_polynomial_companion.py | 39 ++ ..._probabilists_hermite_polynomial_domain.py | 3 + ...babilists_hermite_polynomial_from_roots.py | 90 ++++ .../_probabilists_hermite_polynomial_one.py | 3 + .../_probabilists_hermite_polynomial_power.py | 65 +++ .../_probabilists_hermite_polynomial_roots.py | 27 + ...ilists_hermite_polynomial_to_polynomial.py | 48 ++ ...abilists_hermite_polynomial_vandermonde.py | 22 + ...lists_hermite_polynomial_vandermonde_2d.py | 51 ++ ...lists_hermite_polynomial_vandermonde_3d.py | 53 ++ ..._probabilists_hermite_polynomial_weight.py | 6 + .../_probabilists_hermite_polynomial_x.py | 3 + .../_probabilists_hermite_polynomial_zero.py | 3 + src/beignet/_subtract_chebyshev_polynomial.py | 53 ++ src/beignet/_subtract_laguerre_polynomial.py | 53 ++ src/beignet/_subtract_legendre_polynomial.py | 53 ++ ..._subtract_physicists_hermite_polynomial.py | 56 +++ src/beignet/_subtract_polynomial.py | 53 ++ ...ubtract_probabilists_hermite_polynomial.py | 56 +++ ..._trim_chebyshev_polynomial_coefficients.py | 21 + .../_trim_laguerre_polynomial_coefficients.py | 21 + .../_trim_legendre_polynomial_coefficients.py | 21 + ...sicists_hermite_polynomial_coefficients.py | 21 + src/beignet/_trim_polynomial_coefficients.py | 21 + ...bilists_hermite_polynomial_coefficients.py | 21 + tests/beignet/func/test__space.py | 291 +++++------ .../special/test__dawson_integral_f.py | 110 ++--- .../beignet/test__add_chebyshev_polynomial.py | 25 + .../beignet/test__add_laguerre_polynomial.py | 25 + .../beignet/test__add_legendre_polynomial.py | 25 + ...test__add_physicists_hermite_polynomial.py | 25 + tests/beignet/test__add_polynomial.py | 25 + ...st__add_probabilists_hermite_polynomial.py | 25 + tests/beignet/test__apply_transform.py | 42 +- tests/beignet/test__chebyshev_extrema.py | 31 ++ .../test__chebyshev_gauss_quadrature.py | 27 + .../beignet/test__chebyshev_interpolation.py | 32 ++ .../test__chebyshev_polynomial_companion.py | 28 ++ .../test__chebyshev_polynomial_domain.py | 10 + .../test__chebyshev_polynomial_from_roots.py | 34 ++ .../beignet/test__chebyshev_polynomial_one.py | 10 + .../test__chebyshev_polynomial_power.py | 26 + .../test__chebyshev_polynomial_roots.py | 34 ++ .../test__chebyshev_polynomial_vandermonde.py | 36 ++ ...st__chebyshev_polynomial_vandermonde_2d.py | 31 ++ ...st__chebyshev_polynomial_vandermonde_3d.py | 34 ++ .../test__chebyshev_polynomial_weight.py | 11 + tests/beignet/test__chebyshev_polynomial_x.py | 10 + .../test__chebyshev_polynomial_zero.py | 10 + tests/beignet/test__chebyshev_zeros.py | 28 ++ ...est__differentiate_chebyshev_polynomial.py | 91 ++++ ...test__differentiate_laguerre_polynomial.py | 87 ++++ ...test__differentiate_legendre_polynomial.py | 118 +++++ ...erentiate_physicists_hermite_polynomial.py | 85 ++++ ...entiate_probabilists_hermite_polynomial.py | 90 ++++ .../test__divide_chebyshev_polynomial.py | 37 ++ .../test__divide_laguerre_polynomial.py | 34 ++ .../test__divide_legendre_polynomial.py | 34 ++ ...t__divide_physicists_hermite_polynomial.py | 37 ++ tests/beignet/test__divide_polynomial.py | 67 +++ ..._divide_probabilists_hermite_polynomial.py | 37 ++ .../test__evaluate_chebyshev_polynomial.py | 72 +++ .../test__evaluate_chebyshev_polynomial_2d.py | 50 ++ .../test__evaluate_chebyshev_polynomial_3d.py | 56 +++ ...luate_chebyshev_polynomial_cartesian_2d.py | 42 ++ ...luate_chebyshev_polynomial_cartesian_3d.py | 47 ++ .../test__evaluate_laguerre_polynomial.py | 71 +++ .../test__evaluate_laguerre_polynomial_2d.py | 48 ++ .../test__evaluate_laguerre_polynomial_3d.py | 56 +++ ...aluate_laguerre_polynomial_cartesian_2d.py | 30 ++ ...aluate_laguerre_polynomial_cartesian_3d.py | 24 + .../test__evaluate_legendre_polynomial.py | 72 +++ .../test__evaluate_legendre_polynomial_2d.py | 51 ++ .../test__evaluate_legendre_polynomial_3d.py | 36 ++ ...aluate_legendre_polynomial_cartesian_2d.py | 42 ++ ...aluate_legendre_polynomial_cartesian_3d.py | 47 ++ ..._evaluate_physicists_hermite_polynomial.py | 74 +++ ...aluate_physicists_hermite_polynomial_2d.py | 50 ++ ...aluate_physicists_hermite_polynomial_3d.py | 53 ++ ...sicists_hermite_polynomial_cartesian_2d.py | 31 ++ ...sicists_hermite_polynomial_cartesian_3d.py | 38 ++ tests/beignet/test__evaluate_polynomial.py | 66 +++ tests/beignet/test__evaluate_polynomial_2d.py | 38 ++ tests/beignet/test__evaluate_polynomial_3d.py | 42 ++ .../test__evaluate_polynomial_cartesian_2d.py | 42 ++ .../test__evaluate_polynomial_cartesian_3d.py | 48 ++ .../test__evaluate_polynomial_from_roots.py | 155 ++++++ ...valuate_probabilists_hermite_polynomial.py | 72 +++ ...uate_probabilists_hermite_polynomial_2d.py | 50 ++ ...uate_probabilists_hermite_polynomial_3d.py | 56 +++ ...ilists_hermite_polynomial_cartersian_2d.py | 42 ++ ...ilists_hermite_polynomial_cartersian_3d.py | 22 + .../beignet/test__fit_chebyshev_polynomial.py | 255 ++++++++++ .../beignet/test__fit_laguerre_polynomial.py | 199 ++++++++ .../beignet/test__fit_legendre_polynomial.py | 271 ++++++++++ ...test__fit_physicists_hermite_polynomial.py | 271 ++++++++++ tests/beignet/test__fit_polynomial.py | 244 +++++++++ ...st__fit_probabilists_hermite_polynomial.py | 271 ++++++++++ .../test__gauss_laguerre_quadrature.py | 18 + .../test__gauss_legendre_quadrature.py | 23 + ...hysicists_hermite_polynomial_quadrature.py | 22 + ...babilists_hermite_polynomial_quadrature.py | 20 + .../test__integrate_chebyshev_polynomial.py | 240 +++++++++ .../test__integrate_laguerre_polynomial.py | 245 +++++++++ .../test__integrate_legendre_polynomial.py | 259 ++++++++++ ...integrate_physicists_hermite_polynomial.py | 257 ++++++++++ tests/beignet/test__integrate_polynomial.py | 222 +++++++++ ...tegrate_probabilists_hermite_polynomial.py | 251 ++++++++++ .../test__laguerre_polynomial_companion.py | 28 ++ .../test__laguerre_polynomial_domain.py | 10 + .../test__laguerre_polynomial_from_roots.py | 44 ++ .../beignet/test__laguerre_polynomial_one.py | 10 + .../test__laguerre_polynomial_power.py | 26 + .../test__laguerre_polynomial_roots.py | 34 ++ ...test__laguerre_polynomial_to_polynomial.py | 22 + .../test__laguerre_polynomial_vandermonde.py | 34 ++ ...est__laguerre_polynomial_vandermonde_2d.py | 27 + ...est__laguerre_polynomial_vandermonde_3d.py | 33 ++ .../test__laguerre_polynomial_weight.py | 11 + tests/beignet/test__laguerre_polynomial_x.py | 10 + .../beignet/test__laguerre_polynomial_zero.py | 10 + .../test__legendre_polynomial_companion.py | 20 + .../test__legendre_polynomial_domain.py | 10 + .../test__legendre_polynomial_from_roots.py | 52 ++ .../beignet/test__legendre_polynomial_one.py | 10 + .../test__legendre_polynomial_power.py | 26 + .../test__legendre_polynomial_roots.py | 32 ++ ...test__legendre_polynomial_to_polynomial.py | 25 + .../test__legendre_polynomial_vandermonde.py | 47 ++ ...est__legendre_polynomial_vandermonde_2d.py | 30 ++ .../test__legendre_polynomial_weight.py | 11 + tests/beignet/test__legendre_polynomial_x.py | 10 + .../beignet/test__legendre_polynomial_zero.py | 10 + .../test__linear_chebyshev_polynomial.py | 9 + .../test__linear_legendre_polynomial.py | 17 + ...t__linear_physicists_hermite_polynomial.py | 9 + tests/beignet/test__linear_polynomial.py | 14 + ..._linear_probabilists_hermite_polynomial.py | 9 + .../test__multiply_chebyshev_polynomial.py | 28 ++ ...est__multiply_chebyshev_polynomial_by_x.py | 35 ++ .../test__multiply_laguerre_polynomial.py | 40 ++ ...test__multiply_laguerre_polynomial_by_x.py | 40 ++ .../test__multiply_legendre_polynomial.py | 29 ++ ...test__multiply_legendre_polynomial_by_x.py | 35 ++ ..._multiply_physicists_hermite_polynomial.py | 29 ++ ...iply_physicists_hermite_polynomial_by_x.py | 29 ++ tests/beignet/test__multiply_polynomial.py | 24 + .../beignet/test__multiply_polynomial_by_x.py | 26 + ...ultiply_probabilists_hermite_polynomial.py | 29 ++ ...ly_probabilists_hermite_polynomial_by_x.py | 34 ++ ...physicists_hermite_polynomial_companion.py | 28 ++ ...t__physicists_hermite_polynomial_domain.py | 10 + ...hysicists_hermite_polynomial_from_roots.py | 37 ++ ...test__physicists_hermite_polynomial_one.py | 10 + ...st__physicists_hermite_polynomial_power.py | 26 + ...st__physicists_hermite_polynomial_roots.py | 36 ++ ...icists_hermite_polynomial_to_polynomial.py | 25 + ...ysicists_hermite_polynomial_vandermonde.py | 38 ++ ...cists_hermite_polynomial_vandermonde_2d.py | 31 ++ ...cists_hermite_polynomial_vandermonde_3d.py | 29 ++ ...t__physicists_hermite_polynomial_weight.py | 9 + .../test__physicists_hermite_polynomial_x.py | 10 + ...est__physicists_hermite_polynomial_zero.py | 10 + tests/beignet/test__polynomial_companion.py | 24 + tests/beignet/test__polynomial_domain.py | 10 + tests/beignet/test__polynomial_from_roots.py | 49 ++ tests/beignet/test__polynomial_one.py | 10 + tests/beignet/test__polynomial_power.py | 26 + tests/beignet/test__polynomial_roots.py | 32 ++ ...est__polynomial_to_chebyshev_polynomial.py | 25 + ...test__polynomial_to_laguerre_polynomial.py | 22 + ...test__polynomial_to_legendre_polynomial.py | 25 + ...nomial_to_physicists_hermite_polynomial.py | 28 ++ ...mial_to_probabilists_hermite_polynomial.py | 25 + tests/beignet/test__polynomial_vandermonde.py | 43 ++ .../test__polynomial_vandermonde_2d.py | 27 + .../test__polynomial_vandermonde_3d.py | 34 ++ tests/beignet/test__polynomial_x.py | 10 + tests/beignet/test__polynomial_zero.py | 10 + ...obabilists_hermite_polynomial_companion.py | 26 + ..._probabilists_hermite_polynomial_domain.py | 10 + ...babilists_hermite_polynomial_from_roots.py | 33 ++ ...st__probabilists_hermite_polynomial_one.py | 10 + ...__probabilists_hermite_polynomial_power.py | 26 + ...__probabilists_hermite_polynomial_roots.py | 36 ++ ...ilists_hermite_polynomial_to_polynomial.py | 25 + ...abilists_hermite_polynomial_vandermonde.py | 30 ++ ...lists_hermite_polynomial_vandermonde_2d.py | 31 ++ ...lists_hermite_polynomial_vandermonde_3d.py | 34 ++ ..._probabilists_hermite_polynomial_weight.py | 11 + ...test__probabilists_hermite_polynomial_x.py | 10 + ...t__probabilists_hermite_polynomial_zero.py | 10 + tests/beignet/test__quaternion_slerp.py | 150 ++++++ tests/beignet/test__slerp.py | 151 ------ .../test__subtract_chebyshev_polynomial.py | 28 ++ .../test__subtract_laguerre_polynomial.py | 25 + .../test__subtract_legendre_polynomial.py | 25 + ..._subtract_physicists_hermite_polynomial.py | 25 + tests/beignet/test__subtract_polynomial.py | 25 + ...ubtract_probabilists_hermite_polynomial.py | 28 ++ ..._trim_chebyshev_polynomial_coefficients.py | 34 ++ ...__trim_laguerre_polynomial_coefficients.py | 34 ++ ...__trim_legendre_polynomial_coefficients.py | 34 ++ ...sicists_hermite_polynomial_coefficients.py | 34 ++ .../test__trim_polynomial_coefficients.py | 34 ++ ...bilists_hermite_polynomial_coefficients.py | 34 ++ 366 files changed, 16890 insertions(+), 384 deletions(-) create mode 100644 docs/stylesheets/extra.css create mode 100644 src/beignet/_add_chebyshev_polynomial.py create mode 100644 src/beignet/_add_laguerre_polynomial.py create mode 100644 src/beignet/_add_legendre_polynomial.py create mode 100644 src/beignet/_add_physicists_hermite_polynomial.py create mode 100644 src/beignet/_add_polynomial.py create mode 100644 src/beignet/_add_probabilists_hermite_polynomial.py create mode 100644 src/beignet/_chebyshev_extrema.py create mode 100644 src/beignet/_chebyshev_gauss_quadrature.py create mode 100644 src/beignet/_chebyshev_interpolation.py create mode 100644 src/beignet/_chebyshev_polynomial_companion.py create mode 100644 src/beignet/_chebyshev_polynomial_domain.py create mode 100644 src/beignet/_chebyshev_polynomial_from_roots.py create mode 100644 src/beignet/_chebyshev_polynomial_one.py create mode 100644 src/beignet/_chebyshev_polynomial_power.py create mode 100644 src/beignet/_chebyshev_polynomial_roots.py create mode 100644 src/beignet/_chebyshev_polynomial_to_polynomial.py create mode 100644 src/beignet/_chebyshev_polynomial_vandermonde.py create mode 100644 src/beignet/_chebyshev_polynomial_vandermonde_2d.py create mode 100644 src/beignet/_chebyshev_polynomial_vandermonde_3d.py create mode 100644 src/beignet/_chebyshev_polynomial_weight.py create mode 100644 src/beignet/_chebyshev_polynomial_x.py create mode 100644 src/beignet/_chebyshev_polynomial_zero.py create mode 100644 src/beignet/_chebyshev_zeros.py create mode 100644 src/beignet/_differentiate_chebyshev_polynomial.py create mode 100644 src/beignet/_differentiate_laguerre_polynomial.py create mode 100644 src/beignet/_differentiate_legendre_polynomial.py create mode 100644 src/beignet/_differentiate_physicists_hermite_polynomial.py create mode 100644 src/beignet/_differentiate_polynomial.py create mode 100644 src/beignet/_differentiate_probabilists_hermite_polynomial.py create mode 100644 src/beignet/_divide_chebyshev_polynomial.py create mode 100644 src/beignet/_divide_laguerre_polynomial.py create mode 100644 src/beignet/_divide_legendre_polynomial.py create mode 100644 src/beignet/_divide_physicists_hermite_polynomial.py create mode 100644 src/beignet/_divide_polynomial.py create mode 100644 src/beignet/_divide_probabilists_hermite_polynomial.py create mode 100644 src/beignet/_evaluate_chebyshev_polynomial.py create mode 100644 src/beignet/_evaluate_chebyshev_polynomial_2d.py create mode 100644 src/beignet/_evaluate_chebyshev_polynomial_3d.py create mode 100644 src/beignet/_evaluate_chebyshev_polynomial_cartesian_2d.py create mode 100644 src/beignet/_evaluate_chebyshev_polynomial_cartesian_3d.py create mode 100644 src/beignet/_evaluate_laguerre_polynomial.py create mode 100644 src/beignet/_evaluate_laguerre_polynomial_2d.py create mode 100644 src/beignet/_evaluate_laguerre_polynomial_3d.py create mode 100644 src/beignet/_evaluate_laguerre_polynomial_cartesian_2d.py create mode 100644 src/beignet/_evaluate_laguerre_polynomial_cartesian_3d.py create mode 100644 src/beignet/_evaluate_legendre_polynomial.py create mode 100644 src/beignet/_evaluate_legendre_polynomial_2d.py create mode 100644 src/beignet/_evaluate_legendre_polynomial_3d.py create mode 100644 src/beignet/_evaluate_legendre_polynomial_cartesian_2d.py create mode 100644 src/beignet/_evaluate_legendre_polynomial_cartesian_3d.py create mode 100644 src/beignet/_evaluate_physicists_hermite_polynomial.py create mode 100644 src/beignet/_evaluate_physicists_hermite_polynomial_2d.py create mode 100644 src/beignet/_evaluate_physicists_hermite_polynomial_3d.py create mode 100644 src/beignet/_evaluate_physicists_hermite_polynomial_cartesian_2d.py create mode 100644 src/beignet/_evaluate_physicists_hermite_polynomial_cartesian_3d.py create mode 100644 src/beignet/_evaluate_polynomial.py create mode 100644 src/beignet/_evaluate_polynomial_2d.py create mode 100644 src/beignet/_evaluate_polynomial_3d.py create mode 100644 src/beignet/_evaluate_polynomial_cartesian_2d.py create mode 100644 src/beignet/_evaluate_polynomial_cartesian_3d.py create mode 100644 src/beignet/_evaluate_polynomial_from_roots.py create mode 100644 src/beignet/_evaluate_probabilists_hermite_polynomial.py create mode 100644 src/beignet/_evaluate_probabilists_hermite_polynomial_2d.py create mode 100644 src/beignet/_evaluate_probabilists_hermite_polynomial_3d.py create mode 100644 src/beignet/_evaluate_probabilists_hermite_polynomial_cartersian_2d.py create mode 100644 src/beignet/_evaluate_probabilists_hermite_polynomial_cartersian_3d.py create mode 100644 src/beignet/_fit_chebyshev_polynomial.py create mode 100644 src/beignet/_fit_laguerre_polynomial.py create mode 100644 src/beignet/_fit_legendre_polynomial.py create mode 100644 src/beignet/_fit_physicists_hermite_polynomial.py create mode 100644 src/beignet/_fit_polynomial.py create mode 100644 src/beignet/_fit_probabilists_hermite_polynomial.py create mode 100644 src/beignet/_gauss_laguerre_quadrature.py create mode 100644 src/beignet/_gauss_legendre_quadrature.py create mode 100644 src/beignet/_gauss_physicists_hermite_polynomial_quadrature.py create mode 100644 src/beignet/_gauss_probabilists_hermite_polynomial_quadrature.py create mode 100644 src/beignet/_integrate_chebyshev_polynomial.py create mode 100644 src/beignet/_integrate_laguerre_polynomial.py create mode 100644 src/beignet/_integrate_legendre_polynomial.py create mode 100644 src/beignet/_integrate_physicists_hermite_polynomial.py create mode 100644 src/beignet/_integrate_polynomial.py create mode 100644 src/beignet/_integrate_probabilists_hermite_polynomial.py create mode 100644 src/beignet/_laguerre_polynomial_companion.py create mode 100644 src/beignet/_laguerre_polynomial_domain.py create mode 100644 src/beignet/_laguerre_polynomial_from_roots.py create mode 100644 src/beignet/_laguerre_polynomial_one.py create mode 100644 src/beignet/_laguerre_polynomial_power.py create mode 100644 src/beignet/_laguerre_polynomial_roots.py create mode 100644 src/beignet/_laguerre_polynomial_to_polynomial.py create mode 100644 src/beignet/_laguerre_polynomial_vandermonde.py create mode 100644 src/beignet/_laguerre_polynomial_vandermonde_2d.py create mode 100644 src/beignet/_laguerre_polynomial_vandermonde_3d.py create mode 100644 src/beignet/_laguerre_polynomial_weight.py create mode 100644 src/beignet/_laguerre_polynomial_x.py create mode 100644 src/beignet/_laguerre_polynomial_zero.py create mode 100644 src/beignet/_legendre_polynomial_companion.py create mode 100644 src/beignet/_legendre_polynomial_domain.py create mode 100644 src/beignet/_legendre_polynomial_from_roots.py create mode 100644 src/beignet/_legendre_polynomial_one.py create mode 100644 src/beignet/_legendre_polynomial_power.py create mode 100644 src/beignet/_legendre_polynomial_roots.py create mode 100644 src/beignet/_legendre_polynomial_to_polynomial.py create mode 100644 src/beignet/_legendre_polynomial_vandermonde.py create mode 100644 src/beignet/_legendre_polynomial_vandermonde_2d.py create mode 100644 src/beignet/_legendre_polynomial_vandermonde_3d.py create mode 100644 src/beignet/_legendre_polynomial_weight.py create mode 100644 src/beignet/_legendre_polynomial_x.py create mode 100644 src/beignet/_legendre_polynomial_zero.py create mode 100644 src/beignet/_linear_chebyshev_polynomial.py create mode 100644 src/beignet/_linear_laguerre_polynomial.py create mode 100644 src/beignet/_linear_legendre_polynomial.py create mode 100644 src/beignet/_linear_physicists_hermite_polynomial.py create mode 100644 src/beignet/_linear_polynomial.py create mode 100644 src/beignet/_linear_probabilists_hermite_polynomial.py create mode 100644 src/beignet/_multiply_chebyshev_polynomial.py create mode 100644 src/beignet/_multiply_chebyshev_polynomial_by_x.py create mode 100644 src/beignet/_multiply_laguerre_polynomial.py create mode 100644 src/beignet/_multiply_laguerre_polynomial_by_x.py create mode 100644 src/beignet/_multiply_legendre_polynomial.py create mode 100644 src/beignet/_multiply_legendre_polynomial_by_x.py create mode 100644 src/beignet/_multiply_physicists_hermite_polynomial.py create mode 100644 src/beignet/_multiply_physicists_hermite_polynomial_by_x.py create mode 100644 src/beignet/_multiply_polynomial.py create mode 100644 src/beignet/_multiply_polynomial_by_x.py create mode 100644 src/beignet/_multiply_probabilists_hermite_polynomial.py create mode 100644 src/beignet/_multiply_probabilists_hermite_polynomial_by_x.py create mode 100644 src/beignet/_physicists_hermite_polynomial_companion.py create mode 100644 src/beignet/_physicists_hermite_polynomial_domain.py create mode 100644 src/beignet/_physicists_hermite_polynomial_from_roots.py create mode 100644 src/beignet/_physicists_hermite_polynomial_one.py create mode 100644 src/beignet/_physicists_hermite_polynomial_power.py create mode 100644 src/beignet/_physicists_hermite_polynomial_roots.py create mode 100644 src/beignet/_physicists_hermite_polynomial_to_polynomial.py create mode 100644 src/beignet/_physicists_hermite_polynomial_vandermonde.py create mode 100644 src/beignet/_physicists_hermite_polynomial_vandermonde_2d.py create mode 100644 src/beignet/_physicists_hermite_polynomial_vandermonde_3d.py create mode 100644 src/beignet/_physicists_hermite_polynomial_weight.py create mode 100644 src/beignet/_physicists_hermite_polynomial_x.py create mode 100644 src/beignet/_physicists_hermite_polynomial_zero.py create mode 100644 src/beignet/_polynomial_companion.py create mode 100644 src/beignet/_polynomial_domain.py create mode 100644 src/beignet/_polynomial_from_roots.py create mode 100644 src/beignet/_polynomial_one.py create mode 100644 src/beignet/_polynomial_power.py create mode 100644 src/beignet/_polynomial_roots.py create mode 100644 src/beignet/_polynomial_to_chebyshev_polynomial.py create mode 100644 src/beignet/_polynomial_to_laguerre_polynomial.py create mode 100644 src/beignet/_polynomial_to_legendre_polynomial.py create mode 100644 src/beignet/_polynomial_to_physicists_hermite_polynomial.py create mode 100644 src/beignet/_polynomial_to_probabilists_hermite_polynomial.py create mode 100644 src/beignet/_polynomial_vandermonde.py create mode 100644 src/beignet/_polynomial_vandermonde_2d.py create mode 100644 src/beignet/_polynomial_vandermonde_3d.py create mode 100644 src/beignet/_polynomial_x.py create mode 100644 src/beignet/_polynomial_zero.py create mode 100644 src/beignet/_probabilists_hermite_polynomial_companion.py create mode 100644 src/beignet/_probabilists_hermite_polynomial_domain.py create mode 100644 src/beignet/_probabilists_hermite_polynomial_from_roots.py create mode 100644 src/beignet/_probabilists_hermite_polynomial_one.py create mode 100644 src/beignet/_probabilists_hermite_polynomial_power.py create mode 100644 src/beignet/_probabilists_hermite_polynomial_roots.py create mode 100644 src/beignet/_probabilists_hermite_polynomial_to_polynomial.py create mode 100644 src/beignet/_probabilists_hermite_polynomial_vandermonde.py create mode 100644 src/beignet/_probabilists_hermite_polynomial_vandermonde_2d.py create mode 100644 src/beignet/_probabilists_hermite_polynomial_vandermonde_3d.py create mode 100644 src/beignet/_probabilists_hermite_polynomial_weight.py create mode 100644 src/beignet/_probabilists_hermite_polynomial_x.py create mode 100644 src/beignet/_probabilists_hermite_polynomial_zero.py create mode 100644 src/beignet/_subtract_chebyshev_polynomial.py create mode 100644 src/beignet/_subtract_laguerre_polynomial.py create mode 100644 src/beignet/_subtract_legendre_polynomial.py create mode 100644 src/beignet/_subtract_physicists_hermite_polynomial.py create mode 100644 src/beignet/_subtract_polynomial.py create mode 100644 src/beignet/_subtract_probabilists_hermite_polynomial.py create mode 100644 src/beignet/_trim_chebyshev_polynomial_coefficients.py create mode 100644 src/beignet/_trim_laguerre_polynomial_coefficients.py create mode 100644 src/beignet/_trim_legendre_polynomial_coefficients.py create mode 100644 src/beignet/_trim_physicists_hermite_polynomial_coefficients.py create mode 100644 src/beignet/_trim_polynomial_coefficients.py create mode 100644 src/beignet/_trim_probabilists_hermite_polynomial_coefficients.py create mode 100644 tests/beignet/test__add_chebyshev_polynomial.py create mode 100644 tests/beignet/test__add_laguerre_polynomial.py create mode 100644 tests/beignet/test__add_legendre_polynomial.py create mode 100644 tests/beignet/test__add_physicists_hermite_polynomial.py create mode 100644 tests/beignet/test__add_polynomial.py create mode 100644 tests/beignet/test__add_probabilists_hermite_polynomial.py create mode 100644 tests/beignet/test__chebyshev_extrema.py create mode 100644 tests/beignet/test__chebyshev_gauss_quadrature.py create mode 100644 tests/beignet/test__chebyshev_interpolation.py create mode 100644 tests/beignet/test__chebyshev_polynomial_companion.py create mode 100644 tests/beignet/test__chebyshev_polynomial_domain.py create mode 100644 tests/beignet/test__chebyshev_polynomial_from_roots.py create mode 100644 tests/beignet/test__chebyshev_polynomial_one.py create mode 100644 tests/beignet/test__chebyshev_polynomial_power.py create mode 100644 tests/beignet/test__chebyshev_polynomial_roots.py create mode 100644 tests/beignet/test__chebyshev_polynomial_vandermonde.py create mode 100644 tests/beignet/test__chebyshev_polynomial_vandermonde_2d.py create mode 100644 tests/beignet/test__chebyshev_polynomial_vandermonde_3d.py create mode 100644 tests/beignet/test__chebyshev_polynomial_weight.py create mode 100644 tests/beignet/test__chebyshev_polynomial_x.py create mode 100644 tests/beignet/test__chebyshev_polynomial_zero.py create mode 100644 tests/beignet/test__chebyshev_zeros.py create mode 100644 tests/beignet/test__differentiate_chebyshev_polynomial.py create mode 100644 tests/beignet/test__differentiate_laguerre_polynomial.py create mode 100644 tests/beignet/test__differentiate_legendre_polynomial.py create mode 100644 tests/beignet/test__differentiate_physicists_hermite_polynomial.py create mode 100644 tests/beignet/test__differentiate_probabilists_hermite_polynomial.py create mode 100644 tests/beignet/test__divide_chebyshev_polynomial.py create mode 100644 tests/beignet/test__divide_laguerre_polynomial.py create mode 100644 tests/beignet/test__divide_legendre_polynomial.py create mode 100644 tests/beignet/test__divide_physicists_hermite_polynomial.py create mode 100644 tests/beignet/test__divide_polynomial.py create mode 100644 tests/beignet/test__divide_probabilists_hermite_polynomial.py create mode 100644 tests/beignet/test__evaluate_chebyshev_polynomial.py create mode 100644 tests/beignet/test__evaluate_chebyshev_polynomial_2d.py create mode 100644 tests/beignet/test__evaluate_chebyshev_polynomial_3d.py create mode 100644 tests/beignet/test__evaluate_chebyshev_polynomial_cartesian_2d.py create mode 100644 tests/beignet/test__evaluate_chebyshev_polynomial_cartesian_3d.py create mode 100644 tests/beignet/test__evaluate_laguerre_polynomial.py create mode 100644 tests/beignet/test__evaluate_laguerre_polynomial_2d.py create mode 100644 tests/beignet/test__evaluate_laguerre_polynomial_3d.py create mode 100644 tests/beignet/test__evaluate_laguerre_polynomial_cartesian_2d.py create mode 100644 tests/beignet/test__evaluate_laguerre_polynomial_cartesian_3d.py create mode 100644 tests/beignet/test__evaluate_legendre_polynomial.py create mode 100644 tests/beignet/test__evaluate_legendre_polynomial_2d.py create mode 100644 tests/beignet/test__evaluate_legendre_polynomial_3d.py create mode 100644 tests/beignet/test__evaluate_legendre_polynomial_cartesian_2d.py create mode 100644 tests/beignet/test__evaluate_legendre_polynomial_cartesian_3d.py create mode 100644 tests/beignet/test__evaluate_physicists_hermite_polynomial.py create mode 100644 tests/beignet/test__evaluate_physicists_hermite_polynomial_2d.py create mode 100644 tests/beignet/test__evaluate_physicists_hermite_polynomial_3d.py create mode 100644 tests/beignet/test__evaluate_physicists_hermite_polynomial_cartesian_2d.py create mode 100644 tests/beignet/test__evaluate_physicists_hermite_polynomial_cartesian_3d.py create mode 100644 tests/beignet/test__evaluate_polynomial.py create mode 100644 tests/beignet/test__evaluate_polynomial_2d.py create mode 100644 tests/beignet/test__evaluate_polynomial_3d.py create mode 100644 tests/beignet/test__evaluate_polynomial_cartesian_2d.py create mode 100644 tests/beignet/test__evaluate_polynomial_cartesian_3d.py create mode 100644 tests/beignet/test__evaluate_polynomial_from_roots.py create mode 100644 tests/beignet/test__evaluate_probabilists_hermite_polynomial.py create mode 100644 tests/beignet/test__evaluate_probabilists_hermite_polynomial_2d.py create mode 100644 tests/beignet/test__evaluate_probabilists_hermite_polynomial_3d.py create mode 100644 tests/beignet/test__evaluate_probabilists_hermite_polynomial_cartersian_2d.py create mode 100644 tests/beignet/test__evaluate_probabilists_hermite_polynomial_cartersian_3d.py create mode 100644 tests/beignet/test__fit_chebyshev_polynomial.py create mode 100644 tests/beignet/test__fit_laguerre_polynomial.py create mode 100644 tests/beignet/test__fit_legendre_polynomial.py create mode 100644 tests/beignet/test__fit_physicists_hermite_polynomial.py create mode 100644 tests/beignet/test__fit_polynomial.py create mode 100644 tests/beignet/test__fit_probabilists_hermite_polynomial.py create mode 100644 tests/beignet/test__gauss_laguerre_quadrature.py create mode 100644 tests/beignet/test__gauss_legendre_quadrature.py create mode 100644 tests/beignet/test__gauss_physicists_hermite_polynomial_quadrature.py create mode 100644 tests/beignet/test__gauss_probabilists_hermite_polynomial_quadrature.py create mode 100644 tests/beignet/test__integrate_chebyshev_polynomial.py create mode 100644 tests/beignet/test__integrate_laguerre_polynomial.py create mode 100644 tests/beignet/test__integrate_legendre_polynomial.py create mode 100644 tests/beignet/test__integrate_physicists_hermite_polynomial.py create mode 100644 tests/beignet/test__integrate_polynomial.py create mode 100644 tests/beignet/test__integrate_probabilists_hermite_polynomial.py create mode 100644 tests/beignet/test__laguerre_polynomial_companion.py create mode 100644 tests/beignet/test__laguerre_polynomial_domain.py create mode 100644 tests/beignet/test__laguerre_polynomial_from_roots.py create mode 100644 tests/beignet/test__laguerre_polynomial_one.py create mode 100644 tests/beignet/test__laguerre_polynomial_power.py create mode 100644 tests/beignet/test__laguerre_polynomial_roots.py create mode 100644 tests/beignet/test__laguerre_polynomial_to_polynomial.py create mode 100644 tests/beignet/test__laguerre_polynomial_vandermonde.py create mode 100644 tests/beignet/test__laguerre_polynomial_vandermonde_2d.py create mode 100644 tests/beignet/test__laguerre_polynomial_vandermonde_3d.py create mode 100644 tests/beignet/test__laguerre_polynomial_weight.py create mode 100644 tests/beignet/test__laguerre_polynomial_x.py create mode 100644 tests/beignet/test__laguerre_polynomial_zero.py create mode 100644 tests/beignet/test__legendre_polynomial_companion.py create mode 100644 tests/beignet/test__legendre_polynomial_domain.py create mode 100644 tests/beignet/test__legendre_polynomial_from_roots.py create mode 100644 tests/beignet/test__legendre_polynomial_one.py create mode 100644 tests/beignet/test__legendre_polynomial_power.py create mode 100644 tests/beignet/test__legendre_polynomial_roots.py create mode 100644 tests/beignet/test__legendre_polynomial_to_polynomial.py create mode 100644 tests/beignet/test__legendre_polynomial_vandermonde.py create mode 100644 tests/beignet/test__legendre_polynomial_vandermonde_2d.py create mode 100644 tests/beignet/test__legendre_polynomial_weight.py create mode 100644 tests/beignet/test__legendre_polynomial_x.py create mode 100644 tests/beignet/test__legendre_polynomial_zero.py create mode 100644 tests/beignet/test__linear_chebyshev_polynomial.py create mode 100644 tests/beignet/test__linear_legendre_polynomial.py create mode 100644 tests/beignet/test__linear_physicists_hermite_polynomial.py create mode 100644 tests/beignet/test__linear_polynomial.py create mode 100644 tests/beignet/test__linear_probabilists_hermite_polynomial.py create mode 100644 tests/beignet/test__multiply_chebyshev_polynomial.py create mode 100644 tests/beignet/test__multiply_chebyshev_polynomial_by_x.py create mode 100644 tests/beignet/test__multiply_laguerre_polynomial.py create mode 100644 tests/beignet/test__multiply_laguerre_polynomial_by_x.py create mode 100644 tests/beignet/test__multiply_legendre_polynomial.py create mode 100644 tests/beignet/test__multiply_legendre_polynomial_by_x.py create mode 100644 tests/beignet/test__multiply_physicists_hermite_polynomial.py create mode 100644 tests/beignet/test__multiply_physicists_hermite_polynomial_by_x.py create mode 100644 tests/beignet/test__multiply_polynomial.py create mode 100644 tests/beignet/test__multiply_polynomial_by_x.py create mode 100644 tests/beignet/test__multiply_probabilists_hermite_polynomial.py create mode 100644 tests/beignet/test__multiply_probabilists_hermite_polynomial_by_x.py create mode 100644 tests/beignet/test__physicists_hermite_polynomial_companion.py create mode 100644 tests/beignet/test__physicists_hermite_polynomial_domain.py create mode 100644 tests/beignet/test__physicists_hermite_polynomial_from_roots.py create mode 100644 tests/beignet/test__physicists_hermite_polynomial_one.py create mode 100644 tests/beignet/test__physicists_hermite_polynomial_power.py create mode 100644 tests/beignet/test__physicists_hermite_polynomial_roots.py create mode 100644 tests/beignet/test__physicists_hermite_polynomial_to_polynomial.py create mode 100644 tests/beignet/test__physicists_hermite_polynomial_vandermonde.py create mode 100644 tests/beignet/test__physicists_hermite_polynomial_vandermonde_2d.py create mode 100644 tests/beignet/test__physicists_hermite_polynomial_vandermonde_3d.py create mode 100644 tests/beignet/test__physicists_hermite_polynomial_weight.py create mode 100644 tests/beignet/test__physicists_hermite_polynomial_x.py create mode 100644 tests/beignet/test__physicists_hermite_polynomial_zero.py create mode 100644 tests/beignet/test__polynomial_companion.py create mode 100644 tests/beignet/test__polynomial_domain.py create mode 100644 tests/beignet/test__polynomial_from_roots.py create mode 100644 tests/beignet/test__polynomial_one.py create mode 100644 tests/beignet/test__polynomial_power.py create mode 100644 tests/beignet/test__polynomial_roots.py create mode 100644 tests/beignet/test__polynomial_to_chebyshev_polynomial.py create mode 100644 tests/beignet/test__polynomial_to_laguerre_polynomial.py create mode 100644 tests/beignet/test__polynomial_to_legendre_polynomial.py create mode 100644 tests/beignet/test__polynomial_to_physicists_hermite_polynomial.py create mode 100644 tests/beignet/test__polynomial_to_probabilists_hermite_polynomial.py create mode 100644 tests/beignet/test__polynomial_vandermonde.py create mode 100644 tests/beignet/test__polynomial_vandermonde_2d.py create mode 100644 tests/beignet/test__polynomial_vandermonde_3d.py create mode 100644 tests/beignet/test__polynomial_x.py create mode 100644 tests/beignet/test__polynomial_zero.py create mode 100644 tests/beignet/test__probabilists_hermite_polynomial_companion.py create mode 100644 tests/beignet/test__probabilists_hermite_polynomial_domain.py create mode 100644 tests/beignet/test__probabilists_hermite_polynomial_from_roots.py create mode 100644 tests/beignet/test__probabilists_hermite_polynomial_one.py create mode 100644 tests/beignet/test__probabilists_hermite_polynomial_power.py create mode 100644 tests/beignet/test__probabilists_hermite_polynomial_roots.py create mode 100644 tests/beignet/test__probabilists_hermite_polynomial_to_polynomial.py create mode 100644 tests/beignet/test__probabilists_hermite_polynomial_vandermonde.py create mode 100644 tests/beignet/test__probabilists_hermite_polynomial_vandermonde_2d.py create mode 100644 tests/beignet/test__probabilists_hermite_polynomial_vandermonde_3d.py create mode 100644 tests/beignet/test__probabilists_hermite_polynomial_weight.py create mode 100644 tests/beignet/test__probabilists_hermite_polynomial_x.py create mode 100644 tests/beignet/test__probabilists_hermite_polynomial_zero.py create mode 100644 tests/beignet/test__quaternion_slerp.py delete mode 100644 tests/beignet/test__slerp.py create mode 100644 tests/beignet/test__subtract_chebyshev_polynomial.py create mode 100644 tests/beignet/test__subtract_laguerre_polynomial.py create mode 100644 tests/beignet/test__subtract_legendre_polynomial.py create mode 100644 tests/beignet/test__subtract_physicists_hermite_polynomial.py create mode 100644 tests/beignet/test__subtract_polynomial.py create mode 100644 tests/beignet/test__subtract_probabilists_hermite_polynomial.py create mode 100644 tests/beignet/test__trim_chebyshev_polynomial_coefficients.py create mode 100644 tests/beignet/test__trim_laguerre_polynomial_coefficients.py create mode 100644 tests/beignet/test__trim_legendre_polynomial_coefficients.py create mode 100644 tests/beignet/test__trim_physicists_hermite_polynomial_coefficients.py create mode 100644 tests/beignet/test__trim_polynomial_coefficients.py create mode 100644 tests/beignet/test__trim_probabilists_hermite_polynomial_coefficients.py diff --git a/docs/index.md b/docs/index.md index 37b23d0d1a..5935d0b3b3 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,13 +1,11 @@ -# beignet +# Operators + +## Geometry + +### Euler Angle ::: beignet.apply_euler_angle -::: beignet.apply_quaternion -::: beignet.apply_rotation_matrix -::: beignet.apply_rotation_vector ::: beignet.compose_euler_angle -::: beignet.compose_quaternion -::: beignet.compose_rotation_matrix -::: beignet.compose_rotation_vector ::: beignet.euler_angle_identity ::: beignet.euler_angle_magnitude ::: beignet.euler_angle_mean @@ -15,10 +13,13 @@ ::: beignet.euler_angle_to_rotation_matrix ::: beignet.euler_angle_to_rotation_vector ::: beignet.invert_euler_angle +::: beignet.random_euler_angle + +### Quaternion + +::: beignet.apply_quaternion +::: beignet.compose_quaternion ::: beignet.invert_quaternion -::: beignet.invert_rotation_matrix -::: beignet.invert_rotation_vector -::: beignet.lennard_jones_potential ::: beignet.quaternion_identity ::: beignet.quaternion_magnitude ::: beignet.quaternion_mean @@ -26,20 +27,252 @@ ::: beignet.quaternion_to_euler_angle ::: beignet.quaternion_to_rotation_matrix ::: beignet.quaternion_to_rotation_vector -::: beignet.random_euler_angle ::: beignet.random_quaternion + +### Rotation Matrix + +::: beignet.apply_rotation_matrix +::: beignet.compose_rotation_matrix +::: beignet.invert_rotation_matrix ::: beignet.random_rotation_matrix -::: beignet.random_rotation_vector ::: beignet.rotation_matrix_identity ::: beignet.rotation_matrix_magnitude ::: beignet.rotation_matrix_mean ::: beignet.rotation_matrix_to_euler_angle ::: beignet.rotation_matrix_to_quaternion ::: beignet.rotation_matrix_to_rotation_vector + +### Rotation Vector + +::: beignet.apply_rotation_vector +::: beignet.compose_rotation_vector +::: beignet.invert_rotation_vector +::: beignet.random_rotation_vector ::: beignet.rotation_vector_identity ::: beignet.rotation_vector_magnitude ::: beignet.rotation_vector_mean ::: beignet.rotation_vector_to_euler_angle ::: beignet.rotation_vector_to_quaternion ::: beignet.rotation_vector_to_rotation_matrix + +### Translation + ::: beignet.translation_identity + +### Transform + +::: beignet.apply_transform +::: beignet.invert_transform + +## Interpolation + +## Numerical Integration + +### Gaussian Quadrature + +::: beignet.gauss_laguerre_quadrature +::: beignet.gauss_legendre_quadrature +::: beignet.gauss_physicists_hermite_polynomial_quadrature +::: beignet.gauss_probabilists_hermite_polynomial_quadrature + +## Polynomials + +### Polynomial + +::: beignet.add_polynomial +::: beignet.differentiate_polynomial +::: beignet.divide_polynomial +::: beignet.evaluate_polynomial +::: beignet.evaluate_polynomial_2d +::: beignet.evaluate_polynomial_3d +::: beignet.evaluate_polynomial_cartesian_2d +::: beignet.evaluate_polynomial_cartesian_3d +::: beignet.evaluate_polynomial_from_roots +::: beignet.fit_polynomial +::: beignet.integrate_polynomial +::: beignet.linear_polynomial +::: beignet.multiply_polynomial +::: beignet.multiply_polynomial_by_x +::: beignet.polynomial_companion +::: beignet.polynomial_domain +::: beignet.polynomial_from_roots +::: beignet.polynomial_one +::: beignet.polynomial_power +::: beignet.polynomial_roots +::: beignet.polynomial_to_chebyshev_polynomial +::: beignet.polynomial_to_laguerre_polynomial +::: beignet.polynomial_to_legendre_polynomial +::: beignet.polynomial_to_physicists_hermite_polynomial +::: beignet.polynomial_to_probabilists_hermite_polynomial +::: beignet.polynomial_vandermonde +::: beignet.polynomial_vandermonde_2d +::: beignet.polynomial_vandermonde_3d +::: beignet.polynomial_x +::: beignet.polynomial_zero +::: beignet.subtract_polynomial +::: beignet.trim_polynomial_coefficients + +### Chebyshev Polynomial + +::: beignet.add_chebyshev_polynomial +::: beignet.chebyshev_extrema +::: beignet.chebyshev_gauss_quadrature +::: beignet.chebyshev_interpolation +::: beignet.chebyshev_polynomial_companion +::: beignet.chebyshev_polynomial_domain +::: beignet.chebyshev_polynomial_from_roots +::: beignet.chebyshev_polynomial_one +::: beignet.chebyshev_polynomial_power +::: beignet.chebyshev_polynomial_roots +::: beignet.chebyshev_polynomial_to_polynomial +::: beignet.chebyshev_polynomial_vandermonde +::: beignet.chebyshev_polynomial_vandermonde_2d +::: beignet.chebyshev_polynomial_vandermonde_3d +::: beignet.chebyshev_polynomial_weight +::: beignet.chebyshev_polynomial_x +::: beignet.chebyshev_polynomial_zero +::: beignet.chebyshev_zeros +::: beignet.differentiate_chebyshev_polynomial +::: beignet.divide_chebyshev_polynomial +::: beignet.evaluate_chebyshev_polynomial +::: beignet.evaluate_chebyshev_polynomial_2d +::: beignet.evaluate_chebyshev_polynomial_3d +::: beignet.evaluate_chebyshev_polynomial_cartesian_2d +::: beignet.evaluate_chebyshev_polynomial_cartesian_3d +::: beignet.fit_chebyshev_polynomial +::: beignet.integrate_chebyshev_polynomial +::: beignet.linear_chebyshev_polynomial +::: beignet.multiply_chebyshev_polynomial +::: beignet.multiply_chebyshev_polynomial_by_x +::: beignet.subtract_chebyshev_polynomial +::: beignet.trim_chebyshev_polynomial_coefficients + +### Laguerre Polynomial + +::: beignet.add_laguerre_polynomial +::: beignet.differentiate_laguerre_polynomial +::: beignet.divide_laguerre_polynomial +::: beignet.evaluate_laguerre_polynomial +::: beignet.evaluate_laguerre_polynomial_2d +::: beignet.evaluate_laguerre_polynomial_3d +::: beignet.evaluate_laguerre_polynomial_cartesian_2d +::: beignet.evaluate_laguerre_polynomial_cartesian_3d +::: beignet.fit_laguerre_polynomial +::: beignet.integrate_laguerre_polynomial +::: beignet.laguerre_polynomial_companion +::: beignet.laguerre_polynomial_domain +::: beignet.laguerre_polynomial_from_roots +::: beignet.laguerre_polynomial_one +::: beignet.laguerre_polynomial_power +::: beignet.laguerre_polynomial_roots +::: beignet.laguerre_polynomial_to_polynomial +::: beignet.laguerre_polynomial_vandermonde +::: beignet.laguerre_polynomial_vandermonde_2d +::: beignet.laguerre_polynomial_vandermonde_3d +::: beignet.laguerre_polynomial_weight +::: beignet.laguerre_polynomial_x +::: beignet.laguerre_polynomial_zero +::: beignet.linear_laguerre_polynomial +::: beignet.multiply_laguerre_polynomial +::: beignet.multiply_laguerre_polynomial_by_x +::: beignet.subtract_laguerre_polynomial +::: beignet.trim_laguerre_polynomial_coefficients + +### Legendre Polynomial + +::: beignet.add_legendre_polynomial +::: beignet.differentiate_legendre_polynomial +::: beignet.divide_legendre_polynomial +::: beignet.evaluate_legendre_polynomial +::: beignet.evaluate_legendre_polynomial_2d +::: beignet.evaluate_legendre_polynomial_3d +::: beignet.evaluate_legendre_polynomial_cartesian_2d +::: beignet.evaluate_legendre_polynomial_cartesian_3d +::: beignet.fit_legendre_polynomial +::: beignet.integrate_legendre_polynomial +::: beignet.legendre_polynomial_companion +::: beignet.legendre_polynomial_domain +::: beignet.legendre_polynomial_from_roots +::: beignet.legendre_polynomial_one +::: beignet.legendre_polynomial_power +::: beignet.legendre_polynomial_roots +::: beignet.legendre_polynomial_to_polynomial +::: beignet.legendre_polynomial_vandermonde +::: beignet.legendre_polynomial_vandermonde_2d +::: beignet.legendre_polynomial_vandermonde_3d +::: beignet.legendre_polynomial_weight +::: beignet.legendre_polynomial_x +::: beignet.legendre_polynomial_zero +::: beignet.linear_legendre_polynomial +::: beignet.multiply_legendre_polynomial +::: beignet.multiply_legendre_polynomial_by_x +::: beignet.subtract_legendre_polynomial +::: beignet.trim_legendre_polynomial_coefficients + +### Physicists’ Hermite Polynomial + +::: beignet.add_physicists_hermite_polynomial +::: beignet.differentiate_physicists_hermite_polynomial +::: beignet.divide_physicists_hermite_polynomial +::: beignet.evaluate_physicists_hermite_polynomial +::: beignet.evaluate_physicists_hermite_polynomial_2d +::: beignet.evaluate_physicists_hermite_polynomial_3d +::: beignet.evaluate_physicists_hermite_polynomial_cartesian_2d +::: beignet.evaluate_physicists_hermite_polynomial_cartesian_3d +::: beignet.fit_physicists_hermite_polynomial +::: beignet.integrate_physicists_hermite_polynomial +::: beignet.linear_physicists_hermite_polynomial +::: beignet.multiply_physicists_hermite_polynomial +::: beignet.multiply_physicists_hermite_polynomial_by_x +::: beignet.physicists_hermite_polynomial_companion +::: beignet.physicists_hermite_polynomial_domain +::: beignet.physicists_hermite_polynomial_from_roots +::: beignet.physicists_hermite_polynomial_one +::: beignet.physicists_hermite_polynomial_power +::: beignet.physicists_hermite_polynomial_roots +::: beignet.physicists_hermite_polynomial_to_polynomial +::: beignet.physicists_hermite_polynomial_vandermonde +::: beignet.physicists_hermite_polynomial_vandermonde_2d +::: beignet.physicists_hermite_polynomial_vandermonde_3d +::: beignet.physicists_hermite_polynomial_weight +::: beignet.physicists_hermite_polynomial_x +::: beignet.physicists_hermite_polynomial_zero +::: beignet.subtract_physicists_hermite_polynomial +::: beignet.trim_physicists_hermite_polynomial_coefficients + +### Probabilists’ Hermite Polynomial + +::: beignet.add_probabilists_hermite_polynomial +::: beignet.differentiate_probabilists_hermite_polynomial +::: beignet.divide_probabilists_hermite_polynomial +::: beignet.evaluate_probabilists_hermite_polynomial +::: beignet.evaluate_probabilists_hermite_polynomial_2d +::: beignet.evaluate_probabilists_hermite_polynomial_3d +::: beignet.evaluate_probabilists_hermite_polynomial_cartersian_2d +::: beignet.evaluate_probabilists_hermite_polynomial_cartersian_3d +::: beignet.fit_probabilists_hermite_polynomial +::: beignet.integrate_probabilists_hermite_polynomial +::: beignet.linear_probabilists_hermite_polynomial +::: beignet.multiply_probabilists_hermite_polynomial +::: beignet.multiply_probabilists_hermite_polynomial_by_x +::: beignet.probabilists_hermite_polynomial_companion +::: beignet.probabilists_hermite_polynomial_domain +::: beignet.probabilists_hermite_polynomial_from_roots +::: beignet.probabilists_hermite_polynomial_one +::: beignet.probabilists_hermite_polynomial_power +::: beignet.probabilists_hermite_polynomial_roots +::: beignet.probabilists_hermite_polynomial_to_polynomial +::: beignet.probabilists_hermite_polynomial_vandermonde +::: beignet.probabilists_hermite_polynomial_vandermonde_2d +::: beignet.probabilists_hermite_polynomial_vandermonde_3d +::: beignet.probabilists_hermite_polynomial_weight +::: beignet.probabilists_hermite_polynomial_x +::: beignet.probabilists_hermite_polynomial_zero +::: beignet.subtract_probabilists_hermite_polynomial +::: beignet.trim_probabilists_hermite_polynomial_coefficients + +## Thermodynamics + +### Interatomic Potentials + +::: beignet.lennard_jones_potential diff --git a/docs/stylesheets/extra.css b/docs/stylesheets/extra.css new file mode 100644 index 0000000000..e69de29bb2 diff --git a/mkdocs.yml b/mkdocs.yml index fcf80d567a..2eaac0e318 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -1,3 +1,5 @@ +extra_css: + - "stylesheets/extra.css" extra_javascript: - "javascripts/mathjax.js" - "https://polyfill.io/v3/polyfill.min.js?features=es6" @@ -5,16 +7,25 @@ extra_javascript: markdown_extensions: - pymdownx.arithmatex: generic: true +nav: + - beignet: "index.md" + - beignet.datasets: "beignet.datasets.md" + - beignet.features: "beignet.features.md" + - beignet.func: "beignet.func.md" + - beignet.io: "beignet.io.md" + - beignet.special: "beignet.special.md" + - beignet.transforms: "beignet.transforms.md" plugins: - mkdocstrings: default_handler: "python" handlers: python: options: + heading_level: 4 docstring_style: "numpy" separate_signature: true show_root_heading: true show_source: true site_name: "Beignet" theme: - name: "material" + name: "material" \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml index 3c0e3700c2..9eeba6b742 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -11,6 +11,7 @@ authors = [{ email = "allen.goodman@icloud.com", name = "Allen Goodman" }] dependencies = [ "pooch", "torch==2.2.2", + "torchaudio", "tqdm", ] dynamic = ["version"] @@ -29,6 +30,7 @@ docs = [ ] test = [ "hypothesis", + "numpy==1.26.4", "pytest", "pytest-mock", "scipy", diff --git a/src/beignet/__init__.py b/src/beignet/__init__.py index 89b8ffaa1a..d338a100cb 100644 --- a/src/beignet/__init__.py +++ b/src/beignet/__init__.py @@ -6,6 +6,12 @@ except PackageNotFoundError: __version__ = None +from ._add_chebyshev_polynomial import add_chebyshev_polynomial +from ._add_laguerre_polynomial import add_laguerre_polynomial +from ._add_legendre_polynomial import add_legendre_polynomial +from ._add_physicists_hermite_polynomial import add_physicists_hermite_polynomial +from ._add_polynomial import add_polynomial +from ._add_probabilists_hermite_polynomial import add_probabilists_hermite_polynomial from ._apply_euler_angle import apply_euler_angle from ._apply_quaternion import ( apply_quaternion, @@ -13,10 +19,45 @@ from ._apply_rotation_matrix import apply_rotation_matrix from ._apply_rotation_vector import apply_rotation_vector from ._apply_transform import apply_transform +from ._chebyshev_extrema import chebyshev_extrema +from ._chebyshev_gauss_quadrature import chebyshev_gauss_quadrature +from ._chebyshev_interpolation import chebyshev_interpolation +from ._chebyshev_polynomial_companion import chebyshev_polynomial_companion +from ._chebyshev_polynomial_domain import chebyshev_polynomial_domain +from ._chebyshev_polynomial_from_roots import chebyshev_polynomial_from_roots +from ._chebyshev_polynomial_one import chebyshev_polynomial_one +from ._chebyshev_polynomial_power import chebyshev_polynomial_power +from ._chebyshev_polynomial_roots import chebyshev_polynomial_roots +from ._chebyshev_polynomial_to_polynomial import chebyshev_polynomial_to_polynomial +from ._chebyshev_polynomial_vandermonde import chebyshev_polynomial_vandermonde +from ._chebyshev_polynomial_vandermonde_2d import chebyshev_polynomial_vandermonde_2d +from ._chebyshev_polynomial_vandermonde_3d import chebyshev_polynomial_vandermonde_3d +from ._chebyshev_polynomial_weight import chebyshev_polynomial_weight +from ._chebyshev_polynomial_x import chebyshev_polynomial_x +from ._chebyshev_polynomial_zero import chebyshev_polynomial_zero +from ._chebyshev_zeros import chebyshev_zeros from ._compose_euler_angle import compose_euler_angle from ._compose_quaternion import compose_quaternion from ._compose_rotation_matrix import compose_rotation_matrix from ._compose_rotation_vector import compose_rotation_vector +from ._differentiate_chebyshev_polynomial import differentiate_chebyshev_polynomial +from ._differentiate_laguerre_polynomial import differentiate_laguerre_polynomial +from ._differentiate_legendre_polynomial import differentiate_legendre_polynomial +from ._differentiate_physicists_hermite_polynomial import ( + differentiate_physicists_hermite_polynomial, +) +from ._differentiate_polynomial import differentiate_polynomial +from ._differentiate_probabilists_hermite_polynomial import ( + differentiate_probabilists_hermite_polynomial, +) +from ._divide_chebyshev_polynomial import divide_chebyshev_polynomial +from ._divide_laguerre_polynomial import divide_laguerre_polynomial +from ._divide_legendre_polynomial import divide_legendre_polynomial +from ._divide_physicists_hermite_polynomial import divide_physicists_hermite_polynomial +from ._divide_polynomial import divide_polynomial +from ._divide_probabilists_hermite_polynomial import ( + divide_probabilists_hermite_polynomial, +) from ._euler_angle_identity import euler_angle_identity from ._euler_angle_magnitude import euler_angle_magnitude from ._euler_angle_mean import euler_angle_mean @@ -25,12 +66,231 @@ ) from ._euler_angle_to_rotation_matrix import euler_angle_to_rotation_matrix from ._euler_angle_to_rotation_vector import euler_angle_to_rotation_vector +from ._evaluate_chebyshev_polynomial import evaluate_chebyshev_polynomial +from ._evaluate_chebyshev_polynomial_2d import evaluate_chebyshev_polynomial_2d +from ._evaluate_chebyshev_polynomial_3d import evaluate_chebyshev_polynomial_3d +from ._evaluate_chebyshev_polynomial_cartesian_2d import ( + evaluate_chebyshev_polynomial_cartesian_2d, +) +from ._evaluate_chebyshev_polynomial_cartesian_3d import ( + evaluate_chebyshev_polynomial_cartesian_3d, +) +from ._evaluate_laguerre_polynomial import evaluate_laguerre_polynomial +from ._evaluate_laguerre_polynomial_2d import evaluate_laguerre_polynomial_2d +from ._evaluate_laguerre_polynomial_3d import evaluate_laguerre_polynomial_3d +from ._evaluate_laguerre_polynomial_cartesian_2d import ( + evaluate_laguerre_polynomial_cartesian_2d, +) +from ._evaluate_laguerre_polynomial_cartesian_3d import ( + evaluate_laguerre_polynomial_cartesian_3d, +) +from ._evaluate_legendre_polynomial import evaluate_legendre_polynomial +from ._evaluate_legendre_polynomial_2d import evaluate_legendre_polynomial_2d +from ._evaluate_legendre_polynomial_3d import evaluate_legendre_polynomial_3d +from ._evaluate_legendre_polynomial_cartesian_2d import ( + evaluate_legendre_polynomial_cartesian_2d, +) +from ._evaluate_legendre_polynomial_cartesian_3d import ( + evaluate_legendre_polynomial_cartesian_3d, +) +from ._evaluate_physicists_hermite_polynomial import ( + evaluate_physicists_hermite_polynomial, +) +from ._evaluate_physicists_hermite_polynomial_2d import ( + evaluate_physicists_hermite_polynomial_2d, +) +from ._evaluate_physicists_hermite_polynomial_3d import ( + evaluate_physicists_hermite_polynomial_3d, +) +from ._evaluate_physicists_hermite_polynomial_cartesian_2d import ( + evaluate_physicists_hermite_polynomial_cartesian_2d, +) +from ._evaluate_physicists_hermite_polynomial_cartesian_3d import ( + evaluate_physicists_hermite_polynomial_cartesian_3d, +) +from ._evaluate_polynomial import evaluate_polynomial +from ._evaluate_polynomial_2d import evaluate_polynomial_2d +from ._evaluate_polynomial_3d import evaluate_polynomial_3d +from ._evaluate_polynomial_cartesian_2d import evaluate_polynomial_cartesian_2d +from ._evaluate_polynomial_cartesian_3d import evaluate_polynomial_cartesian_3d +from ._evaluate_polynomial_from_roots import evaluate_polynomial_from_roots +from ._evaluate_probabilists_hermite_polynomial import ( + evaluate_probabilists_hermite_polynomial, +) +from ._evaluate_probabilists_hermite_polynomial_2d import ( + evaluate_probabilists_hermite_polynomial_2d, +) +from ._evaluate_probabilists_hermite_polynomial_3d import ( + evaluate_probabilists_hermite_polynomial_3d, +) +from ._evaluate_probabilists_hermite_polynomial_cartersian_2d import ( + evaluate_probabilists_hermite_polynomial_cartersian_2d, +) +from ._evaluate_probabilists_hermite_polynomial_cartersian_3d import ( + evaluate_probabilists_hermite_polynomial_cartersian_3d, +) +from ._fit_chebyshev_polynomial import fit_chebyshev_polynomial +from ._fit_laguerre_polynomial import fit_laguerre_polynomial +from ._fit_legendre_polynomial import fit_legendre_polynomial +from ._fit_physicists_hermite_polynomial import fit_physicists_hermite_polynomial +from ._fit_polynomial import fit_polynomial +from ._fit_probabilists_hermite_polynomial import fit_probabilists_hermite_polynomial +from ._gauss_laguerre_quadrature import gauss_laguerre_quadrature +from ._gauss_legendre_quadrature import gauss_legendre_quadrature +from ._gauss_physicists_hermite_polynomial_quadrature import ( + gauss_physicists_hermite_polynomial_quadrature, +) +from ._gauss_probabilists_hermite_polynomial_quadrature import ( + gauss_probabilists_hermite_polynomial_quadrature, +) +from ._integrate_chebyshev_polynomial import integrate_chebyshev_polynomial +from ._integrate_laguerre_polynomial import integrate_laguerre_polynomial +from ._integrate_legendre_polynomial import integrate_legendre_polynomial +from ._integrate_physicists_hermite_polynomial import ( + integrate_physicists_hermite_polynomial, +) +from ._integrate_polynomial import integrate_polynomial +from ._integrate_probabilists_hermite_polynomial import ( + integrate_probabilists_hermite_polynomial, +) from ._invert_euler_angle import invert_euler_angle from ._invert_quaternion import invert_quaternion from ._invert_rotation_matrix import invert_rotation_matrix from ._invert_rotation_vector import invert_rotation_vector from ._invert_transform import invert_transform +from ._laguerre_polynomial_companion import laguerre_polynomial_companion +from ._laguerre_polynomial_domain import laguerre_polynomial_domain +from ._laguerre_polynomial_from_roots import laguerre_polynomial_from_roots +from ._laguerre_polynomial_one import laguerre_polynomial_one +from ._laguerre_polynomial_power import laguerre_polynomial_power +from ._laguerre_polynomial_roots import laguerre_polynomial_roots +from ._laguerre_polynomial_to_polynomial import laguerre_polynomial_to_polynomial +from ._laguerre_polynomial_vandermonde import laguerre_polynomial_vandermonde +from ._laguerre_polynomial_vandermonde_2d import laguerre_polynomial_vandermonde_2d +from ._laguerre_polynomial_vandermonde_3d import laguerre_polynomial_vandermonde_3d +from ._laguerre_polynomial_weight import laguerre_polynomial_weight +from ._laguerre_polynomial_x import laguerre_polynomial_x +from ._laguerre_polynomial_zero import laguerre_polynomial_zero +from ._legendre_polynomial_companion import legendre_polynomial_companion +from ._legendre_polynomial_domain import legendre_polynomial_domain +from ._legendre_polynomial_from_roots import legendre_polynomial_from_roots +from ._legendre_polynomial_one import legendre_polynomial_one +from ._legendre_polynomial_power import legendre_polynomial_power +from ._legendre_polynomial_roots import legendre_polynomial_roots +from ._legendre_polynomial_to_polynomial import legendre_polynomial_to_polynomial +from ._legendre_polynomial_vandermonde import legendre_polynomial_vandermonde +from ._legendre_polynomial_vandermonde_2d import legendre_polynomial_vandermonde_2d +from ._legendre_polynomial_vandermonde_3d import legendre_polynomial_vandermonde_3d +from ._legendre_polynomial_weight import legendre_polynomial_weight +from ._legendre_polynomial_x import legendre_polynomial_x +from ._legendre_polynomial_zero import legendre_polynomial_zero from ._lennard_jones_potential import lennard_jones_potential +from ._linear_chebyshev_polynomial import linear_chebyshev_polynomial +from ._linear_laguerre_polynomial import linear_laguerre_polynomial +from ._linear_legendre_polynomial import linear_legendre_polynomial +from ._linear_physicists_hermite_polynomial import linear_physicists_hermite_polynomial +from ._linear_polynomial import linear_polynomial +from ._linear_probabilists_hermite_polynomial import ( + linear_probabilists_hermite_polynomial, +) +from ._multiply_chebyshev_polynomial import multiply_chebyshev_polynomial +from ._multiply_chebyshev_polynomial_by_x import multiply_chebyshev_polynomial_by_x +from ._multiply_laguerre_polynomial import multiply_laguerre_polynomial +from ._multiply_laguerre_polynomial_by_x import multiply_laguerre_polynomial_by_x +from ._multiply_legendre_polynomial import multiply_legendre_polynomial +from ._multiply_legendre_polynomial_by_x import multiply_legendre_polynomial_by_x +from ._multiply_physicists_hermite_polynomial import ( + multiply_physicists_hermite_polynomial, +) +from ._multiply_physicists_hermite_polynomial_by_x import ( + multiply_physicists_hermite_polynomial_by_x, +) +from ._multiply_polynomial import multiply_polynomial +from ._multiply_polynomial_by_x import multiply_polynomial_by_x +from ._multiply_probabilists_hermite_polynomial import ( + multiply_probabilists_hermite_polynomial, +) +from ._multiply_probabilists_hermite_polynomial_by_x import ( + multiply_probabilists_hermite_polynomial_by_x, +) +from ._physicists_hermite_polynomial_companion import ( + physicists_hermite_polynomial_companion, +) +from ._physicists_hermite_polynomial_domain import physicists_hermite_polynomial_domain +from ._physicists_hermite_polynomial_from_roots import ( + physicists_hermite_polynomial_from_roots, +) +from ._physicists_hermite_polynomial_one import physicists_hermite_polynomial_one +from ._physicists_hermite_polynomial_power import physicists_hermite_polynomial_power +from ._physicists_hermite_polynomial_roots import physicists_hermite_polynomial_roots +from ._physicists_hermite_polynomial_to_polynomial import ( + physicists_hermite_polynomial_to_polynomial, +) +from ._physicists_hermite_polynomial_vandermonde import ( + physicists_hermite_polynomial_vandermonde, +) +from ._physicists_hermite_polynomial_vandermonde_2d import ( + physicists_hermite_polynomial_vandermonde_2d, +) +from ._physicists_hermite_polynomial_vandermonde_3d import ( + physicists_hermite_polynomial_vandermonde_3d, +) +from ._physicists_hermite_polynomial_weight import physicists_hermite_polynomial_weight +from ._physicists_hermite_polynomial_x import physicists_hermite_polynomial_x +from ._physicists_hermite_polynomial_zero import physicists_hermite_polynomial_zero +from ._polynomial_companion import polynomial_companion +from ._polynomial_domain import polynomial_domain +from ._polynomial_from_roots import polynomial_from_roots +from ._polynomial_one import polynomial_one +from ._polynomial_power import polynomial_power +from ._polynomial_roots import polynomial_roots +from ._polynomial_to_chebyshev_polynomial import polynomial_to_chebyshev_polynomial +from ._polynomial_to_laguerre_polynomial import polynomial_to_laguerre_polynomial +from ._polynomial_to_legendre_polynomial import polynomial_to_legendre_polynomial +from ._polynomial_to_physicists_hermite_polynomial import ( + polynomial_to_physicists_hermite_polynomial, +) +from ._polynomial_to_probabilists_hermite_polynomial import ( + polynomial_to_probabilists_hermite_polynomial, +) +from ._polynomial_vandermonde import polynomial_vandermonde +from ._polynomial_vandermonde_2d import polynomial_vandermonde_2d +from ._polynomial_vandermonde_3d import polynomial_vandermonde_3d +from ._polynomial_x import polynomial_x +from ._polynomial_zero import polynomial_zero +from ._probabilists_hermite_polynomial_companion import ( + probabilists_hermite_polynomial_companion, +) +from ._probabilists_hermite_polynomial_domain import ( + probabilists_hermite_polynomial_domain, +) +from ._probabilists_hermite_polynomial_from_roots import ( + probabilists_hermite_polynomial_from_roots, +) +from ._probabilists_hermite_polynomial_one import probabilists_hermite_polynomial_one +from ._probabilists_hermite_polynomial_power import ( + probabilists_hermite_polynomial_power, +) +from ._probabilists_hermite_polynomial_roots import ( + probabilists_hermite_polynomial_roots, +) +from ._probabilists_hermite_polynomial_to_polynomial import ( + probabilists_hermite_polynomial_to_polynomial, +) +from ._probabilists_hermite_polynomial_vandermonde import ( + probabilists_hermite_polynomial_vandermonde, +) +from ._probabilists_hermite_polynomial_vandermonde_2d import ( + probabilists_hermite_polynomial_vandermonde_2d, +) +from ._probabilists_hermite_polynomial_vandermonde_3d import ( + probabilists_hermite_polynomial_vandermonde_3d, +) +from ._probabilists_hermite_polynomial_weight import ( + probabilists_hermite_polynomial_weight, +) +from ._probabilists_hermite_polynomial_x import probabilists_hermite_polynomial_x +from ._probabilists_hermite_polynomial_zero import probabilists_hermite_polynomial_zero from ._quaternion_identity import quaternion_identity from ._quaternion_magnitude import quaternion_magnitude from ._quaternion_mean import quaternion_mean @@ -68,31 +328,225 @@ from ._rotation_vector_to_rotation_matrix import ( rotation_vector_to_rotation_matrix, ) +from ._subtract_chebyshev_polynomial import subtract_chebyshev_polynomial +from ._subtract_laguerre_polynomial import subtract_laguerre_polynomial +from ._subtract_legendre_polynomial import subtract_legendre_polynomial +from ._subtract_physicists_hermite_polynomial import ( + subtract_physicists_hermite_polynomial, +) +from ._subtract_polynomial import subtract_polynomial +from ._subtract_probabilists_hermite_polynomial import ( + subtract_probabilists_hermite_polynomial, +) from ._translation_identity import translation_identity +from ._trim_chebyshev_polynomial_coefficients import ( + trim_chebyshev_polynomial_coefficients, +) +from ._trim_laguerre_polynomial_coefficients import ( + trim_laguerre_polynomial_coefficients, +) +from ._trim_legendre_polynomial_coefficients import ( + trim_legendre_polynomial_coefficients, +) +from ._trim_physicists_hermite_polynomial_coefficients import ( + trim_physicists_hermite_polynomial_coefficients, +) +from ._trim_polynomial_coefficients import trim_polynomial_coefficients +from ._trim_probabilists_hermite_polynomial_coefficients import ( + trim_probabilists_hermite_polynomial_coefficients, +) from .special import error_erf, error_erfc __all__ = [ + "add_chebyshev_polynomial", + "add_laguerre_polynomial", + "add_legendre_polynomial", + "add_physicists_hermite_polynomial", + "add_polynomial", + "add_probabilists_hermite_polynomial", "apply_euler_angle", "apply_quaternion", "apply_rotation_matrix", "apply_rotation_vector", "apply_transform", + "evaluate_chebyshev_polynomial_cartesian_2d", + "evaluate_chebyshev_polynomial_cartesian_3d", + "chebyshev_interpolation", + "linear_chebyshev_polynomial", + "multiply_chebyshev_polynomial_by_x", + "chebyshev_zeros", + "chebyshev_extrema", + "chebyshev_gauss_quadrature", + "chebyshev_polynomial_companion", + "chebyshev_polynomial_domain", + "chebyshev_polynomial_from_roots", + "chebyshev_polynomial_one", + "chebyshev_polynomial_power", + "chebyshev_polynomial_roots", + "chebyshev_polynomial_to_polynomial", + "chebyshev_polynomial_vandermonde", + "chebyshev_polynomial_vandermonde_2d", + "chebyshev_polynomial_vandermonde_3d", + "chebyshev_polynomial_weight", + "chebyshev_polynomial_x", + "chebyshev_polynomial_zero", "compose_euler_angle", "compose_quaternion", "compose_rotation_matrix", "compose_rotation_vector", + "differentiate_chebyshev_polynomial", + "differentiate_laguerre_polynomial", + "differentiate_legendre_polynomial", + "differentiate_physicists_hermite_polynomial", + "differentiate_polynomial", + "differentiate_probabilists_hermite_polynomial", + "divide_chebyshev_polynomial", + "divide_laguerre_polynomial", + "divide_legendre_polynomial", + "divide_physicists_hermite_polynomial", + "divide_polynomial", + "divide_probabilists_hermite_polynomial", "euler_angle_identity", "euler_angle_magnitude", "euler_angle_mean", "euler_angle_to_quaternion", "euler_angle_to_rotation_matrix", "euler_angle_to_rotation_vector", + "evaluate_chebyshev_polynomial", + "evaluate_chebyshev_polynomial_2d", + "evaluate_chebyshev_polynomial_3d", + "evaluate_laguerre_polynomial", + "evaluate_laguerre_polynomial_2d", + "evaluate_laguerre_polynomial_3d", + "evaluate_legendre_polynomial", + "evaluate_legendre_polynomial_2d", + "evaluate_legendre_polynomial_3d", + "evaluate_physicists_hermite_polynomial", + "evaluate_physicists_hermite_polynomial_2d", + "evaluate_physicists_hermite_polynomial_3d", + "evaluate_polynomial", + "evaluate_polynomial_2d", + "evaluate_polynomial_3d", + "evaluate_polynomial_from_roots", + "evaluate_probabilists_hermite_polynomial", + "evaluate_probabilists_hermite_polynomial_2d", + "evaluate_probabilists_hermite_polynomial_3d", + "fit_chebyshev_polynomial", + "fit_laguerre_polynomial", + "fit_legendre_polynomial", + "fit_physicists_hermite_polynomial", + "fit_polynomial", + "fit_probabilists_hermite_polynomial", + "gauss_laguerre_quadrature", + "gauss_legendre_quadrature", + "gauss_physicists_hermite_polynomial_quadrature", + "gauss_probabilists_hermite_polynomial_quadrature", + "evaluate_probabilists_hermite_polynomial_cartersian_2d", + "evaluate_probabilists_hermite_polynomial_cartersian_3d", + "linear_probabilists_hermite_polynomial", + "multiply_probabilists_hermite_polynomial_by_x", + "evaluate_physicists_hermite_polynomial_cartesian_2d", + "evaluate_physicists_hermite_polynomial_cartesian_3d", + "linear_physicists_hermite_polynomial", + "multiply_physicists_hermite_polynomial_by_x", + "integrate_chebyshev_polynomial", + "integrate_laguerre_polynomial", + "integrate_legendre_polynomial", + "integrate_physicists_hermite_polynomial", + "integrate_polynomial", + "integrate_probabilists_hermite_polynomial", "invert_euler_angle", "invert_quaternion", "invert_rotation_matrix", "invert_rotation_vector", "invert_transform", + "evaluate_laguerre_polynomial_cartesian_2d", + "evaluate_laguerre_polynomial_cartesian_3d", + "linear_laguerre_polynomial", + "multiply_laguerre_polynomial_by_x", + "laguerre_polynomial_companion", + "laguerre_polynomial_domain", + "laguerre_polynomial_from_roots", + "laguerre_polynomial_one", + "laguerre_polynomial_power", + "laguerre_polynomial_roots", + "laguerre_polynomial_to_polynomial", + "laguerre_polynomial_vandermonde", + "laguerre_polynomial_vandermonde_2d", + "laguerre_polynomial_vandermonde_3d", + "laguerre_polynomial_weight", + "laguerre_polynomial_x", + "laguerre_polynomial_zero", + "legendre_polynomial_companion", + "legendre_polynomial_domain", + "legendre_polynomial_from_roots", + "legendre_polynomial_one", + "legendre_polynomial_power", + "legendre_polynomial_roots", + "legendre_polynomial_to_polynomial", + "legendre_polynomial_vandermonde", + "legendre_polynomial_vandermonde_2d", + "legendre_polynomial_vandermonde_3d", + "legendre_polynomial_weight", + "legendre_polynomial_x", + "legendre_polynomial_zero", + "evaluate_legendre_polynomial_cartesian_2d", + "evaluate_legendre_polynomial_cartesian_3d", + "linear_legendre_polynomial", + "multiply_legendre_polynomial_by_x", "lennard_jones_potential", + "multiply_chebyshev_polynomial", + "multiply_laguerre_polynomial", + "multiply_legendre_polynomial", + "multiply_physicists_hermite_polynomial", + "multiply_polynomial", + "multiply_probabilists_hermite_polynomial", + "physicists_hermite_polynomial_companion", + "physicists_hermite_polynomial_domain", + "physicists_hermite_polynomial_from_roots", + "physicists_hermite_polynomial_one", + "physicists_hermite_polynomial_power", + "physicists_hermite_polynomial_roots", + "physicists_hermite_polynomial_to_polynomial", + "physicists_hermite_polynomial_vandermonde", + "physicists_hermite_polynomial_vandermonde_2d", + "physicists_hermite_polynomial_vandermonde_3d", + "physicists_hermite_polynomial_weight", + "physicists_hermite_polynomial_x", + "physicists_hermite_polynomial_zero", + "evaluate_polynomial_cartesian_2d", + "evaluate_polynomial_cartesian_3d", + "linear_polynomial", + "multiply_polynomial_by_x", + "polynomial_companion", + "polynomial_domain", + "polynomial_from_roots", + "polynomial_one", + "polynomial_power", + "polynomial_roots", + "polynomial_to_chebyshev_polynomial", + "polynomial_to_laguerre_polynomial", + "polynomial_to_legendre_polynomial", + "polynomial_to_physicists_hermite_polynomial", + "polynomial_to_probabilists_hermite_polynomial", + "polynomial_vandermonde", + "polynomial_vandermonde_2d", + "polynomial_vandermonde_3d", + "polynomial_x", + "polynomial_zero", + "probabilists_hermite_polynomial_companion", + "probabilists_hermite_polynomial_domain", + "probabilists_hermite_polynomial_from_roots", + "probabilists_hermite_polynomial_one", + "probabilists_hermite_polynomial_power", + "probabilists_hermite_polynomial_roots", + "probabilists_hermite_polynomial_to_polynomial", + "probabilists_hermite_polynomial_vandermonde", + "probabilists_hermite_polynomial_vandermonde_2d", + "probabilists_hermite_polynomial_vandermonde_3d", + "probabilists_hermite_polynomial_weight", + "probabilists_hermite_polynomial_x", + "probabilists_hermite_polynomial_zero", "quaternion_identity", "quaternion_magnitude", "quaternion_mean", @@ -116,5 +570,17 @@ "rotation_vector_to_euler_angle", "rotation_vector_to_quaternion", "rotation_vector_to_rotation_matrix", + "subtract_chebyshev_polynomial", + "subtract_laguerre_polynomial", + "subtract_legendre_polynomial", + "subtract_physicists_hermite_polynomial", + "subtract_polynomial", + "subtract_probabilists_hermite_polynomial", "translation_identity", + "trim_chebyshev_polynomial_coefficients", + "trim_laguerre_polynomial_coefficients", + "trim_legendre_polynomial_coefficients", + "trim_physicists_hermite_polynomial_coefficients", + "trim_polynomial_coefficients", + "trim_probabilists_hermite_polynomial_coefficients", ] diff --git a/src/beignet/_add_chebyshev_polynomial.py b/src/beignet/_add_chebyshev_polynomial.py new file mode 100644 index 0000000000..cc620c3642 --- /dev/null +++ b/src/beignet/_add_chebyshev_polynomial.py @@ -0,0 +1,55 @@ +import torch +from torch import Tensor + + +def add_chebyshev_polynomial(input: Tensor, other: Tensor) -> Tensor: + r""" + Returns the sum of two polynomials. + + Parameters + ---------- + input : Tensor + Polynomial coefficients. + + other : Tensor + Polynomial coefficients. + + Returns + ------- + output : Tensor + Polynomial coefficients. + """ + input = torch.atleast_1d(input) + other = torch.atleast_1d(other) + + dtype = torch.promote_types(input.dtype, other.dtype) + + input = input.to(dtype) + other = other.to(dtype) + + if input.shape[0] > other.shape[0]: + output = torch.concatenate( + [ + other, + torch.zeros( + input.shape[0] - other.shape[0], + dtype=other.dtype, + ), + ], + ) + + output = input + output + else: + output = torch.concatenate( + [ + input, + torch.zeros( + other.shape[0] - input.shape[0], + dtype=input.dtype, + ), + ] + ) + + output = other + output + + return output diff --git a/src/beignet/_add_laguerre_polynomial.py b/src/beignet/_add_laguerre_polynomial.py new file mode 100644 index 0000000000..e42ea5468f --- /dev/null +++ b/src/beignet/_add_laguerre_polynomial.py @@ -0,0 +1,55 @@ +import torch +from torch import Tensor + + +def add_laguerre_polynomial(input: Tensor, other: Tensor) -> Tensor: + r""" + Returns the sum of two polynomials. + + Parameters + ---------- + input : Tensor + Polynomial coefficients. + + other : Tensor + Polynomial coefficients. + + Returns + ------- + output : Tensor + Polynomial coefficients. + """ + input = torch.atleast_1d(input) + other = torch.atleast_1d(other) + + dtype = torch.promote_types(input.dtype, other.dtype) + + input = input.to(dtype) + other = other.to(dtype) + + if input.shape[0] > other.shape[0]: + output = torch.concatenate( + [ + other, + torch.zeros( + input.shape[0] - other.shape[0], + dtype=other.dtype, + ), + ], + ) + + output = input + output + else: + output = torch.concatenate( + [ + input, + torch.zeros( + other.shape[0] - input.shape[0], + dtype=input.dtype, + ), + ] + ) + + output = other + output + + return output diff --git a/src/beignet/_add_legendre_polynomial.py b/src/beignet/_add_legendre_polynomial.py new file mode 100644 index 0000000000..1376742b18 --- /dev/null +++ b/src/beignet/_add_legendre_polynomial.py @@ -0,0 +1,55 @@ +import torch +from torch import Tensor + + +def add_legendre_polynomial(input: Tensor, other: Tensor) -> Tensor: + r""" + Returns the sum of two polynomials. + + Parameters + ---------- + input : Tensor + Polynomial coefficients. + + other : Tensor + Polynomial coefficients. + + Returns + ------- + output : Tensor + Polynomial coefficients. + """ + input = torch.atleast_1d(input) + other = torch.atleast_1d(other) + + dtype = torch.promote_types(input.dtype, other.dtype) + + input = input.to(dtype) + other = other.to(dtype) + + if input.shape[0] > other.shape[0]: + output = torch.concatenate( + [ + other, + torch.zeros( + input.shape[0] - other.shape[0], + dtype=other.dtype, + ), + ], + ) + + output = input + output + else: + output = torch.concatenate( + [ + input, + torch.zeros( + other.shape[0] - input.shape[0], + dtype=input.dtype, + ), + ] + ) + + output = other + output + + return output diff --git a/src/beignet/_add_physicists_hermite_polynomial.py b/src/beignet/_add_physicists_hermite_polynomial.py new file mode 100644 index 0000000000..89a81eda5a --- /dev/null +++ b/src/beignet/_add_physicists_hermite_polynomial.py @@ -0,0 +1,55 @@ +import torch +from torch import Tensor + + +def add_physicists_hermite_polynomial(input: Tensor, other: Tensor) -> Tensor: + r""" + Returns the sum of two polynomials. + + Parameters + ---------- + input : Tensor + Polynomial coefficients. + + other : Tensor + Polynomial coefficients. + + Returns + ------- + output : Tensor + Polynomial coefficients. + """ + input = torch.atleast_1d(input) + other = torch.atleast_1d(other) + + dtype = torch.promote_types(input.dtype, other.dtype) + + input = input.to(dtype) + other = other.to(dtype) + + if input.shape[0] > other.shape[0]: + output = torch.concatenate( + [ + other, + torch.zeros( + input.shape[0] - other.shape[0], + dtype=other.dtype, + ), + ], + ) + + output = input + output + else: + output = torch.concatenate( + [ + input, + torch.zeros( + other.shape[0] - input.shape[0], + dtype=input.dtype, + ), + ] + ) + + output = other + output + + return output diff --git a/src/beignet/_add_polynomial.py b/src/beignet/_add_polynomial.py new file mode 100644 index 0000000000..8ab149f446 --- /dev/null +++ b/src/beignet/_add_polynomial.py @@ -0,0 +1,55 @@ +import torch +from torch import Tensor + + +def add_polynomial(input: Tensor, other: Tensor) -> Tensor: + r""" + Returns the sum of two polynomials. + + Parameters + ---------- + input : Tensor + Polynomial coefficients. + + other : Tensor + Polynomial coefficients. + + Returns + ------- + output : Tensor + Polynomial coefficients. + """ + input = torch.atleast_1d(input) + other = torch.atleast_1d(other) + + dtype = torch.promote_types(input.dtype, other.dtype) + + input = input.to(dtype) + other = other.to(dtype) + + if input.shape[0] > other.shape[0]: + output = torch.concatenate( + [ + other, + torch.zeros( + input.shape[0] - other.shape[0], + dtype=other.dtype, + ), + ], + ) + + output = input + output + else: + output = torch.concatenate( + [ + input, + torch.zeros( + other.shape[0] - input.shape[0], + dtype=input.dtype, + ), + ] + ) + + output = other + output + + return output diff --git a/src/beignet/_add_probabilists_hermite_polynomial.py b/src/beignet/_add_probabilists_hermite_polynomial.py new file mode 100644 index 0000000000..12bf635141 --- /dev/null +++ b/src/beignet/_add_probabilists_hermite_polynomial.py @@ -0,0 +1,55 @@ +import torch +from torch import Tensor + + +def add_probabilists_hermite_polynomial(input: Tensor, other: Tensor) -> Tensor: + r""" + Returns the sum of two polynomials. + + Parameters + ---------- + input : Tensor + Polynomial coefficients. + + other : Tensor + Polynomial coefficients. + + Returns + ------- + output : Tensor + Polynomial coefficients. + """ + input = torch.atleast_1d(input) + other = torch.atleast_1d(other) + + dtype = torch.promote_types(input.dtype, other.dtype) + + input = input.to(dtype) + other = other.to(dtype) + + if input.shape[0] > other.shape[0]: + output = torch.concatenate( + [ + other, + torch.zeros( + input.shape[0] - other.shape[0], + dtype=other.dtype, + ), + ], + ) + + output = input + output + else: + output = torch.concatenate( + [ + input, + torch.zeros( + other.shape[0] - input.shape[0], + dtype=input.dtype, + ), + ] + ) + + output = other + output + + return output diff --git a/src/beignet/_chebyshev_extrema.py b/src/beignet/_chebyshev_extrema.py new file mode 100644 index 0000000000..4a25411b51 --- /dev/null +++ b/src/beignet/_chebyshev_extrema.py @@ -0,0 +1,11 @@ +import math + +import torch +from torch import Tensor + + +def chebyshev_extrema(input: int) -> Tensor: + if input < 2: + raise ValueError + + return torch.cos(torch.linspace(-math.pi, 0, input)) diff --git a/src/beignet/_chebyshev_gauss_quadrature.py b/src/beignet/_chebyshev_gauss_quadrature.py new file mode 100644 index 0000000000..9a53473a75 --- /dev/null +++ b/src/beignet/_chebyshev_gauss_quadrature.py @@ -0,0 +1,16 @@ +import math +from typing import Tuple + +import torch +from torch import Tensor + + +def chebyshev_gauss_quadrature(degree: int) -> Tuple[Tensor, Tensor]: + if not degree > 0: + raise ValueError + + output = torch.cos(torch.arange(1, 2 * degree, 2) / (2 * degree) * math.pi) + + weight = torch.ones(degree) * (math.pi / degree) + + return output, weight diff --git a/src/beignet/_chebyshev_interpolation.py b/src/beignet/_chebyshev_interpolation.py new file mode 100644 index 0000000000..bce34541d3 --- /dev/null +++ b/src/beignet/_chebyshev_interpolation.py @@ -0,0 +1,45 @@ +import math +from typing import Callable + +import torch +from torch import Tensor + + +def chebyshev_interpolation( + func: Callable[[Tensor, ...], Tensor], + degree: int, + *args, +): + if degree < 0: + raise ValueError + + order = degree + 1 + + if order < 1: + raise ValueError + + zeros = torch.arange(-order + 1, order + 1, 2) + + zeros = torch.sin(zeros * 0.5 * math.pi / order) + + vandermonde = torch.empty([degree + 1, *zeros.shape], dtype=zeros.dtype) + + vandermonde[0] = torch.ones_like(zeros) + + if degree > 0: + vandermonde[1] = zeros + + for i in range(2, degree + 1): + v = vandermonde[i - 1] * zeros * 2.0 - vandermonde[i - 2] + + vandermonde[i] = v + + vandermonde = torch.moveaxis(vandermonde, 0, -1) + + output = vandermonde.T @ func(zeros, *args) + + output[0] = output[0] / order + + output[1:] = output[1:] / (order * 0.5) + + return output diff --git a/src/beignet/_chebyshev_polynomial_companion.py b/src/beignet/_chebyshev_polynomial_companion.py new file mode 100644 index 0000000000..01428885d8 --- /dev/null +++ b/src/beignet/_chebyshev_polynomial_companion.py @@ -0,0 +1,47 @@ +import math + +import torch +from torch import Tensor + + +def chebyshev_polynomial_companion(input: Tensor) -> Tensor: + input = torch.atleast_1d(input) + + if input.shape[0] < 2: + raise ValueError + + if input.shape[0] == 2: + return torch.tensor([[-input[0] / input[1]]]) + + n = input.shape[0] - 1 + + output = torch.zeros( + [ + n, + n, + ], + dtype=input.dtype, + ) + + scale = torch.ones([n]) + + scale[1:] = math.sqrt(0.5) + + shape = output.shape + + output = torch.reshape(output, [-1]) + + x = torch.full([n - 1], 1 / 2) + + x[0] = math.sqrt(0.5) + + output[1 :: n + 1] = x + output[n :: n + 1] = x + + output = torch.reshape(output, shape) + + output[:, -1] = ( + output[:, -1] + -(input[:-1] / input[-1]) * (scale / scale[-1]) * 0.5 + ) + + return output diff --git a/src/beignet/_chebyshev_polynomial_domain.py b/src/beignet/_chebyshev_polynomial_domain.py new file mode 100644 index 0000000000..e82992ab84 --- /dev/null +++ b/src/beignet/_chebyshev_polynomial_domain.py @@ -0,0 +1,3 @@ +import torch + +chebyshev_polynomial_domain = torch.tensor([-1.0, 1.0]) diff --git a/src/beignet/_chebyshev_polynomial_from_roots.py b/src/beignet/_chebyshev_polynomial_from_roots.py new file mode 100644 index 0000000000..05dc168a84 --- /dev/null +++ b/src/beignet/_chebyshev_polynomial_from_roots.py @@ -0,0 +1,86 @@ +import math + +import torch +from torch import Tensor + +from ._linear_chebyshev_polynomial import linear_chebyshev_polynomial +from ._multiply_chebyshev_polynomial import multiply_chebyshev_polynomial + + +def chebyshev_polynomial_from_roots(input: Tensor) -> Tensor: + f = linear_chebyshev_polynomial + g = multiply_chebyshev_polynomial + if math.prod(input.shape) == 0: + return torch.ones([1]) + + input, _ = torch.sort(input) + + ys = [] + + for x in input: + a = torch.zeros(input.shape[0] + 1, dtype=x.dtype) + b = f(-x, 1) + + a = torch.atleast_1d(a) + b = torch.atleast_1d(b) + + dtype = torch.promote_types(a.dtype, b.dtype) + + a = a.to(dtype) + b = b.to(dtype) + + if a.shape[0] > b.shape[0]: + y = torch.concatenate( + [ + b, + torch.zeros( + a.shape[0] - b.shape[0], + dtype=b.dtype, + ), + ], + ) + + y = a + y + else: + y = torch.concatenate( + [ + a, + torch.zeros( + b.shape[0] - a.shape[0], + dtype=a.dtype, + ), + ] + ) + + y = b + y + + ys = [*ys, y] + + p = torch.stack(ys) + + m = p.shape[0] + + x = m, p + + while x[0] > 1: + m, r = divmod(x[0], 2) + + z = x[1] + + previous = torch.zeros([len(p), input.shape[0] + 1]) + + y = previous + + for i in range(0, m): + y[i] = g(z[i], z[i + m])[: input.shape[0] + 1] + + previous = y + + if r: + previous[0] = g(previous[0], z[2 * m])[: input.shape[0] + 1] + + x = m, previous + + _, output = x + + return output[0] diff --git a/src/beignet/_chebyshev_polynomial_one.py b/src/beignet/_chebyshev_polynomial_one.py new file mode 100644 index 0000000000..dbb5ba7803 --- /dev/null +++ b/src/beignet/_chebyshev_polynomial_one.py @@ -0,0 +1,3 @@ +import torch + +chebyshev_polynomial_one = torch.tensor([1.0]) diff --git a/src/beignet/_chebyshev_polynomial_power.py b/src/beignet/_chebyshev_polynomial_power.py new file mode 100644 index 0000000000..6667e1eacf --- /dev/null +++ b/src/beignet/_chebyshev_polynomial_power.py @@ -0,0 +1,55 @@ +import math + +import torch +import torchaudio.functional +from torch import Tensor + +from ._add_chebyshev_polynomial import add_chebyshev_polynomial + + +def chebyshev_polynomial_power( + input: Tensor, + exponent: float | Tensor, + maximum_exponent: float | Tensor = 16.0, +) -> Tensor: + input = torch.atleast_1d(input) + + _exponent = int(exponent) + + if _exponent != exponent or _exponent < 0: + raise ValueError + + if maximum_exponent is not None and _exponent > maximum_exponent: + raise ValueError + + match _exponent: + case 0: + output = torch.tensor([1.0], dtype=input.dtype) + case 1: + output = input + case _: + output = torch.zeros(input.shape[0] * exponent, dtype=input.dtype) + + output = add_chebyshev_polynomial(output, input) + + index1 = math.prod(input.shape) + output2 = torch.zeros(2 * index1 - 1, dtype=input.dtype) + output2[index1 - 1 :] = input / 2.0 + output2 = torch.flip(output2, dims=[0]) + output2 + zs = output2 + + index = math.prod(output.shape) + output1 = torch.zeros(2 * index - 1, dtype=output.dtype) + output1[index - 1 :] = output / 2.0 + output1 = torch.flip(output1, dims=[0]) + output1 + output = output1 + + for _ in range(2, _exponent + 1): + output = torchaudio.functional.convolve(output, zs, mode="same") + + n = (math.prod(output.shape) + 1) // 2 + c = output[n - 1 :] + c[1:n] = c[1:n] * 2.0 + output = c + + return output diff --git a/src/beignet/_chebyshev_polynomial_roots.py b/src/beignet/_chebyshev_polynomial_roots.py new file mode 100644 index 0000000000..08d166808e --- /dev/null +++ b/src/beignet/_chebyshev_polynomial_roots.py @@ -0,0 +1,25 @@ +import torch +from torch import Tensor + +from ._chebyshev_polynomial_companion import chebyshev_polynomial_companion + + +def chebyshev_polynomial_roots(input: Tensor) -> Tensor: + input = torch.atleast_1d(input) + + if input.shape[0] <= 1: + return torch.tensor([], dtype=input.dtype) + + if input.shape[0] == 2: + return torch.tensor([-input[0] / input[1]]) + + output = chebyshev_polynomial_companion(input) + + output = torch.flip(output, dims=[0]) + output = torch.flip(output, dims=[1]) + + output = torch.linalg.eigvals(output) + + output, _ = torch.sort(output.real) + + return output diff --git a/src/beignet/_chebyshev_polynomial_to_polynomial.py b/src/beignet/_chebyshev_polynomial_to_polynomial.py new file mode 100644 index 0000000000..d82fded563 --- /dev/null +++ b/src/beignet/_chebyshev_polynomial_to_polynomial.py @@ -0,0 +1,36 @@ +import torch +from torch import Tensor + +from ._add_polynomial import add_polynomial +from ._multiply_polynomial_by_x import multiply_polynomial_by_x +from ._subtract_polynomial import subtract_polynomial + + +def chebyshev_polynomial_to_polynomial(input: Tensor) -> Tensor: + input = torch.atleast_1d(input) + + n = input.shape[0] + + if n < 3: + return input + + c0 = torch.zeros_like(input) + c0[0] = input[-2] + + c1 = torch.zeros_like(input) + c1[0] = input[-1] + + for index in range(0, n - 2): + i1 = n - 1 - index + + tmp = c0 + + c0 = subtract_polynomial(input[i1 - 2], c1) + + c1 = add_polynomial(tmp, multiply_polynomial_by_x(c1, "same") * 2) + + output = multiply_polynomial_by_x(c1, "same") + + output = add_polynomial(c0, output) + + return output diff --git a/src/beignet/_chebyshev_polynomial_vandermonde.py b/src/beignet/_chebyshev_polynomial_vandermonde.py new file mode 100644 index 0000000000..25a0be6402 --- /dev/null +++ b/src/beignet/_chebyshev_polynomial_vandermonde.py @@ -0,0 +1,28 @@ +import torch +from torch import Tensor + + +def chebyshev_polynomial_vandermonde( + x: Tensor, + degree: Tensor, +) -> Tensor: + if degree < 0: + raise ValueError + + x = torch.atleast_1d(x) + dims = (degree + 1,) + x.shape + dtyp = torch.promote_types(x.dtype, torch.tensor(0.0).dtype) + x = x.to(dtyp) + v = torch.empty(dims, dtype=dtyp) + + v[0] = torch.ones_like(x) + + if degree > 0: + v[1] = x + + x2 = 2 * x + + for index in range(2, degree + 1): + v[index] = v[index - 1] * x2 - v[index - 2] + + return torch.moveaxis(v, 0, -1) diff --git a/src/beignet/_chebyshev_polynomial_vandermonde_2d.py b/src/beignet/_chebyshev_polynomial_vandermonde_2d.py new file mode 100644 index 0000000000..8acb5539e1 --- /dev/null +++ b/src/beignet/_chebyshev_polynomial_vandermonde_2d.py @@ -0,0 +1,49 @@ +import functools +import operator + +import torch +from torch import Tensor + +from ._chebyshev_polynomial_vandermonde import chebyshev_polynomial_vandermonde + + +def chebyshev_polynomial_vandermonde_2d( + x: Tensor, + y: Tensor, + degree: Tensor, +) -> Tensor: + functions = ( + chebyshev_polynomial_vandermonde, + chebyshev_polynomial_vandermonde, + ) + + n = len(functions) + + if n != len([x, y]): + raise ValueError + + if n != len(degree): + raise ValueError + + if n == 0: + raise ValueError + + matrices = [] + + for i in range(n): + matrix = functions[i]((x, y)[i], degree[i]) + + matrices = [ + *matrices, + matrix[(..., *tuple(slice(None) if j == i else None for j in range(n)))], + ] + + vandermonde = functools.reduce( + operator.mul, + matrices, + ) + + return torch.reshape( + vandermonde, + [*vandermonde.shape[: -len(degree)], -1], + ) diff --git a/src/beignet/_chebyshev_polynomial_vandermonde_3d.py b/src/beignet/_chebyshev_polynomial_vandermonde_3d.py new file mode 100644 index 0000000000..0cface76a0 --- /dev/null +++ b/src/beignet/_chebyshev_polynomial_vandermonde_3d.py @@ -0,0 +1,51 @@ +import functools +import operator + +import torch +from torch import Tensor + +from ._chebyshev_polynomial_vandermonde import chebyshev_polynomial_vandermonde + + +def chebyshev_polynomial_vandermonde_3d( + x: Tensor, + y: Tensor, + z: Tensor, + degree: Tensor, +) -> Tensor: + functions = ( + chebyshev_polynomial_vandermonde, + chebyshev_polynomial_vandermonde, + chebyshev_polynomial_vandermonde, + ) + + n = len(functions) + + if n != len([x, y, z]): + raise ValueError + + if n != len(degree): + raise ValueError + + if n == 0: + raise ValueError + + matrices = [] + + for i in range(n): + matrix = functions[i]((x, y, z)[i], degree[i]) + + matrices = [ + *matrices, + matrix[(..., *tuple(slice(None) if j == i else None for j in range(n)))], + ] + + vandermonde = functools.reduce( + operator.mul, + matrices, + ) + + return torch.reshape( + vandermonde, + [*vandermonde.shape[: -len(degree)], -1], + ) diff --git a/src/beignet/_chebyshev_polynomial_weight.py b/src/beignet/_chebyshev_polynomial_weight.py new file mode 100644 index 0000000000..6092093b58 --- /dev/null +++ b/src/beignet/_chebyshev_polynomial_weight.py @@ -0,0 +1,6 @@ +import torch +from torch import Tensor + + +def chebyshev_polynomial_weight(input: Tensor) -> Tensor: + return 1.0 / (torch.sqrt(1.0 + input) * torch.sqrt(1.0 - input)) diff --git a/src/beignet/_chebyshev_polynomial_x.py b/src/beignet/_chebyshev_polynomial_x.py new file mode 100644 index 0000000000..fd8562d8fc --- /dev/null +++ b/src/beignet/_chebyshev_polynomial_x.py @@ -0,0 +1,3 @@ +import torch + +chebyshev_polynomial_x = torch.tensor([0.0, 1.0]) diff --git a/src/beignet/_chebyshev_polynomial_zero.py b/src/beignet/_chebyshev_polynomial_zero.py new file mode 100644 index 0000000000..5cfacddb3f --- /dev/null +++ b/src/beignet/_chebyshev_polynomial_zero.py @@ -0,0 +1,3 @@ +import torch + +chebyshev_polynomial_zero = torch.tensor([0.0]) diff --git a/src/beignet/_chebyshev_zeros.py b/src/beignet/_chebyshev_zeros.py new file mode 100644 index 0000000000..a1d583c354 --- /dev/null +++ b/src/beignet/_chebyshev_zeros.py @@ -0,0 +1,11 @@ +import math + +import torch +from torch import Tensor + + +def chebyshev_zeros(input: int) -> Tensor: + if input < 1: + raise ValueError + + return torch.sin(0.5 * math.pi / input * torch.arange(-input + 1, input + 1, 2)) diff --git a/src/beignet/_differentiate_chebyshev_polynomial.py b/src/beignet/_differentiate_chebyshev_polynomial.py new file mode 100644 index 0000000000..2bb2ca57a2 --- /dev/null +++ b/src/beignet/_differentiate_chebyshev_polynomial.py @@ -0,0 +1,64 @@ +import torch +from torch import Tensor + + +def differentiate_chebyshev_polynomial( + input: Tensor, + order=1, + scale=1, + axis=0, +) -> Tensor: + r""" + Returns the derivative of a polynomial. + + Parameters + ---------- + input : Tensor + Polynomial coefficients. + + order : Tensor, optional + + scale : Tensor, optional + + dim : int, default=0 + + Returns + ------- + output : Tensor + Polynomial coefficients of the derivative. + """ + if order < 0: + raise ValueError + + input = torch.atleast_1d(input) + + if order == 0: + return input + + output = torch.moveaxis(input, axis, 0) + + n = output.shape[0] + + if order >= n: + output = torch.zeros_like(output[:1]) + else: + for _ in range(order): + n = n - 1 + + output = output * scale + + derivative = torch.empty((n,) + output.shape[1:], dtype=output.dtype) + + for i in range(0, n - 2): + j = n - i + + derivative[j - 1] = (2 * j) * output[j] + + output[j - 2] += (j * output[j]) / (j - 2) + + if n > 1: + derivative[1] = 4 * output[2] + + derivative[0] = output[1] + + return torch.moveaxis(output, 0, axis) diff --git a/src/beignet/_differentiate_laguerre_polynomial.py b/src/beignet/_differentiate_laguerre_polynomial.py new file mode 100644 index 0000000000..aa869864ef --- /dev/null +++ b/src/beignet/_differentiate_laguerre_polynomial.py @@ -0,0 +1,78 @@ +import torch +from torch import Tensor + + +def differentiate_laguerre_polynomial( + input, + order=1, + scale=1, + axis=0, +) -> Tensor: + r""" + Returns the derivative of a polynomial. + + Parameters + ---------- + input : Tensor + Polynomial coefficients. + + order : Tensor, optional + + scale : Tensor, optional + + dim : int, default=0 + + Returns + ------- + output : Tensor + Polynomial coefficients of the derivative. + """ + if order < 0: + raise ValueError + + input = torch.atleast_1d(input) + + if order == 0: + return input + + input = torch.moveaxis(input, axis, 0) + n = input.shape[0] + if order >= n: + input = torch.zeros_like(input[:1]) + else: + for _ in range(order): + n = n - 1 + + input *= scale + + der = torch.empty((n,) + input.shape[1:], dtype=input.dtype) + + def body(k, der_c, n=n): + j = n - k + + der, c = der_c + + der[j - 1] = -c[j] + + c[j - 1] += c[j] + + return der, c + + b = n - 1 + + x = (der, input) + + y = x + + for index in range(0, b): + y = body(index, y) + + der, input = y + + der[0] = -input[1] + + input = der + + input = torch.moveaxis(input, 0, axis) + + return input diff --git a/src/beignet/_differentiate_legendre_polynomial.py b/src/beignet/_differentiate_legendre_polynomial.py new file mode 100644 index 0000000000..a1ea826830 --- /dev/null +++ b/src/beignet/_differentiate_legendre_polynomial.py @@ -0,0 +1,81 @@ +import torch +from torch import Tensor + + +def differentiate_legendre_polynomial( + input, + order=1, + scale=1, + axis=0, +) -> Tensor: + r""" + Returns the derivative of a polynomial. + + Parameters + ---------- + input : Tensor + Polynomial coefficients. + + order : Tensor, optional + + scale : Tensor, optional + + dim : int, default=0 + + Returns + ------- + output : Tensor + Polynomial coefficients of the derivative. + """ + if order < 0: + raise ValueError + + input = torch.atleast_1d(input) + + if order == 0: + return input + + input = torch.moveaxis(input, axis, 0) + + n = input.shape[0] + + if order >= n: + input = torch.zeros_like(input[:1]) + else: + for _ in range(order): + n = n - 1 + input *= scale + der = torch.empty((n,) + input.shape[1:], dtype=input.dtype) + + def body(k, der_c, n=n): + j = n - k + + der, c = der_c + + der[j - 1] = (2 * j - 1) * c[j] + + c[j - 2] += c[j] + + return der, c + + b = n - 2 + + x = (der, input) + + y = x + + for index in range(0, b): + y = body(index, y) + + der, input = y + + if n > 1: + der[1] = 3 * input[2] + + der[0] = input[1] + + input = der + + input = torch.moveaxis(input, 0, axis) + + return input diff --git a/src/beignet/_differentiate_physicists_hermite_polynomial.py b/src/beignet/_differentiate_physicists_hermite_polynomial.py new file mode 100644 index 0000000000..bbdefa2dd6 --- /dev/null +++ b/src/beignet/_differentiate_physicists_hermite_polynomial.py @@ -0,0 +1,60 @@ +import torch +from torch import Tensor + + +def differentiate_physicists_hermite_polynomial( + input, + order=1, + scale=1, + axis=0, +) -> Tensor: + r""" + Returns the derivative of a polynomial. + + Parameters + ---------- + input : Tensor + Polynomial coefficients. + + order : Tensor, optional + + scale : Tensor, optional + + dim : int, default=0 + + Returns + ------- + output : Tensor + Polynomial coefficients of the derivative. + """ + if order < 0: + raise ValueError + + input = torch.atleast_1d(input) + + if order == 0: + return input + + input = torch.moveaxis(input, axis, 0) + + n = input.shape[0] + + if order >= n: + input = torch.zeros_like(input[:1]) + else: + for _ in range(order): + n = n - 1 + + input *= scale + + der = torch.empty((n,) + input.shape[1:], dtype=input.dtype) + + j = torch.arange(n, 0, -1) + + der[j - 1] = (2 * j * (input[j]).T).T + + input = der + + input = torch.moveaxis(input, 0, axis) + + return input diff --git a/src/beignet/_differentiate_polynomial.py b/src/beignet/_differentiate_polynomial.py new file mode 100644 index 0000000000..80941fffd3 --- /dev/null +++ b/src/beignet/_differentiate_polynomial.py @@ -0,0 +1,55 @@ +import torch +from torch import Tensor + + +def differentiate_polynomial( + input: Tensor, + order: Tensor | None = None, + scale: Tensor | None = None, + dim: int = 0, +) -> Tensor: + r""" + Returns the derivative of a polynomial. + + Parameters + ---------- + input : Tensor + Polynomial coefficients. + + order : Tensor, optional + + scale : Tensor, optional + + dim : int, default=0 + + Returns + ------- + output : Tensor + Polynomial coefficients of the derivative. + """ + input = torch.atleast_1d(input) + + if order == 0: + return input + + input = torch.moveaxis(input, dim, 0) + + if order >= input.shape[0]: + output = torch.zeros_like(input[:1]) + else: + d = torch.arange(input.shape[0]) + + output = input + + for _ in range(0, order): + output = (d * output.T).T + + output = torch.roll(output, -1, dims=[0]) * scale + + output[-1] = 0.0 + + output = output[:-order] + + output = torch.moveaxis(output, 0, dim) + + return output diff --git a/src/beignet/_differentiate_probabilists_hermite_polynomial.py b/src/beignet/_differentiate_probabilists_hermite_polynomial.py new file mode 100644 index 0000000000..d5bc1f7530 --- /dev/null +++ b/src/beignet/_differentiate_probabilists_hermite_polynomial.py @@ -0,0 +1,60 @@ +import torch +from torch import Tensor + + +def differentiate_probabilists_hermite_polynomial( + input, + order=1, + scale=1, + axis=0, +) -> Tensor: + r""" + Returns the derivative of a polynomial. + + Parameters + ---------- + input : Tensor + Polynomial coefficients. + + order : Tensor, optional + + scale : Tensor, optional + + dim : int, default=0 + + Returns + ------- + output : Tensor + Polynomial coefficients of the derivative. + """ + if order < 0: + raise ValueError + + input = torch.atleast_1d(input) + + if order == 0: + return input + + input = torch.moveaxis(input, axis, 0) + + n = input.shape[0] + + if order >= n: + input = torch.zeros_like(input[:1]) + else: + for _ in range(order): + n = n - 1 + + input = input * scale + + der = torch.empty((n,) + input.shape[1:], dtype=input.dtype) + + j = torch.arange(n, 0, -1) + + der[j - 1] = (j * (input[j]).T).T + + input = der + + input = torch.moveaxis(input, 0, axis) + + return input diff --git a/src/beignet/_divide_chebyshev_polynomial.py b/src/beignet/_divide_chebyshev_polynomial.py new file mode 100644 index 0000000000..ff0dadb0af --- /dev/null +++ b/src/beignet/_divide_chebyshev_polynomial.py @@ -0,0 +1,149 @@ +from typing import Tuple + +import torch +from torch import Tensor + +from ._multiply_chebyshev_polynomial import multiply_chebyshev_polynomial + + +def divide_chebyshev_polynomial( + input: Tensor, + other: Tensor, +) -> Tuple[Tensor, Tensor]: + r""" + Returns the quotient and remainder of two polynomials. + + Parameters + ---------- + input : Tensor + Polynomial coefficients. + + other : Tensor + Polynomial coefficients. + + Returns + ------- + output : Tuple[Tensor, Tensor] + Polynomial coefficients of the quotient and remainder. + """ + input = torch.atleast_1d(input) + other = torch.atleast_1d(other) + + dtype = torch.promote_types(input.dtype, other.dtype) + + input = input.to(dtype) + other = other.to(dtype) + + m = input.shape[0] + n = other.shape[0] + + if m < n: + return torch.zeros_like(input[:1]), input + + if n == 1: + return input / other[-1], torch.zeros_like(input[:1]) + + def f(x: Tensor) -> Tensor: + indicies = torch.flip(x, [0]) + + indicies = torch.nonzero(indicies, as_tuple=False) + + if indicies.shape[0] > 1: + indicies = indicies[:1] + + if indicies.shape[0] < 1: + indicies = torch.concatenate( + [ + indicies, + torch.full( + [ + 1 - indicies.shape[0], + indicies.shape[1], + ], + 0, + ), + ], + 0, + ) + + return x.shape[0] - 1 - indicies[0][0] + + quotient = torch.zeros(m - n + 1, dtype=input.dtype) + + ridx = input.shape[0] - 1 + + size = m - f(other) - 1 + + y = torch.zeros(m + n + 1, dtype=input.dtype) + + y[size] = 1.0 + + x = quotient, input, y, ridx + + for index in range(0, size): + quotient, remainder, y2, ridx1 = x + + j = size - index + + p = multiply_chebyshev_polynomial(y2, other) + + pidx = f(p) + + t = remainder[ridx1] / p[pidx] + + remainder_modified = remainder.clone() + remainder_modified[ridx1] = 0.0 + + a = remainder_modified + + p_modified = p.clone() + p_modified[pidx] = 0.0 + + b = t * p_modified + + a = torch.atleast_1d(a) + b = torch.atleast_1d(b) + + dtype = torch.promote_types(a.dtype, b.dtype) + + a = a.to(dtype) + b = b.to(dtype) + + if a.shape[0] > b.shape[0]: + output = -b + + output = torch.concatenate( + [ + output, + torch.zeros( + a.shape[0] - b.shape[0], + dtype=b.dtype, + ), + ], + ) + output = a + output + else: + output = -b + + output = torch.concatenate( + [ + output[: a.shape[0]] + a, + output[a.shape[0] :], + ], + ) + + remainder = output + + remainder = remainder[: remainder.shape[0]] + + quotient[j] = t + + ridx1 = ridx1 - 1 + + y2 = torch.roll(y2, -1) + + x = quotient, remainder, y2, ridx1 + + quotient, remainder, _, _ = x + + return quotient, remainder diff --git a/src/beignet/_divide_laguerre_polynomial.py b/src/beignet/_divide_laguerre_polynomial.py new file mode 100644 index 0000000000..02b6e6a33e --- /dev/null +++ b/src/beignet/_divide_laguerre_polynomial.py @@ -0,0 +1,149 @@ +from typing import Tuple + +import torch +from torch import Tensor + +from ._multiply_laguerre_polynomial import multiply_laguerre_polynomial + + +def divide_laguerre_polynomial( + input: Tensor, + other: Tensor, +) -> Tuple[Tensor, Tensor]: + r""" + Returns the quotient and remainder of two polynomials. + + Parameters + ---------- + input : Tensor + Polynomial coefficients. + + other : Tensor + Polynomial coefficients. + + Returns + ------- + output : Tuple[Tensor, Tensor] + Polynomial coefficients of the quotient and remainder. + """ + input = torch.atleast_1d(input) + other = torch.atleast_1d(other) + + dtype = torch.promote_types(input.dtype, other.dtype) + + input = input.to(dtype) + other = other.to(dtype) + + m = input.shape[0] + n = other.shape[0] + + if m < n: + return torch.zeros_like(input[:1]), input + + if n == 1: + return input / other[-1], torch.zeros_like(input[:1]) + + def f(x: Tensor) -> Tensor: + indicies = torch.flip(x, [0]) + + indicies = torch.nonzero(indicies, as_tuple=False) + + if indicies.shape[0] > 1: + indicies = indicies[:1] + + if indicies.shape[0] < 1: + indicies = torch.concatenate( + [ + indicies, + torch.full( + [ + 1 - indicies.shape[0], + indicies.shape[1], + ], + 0, + ), + ], + 0, + ) + + return x.shape[0] - 1 - indicies[0][0] + + quotient = torch.zeros(m - n + 1, dtype=input.dtype) + + ridx = input.shape[0] - 1 + + size = m - f(other) - 1 + + y = torch.zeros(m + n + 1, dtype=input.dtype) + + y[size] = 1.0 + + x = quotient, input, y, ridx + + for index in range(0, size): + quotient, remainder, y2, ridx1 = x + + j = size - index + + p = multiply_laguerre_polynomial(y2, other) + + pidx = f(p) + + t = remainder[ridx1] / p[pidx] + + remainder_modified = remainder.clone() + remainder_modified[ridx1] = 0.0 + + a = remainder_modified + + p_modified = p.clone() + p_modified[pidx] = 0.0 + + b = t * p_modified + + a = torch.atleast_1d(a) + b = torch.atleast_1d(b) + + dtype = torch.promote_types(a.dtype, b.dtype) + + a = a.to(dtype) + b = b.to(dtype) + + if a.shape[0] > b.shape[0]: + output = -b + + output = torch.concatenate( + [ + output, + torch.zeros( + a.shape[0] - b.shape[0], + dtype=b.dtype, + ), + ], + ) + output = a + output + else: + output = -b + + output = torch.concatenate( + [ + output[: a.shape[0]] + a, + output[a.shape[0] :], + ], + ) + + remainder = output + + remainder = remainder[: remainder.shape[0]] + + quotient[j] = t + + ridx1 = ridx1 - 1 + + y2 = torch.roll(y2, -1) + + x = quotient, remainder, y2, ridx1 + + quotient, remainder, _, _ = x + + return quotient, remainder diff --git a/src/beignet/_divide_legendre_polynomial.py b/src/beignet/_divide_legendre_polynomial.py new file mode 100644 index 0000000000..b1cdce5a13 --- /dev/null +++ b/src/beignet/_divide_legendre_polynomial.py @@ -0,0 +1,149 @@ +from typing import Tuple + +import torch +from torch import Tensor + +from ._multiply_legendre_polynomial import multiply_legendre_polynomial + + +def divide_legendre_polynomial( + input: Tensor, + other: Tensor, +) -> Tuple[Tensor, Tensor]: + r""" + Returns the quotient and remainder of two polynomials. + + Parameters + ---------- + input : Tensor + Polynomial coefficients. + + other : Tensor + Polynomial coefficients. + + Returns + ------- + output : Tuple[Tensor, Tensor] + Polynomial coefficients of the quotient and remainder. + """ + input = torch.atleast_1d(input) + other = torch.atleast_1d(other) + + dtype = torch.promote_types(input.dtype, other.dtype) + + input = input.to(dtype) + other = other.to(dtype) + + m = input.shape[0] + n = other.shape[0] + + if m < n: + return torch.zeros_like(input[:1]), input + + if n == 1: + return input / other[-1], torch.zeros_like(input[:1]) + + def f(x: Tensor) -> Tensor: + indicies = torch.flip(x, [0]) + + indicies = torch.nonzero(indicies, as_tuple=False) + + if indicies.shape[0] > 1: + indicies = indicies[:1] + + if indicies.shape[0] < 1: + indicies = torch.concatenate( + [ + indicies, + torch.full( + [ + 1 - indicies.shape[0], + indicies.shape[1], + ], + 0, + ), + ], + 0, + ) + + return x.shape[0] - 1 - indicies[0][0] + + quotient = torch.zeros(m - n + 1, dtype=input.dtype) + + ridx = input.shape[0] - 1 + + size = m - f(other) - 1 + + y = torch.zeros(m + n + 1, dtype=input.dtype) + + y[size] = 1.0 + + x = quotient, input, y, ridx + + for index in range(0, size): + quotient, remainder, y2, ridx1 = x + + j = size - index + + p = multiply_legendre_polynomial(y2, other) + + pidx = f(p) + + t = remainder[ridx1] / p[pidx] + + remainder_modified = remainder.clone() + remainder_modified[ridx1] = 0.0 + + a = remainder_modified + + p_modified = p.clone() + p_modified[pidx] = 0.0 + + b = t * p_modified + + a = torch.atleast_1d(a) + b = torch.atleast_1d(b) + + dtype = torch.promote_types(a.dtype, b.dtype) + + a = a.to(dtype) + b = b.to(dtype) + + if a.shape[0] > b.shape[0]: + output = -b + + output = torch.concatenate( + [ + output, + torch.zeros( + a.shape[0] - b.shape[0], + dtype=b.dtype, + ), + ], + ) + output = a + output + else: + output = -b + + output = torch.concatenate( + [ + output[: a.shape[0]] + a, + output[a.shape[0] :], + ], + ) + + remainder = output + + remainder = remainder[: remainder.shape[0]] + + quotient[j] = t + + ridx1 = ridx1 - 1 + + y2 = torch.roll(y2, -1) + + x = quotient, remainder, y2, ridx1 + + quotient, remainder, _, _ = x + + return quotient, remainder diff --git a/src/beignet/_divide_physicists_hermite_polynomial.py b/src/beignet/_divide_physicists_hermite_polynomial.py new file mode 100644 index 0000000000..b0bfba74b4 --- /dev/null +++ b/src/beignet/_divide_physicists_hermite_polynomial.py @@ -0,0 +1,151 @@ +from typing import Tuple + +import torch +from torch import Tensor + +from ._multiply_physicists_hermite_polynomial import ( + multiply_physicists_hermite_polynomial, +) + + +def divide_physicists_hermite_polynomial( + input: Tensor, + other: Tensor, +) -> Tuple[Tensor, Tensor]: + r""" + Returns the quotient and remainder of two polynomials. + + Parameters + ---------- + input : Tensor + Polynomial coefficients. + + other : Tensor + Polynomial coefficients. + + Returns + ------- + output : Tuple[Tensor, Tensor] + Polynomial coefficients of the quotient and remainder. + """ + input = torch.atleast_1d(input) + other = torch.atleast_1d(other) + + dtype = torch.promote_types(input.dtype, other.dtype) + + input = input.to(dtype) + other = other.to(dtype) + + m = input.shape[0] + n = other.shape[0] + + if m < n: + return torch.zeros_like(input[:1]), input + + if n == 1: + return input / other[-1], torch.zeros_like(input[:1]) + + def f(x: Tensor) -> Tensor: + indicies = torch.flip(x, [0]) + + indicies = torch.nonzero(indicies, as_tuple=False) + + if indicies.shape[0] > 1: + indicies = indicies[:1] + + if indicies.shape[0] < 1: + indicies = torch.concatenate( + [ + indicies, + torch.full( + [ + 1 - indicies.shape[0], + indicies.shape[1], + ], + 0, + ), + ], + 0, + ) + + return x.shape[0] - 1 - indicies[0][0] + + quotient = torch.zeros(m - n + 1, dtype=input.dtype) + + ridx = input.shape[0] - 1 + + size = m - f(other) - 1 + + y = torch.zeros(m + n + 1, dtype=input.dtype) + + y[size] = 1.0 + + x = quotient, input, y, ridx + + for index in range(0, size): + quotient, remainder, y2, ridx1 = x + + j = size - index + + p = multiply_physicists_hermite_polynomial(y2, other) + + pidx = f(p) + + t = remainder[ridx1] / p[pidx] + + remainder_modified = remainder.clone() + remainder_modified[ridx1] = 0.0 + + a = remainder_modified + + p_modified = p.clone() + p_modified[pidx] = 0.0 + + b = t * p_modified + + a = torch.atleast_1d(a) + b = torch.atleast_1d(b) + + dtype = torch.promote_types(a.dtype, b.dtype) + + a = a.to(dtype) + b = b.to(dtype) + + if a.shape[0] > b.shape[0]: + output = -b + + output = torch.concatenate( + [ + output, + torch.zeros( + a.shape[0] - b.shape[0], + dtype=b.dtype, + ), + ], + ) + output = a + output + else: + output = -b + + output = torch.concatenate( + [ + output[: a.shape[0]] + a, + output[a.shape[0] :], + ], + ) + + remainder = output + + remainder = remainder[: remainder.shape[0]] + + quotient[j] = t + + ridx1 = ridx1 - 1 + + y2 = torch.roll(y2, -1) + + x = quotient, remainder, y2, ridx1 + + quotient, remainder, _, _ = x + + return quotient, remainder diff --git a/src/beignet/_divide_polynomial.py b/src/beignet/_divide_polynomial.py new file mode 100644 index 0000000000..7f71922bb4 --- /dev/null +++ b/src/beignet/_divide_polynomial.py @@ -0,0 +1,149 @@ +from typing import Tuple + +import torch +from torch import Tensor + +from ._multiply_polynomial import multiply_polynomial + + +def divide_polynomial( + input: Tensor, + other: Tensor, +) -> Tuple[Tensor, Tensor]: + r""" + Returns the quotient and remainder of two polynomials. + + Parameters + ---------- + input : Tensor + Polynomial coefficients. + + other : Tensor + Polynomial coefficients. + + Returns + ------- + output : Tuple[Tensor, Tensor] + Polynomial coefficients of the quotient and remainder. + """ + input = torch.atleast_1d(input) + other = torch.atleast_1d(other) + + dtype = torch.promote_types(input.dtype, other.dtype) + + input = input.to(dtype) + other = other.to(dtype) + + m = input.shape[0] + n = other.shape[0] + + if m < n: + return torch.zeros_like(input[:1]), input + + if n == 1: + return input / other[-1], torch.zeros_like(input[:1]) + + def f(x: Tensor) -> Tensor: + indicies = torch.flip(x, [0]) + + indicies = torch.nonzero(indicies, as_tuple=False) + + if indicies.shape[0] > 1: + indicies = indicies[:1] + + if indicies.shape[0] < 1: + indicies = torch.concatenate( + [ + indicies, + torch.full( + [ + 1 - indicies.shape[0], + indicies.shape[1], + ], + 0, + ), + ], + 0, + ) + + return x.shape[0] - 1 - indicies[0][0] + + quotient = torch.zeros(m - n + 1, dtype=input.dtype) + + ridx = input.shape[0] - 1 + + size = m - f(other) - 1 + + y = torch.zeros(m + n + 1, dtype=input.dtype) + + y[size] = 1.0 + + x = quotient, input, y, ridx + + for index in range(0, size): + quotient, remainder, y2, ridx1 = x + + j = size - index + + p = multiply_polynomial(y2, other) + + pidx = f(p) + + t = remainder[ridx1] / p[pidx] + + remainder_modified = remainder.clone() + remainder_modified[ridx1] = 0.0 + + a = remainder_modified + + p_modified = p.clone() + p_modified[pidx] = 0.0 + + b = t * p_modified + + a = torch.atleast_1d(a) + b = torch.atleast_1d(b) + + dtype = torch.promote_types(a.dtype, b.dtype) + + a = a.to(dtype) + b = b.to(dtype) + + if a.shape[0] > b.shape[0]: + output = -b + + output = torch.concatenate( + [ + output, + torch.zeros( + a.shape[0] - b.shape[0], + dtype=b.dtype, + ), + ], + ) + output = a + output + else: + output = -b + + output = torch.concatenate( + [ + output[: a.shape[0]] + a, + output[a.shape[0] :], + ], + ) + + remainder = output + + remainder = remainder[: remainder.shape[0]] + + quotient[j] = t + + ridx1 = ridx1 - 1 + + y2 = torch.roll(y2, -1) + + x = quotient, remainder, y2, ridx1 + + quotient, remainder, _, _ = x + + return quotient, remainder diff --git a/src/beignet/_divide_probabilists_hermite_polynomial.py b/src/beignet/_divide_probabilists_hermite_polynomial.py new file mode 100644 index 0000000000..701b2f219c --- /dev/null +++ b/src/beignet/_divide_probabilists_hermite_polynomial.py @@ -0,0 +1,151 @@ +from typing import Tuple + +import torch +from torch import Tensor + +from ._multiply_probabilists_hermite_polynomial import ( + multiply_probabilists_hermite_polynomial, +) + + +def divide_probabilists_hermite_polynomial( + input: Tensor, + other: Tensor, +) -> Tuple[Tensor, Tensor]: + r""" + Returns the quotient and remainder of two polynomials. + + Parameters + ---------- + input : Tensor + Polynomial coefficients. + + other : Tensor + Polynomial coefficients. + + Returns + ------- + output : Tuple[Tensor, Tensor] + Polynomial coefficients of the quotient and remainder. + """ + input = torch.atleast_1d(input) + other = torch.atleast_1d(other) + + dtype = torch.promote_types(input.dtype, other.dtype) + + input = input.to(dtype) + other = other.to(dtype) + + m = input.shape[0] + n = other.shape[0] + + if m < n: + return torch.zeros_like(input[:1]), input + + if n == 1: + return input / other[-1], torch.zeros_like(input[:1]) + + def f(x: Tensor) -> Tensor: + indicies = torch.flip(x, [0]) + + indicies = torch.nonzero(indicies, as_tuple=False) + + if indicies.shape[0] > 1: + indicies = indicies[:1] + + if indicies.shape[0] < 1: + indicies = torch.concatenate( + [ + indicies, + torch.full( + [ + 1 - indicies.shape[0], + indicies.shape[1], + ], + 0, + ), + ], + 0, + ) + + return x.shape[0] - 1 - indicies[0][0] + + quotient = torch.zeros(m - n + 1, dtype=input.dtype) + + ridx = input.shape[0] - 1 + + size = m - f(other) - 1 + + y = torch.zeros(m + n + 1, dtype=input.dtype) + + y[size] = 1.0 + + x = quotient, input, y, ridx + + for index in range(0, size): + quotient, remainder, y2, ridx1 = x + + j = size - index + + p = multiply_probabilists_hermite_polynomial(y2, other) + + pidx = f(p) + + t = remainder[ridx1] / p[pidx] + + remainder_modified = remainder.clone() + remainder_modified[ridx1] = 0.0 + + a = remainder_modified + + p_modified = p.clone() + p_modified[pidx] = 0.0 + + b = t * p_modified + + a = torch.atleast_1d(a) + b = torch.atleast_1d(b) + + dtype = torch.promote_types(a.dtype, b.dtype) + + a = a.to(dtype) + b = b.to(dtype) + + if a.shape[0] > b.shape[0]: + output = -b + + output = torch.concatenate( + [ + output, + torch.zeros( + a.shape[0] - b.shape[0], + dtype=b.dtype, + ), + ], + ) + output = a + output + else: + output = -b + + output = torch.concatenate( + [ + output[: a.shape[0]] + a, + output[a.shape[0] :], + ], + ) + + remainder = output + + remainder = remainder[: remainder.shape[0]] + + quotient[j] = t + + ridx1 = ridx1 - 1 + + y2 = torch.roll(y2, -1) + + x = quotient, remainder, y2, ridx1 + + quotient, remainder, _, _ = x + + return quotient, remainder diff --git a/src/beignet/_evaluate_chebyshev_polynomial.py b/src/beignet/_evaluate_chebyshev_polynomial.py new file mode 100644 index 0000000000..623cefda39 --- /dev/null +++ b/src/beignet/_evaluate_chebyshev_polynomial.py @@ -0,0 +1,35 @@ +import torch +from torch import Tensor + + +def evaluate_chebyshev_polynomial( + input: Tensor, + coefficients: Tensor, + tensor: bool = True, +) -> Tensor: + coefficients = torch.atleast_1d(coefficients) + + if tensor: + coefficients = torch.reshape( + coefficients, + coefficients.shape + (1,) * input.ndim, + ) + + match coefficients.shape[0]: + case 1: + a = coefficients[0] + b = 0.0 + case 2: + a = coefficients[0] + b = coefficients[1] + case _: + a = coefficients[-2] * torch.ones_like(input) + b = coefficients[-1] * torch.ones_like(input) + + for i in range(3, coefficients.shape[0] + 1): + previous = a + + a = coefficients[-i] - b + b = previous + b * 2.0 * input + + return a + b * input diff --git a/src/beignet/_evaluate_chebyshev_polynomial_2d.py b/src/beignet/_evaluate_chebyshev_polynomial_2d.py new file mode 100644 index 0000000000..54da45d016 --- /dev/null +++ b/src/beignet/_evaluate_chebyshev_polynomial_2d.py @@ -0,0 +1,36 @@ +from torch import Tensor + +from ._evaluate_chebyshev_polynomial import evaluate_chebyshev_polynomial + + +def evaluate_chebyshev_polynomial_2d( + x: Tensor, + y: Tensor, + coefficients: Tensor, +) -> Tensor: + points = [x, y] + + if not all(a.shape == points[0].shape for a in points[1:]): + match len(points): + case 2: + raise ValueError + case 3: + raise ValueError + case _: + raise ValueError + + points = iter(points) + + output = evaluate_chebyshev_polynomial( + next(points), + coefficients, + ) + + for x in points: + output = evaluate_chebyshev_polynomial( + x, + output, + tensor=False, + ) + + return output diff --git a/src/beignet/_evaluate_chebyshev_polynomial_3d.py b/src/beignet/_evaluate_chebyshev_polynomial_3d.py new file mode 100644 index 0000000000..8048cf482c --- /dev/null +++ b/src/beignet/_evaluate_chebyshev_polynomial_3d.py @@ -0,0 +1,37 @@ +from torch import Tensor + +from ._evaluate_chebyshev_polynomial import evaluate_chebyshev_polynomial + + +def evaluate_chebyshev_polynomial_3d( + x: Tensor, + y: Tensor, + z: Tensor, + coefficients: Tensor, +) -> Tensor: + points = [x, y, z] + + if not all(a.shape == points[0].shape for a in points[1:]): + match len(points): + case 2: + raise ValueError + case 3: + raise ValueError + case _: + raise ValueError + + points = iter(points) + + output = evaluate_chebyshev_polynomial( + next(points), + coefficients, + ) + + for x in points: + output = evaluate_chebyshev_polynomial( + x, + output, + tensor=False, + ) + + return output diff --git a/src/beignet/_evaluate_chebyshev_polynomial_cartesian_2d.py b/src/beignet/_evaluate_chebyshev_polynomial_cartesian_2d.py new file mode 100644 index 0000000000..316fd62a0e --- /dev/null +++ b/src/beignet/_evaluate_chebyshev_polynomial_cartesian_2d.py @@ -0,0 +1,13 @@ +from torch import Tensor + +from ._evaluate_chebyshev_polynomial import evaluate_chebyshev_polynomial + + +def evaluate_chebyshev_polynomial_cartesian_2d( + x: Tensor, + y: Tensor, + c: Tensor, +) -> Tensor: + for arg in [x, y]: + c = evaluate_chebyshev_polynomial(arg, c) + return c diff --git a/src/beignet/_evaluate_chebyshev_polynomial_cartesian_3d.py b/src/beignet/_evaluate_chebyshev_polynomial_cartesian_3d.py new file mode 100644 index 0000000000..8f157441ab --- /dev/null +++ b/src/beignet/_evaluate_chebyshev_polynomial_cartesian_3d.py @@ -0,0 +1,14 @@ +from torch import Tensor + +from ._evaluate_chebyshev_polynomial import evaluate_chebyshev_polynomial + + +def evaluate_chebyshev_polynomial_cartesian_3d( + x: Tensor, + y: Tensor, + z: Tensor, + c: Tensor, +) -> Tensor: + for arg in [x, y, z]: + c = evaluate_chebyshev_polynomial(arg, c) + return c diff --git a/src/beignet/_evaluate_laguerre_polynomial.py b/src/beignet/_evaluate_laguerre_polynomial.py new file mode 100644 index 0000000000..a3f83003c8 --- /dev/null +++ b/src/beignet/_evaluate_laguerre_polynomial.py @@ -0,0 +1,38 @@ +import torch +from torch import Tensor + + +def evaluate_laguerre_polynomial( + input: Tensor, coefficients: Tensor, tensor: bool = True +): + coefficients = torch.atleast_1d(coefficients) + + if tensor: + coefficients = torch.reshape( + coefficients, + coefficients.shape + (1,) * input.ndim, + ) + + match coefficients.shape[0]: + case 1: + a = coefficients[0] + b = 0.0 + case 2: + a = coefficients[0] + b = coefficients[1] + case _: + size = coefficients.shape[0] + + a = coefficients[-2] * torch.ones_like(input) + b = coefficients[-1] * torch.ones_like(input) + + for index in range(3, coefficients.shape[0] + 1): + previous = a + + size = size - 1 + + a = coefficients[-index] - (b * (size - 1.0)) / size + + b = previous + (b * ((2.0 * size - 1.0) - input)) / size + + return a + b * (1.0 - input) diff --git a/src/beignet/_evaluate_laguerre_polynomial_2d.py b/src/beignet/_evaluate_laguerre_polynomial_2d.py new file mode 100644 index 0000000000..6b1f043a2f --- /dev/null +++ b/src/beignet/_evaluate_laguerre_polynomial_2d.py @@ -0,0 +1,36 @@ +from torch import Tensor + +from ._evaluate_laguerre_polynomial import evaluate_laguerre_polynomial + + +def evaluate_laguerre_polynomial_2d( + x: Tensor, + y: Tensor, + coefficients: Tensor, +) -> Tensor: + points = [x, y] + + if not all(a.shape == points[0].shape for a in points[1:]): + match len(points): + case 2: + raise ValueError + case 3: + raise ValueError + case _: + raise ValueError + + points = iter(points) + + output = evaluate_laguerre_polynomial( + next(points), + coefficients, + ) + + for x in points: + output = evaluate_laguerre_polynomial( + x, + output, + tensor=False, + ) + + return output diff --git a/src/beignet/_evaluate_laguerre_polynomial_3d.py b/src/beignet/_evaluate_laguerre_polynomial_3d.py new file mode 100644 index 0000000000..a421e75f7f --- /dev/null +++ b/src/beignet/_evaluate_laguerre_polynomial_3d.py @@ -0,0 +1,37 @@ +from torch import Tensor + +from ._evaluate_laguerre_polynomial import evaluate_laguerre_polynomial + + +def evaluate_laguerre_polynomial_3d( + x: Tensor, + y: Tensor, + z: Tensor, + coefficients: Tensor, +) -> Tensor: + points = [x, y, z] + + if not all(a.shape == points[0].shape for a in points[1:]): + match len(points): + case 2: + raise ValueError + case 3: + raise ValueError + case _: + raise ValueError + + points = iter(points) + + output = evaluate_laguerre_polynomial( + next(points), + coefficients, + ) + + for x in points: + output = evaluate_laguerre_polynomial( + x, + output, + tensor=False, + ) + + return output diff --git a/src/beignet/_evaluate_laguerre_polynomial_cartesian_2d.py b/src/beignet/_evaluate_laguerre_polynomial_cartesian_2d.py new file mode 100644 index 0000000000..e2bac82c7c --- /dev/null +++ b/src/beignet/_evaluate_laguerre_polynomial_cartesian_2d.py @@ -0,0 +1,13 @@ +from torch import Tensor + +from ._evaluate_laguerre_polynomial import evaluate_laguerre_polynomial + + +def evaluate_laguerre_polynomial_cartesian_2d( + x: Tensor, + y: Tensor, + c: Tensor, +) -> Tensor: + for arg in [x, y]: + c = evaluate_laguerre_polynomial(arg, c) + return c diff --git a/src/beignet/_evaluate_laguerre_polynomial_cartesian_3d.py b/src/beignet/_evaluate_laguerre_polynomial_cartesian_3d.py new file mode 100644 index 0000000000..0e04cd2f2e --- /dev/null +++ b/src/beignet/_evaluate_laguerre_polynomial_cartesian_3d.py @@ -0,0 +1,14 @@ +from torch import Tensor + +from ._evaluate_laguerre_polynomial import evaluate_laguerre_polynomial + + +def evaluate_laguerre_polynomial_cartesian_3d( + x: Tensor, + y: Tensor, + z: Tensor, + c: Tensor, +) -> Tensor: + for arg in [x, y, z]: + c = evaluate_laguerre_polynomial(arg, c) + return c diff --git a/src/beignet/_evaluate_legendre_polynomial.py b/src/beignet/_evaluate_legendre_polynomial.py new file mode 100644 index 0000000000..aaf0712755 --- /dev/null +++ b/src/beignet/_evaluate_legendre_polynomial.py @@ -0,0 +1,40 @@ +import torch +from torch import Tensor + + +def evaluate_legendre_polynomial( + input: Tensor, + coefficients: Tensor, + tensor: bool = True, +) -> Tensor: + coefficients = torch.atleast_1d(coefficients) + + if tensor: + coefficients = torch.reshape( + coefficients, + coefficients.shape + (1,) * input.ndim, + ) + + match coefficients.shape[0]: + case 1: + a = coefficients[0] + b = 0.0 + case 2: + a = coefficients[0] + b = coefficients[1] + case _: + size = coefficients.shape[0] + + a = coefficients[-2] * torch.ones_like(input) + b = coefficients[-1] * torch.ones_like(input) + + for index in range(3, coefficients.shape[0] + 1): + previous = a + + size = size - 1 + + a = coefficients[-index] - (b * (size - 1.0)) / size + + b = previous + (b * input * (2.0 * size - 1.0)) / size + + return a + b * input diff --git a/src/beignet/_evaluate_legendre_polynomial_2d.py b/src/beignet/_evaluate_legendre_polynomial_2d.py new file mode 100644 index 0000000000..5e58409fe5 --- /dev/null +++ b/src/beignet/_evaluate_legendre_polynomial_2d.py @@ -0,0 +1,36 @@ +from torch import Tensor + +from ._evaluate_legendre_polynomial import evaluate_legendre_polynomial + + +def evaluate_legendre_polynomial_2d( + x: Tensor, + y: Tensor, + coefficients: Tensor, +) -> Tensor: + points = [x, y] + + if not all(a.shape == points[0].shape for a in points[1:]): + match len(points): + case 2: + raise ValueError + case 3: + raise ValueError + case _: + raise ValueError + + points = iter(points) + + output = evaluate_legendre_polynomial( + next(points), + coefficients, + ) + + for x in points: + output = evaluate_legendre_polynomial( + x, + output, + tensor=False, + ) + + return output diff --git a/src/beignet/_evaluate_legendre_polynomial_3d.py b/src/beignet/_evaluate_legendre_polynomial_3d.py new file mode 100644 index 0000000000..e13c9a503f --- /dev/null +++ b/src/beignet/_evaluate_legendre_polynomial_3d.py @@ -0,0 +1,37 @@ +from torch import Tensor + +from ._evaluate_legendre_polynomial import evaluate_legendre_polynomial + + +def evaluate_legendre_polynomial_3d( + x: Tensor, + y: Tensor, + z: Tensor, + coefficients: Tensor, +) -> Tensor: + points = [x, y, z] + + if not all(a.shape == points[0].shape for a in points[1:]): + match len(points): + case 2: + raise ValueError + case 3: + raise ValueError + case _: + raise ValueError + + points = iter(points) + + output = evaluate_legendre_polynomial( + next(points), + coefficients, + ) + + for x in points: + output = evaluate_legendre_polynomial( + x, + output, + tensor=False, + ) + + return output diff --git a/src/beignet/_evaluate_legendre_polynomial_cartesian_2d.py b/src/beignet/_evaluate_legendre_polynomial_cartesian_2d.py new file mode 100644 index 0000000000..8c493c58e4 --- /dev/null +++ b/src/beignet/_evaluate_legendre_polynomial_cartesian_2d.py @@ -0,0 +1,13 @@ +from torch import Tensor + +from ._evaluate_legendre_polynomial import evaluate_legendre_polynomial + + +def evaluate_legendre_polynomial_cartesian_2d( + x: Tensor, + y: Tensor, + c: Tensor, +) -> Tensor: + for arg in [x, y]: + c = evaluate_legendre_polynomial(arg, c) + return c diff --git a/src/beignet/_evaluate_legendre_polynomial_cartesian_3d.py b/src/beignet/_evaluate_legendre_polynomial_cartesian_3d.py new file mode 100644 index 0000000000..da41d89b78 --- /dev/null +++ b/src/beignet/_evaluate_legendre_polynomial_cartesian_3d.py @@ -0,0 +1,14 @@ +from torch import Tensor + +from ._evaluate_legendre_polynomial import evaluate_legendre_polynomial + + +def evaluate_legendre_polynomial_cartesian_3d( + x: Tensor, + y: Tensor, + z: Tensor, + c: Tensor, +) -> Tensor: + for arg in [x, y, z]: + c = evaluate_legendre_polynomial(arg, c) + return c diff --git a/src/beignet/_evaluate_physicists_hermite_polynomial.py b/src/beignet/_evaluate_physicists_hermite_polynomial.py new file mode 100644 index 0000000000..789149d6ca --- /dev/null +++ b/src/beignet/_evaluate_physicists_hermite_polynomial.py @@ -0,0 +1,40 @@ +import torch +from torch import Tensor + + +def evaluate_physicists_hermite_polynomial( + input: Tensor, + coefficients: Tensor, + tensor: bool = True, +): + coefficients = torch.atleast_1d(coefficients) + + if tensor: + coefficients = torch.reshape( + coefficients, + coefficients.shape + (1,) * input.ndim, + ) + + match coefficients.shape[0]: + case 1: + a = coefficients[0] + b = 0.0 + case 2: + a = coefficients[0] + b = coefficients[1] + case _: + size = coefficients.shape[0] + + a = coefficients[-2] * torch.ones_like(input) + b = coefficients[-1] * torch.ones_like(input) + + for i in range(3, coefficients.shape[0] + 1): + previous = a + + size = size - 1 + + a = coefficients[-i] - b * (2.0 * (size - 1.0)) + + b = previous + b * input * 2.0 + + return a + b * input * 2.0 diff --git a/src/beignet/_evaluate_physicists_hermite_polynomial_2d.py b/src/beignet/_evaluate_physicists_hermite_polynomial_2d.py new file mode 100644 index 0000000000..1af7ff39f1 --- /dev/null +++ b/src/beignet/_evaluate_physicists_hermite_polynomial_2d.py @@ -0,0 +1,38 @@ +from torch import Tensor + +from ._evaluate_physicists_hermite_polynomial import ( + evaluate_physicists_hermite_polynomial, +) + + +def evaluate_physicists_hermite_polynomial_2d( + x: Tensor, + y: Tensor, + coefficients: Tensor, +) -> Tensor: + points = [x, y] + + if not all(a.shape == points[0].shape for a in points[1:]): + match len(points): + case 2: + raise ValueError + case 3: + raise ValueError + case _: + raise ValueError + + points = iter(points) + + output = evaluate_physicists_hermite_polynomial( + next(points), + coefficients, + ) + + for x in points: + output = evaluate_physicists_hermite_polynomial( + x, + output, + tensor=False, + ) + + return output diff --git a/src/beignet/_evaluate_physicists_hermite_polynomial_3d.py b/src/beignet/_evaluate_physicists_hermite_polynomial_3d.py new file mode 100644 index 0000000000..c95179508e --- /dev/null +++ b/src/beignet/_evaluate_physicists_hermite_polynomial_3d.py @@ -0,0 +1,39 @@ +from torch import Tensor + +from ._evaluate_physicists_hermite_polynomial import ( + evaluate_physicists_hermite_polynomial, +) + + +def evaluate_physicists_hermite_polynomial_3d( + x: Tensor, + y: Tensor, + z: Tensor, + coefficients: Tensor, +) -> Tensor: + points = [x, y, z] + + if not all(a.shape == points[0].shape for a in points[1:]): + match len(points): + case 2: + raise ValueError + case 3: + raise ValueError + case _: + raise ValueError + + points = iter(points) + + output = evaluate_physicists_hermite_polynomial( + next(points), + coefficients, + ) + + for x in points: + output = evaluate_physicists_hermite_polynomial( + x, + output, + tensor=False, + ) + + return output diff --git a/src/beignet/_evaluate_physicists_hermite_polynomial_cartesian_2d.py b/src/beignet/_evaluate_physicists_hermite_polynomial_cartesian_2d.py new file mode 100644 index 0000000000..d80cdfab99 --- /dev/null +++ b/src/beignet/_evaluate_physicists_hermite_polynomial_cartesian_2d.py @@ -0,0 +1,19 @@ +from torch import Tensor + +from ._evaluate_physicists_hermite_polynomial import ( + evaluate_physicists_hermite_polynomial, +) + + +def evaluate_physicists_hermite_polynomial_cartesian_2d( + x: Tensor, + y: Tensor, + coefficients: Tensor, +) -> Tensor: + for point in [x, y]: + coefficients = evaluate_physicists_hermite_polynomial( + point, + coefficients, + ) + + return coefficients diff --git a/src/beignet/_evaluate_physicists_hermite_polynomial_cartesian_3d.py b/src/beignet/_evaluate_physicists_hermite_polynomial_cartesian_3d.py new file mode 100644 index 0000000000..f1d86fe042 --- /dev/null +++ b/src/beignet/_evaluate_physicists_hermite_polynomial_cartesian_3d.py @@ -0,0 +1,16 @@ +from torch import Tensor + +from ._evaluate_physicists_hermite_polynomial import ( + evaluate_physicists_hermite_polynomial, +) + + +def evaluate_physicists_hermite_polynomial_cartesian_3d( + x: Tensor, + y: Tensor, + z: Tensor, + c: Tensor, +) -> Tensor: + for arg in [x, y, z]: + c = evaluate_physicists_hermite_polynomial(arg, c) + return c diff --git a/src/beignet/_evaluate_polynomial.py b/src/beignet/_evaluate_polynomial.py new file mode 100644 index 0000000000..7784c6c04b --- /dev/null +++ b/src/beignet/_evaluate_polynomial.py @@ -0,0 +1,34 @@ +import torch +from torch import Tensor + + +def evaluate_polynomial( + input: Tensor, coefficients: Tensor, tensor: bool = True +) -> Tensor: + r""" + Parameters + ---------- + input : Tensor + + coefficients : Tensor + + tensor : bool + + Returns + ------- + output : Tensor + """ + coefficients = torch.atleast_1d(coefficients) + + if tensor: + coefficients = torch.reshape( + coefficients, + coefficients.shape + (1,) * input.ndim, + ) + + output = coefficients[-1] + torch.zeros_like(input) + + for i in range(2, coefficients.shape[0] + 1): + output = coefficients[-i] + output * input + + return output diff --git a/src/beignet/_evaluate_polynomial_2d.py b/src/beignet/_evaluate_polynomial_2d.py new file mode 100644 index 0000000000..cc8887ac08 --- /dev/null +++ b/src/beignet/_evaluate_polynomial_2d.py @@ -0,0 +1,45 @@ +from torch import Tensor + +from ._evaluate_polynomial import evaluate_polynomial + + +def evaluate_polynomial_2d(x: Tensor, y: Tensor, coefficients: Tensor) -> Tensor: + r""" + Parameters + ---------- + x : Tensor + + y : Tensor + + coefficients : Tensor + + Returns + ------- + output : Tensor + """ + points = [x, y] + + if not all(a.shape == points[0].shape for a in points[1:]): + match len(points): + case 2: + raise ValueError + case 3: + raise ValueError + case _: + raise ValueError + + points = iter(points) + + output = evaluate_polynomial( + next(points), + coefficients, + ) + + for x in points: + output = evaluate_polynomial( + x, + output, + tensor=False, + ) + + return output diff --git a/src/beignet/_evaluate_polynomial_3d.py b/src/beignet/_evaluate_polynomial_3d.py new file mode 100644 index 0000000000..913f6e43a8 --- /dev/null +++ b/src/beignet/_evaluate_polynomial_3d.py @@ -0,0 +1,52 @@ +from torch import Tensor + +from ._evaluate_polynomial import evaluate_polynomial + + +def evaluate_polynomial_3d( + x: Tensor, + y: Tensor, + z: Tensor, + coefficients: Tensor, +) -> Tensor: + r""" + Parameters + ---------- + x : Tensor + + y : Tensor + + z : Tensor + + coefficients : Tensor + + Returns + ------- + output : Tensor + """ + points = [x, y, z] + + if not all(a.shape == points[0].shape for a in points[1:]): + match len(points): + case 2: + raise ValueError + case 3: + raise ValueError + case _: + raise ValueError + + points = iter(points) + + output = evaluate_polynomial( + next(points), + coefficients, + ) + + for x in points: + output = evaluate_polynomial( + x, + output, + tensor=False, + ) + + return output diff --git a/src/beignet/_evaluate_polynomial_cartesian_2d.py b/src/beignet/_evaluate_polynomial_cartesian_2d.py new file mode 100644 index 0000000000..f1851d25c6 --- /dev/null +++ b/src/beignet/_evaluate_polynomial_cartesian_2d.py @@ -0,0 +1,25 @@ +from torch import Tensor + +from ._evaluate_polynomial import evaluate_polynomial + + +def evaluate_polynomial_cartesian_2d( + x: Tensor, y: Tensor, coefficients: Tensor +) -> Tensor: + r""" + Parameters + ---------- + x : Tensor + + y : Tensor + + coefficients : Tensor + + Returns + ------- + output : Tensor + """ + for input in [x, y]: + coefficients = evaluate_polynomial(input, coefficients) + + return coefficients diff --git a/src/beignet/_evaluate_polynomial_cartesian_3d.py b/src/beignet/_evaluate_polynomial_cartesian_3d.py new file mode 100644 index 0000000000..f8a29fd515 --- /dev/null +++ b/src/beignet/_evaluate_polynomial_cartesian_3d.py @@ -0,0 +1,30 @@ +from torch import Tensor + +from ._evaluate_polynomial import evaluate_polynomial + + +def evaluate_polynomial_cartesian_3d( + x: Tensor, y: Tensor, z: Tensor, coefficients: Tensor +) -> Tensor: + r""" + Parameters + ---------- + x : Tensor + + y : Tensor + + z : Tensor + + coefficients : Tensor + + Returns + ------- + out : Tensor + """ + for input in [x, y, z]: + coefficients = evaluate_polynomial( + input, + coefficients, + ) + + return coefficients diff --git a/src/beignet/_evaluate_polynomial_from_roots.py b/src/beignet/_evaluate_polynomial_from_roots.py new file mode 100644 index 0000000000..0f7a38ef74 --- /dev/null +++ b/src/beignet/_evaluate_polynomial_from_roots.py @@ -0,0 +1,21 @@ +import torch +from torch import Tensor + + +def evaluate_polynomial_from_roots( + input: Tensor, + other: Tensor, + tensor: bool = True, +) -> Tensor: + if other.ndim == 0: + other = torch.ravel(other) + + if tensor: + other = torch.reshape(other, other.shape + (1,) * input.ndim) + + if input.ndim >= other.ndim: + raise ValueError + + output = torch.prod(input - other, dim=0) + + return output diff --git a/src/beignet/_evaluate_probabilists_hermite_polynomial.py b/src/beignet/_evaluate_probabilists_hermite_polynomial.py new file mode 100644 index 0000000000..b372f21cc9 --- /dev/null +++ b/src/beignet/_evaluate_probabilists_hermite_polynomial.py @@ -0,0 +1,40 @@ +import torch +from torch import Tensor + + +def evaluate_probabilists_hermite_polynomial( + input: Tensor, + coefficients: Tensor, + tensor: bool = True, +): + coefficients = torch.atleast_1d(coefficients) + + if tensor: + coefficients = torch.reshape( + coefficients, + coefficients.shape + (1,) * input.ndim, + ) + + match coefficients.shape[0]: + case 1: + a = coefficients[0] + b = 0.0 + case 2: + a = coefficients[0] + b = coefficients[1] + case _: + size = coefficients.shape[0] + + a = coefficients[-2] * torch.ones_like(input) + b = coefficients[-1] * torch.ones_like(input) + + for i in range(3, coefficients.shape[0] + 1): + previous = a + + size = size - 1 + + a = coefficients[-i] - b * (size - 1.0) + + b = previous + b * input + + return a + b * input diff --git a/src/beignet/_evaluate_probabilists_hermite_polynomial_2d.py b/src/beignet/_evaluate_probabilists_hermite_polynomial_2d.py new file mode 100644 index 0000000000..ba1c9f6cf2 --- /dev/null +++ b/src/beignet/_evaluate_probabilists_hermite_polynomial_2d.py @@ -0,0 +1,38 @@ +from torch import Tensor + +from ._evaluate_probabilists_hermite_polynomial import ( + evaluate_probabilists_hermite_polynomial, +) + + +def evaluate_probabilists_hermite_polynomial_2d( + x: Tensor, + y: Tensor, + coefficients: Tensor, +) -> Tensor: + points = [x, y] + + if not all(a.shape == points[0].shape for a in points[1:]): + match len(points): + case 2: + raise ValueError + case 3: + raise ValueError + case _: + raise ValueError + + points = iter(points) + + output = evaluate_probabilists_hermite_polynomial( + next(points), + coefficients, + ) + + for x in points: + output = evaluate_probabilists_hermite_polynomial( + x, + output, + tensor=False, + ) + + return output diff --git a/src/beignet/_evaluate_probabilists_hermite_polynomial_3d.py b/src/beignet/_evaluate_probabilists_hermite_polynomial_3d.py new file mode 100644 index 0000000000..6041100824 --- /dev/null +++ b/src/beignet/_evaluate_probabilists_hermite_polynomial_3d.py @@ -0,0 +1,39 @@ +from torch import Tensor + +from ._evaluate_probabilists_hermite_polynomial import ( + evaluate_probabilists_hermite_polynomial, +) + + +def evaluate_probabilists_hermite_polynomial_3d( + x: Tensor, + y: Tensor, + z: Tensor, + coefficients: Tensor, +) -> Tensor: + points = [x, y, z] + + if not all(a.shape == points[0].shape for a in points[1:]): + match len(points): + case 2: + raise ValueError + case 3: + raise ValueError + case _: + raise ValueError + + points = iter(points) + + output = evaluate_probabilists_hermite_polynomial( + next(points), + coefficients, + ) + + for x in points: + output = evaluate_probabilists_hermite_polynomial( + x, + output, + tensor=False, + ) + + return output diff --git a/src/beignet/_evaluate_probabilists_hermite_polynomial_cartersian_2d.py b/src/beignet/_evaluate_probabilists_hermite_polynomial_cartersian_2d.py new file mode 100644 index 0000000000..7ae6528ff2 --- /dev/null +++ b/src/beignet/_evaluate_probabilists_hermite_polynomial_cartersian_2d.py @@ -0,0 +1,15 @@ +from torch import Tensor + +from ._evaluate_probabilists_hermite_polynomial import ( + evaluate_probabilists_hermite_polynomial, +) + + +def evaluate_probabilists_hermite_polynomial_cartersian_2d( + x: Tensor, + y: Tensor, + c: Tensor, +) -> Tensor: + for arg in [x, y]: + c = evaluate_probabilists_hermite_polynomial(arg, c) + return c diff --git a/src/beignet/_evaluate_probabilists_hermite_polynomial_cartersian_3d.py b/src/beignet/_evaluate_probabilists_hermite_polynomial_cartersian_3d.py new file mode 100644 index 0000000000..9d3bf8d5a7 --- /dev/null +++ b/src/beignet/_evaluate_probabilists_hermite_polynomial_cartersian_3d.py @@ -0,0 +1,16 @@ +from torch import Tensor + +from ._evaluate_probabilists_hermite_polynomial import ( + evaluate_probabilists_hermite_polynomial, +) + + +def evaluate_probabilists_hermite_polynomial_cartersian_3d( + x: Tensor, + y: Tensor, + z: Tensor, + c: Tensor, +) -> Tensor: + for arg in [x, y, z]: + c = evaluate_probabilists_hermite_polynomial(arg, c) + return c diff --git a/src/beignet/_fit_chebyshev_polynomial.py b/src/beignet/_fit_chebyshev_polynomial.py new file mode 100644 index 0000000000..a2b4b9b625 --- /dev/null +++ b/src/beignet/_fit_chebyshev_polynomial.py @@ -0,0 +1,84 @@ +import math + +import torch +from torch import Tensor + +from ._chebyshev_polynomial_vandermonde import chebyshev_polynomial_vandermonde + + +def fit_chebyshev_polynomial( + input: Tensor, + other: Tensor, + degree: Tensor | int, + relative_condition: float | None = None, + full: bool = False, + weight: Tensor | None = None, +): + func = chebyshev_polynomial_vandermonde + input = torch.tensor(input) + other = torch.tensor(other) + degree = torch.tensor(degree) + if degree.ndim > 1: + raise TypeError + # if deg.dtype.kind not in "iu": + # raise TypeError + if math.prod(degree.shape) == 0: + raise TypeError + if degree.min() < 0: + raise ValueError + if input.ndim != 1: + raise TypeError + if input.size == 0: + raise TypeError + if other.ndim < 1 or other.ndim > 2: + raise TypeError + if len(input) != len(other): + raise TypeError + if degree.ndim == 0: + lmax = int(degree) + van = func(input, lmax) + else: + degree, _ = torch.sort(degree) + lmax = int(degree[-1]) + van = func(input, lmax)[:, degree] + # set up the least squares matrices in transposed form + lhs = van.T + rhs = other.T + if weight is not None: + if weight.ndim != 1: + raise TypeError("expected 1D vector for w") + + if len(input) != len(weight): + raise TypeError("expected x and w to have same length") + + # apply weights. Don't use inplace operations as they + # can cause problems with NA. + lhs = lhs * weight + rhs = rhs * weight + # set rcond + if relative_condition is None: + relative_condition = len(input) * torch.finfo(input.dtype).eps + # Determine the norms of the design matrix columns. + if torch.is_complex(lhs): + scl = torch.sqrt((torch.square(lhs.real) + torch.square(lhs.imag)).sum(1)) + else: + scl = torch.sqrt(torch.square(lhs).sum(1)) + scl = torch.where(scl == 0, 1, scl) + # Solve the least squares problem. + c, resids, rank, s = torch.linalg.lstsq(lhs.T / scl, rhs.T, relative_condition) + c = (c.T / scl).T + # Expand c to include non-fitted coefficients which are set to zero + if degree.ndim > 0: + if c.ndim == 2: + cc = torch.zeros((lmax + 1, c.shape[1]), dtype=c.dtype) + else: + cc = torch.zeros(lmax + 1, dtype=c.dtype) + + cc[degree] = c + + c = cc + if full: + result = c, [resids, rank, s, relative_condition] + else: + result = c + return result diff --git a/src/beignet/_fit_laguerre_polynomial.py b/src/beignet/_fit_laguerre_polynomial.py new file mode 100644 index 0000000000..b87a387309 --- /dev/null +++ b/src/beignet/_fit_laguerre_polynomial.py @@ -0,0 +1,83 @@ +import math + +import torch +from torch import Tensor + +from ._laguerre_polynomial_vandermonde import laguerre_polynomial_vandermonde + + +def fit_laguerre_polynomial( + input: Tensor, + other: Tensor, + degree: Tensor | int, + relative_condition: float | None = None, + full: bool = False, + weight: Tensor | None = None, +): + input = torch.tensor(input) + other = torch.tensor(other) + degree = torch.tensor(degree) + if degree.ndim > 1: + raise TypeError + # if deg.dtype.kind not in "iu": + # raise TypeError + if math.prod(degree.shape) == 0: + raise TypeError + if degree.min() < 0: + raise ValueError + if input.ndim != 1: + raise TypeError + if input.size == 0: + raise TypeError + if other.ndim < 1 or other.ndim > 2: + raise TypeError + if len(input) != len(other): + raise TypeError + if degree.ndim == 0: + lmax = int(degree) + van = laguerre_polynomial_vandermonde(input, lmax) + else: + degree, _ = torch.sort(degree) + lmax = int(degree[-1]) + van = laguerre_polynomial_vandermonde(input, lmax)[:, degree] + # set up the least squares matrices in transposed form + lhs = van.T + rhs = other.T + if weight is not None: + if weight.ndim != 1: + raise TypeError("expected 1D vector for w") + + if len(input) != len(weight): + raise TypeError("expected x and w to have same length") + + # apply weights. Don't use inplace operations as they + # can cause problems with NA. + lhs = lhs * weight + rhs = rhs * weight + # set rcond + if relative_condition is None: + relative_condition = len(input) * torch.finfo(input.dtype).eps + # Determine the norms of the design matrix columns. + if torch.is_complex(lhs): + scl = torch.sqrt((torch.square(lhs.real) + torch.square(lhs.imag)).sum(1)) + else: + scl = torch.sqrt(torch.square(lhs).sum(1)) + scl = torch.where(scl == 0, 1, scl) + # Solve the least squares problem. + c, resids, rank, s = torch.linalg.lstsq(lhs.T / scl, rhs.T, relative_condition) + c = (c.T / scl).T + # Expand c to include non-fitted coefficients which are set to zero + if degree.ndim > 0: + if c.ndim == 2: + cc = torch.zeros((lmax + 1, c.shape[1]), dtype=c.dtype) + else: + cc = torch.zeros(lmax + 1, dtype=c.dtype) + + cc[degree] = c + + c = cc + if full: + result = c, [resids, rank, s, relative_condition] + else: + result = c + return result diff --git a/src/beignet/_fit_legendre_polynomial.py b/src/beignet/_fit_legendre_polynomial.py new file mode 100644 index 0000000000..0a1f8d043a --- /dev/null +++ b/src/beignet/_fit_legendre_polynomial.py @@ -0,0 +1,83 @@ +import math + +import torch +from torch import Tensor + +from ._legendre_polynomial_vandermonde import legendre_polynomial_vandermonde + + +def fit_legendre_polynomial( + input: Tensor, + other: Tensor, + degree: Tensor | int, + relative_condition: float | None = None, + full: bool = False, + weight: Tensor | None = None, +): + input = torch.tensor(input) + other = torch.tensor(other) + degree = torch.tensor(degree) + if degree.ndim > 1: + raise TypeError + # if deg.dtype.kind not in "iu": + # raise TypeError + if math.prod(degree.shape) == 0: + raise TypeError + if degree.min() < 0: + raise ValueError + if input.ndim != 1: + raise TypeError + if input.size == 0: + raise TypeError + if other.ndim < 1 or other.ndim > 2: + raise TypeError + if len(input) != len(other): + raise TypeError + if degree.ndim == 0: + lmax = int(degree) + van = legendre_polynomial_vandermonde(input, lmax) + else: + degree, _ = torch.sort(degree) + lmax = int(degree[-1]) + van = legendre_polynomial_vandermonde(input, lmax)[:, degree] + # set up the least squares matrices in transposed form + lhs = van.T + rhs = other.T + if weight is not None: + if weight.ndim != 1: + raise TypeError("expected 1D vector for w") + + if len(input) != len(weight): + raise TypeError("expected x and w to have same length") + + # apply weights. Don't use inplace operations as they + # can cause problems with NA. + lhs = lhs * weight + rhs = rhs * weight + # set rcond + if relative_condition is None: + relative_condition = len(input) * torch.finfo(input.dtype).eps + # Determine the norms of the design matrix columns. + if torch.is_complex(lhs): + scl = torch.sqrt((torch.square(lhs.real) + torch.square(lhs.imag)).sum(1)) + else: + scl = torch.sqrt(torch.square(lhs).sum(1)) + scl = torch.where(scl == 0, 1, scl) + # Solve the least squares problem. + c, resids, rank, s = torch.linalg.lstsq(lhs.T / scl, rhs.T, relative_condition) + c = (c.T / scl).T + # Expand c to include non-fitted coefficients which are set to zero + if degree.ndim > 0: + if c.ndim == 2: + cc = torch.zeros((lmax + 1, c.shape[1]), dtype=c.dtype) + else: + cc = torch.zeros(lmax + 1, dtype=c.dtype) + + cc[degree] = c + + c = cc + if full: + result = c, [resids, rank, s, relative_condition] + else: + result = c + return result diff --git a/src/beignet/_fit_physicists_hermite_polynomial.py b/src/beignet/_fit_physicists_hermite_polynomial.py new file mode 100644 index 0000000000..7d1014a4ea --- /dev/null +++ b/src/beignet/_fit_physicists_hermite_polynomial.py @@ -0,0 +1,85 @@ +import math + +import torch +from torch import Tensor + +from ._physicists_hermite_polynomial_vandermonde import ( + physicists_hermite_polynomial_vandermonde, +) + + +def fit_physicists_hermite_polynomial( + input: Tensor, + other: Tensor, + degree: Tensor | int, + relative_condition: float | None = None, + full: bool = False, + weight: Tensor | None = None, +): + input = torch.tensor(input) + other = torch.tensor(other) + degree = torch.tensor(degree) + if degree.ndim > 1: + raise TypeError + # if deg.dtype.kind not in "iu": + # raise TypeError + if math.prod(degree.shape) == 0: + raise TypeError + if degree.min() < 0: + raise ValueError + if input.ndim != 1: + raise TypeError + if input.size == 0: + raise TypeError + if other.ndim < 1 or other.ndim > 2: + raise TypeError + if len(input) != len(other): + raise TypeError + if degree.ndim == 0: + lmax = int(degree) + van = physicists_hermite_polynomial_vandermonde(input, lmax) + else: + degree, _ = torch.sort(degree) + lmax = int(degree[-1]) + van = physicists_hermite_polynomial_vandermonde(input, lmax)[:, degree] + # set up the least squares matrices in transposed form + lhs = van.T + rhs = other.T + if weight is not None: + if weight.ndim != 1: + raise TypeError("expected 1D vector for w") + + if len(input) != len(weight): + raise TypeError("expected x and w to have same length") + + # apply weights. Don't use inplace operations as they + # can cause problems with NA. + lhs = lhs * weight + rhs = rhs * weight + # set rcond + if relative_condition is None: + relative_condition = len(input) * torch.finfo(input.dtype).eps + # Determine the norms of the design matrix columns. + if torch.is_complex(lhs): + scl = torch.sqrt((torch.square(lhs.real) + torch.square(lhs.imag)).sum(1)) + else: + scl = torch.sqrt(torch.square(lhs).sum(1)) + scl = torch.where(scl == 0, 1, scl) + # Solve the least squares problem. + c, resids, rank, s = torch.linalg.lstsq(lhs.T / scl, rhs.T, relative_condition) + c = (c.T / scl).T + # Expand c to include non-fitted coefficients which are set to zero + if degree.ndim > 0: + if c.ndim == 2: + cc = torch.zeros((lmax + 1, c.shape[1]), dtype=c.dtype) + else: + cc = torch.zeros(lmax + 1, dtype=c.dtype) + + cc[degree] = c + + c = cc + if full: + result = c, [resids, rank, s, relative_condition] + else: + result = c + return result diff --git a/src/beignet/_fit_polynomial.py b/src/beignet/_fit_polynomial.py new file mode 100644 index 0000000000..2521f2977b --- /dev/null +++ b/src/beignet/_fit_polynomial.py @@ -0,0 +1,109 @@ +import math + +import torch +from torch import Tensor + +from ._polynomial_vandermonde import polynomial_vandermonde + + +def fit_polynomial( + input: Tensor, + other: Tensor, + degree: Tensor | int, + relative_condition: float | None = None, + full: bool = False, + weight: Tensor | None = None, +): + r""" + Parameters + ---------- + input : Tensor + Independent variable. + + other : Tensor + Dependent variable. + + degree : Tensor or int + Degree of the fitting polynomial. + + relative_condition : float, optional + Relative condition number. + + full : bool, default=False + Return additional information. + + weight : Tensor, optional + Weights. + + Returns + ------- + output : Tensor + Polynomial coefficients of the fit. + """ + input = torch.tensor(input) + other = torch.tensor(other) + degree = torch.tensor(degree) + if degree.ndim > 1: + raise TypeError + # if deg.dtype.kind not in "iu": + # raise TypeError + if math.prod(degree.shape) == 0: + raise TypeError + if degree.min() < 0: + raise ValueError + if input.ndim != 1: + raise TypeError + if input.size == 0: + raise TypeError + if other.ndim < 1 or other.ndim > 2: + raise TypeError + if len(input) != len(other): + raise TypeError + if degree.ndim == 0: + lmax = int(degree) + van = polynomial_vandermonde(input, lmax) + else: + degree, _ = torch.sort(degree) + lmax = int(degree[-1]) + van = polynomial_vandermonde(input, lmax)[:, degree] + # set up the least squares matrices in transposed form + lhs = van.T + rhs = other.T + if weight is not None: + if weight.ndim != 1: + raise TypeError("expected 1D vector for w") + + if len(input) != len(weight): + raise TypeError("expected x and w to have same length") + + # apply weights. Don't use inplace operations as they + # can cause problems with NA. + lhs = lhs * weight + rhs = rhs * weight + # set rcond + if relative_condition is None: + relative_condition = len(input) * torch.finfo(input.dtype).eps + # Determine the norms of the design matrix columns. + if torch.is_complex(lhs): + scl = torch.sqrt((torch.square(lhs.real) + torch.square(lhs.imag)).sum(1)) + else: + scl = torch.sqrt(torch.square(lhs).sum(1)) + scl = torch.where(scl == 0, 1, scl) + # Solve the least squares problem. + c, resids, rank, s = torch.linalg.lstsq(lhs.T / scl, rhs.T, relative_condition) + c = (c.T / scl).T + # Expand c to include non-fitted coefficients which are set to zero + if degree.ndim > 0: + if c.ndim == 2: + cc = torch.zeros((lmax + 1, c.shape[1]), dtype=c.dtype) + else: + cc = torch.zeros(lmax + 1, dtype=c.dtype) + + cc[degree] = c + + c = cc + if full: + result = c, [resids, rank, s, relative_condition] + else: + result = c + return result diff --git a/src/beignet/_fit_probabilists_hermite_polynomial.py b/src/beignet/_fit_probabilists_hermite_polynomial.py new file mode 100644 index 0000000000..da26a5536e --- /dev/null +++ b/src/beignet/_fit_probabilists_hermite_polynomial.py @@ -0,0 +1,85 @@ +import math + +import torch +from torch import Tensor + +from ._probabilists_hermite_polynomial_vandermonde import ( + probabilists_hermite_polynomial_vandermonde, +) + + +def fit_probabilists_hermite_polynomial( + input: Tensor, + other: Tensor, + degree: Tensor | int, + relative_condition: float | None = None, + full: bool = False, + weight: Tensor | None = None, +): + input = torch.tensor(input) + other = torch.tensor(other) + degree = torch.tensor(degree) + if degree.ndim > 1: + raise TypeError + # if deg.dtype.kind not in "iu": + # raise TypeError + if math.prod(degree.shape) == 0: + raise TypeError + if degree.min() < 0: + raise ValueError + if input.ndim != 1: + raise TypeError + if input.size == 0: + raise TypeError + if other.ndim < 1 or other.ndim > 2: + raise TypeError + if len(input) != len(other): + raise TypeError + if degree.ndim == 0: + lmax = int(degree) + van = probabilists_hermite_polynomial_vandermonde(input, lmax) + else: + degree, _ = torch.sort(degree) + lmax = int(degree[-1]) + van = probabilists_hermite_polynomial_vandermonde(input, lmax)[:, degree] + # set up the least squares matrices in transposed form + lhs = van.T + rhs = other.T + if weight is not None: + if weight.ndim != 1: + raise TypeError("expected 1D vector for w") + + if len(input) != len(weight): + raise TypeError("expected x and w to have same length") + + # apply weights. Don't use inplace operations as they + # can cause problems with NA. + lhs = lhs * weight + rhs = rhs * weight + # set rcond + if relative_condition is None: + relative_condition = len(input) * torch.finfo(input.dtype).eps + # Determine the norms of the design matrix columns. + if torch.is_complex(lhs): + scl = torch.sqrt((torch.square(lhs.real) + torch.square(lhs.imag)).sum(1)) + else: + scl = torch.sqrt(torch.square(lhs).sum(1)) + scl = torch.where(scl == 0, 1, scl) + # Solve the least squares problem. + c, resids, rank, s = torch.linalg.lstsq(lhs.T / scl, rhs.T, relative_condition) + c = (c.T / scl).T + # Expand c to include non-fitted coefficients which are set to zero + if degree.ndim > 0: + if c.ndim == 2: + cc = torch.zeros((lmax + 1, c.shape[1]), dtype=c.dtype) + else: + cc = torch.zeros(lmax + 1, dtype=c.dtype) + + cc[degree] = c + + c = cc + if full: + result = c, [resids, rank, s, relative_condition] + else: + result = c + return result diff --git a/src/beignet/_gauss_laguerre_quadrature.py b/src/beignet/_gauss_laguerre_quadrature.py new file mode 100644 index 0000000000..eddfdf67fd --- /dev/null +++ b/src/beignet/_gauss_laguerre_quadrature.py @@ -0,0 +1,30 @@ +import torch + +from ._differentiate_laguerre_polynomial import differentiate_laguerre_polynomial +from ._evaluate_laguerre_polynomial import evaluate_laguerre_polynomial +from ._laguerre_polynomial_companion import laguerre_polynomial_companion + + +def gauss_laguerre_quadrature(degree): + degree = int(degree) + if degree <= 0: + raise ValueError + + c = torch.zeros(degree + 1) + c[-1] = 1.0 + + m = laguerre_polynomial_companion(c) + x = torch.linalg.eigvalsh(m) + + dy = evaluate_laguerre_polynomial(x, c) + df = evaluate_laguerre_polynomial(x, differentiate_laguerre_polynomial(c)) + x = x - (dy / df) + + fm = evaluate_laguerre_polynomial(x, c[1:]) + fm = fm / torch.abs(fm).max() + df = df / torch.abs(df).max() + w = 1 / (fm * df) + + w = w / torch.sum(w) + + return x, w diff --git a/src/beignet/_gauss_legendre_quadrature.py b/src/beignet/_gauss_legendre_quadrature.py new file mode 100644 index 0000000000..2f627815ff --- /dev/null +++ b/src/beignet/_gauss_legendre_quadrature.py @@ -0,0 +1,38 @@ +import torch + +from ._differentiate_legendre_polynomial import differentiate_legendre_polynomial +from ._evaluate_legendre_polynomial import evaluate_legendre_polynomial +from ._legendre_polynomial_companion import legendre_polynomial_companion + + +def gauss_legendre_quadrature(degree): + degree = int(degree) + + if degree <= 0: + raise ValueError + + c = torch.zeros(degree + 1) + c[-1] = 1.0 + m = legendre_polynomial_companion(c) + x = torch.linalg.eigvalsh(m) + + dy = evaluate_legendre_polynomial(x, c) + df = evaluate_legendre_polynomial(x, differentiate_legendre_polynomial(c)) + x -= dy / df + + fm = evaluate_legendre_polynomial(x, c[1:]) + + fm /= torch.abs(fm).max() + df /= torch.abs(df).max() + + w = 1 / (fm * df) + + a = torch.flip(w, dims=[0]) + b = torch.flip(x, dims=[0]) + + w = (w + a) / 2 + x = (x - b) / 2 + + w = w * (2.0 / torch.sum(w)) + + return x, w diff --git a/src/beignet/_gauss_physicists_hermite_polynomial_quadrature.py b/src/beignet/_gauss_physicists_hermite_polynomial_quadrature.py new file mode 100644 index 0000000000..c0d0d63b15 --- /dev/null +++ b/src/beignet/_gauss_physicists_hermite_polynomial_quadrature.py @@ -0,0 +1,102 @@ +import math + +import torch + +from ._physicists_hermite_polynomial_companion import ( + physicists_hermite_polynomial_companion, +) + + +def gauss_physicists_hermite_polynomial_quadrature(degree): + degree = int(degree) + if degree <= 0: + raise ValueError + + c = torch.zeros(degree + 1) + c[-1] = 1.0 + + x = torch.linalg.eigvalsh(physicists_hermite_polynomial_companion(c)) + + if degree == 0: + output = torch.full(x.shape, 1 / math.sqrt(math.sqrt(math.pi))) + else: + a1 = torch.zeros_like(x) + + b1 = torch.ones_like(x) / math.sqrt(math.sqrt(math.pi)) + + size = torch.tensor(degree) + + for _ in range(0, degree - 1): + previous = a1 + + a1 = -b1 * torch.sqrt((size - 1.0) / size) + + b1 = previous + b1 * x * torch.sqrt(2.0 / size) + + size = size - 1.0 + + output = a1 + b1 * x * math.sqrt(2.0) + + dy = output + + n = degree - 1 + + if n == 0: + df = torch.full(x.shape, 1 / math.sqrt(math.sqrt(math.pi))) + else: + a = torch.zeros_like(x) + + b = torch.ones_like(x) / math.sqrt(math.sqrt(math.pi)) + + size = torch.tensor(n) + + for _ in range(0, n - 1): + previous = a + + a = -b * torch.sqrt((size - 1.0) / size) + + b = previous + b * x * torch.sqrt(2.0 / size) + + size = size - 1.0 + + df = a + b * x * math.sqrt(2.0) + + df = df * math.sqrt(2 * degree) + + x = x - (dy / df) + + n = degree - 1 + + if n == 0: + fm = torch.full(x.shape, 1 / math.sqrt(math.sqrt(math.pi))) + else: + a = torch.zeros_like(x) + + b = torch.ones_like(x) / math.sqrt(math.sqrt(math.pi)) + + size = torch.tensor(n) + + for _ in range(0, n - 1): + previous = a + + a = -b * torch.sqrt((size - 1.0) / size) + + b = previous + b * x * torch.sqrt(2.0 / size) + + size = size - 1.0 + + fm = a + b * x * math.sqrt(2.0) + + fm = fm / torch.abs(fm).max() + + w = 1 / (fm * fm) + + a = torch.flip(w, dims=[0]) + b = torch.flip(x, dims=[0]) + + w = (w + a) / 2 + x = (x - b) / 2 + + w = w * (math.sqrt(math.pi) / torch.sum(w)) + + return x, w diff --git a/src/beignet/_gauss_probabilists_hermite_polynomial_quadrature.py b/src/beignet/_gauss_probabilists_hermite_polynomial_quadrature.py new file mode 100644 index 0000000000..67a31847d8 --- /dev/null +++ b/src/beignet/_gauss_probabilists_hermite_polynomial_quadrature.py @@ -0,0 +1,98 @@ +import math + +import torch + +from ._probabilists_hermite_polynomial_companion import ( + probabilists_hermite_polynomial_companion, +) + + +def gauss_probabilists_hermite_polynomial_quadrature(degree): + degree = int(degree) + if degree <= 0: + raise ValueError + + c = torch.zeros(degree + 1) + c[-1] = 1.0 + m = probabilists_hermite_polynomial_companion(c) + x = torch.linalg.eigvalsh(m) + + if degree == 0: + dy = torch.full(x.shape, 1.0 / math.sqrt(math.sqrt(2.0 * math.pi))) + else: + a1 = torch.zeros_like(x) + b1 = torch.ones_like(x) / math.sqrt(math.sqrt(2.0 * math.pi)) + + size = torch.tensor(degree) + + for _ in range(0, degree - 1): + previous = a1 + + a1 = -b1 * torch.sqrt((size - 1.0) / size) + + b1 = previous + b1 * x * torch.sqrt(1.0 / size) + + size = size - 1.0 + + dy = a1 + b1 * x + + n = degree - 1 + + if n == 0: + df = torch.full(x.shape, 1 / math.sqrt(math.sqrt(math.pi))) + else: + a = torch.zeros_like(x) + + b = torch.ones_like(x) / math.sqrt(math.sqrt(math.pi)) + + size = torch.tensor(n) + + for _ in range(0, n - 1): + previous = a + + a = -b * torch.sqrt((size - 1.0) / size) + + b = previous + b * x * torch.sqrt(2.0 / size) + + size = size - 1.0 + + df = a + b * x * math.sqrt(2.0) + + df = df * math.sqrt(degree) + + x = x - (dy / df) + + n = degree - 1 + + if n == 0: + fm = torch.full(x.shape, 1.0 / math.sqrt(math.sqrt(2.0 * math.pi))) + else: + a = torch.zeros_like(x) + b = torch.ones_like(x) / math.sqrt(math.sqrt(2.0 * math.pi)) + + size = torch.tensor(n) + + for _ in range(0, n - 1): + previous = a + + a = -b * torch.sqrt((size - 1.0) / size) + + b = previous + b * x * torch.sqrt(1.0 / size) + + size = size - 1.0 + + fm = a + b * x + + fm = fm / torch.abs(fm).max() + + w = 1 / (fm * fm) + + a = torch.flip(w, dims=[0]) + b = torch.flip(x, dims=[0]) + + w = (w + a) / 2 + x = (x - b) / 2 + + w = w * (math.sqrt(2 * math.pi) / torch.sum(w)) + + return x, w diff --git a/src/beignet/_integrate_chebyshev_polynomial.py b/src/beignet/_integrate_chebyshev_polynomial.py new file mode 100644 index 0000000000..2757f5a6a8 --- /dev/null +++ b/src/beignet/_integrate_chebyshev_polynomial.py @@ -0,0 +1,73 @@ +import numpy +import torch +from torch import Tensor + +from ._evaluate_chebyshev_polynomial import evaluate_chebyshev_polynomial + + +def integrate_chebyshev_polynomial( + input: Tensor, + order=1, + k=None, + lower_bound=0, + scale=1, + axis=0, +) -> Tensor: + if k is None: + k = [] + + input = torch.atleast_1d(input) + + lower_bound = torch.tensor(lower_bound) + + scale = torch.tensor(scale) + + if not numpy.iterable(k): + k = [k] + + if len(k) > order: + raise ValueError + + if lower_bound.ndim != 0: + raise ValueError + + if scale.ndim != 0: + raise ValueError + + if order == 0: + return input + + input = torch.moveaxis(input, axis, 0) + + k = torch.tensor([*k] + [0.0] * (order - len(k))) + + k = torch.atleast_1d(k) + + for i in range(order): + n = input.shape[0] + + input = input * scale + + tmp = torch.empty([n + 1, *input.shape[1:]]) + + tmp[0] = input[0] * 0 + tmp[1] = input[0] + + if n > 1: + tmp[2] = input[1] / 4 + + if n < 2: + j = torch.tensor([], dtype=torch.int32) + else: + j = torch.arange(2, n) + + tmp[j + 1] = (input[j].T / (2 * (j + 1))).T + tmp[j - 1] = tmp[j - 1] + -(input[j] / (2 * (j - 1))) + + tmp[0] = tmp[0] + (k[i] - evaluate_chebyshev_polynomial(lower_bound, tmp)) + + input = tmp + + input = torch.moveaxis(input, 0, axis) + + return input diff --git a/src/beignet/_integrate_laguerre_polynomial.py b/src/beignet/_integrate_laguerre_polynomial.py new file mode 100644 index 0000000000..fe653754d7 --- /dev/null +++ b/src/beignet/_integrate_laguerre_polynomial.py @@ -0,0 +1,60 @@ +import numpy +import torch + +from ._evaluate_laguerre_polynomial import evaluate_laguerre_polynomial + + +def integrate_laguerre_polynomial( + input, + order=1, + k=None, + lower_bound=0, + scale=1, + axis=0, +): + if k is None: + k = [] + + input = torch.atleast_1d(input) + + lower_bound, scale = map(torch.tensor, (lower_bound, scale)) + + if not numpy.iterable(k): + k = [k] + if len(k) > order: + raise ValueError + + if lower_bound.ndim != 0: + raise ValueError + + if scale.ndim != 0: + raise ValueError + + if order == 0: + return input + + input = torch.moveaxis(input, axis, 0) + k = torch.tensor(list(k) + [0] * (order - len(k))) + k = torch.atleast_1d(k) + + for i in range(order): + n = input.shape[0] + input *= scale + + tmp = torch.empty((n + 1,) + input.shape[1:], dtype=input.dtype) + + tmp[0] = input[0] + tmp[1] = -input[0] + + j = torch.arange(1, n) + + tmp[j] += input[j] + tmp[j + 1] += -input[j] + + tmp_value = torch.tensor(evaluate_laguerre_polynomial(lower_bound, tmp)) + tmp[0] += k[i] - tmp_value + + input = tmp + + input = torch.moveaxis(input, 0, axis) + return input diff --git a/src/beignet/_integrate_legendre_polynomial.py b/src/beignet/_integrate_legendre_polynomial.py new file mode 100644 index 0000000000..51cc34a518 --- /dev/null +++ b/src/beignet/_integrate_legendre_polynomial.py @@ -0,0 +1,65 @@ +import numpy +import torch + +from ._evaluate_legendre_polynomial import evaluate_legendre_polynomial + + +def integrate_legendre_polynomial( + input, + order=1, + k=None, + lower_bound=0, + scale=1, + axis=0, +): + if k is None: + k = [] + + input = torch.atleast_1d(input) + + lbnd, scl = map(torch.tensor, (lower_bound, scale)) + + if not numpy.iterable(k): + k = [k] + + if len(k) > order: + raise ValueError("Too many integration constants") + + if lbnd.ndim != 0: + raise ValueError("lbnd must be a scalar.") + + if scl.ndim != 0: + raise ValueError("scl must be a scalar.") + + if order == 0: + return input + + output = torch.moveaxis(input, axis, 0) + + k = torch.tensor(list(k) + [0] * (order - len(k))) + k = torch.atleast_1d(k) + + for i in range(order): + n = len(output) + output *= scl + tmp = torch.empty((n + 1,) + output.shape[1:], dtype=output.dtype) + tmp[0] = output[0] * 0 + tmp[1] = output[0] + if n > 1: + tmp[2] = output[1] / 3 + + if n < 2: + j = torch.tensor([], dtype=torch.int32) + else: + j = torch.arange(2, n) + + t = (output[j].T / (2 * j + 1)).T + tmp[j + 1] = t + tmp[j - 1] += -t + legval_value = evaluate_legendre_polynomial(lbnd, tmp) + tmp[0] += k[i] - legval_value + output = tmp + + output = torch.moveaxis(output, 0, axis) + + return output diff --git a/src/beignet/_integrate_physicists_hermite_polynomial.py b/src/beignet/_integrate_physicists_hermite_polynomial.py new file mode 100644 index 0000000000..6e34531a46 --- /dev/null +++ b/src/beignet/_integrate_physicists_hermite_polynomial.py @@ -0,0 +1,63 @@ +import numpy +import torch + +from ._evaluate_physicists_hermite_polynomial import ( + evaluate_physicists_hermite_polynomial, +) + + +def integrate_physicists_hermite_polynomial( + input, + order=1, + k=None, + lower_bound=0, + scale=1, + axis=0, +): + if k is None: + k = [] + + input = torch.atleast_1d(input) + + lower_bound, scale = map(torch.tensor, (lower_bound, scale)) + + if not numpy.iterable(k): + k = [k] + + if len(k) > order: + raise ValueError + + if lower_bound.ndim != 0: + raise ValueError + + if scale.ndim != 0: + raise ValueError + + if order == 0: + return input + + input = torch.moveaxis(input, axis, 0) + + k = torch.tensor(list(k) + [0] * (order - len(k))) + k = torch.atleast_1d(k) + + for i in range(order): + n = input.shape[0] + input *= scale + tmp = torch.empty((n + 1,) + input.shape[1:], dtype=input.dtype) + + tmp[0] = input[0] * 0 + tmp[1] = input[0] / 2 + + j = torch.arange(1, n) + + tmp[j + 1] = (input[j].T / (2 * (j + 1))).T + + tmp_value = evaluate_physicists_hermite_polynomial(lower_bound, tmp) + tmp[0] += k[i] - tmp_value + + input = tmp + + input = torch.moveaxis(input, 0, axis) + + return input diff --git a/src/beignet/_integrate_polynomial.py b/src/beignet/_integrate_polynomial.py new file mode 100644 index 0000000000..f1fe3324b1 --- /dev/null +++ b/src/beignet/_integrate_polynomial.py @@ -0,0 +1,103 @@ +import numpy +import torch +import torch._numpy._funcs_impl +from torch import Tensor + +from ._evaluate_polynomial import evaluate_polynomial + + +def integrate_polynomial( + input: Tensor, + order: int = 1, + k=None, + lower_bound: float = 0, + scale: float = 1, + dim: int = 0, +) -> Tensor: + r""" + Parameters + ---------- + input : Tensor + Polynomial coefficients. + + order : int, default=1 + + k : int, optional + + lower_bound : float, default=0 + + scale : float, default=1 + + dim : int, default=0 + + Returns + ------- + output : Tensor + Polynomial coefficients of the integral. + """ + if k is None: + k = [] + + input = torch.atleast_1d(input) + + lower_bound, scale = map(torch.tensor, (lower_bound, scale)) + + if not numpy.iterable(k): + k = [k] + + if order < 0: + raise ValueError + + if len(k) > order: + raise ValueError + + if lower_bound.ndim != 0: + raise ValueError + + if scale.ndim != 0: + raise ValueError + + if order == 0: + return input + + k = torch.tensor(list(k) + [0] * (order - len(k))) + k = torch.atleast_1d(k) + + n = input.shape[dim] + + padding = torch.tensor([0, order]) + input = torch.moveaxis(input, dim, 0) + if padding[0] < 0: + input = input[torch.abs(padding[0]) :] + + padding = (0, padding[1]) + if padding[1] < 0: + input = input[: -torch.abs(padding[1])] + + padding = (padding[0], 0) + npad = torch.tensor([(0, 0)] * input.ndim) + npad[0] = padding + output = torch._numpy._funcs_impl.pad( + input, + pad_width=npad, + mode="constant", + constant_values=0, + ) + input = torch.moveaxis(output, 0, dim) + + input = torch.moveaxis(input, dim, 0) + + d = torch.arange(n + order) + 1 + + for i in range(0, order): + input = input * scale + + input = (input.T / d).T + + input = torch.roll(input, 1, dims=[0]) + + input[0] = 0.0 + + input[0] += k[i] - evaluate_polynomial(lower_bound, input) + + return torch.moveaxis(input, 0, dim) diff --git a/src/beignet/_integrate_probabilists_hermite_polynomial.py b/src/beignet/_integrate_probabilists_hermite_polynomial.py new file mode 100644 index 0000000000..b3c033251c --- /dev/null +++ b/src/beignet/_integrate_probabilists_hermite_polynomial.py @@ -0,0 +1,63 @@ +import numpy +import torch + +from ._evaluate_probabilists_hermite_polynomial import ( + evaluate_probabilists_hermite_polynomial, +) + + +def integrate_probabilists_hermite_polynomial( + input, + order=1, + k=None, + lower_bound=0, + scale=1, + axis=0, +): + if k is None: + k = [] + + input = torch.atleast_1d(input) + + lower_bound = torch.tensor(lower_bound) + scale = torch.tensor(scale) + + if not numpy.iterable(k): + k = [k] + + if len(k) > order: + raise ValueError + + if lower_bound.ndim != 0: + raise ValueError + + if scale.ndim != 0: + raise ValueError + + if order == 0: + return input + + input = torch.moveaxis(input, axis, 0) + k = torch.tensor(list(k) + [0] * (order - len(k))) + k = torch.atleast_1d(k) + + for i in range(order): + n = input.shape[0] + input *= scale + tmp = torch.empty((n + 1,) + input.shape[1:], dtype=input.dtype) + + tmp[0] = input[0] * 0 + tmp[1] = input[0] + + j = torch.arange(1, n) + + tmp[j + 1] = (input[j].T / (j + 1)).T + + hermeval_value = torch.tensor( + evaluate_probabilists_hermite_polynomial(lower_bound, tmp) + ) + tmp[0] += k[i] - hermeval_value + + input = tmp + + return torch.moveaxis(input, 0, axis) diff --git a/src/beignet/_laguerre_polynomial_companion.py b/src/beignet/_laguerre_polynomial_companion.py new file mode 100644 index 0000000000..88f66b6727 --- /dev/null +++ b/src/beignet/_laguerre_polynomial_companion.py @@ -0,0 +1,28 @@ +import torch +from torch import Tensor + + +def laguerre_polynomial_companion(input: Tensor) -> Tensor: + input = torch.atleast_1d(input) + + if input.shape[0] < 2: + raise ValueError + + if input.shape[0] == 2: + return torch.tensor([[1 + input[0] / input[1]]]) + + n = input.shape[0] - 1 + + output = torch.reshape(torch.zeros([n, n], dtype=input.dtype), [-1]) + + output[1 :: n + 1] = -torch.arange(1, n) + + output[0 :: n + 1] = 2.0 * torch.arange(n) + 1.0 + + output[n :: n + 1] = -torch.arange(1, n) + + output = torch.reshape(output, [n, n]) + + output[:, -1] += (input[:-1] / input[-1]) * n + + return output diff --git a/src/beignet/_laguerre_polynomial_domain.py b/src/beignet/_laguerre_polynomial_domain.py new file mode 100644 index 0000000000..56d97c79d9 --- /dev/null +++ b/src/beignet/_laguerre_polynomial_domain.py @@ -0,0 +1,3 @@ +import torch + +laguerre_polynomial_domain = torch.tensor([0.0, 1.0]) diff --git a/src/beignet/_laguerre_polynomial_from_roots.py b/src/beignet/_laguerre_polynomial_from_roots.py new file mode 100644 index 0000000000..af901242ad --- /dev/null +++ b/src/beignet/_laguerre_polynomial_from_roots.py @@ -0,0 +1,85 @@ +import math + +import torch + +from ._linear_laguerre_polynomial import linear_laguerre_polynomial +from ._multiply_laguerre_polynomial import multiply_laguerre_polynomial + + +def laguerre_polynomial_from_roots(input): + f = linear_laguerre_polynomial + g = multiply_laguerre_polynomial + if math.prod(input.shape) == 0: + return torch.ones([1]) + + input, _ = torch.sort(input) + + ys = [] + + for x in input: + a = torch.zeros(input.shape[0] + 1, dtype=x.dtype) + b = f(-x, 1) + + a = torch.atleast_1d(a) + b = torch.atleast_1d(b) + + dtype = torch.promote_types(a.dtype, b.dtype) + + a = a.to(dtype) + b = b.to(dtype) + + if a.shape[0] > b.shape[0]: + y = torch.concatenate( + [ + b, + torch.zeros( + a.shape[0] - b.shape[0], + dtype=b.dtype, + ), + ], + ) + + y = a + y + else: + y = torch.concatenate( + [ + a, + torch.zeros( + b.shape[0] - a.shape[0], + dtype=a.dtype, + ), + ] + ) + + y = b + y + + ys = [*ys, y] + + p = torch.stack(ys) + + m = p.shape[0] + + x = m, p + + while x[0] > 1: + m, r = divmod(x[0], 2) + + z = x[1] + + previous = torch.zeros([len(p), input.shape[0] + 1]) + + y = previous + + for i in range(0, m): + y[i] = g(z[i], z[i + m])[: input.shape[0] + 1] + + previous = y + + if r: + previous[0] = g(previous[0], z[2 * m])[: input.shape[0] + 1] + + x = m, previous + + _, output = x + + return output[0] diff --git a/src/beignet/_laguerre_polynomial_one.py b/src/beignet/_laguerre_polynomial_one.py new file mode 100644 index 0000000000..81ff015fe7 --- /dev/null +++ b/src/beignet/_laguerre_polynomial_one.py @@ -0,0 +1,3 @@ +import torch + +laguerre_polynomial_one = torch.tensor([1.0]) diff --git a/src/beignet/_laguerre_polynomial_power.py b/src/beignet/_laguerre_polynomial_power.py new file mode 100644 index 0000000000..17c0212545 --- /dev/null +++ b/src/beignet/_laguerre_polynomial_power.py @@ -0,0 +1,61 @@ +import torch +from torch import Tensor + +from ._multiply_laguerre_polynomial import multiply_laguerre_polynomial + + +def laguerre_polynomial_power( + input: Tensor, + exponent: float | Tensor, + maximum_exponent: float | Tensor = 16.0, +) -> Tensor: + input = torch.atleast_1d(input) + _exponent = int(exponent) + if _exponent != exponent or _exponent < 0: + raise ValueError + if maximum_exponent is not None and _exponent > maximum_exponent: + raise ValueError + match _exponent: + case 0: + output = torch.tensor([1], dtype=input.dtype) + case 1: + output = input + case _: + output = torch.zeros(input.shape[0] * exponent, dtype=input.dtype) + + input = torch.atleast_1d(input) + output = torch.atleast_1d(output) + + dtype = torch.promote_types(input.dtype, output.dtype) + + input = input.to(dtype) + output = output.to(dtype) + + if output.shape[0] > input.shape[0]: + input = torch.concatenate( + [ + input, + torch.zeros( + output.shape[0] - input.shape[0], + dtype=input.dtype, + ), + ], + ) + + output = output + input + else: + output = torch.concatenate( + [ + output, + torch.zeros( + input.shape[0] - output.shape[0], + dtype=output.dtype, + ), + ] + ) + + output = input + output + + for _ in range(2, _exponent + 1): + output = multiply_laguerre_polynomial(output, input, mode="same") + return output diff --git a/src/beignet/_laguerre_polynomial_roots.py b/src/beignet/_laguerre_polynomial_roots.py new file mode 100644 index 0000000000..9330db8f1d --- /dev/null +++ b/src/beignet/_laguerre_polynomial_roots.py @@ -0,0 +1,25 @@ +import torch +from torch import Tensor + +from ._laguerre_polynomial_companion import laguerre_polynomial_companion + + +def laguerre_polynomial_roots(input: Tensor) -> Tensor: + input = torch.atleast_1d(input) + + if input.shape[0] <= 1: + return torch.tensor([], dtype=input.dtype) + + if input.shape[0] == 2: + return torch.tensor([1 + input[0] / input[1]]) + + output = laguerre_polynomial_companion(input) + + output = torch.flip(output, dims=[0]) + output = torch.flip(output, dims=[1]) + + output = torch.linalg.eigvals(output) + + output, _ = torch.sort(output.real) + + return output diff --git a/src/beignet/_laguerre_polynomial_to_polynomial.py b/src/beignet/_laguerre_polynomial_to_polynomial.py new file mode 100644 index 0000000000..3160555e63 --- /dev/null +++ b/src/beignet/_laguerre_polynomial_to_polynomial.py @@ -0,0 +1,55 @@ +import torch +from torch import Tensor + +from ._add_polynomial import add_polynomial +from ._multiply_polynomial_by_x import multiply_polynomial_by_x +from ._subtract_polynomial import subtract_polynomial + + +def laguerre_polynomial_to_polynomial(input: Tensor) -> Tensor: + input = torch.atleast_1d(input) + + n = input.shape[0] + + if n == 1: + return input + else: + c0 = torch.zeros_like(input) + c0[0] = input[-2] + + c1 = torch.zeros_like(input) + c1[0] = input[-1] + + def body(k, c0c1): + i = n - 1 - k + + c0, c1 = c0c1 + + tmp = c0 + + c0 = subtract_polynomial(input[i - 2], (c1 * (i - 1)) / i) + + c1 = add_polynomial( + tmp, + subtract_polynomial( + (2 * i - 1) * c1, multiply_polynomial_by_x(c1, "same") + ) + / i, + ) + + return c0, c1 + + b = n - 2 + + x = (c0, c1) + + y = x + + for index in range(0, b): + y = body(index, y) + + c0, c1 = y + + return add_polynomial( + c0, subtract_polynomial(c1, multiply_polynomial_by_x(c1, "same")) + ) diff --git a/src/beignet/_laguerre_polynomial_vandermonde.py b/src/beignet/_laguerre_polynomial_vandermonde.py new file mode 100644 index 0000000000..22e41ae0ed --- /dev/null +++ b/src/beignet/_laguerre_polynomial_vandermonde.py @@ -0,0 +1,30 @@ +import torch +from torch import Tensor + + +def laguerre_polynomial_vandermonde( + x: Tensor, + degree: Tensor, +) -> Tensor: + if degree < 0: + raise ValueError + + x = torch.atleast_1d(x) + + dtype = torch.promote_types(x.dtype, torch.get_default_dtype()) + + x = x.to(dtype) + + v = torch.empty([degree + 1, *x.shape], dtype=dtype) + + v[0] = torch.ones_like(x) + + if degree > 0: + v[1] = 1 - x + + for index in range(2, degree + 1): + v[index] = ( + v[index - 1] * (2 * index - 1 - x) - v[index - 2] * (index - 1) + ) / index + + return torch.moveaxis(v, 0, -1) diff --git a/src/beignet/_laguerre_polynomial_vandermonde_2d.py b/src/beignet/_laguerre_polynomial_vandermonde_2d.py new file mode 100644 index 0000000000..ae2aa5a764 --- /dev/null +++ b/src/beignet/_laguerre_polynomial_vandermonde_2d.py @@ -0,0 +1,49 @@ +import functools +import operator + +import torch +from torch import Tensor + +from ._laguerre_polynomial_vandermonde import laguerre_polynomial_vandermonde + + +def laguerre_polynomial_vandermonde_2d( + x: Tensor, + y: Tensor, + degree: Tensor, +) -> Tensor: + functions = ( + laguerre_polynomial_vandermonde, + laguerre_polynomial_vandermonde, + ) + + n = len(functions) + + if n != len([x, y]): + raise ValueError + + if n != len(degree): + raise ValueError + + if n == 0: + raise ValueError + + matrices = [] + + for i in range(n): + matrix = functions[i]((x, y)[i], degree[i]) + + matrices = [ + *matrices, + matrix[(..., *tuple(slice(None) if j == i else None for j in range(n)))], + ] + + vandermonde = functools.reduce( + operator.mul, + matrices, + ) + + return torch.reshape( + vandermonde, + [*vandermonde.shape[: -len(degree)], -1], + ) diff --git a/src/beignet/_laguerre_polynomial_vandermonde_3d.py b/src/beignet/_laguerre_polynomial_vandermonde_3d.py new file mode 100644 index 0000000000..55517cd62e --- /dev/null +++ b/src/beignet/_laguerre_polynomial_vandermonde_3d.py @@ -0,0 +1,51 @@ +import functools +import operator + +import torch +from torch import Tensor + +from ._laguerre_polynomial_vandermonde import laguerre_polynomial_vandermonde + + +def laguerre_polynomial_vandermonde_3d( + x: Tensor, + y: Tensor, + z: Tensor, + degree: Tensor, +) -> Tensor: + functions = ( + laguerre_polynomial_vandermonde, + laguerre_polynomial_vandermonde, + laguerre_polynomial_vandermonde, + ) + + n = len(functions) + + if n != len([x, y, z]): + raise ValueError + + if n != len(degree): + raise ValueError + + if n == 0: + raise ValueError + + matrices = [] + + for i in range(n): + matrix = functions[i]((x, y, z)[i], degree[i]) + + matrices = [ + *matrices, + matrix[(..., *tuple(slice(None) if j == i else None for j in range(n)))], + ] + + vandermonde = functools.reduce( + operator.mul, + matrices, + ) + + return torch.reshape( + vandermonde, + [*vandermonde.shape[: -len(degree)], -1], + ) diff --git a/src/beignet/_laguerre_polynomial_weight.py b/src/beignet/_laguerre_polynomial_weight.py new file mode 100644 index 0000000000..3322e7d91e --- /dev/null +++ b/src/beignet/_laguerre_polynomial_weight.py @@ -0,0 +1,6 @@ +import torch +from torch import Tensor + + +def laguerre_polynomial_weight(x: Tensor) -> Tensor: + return torch.exp(-x) diff --git a/src/beignet/_laguerre_polynomial_x.py b/src/beignet/_laguerre_polynomial_x.py new file mode 100644 index 0000000000..4ae15b4131 --- /dev/null +++ b/src/beignet/_laguerre_polynomial_x.py @@ -0,0 +1,3 @@ +import torch + +laguerre_polynomial_x = torch.tensor([1.0, -1.0]) diff --git a/src/beignet/_laguerre_polynomial_zero.py b/src/beignet/_laguerre_polynomial_zero.py new file mode 100644 index 0000000000..7235717ff8 --- /dev/null +++ b/src/beignet/_laguerre_polynomial_zero.py @@ -0,0 +1,3 @@ +import torch + +laguerre_polynomial_zero = torch.tensor([0.0]) diff --git a/src/beignet/_legendre_polynomial_companion.py b/src/beignet/_legendre_polynomial_companion.py new file mode 100644 index 0000000000..235905adc9 --- /dev/null +++ b/src/beignet/_legendre_polynomial_companion.py @@ -0,0 +1,32 @@ +import torch +from torch import Tensor + + +def legendre_polynomial_companion(input: Tensor) -> Tensor: + input = torch.atleast_1d(input) + + if input.shape[0] < 2: + raise ValueError + + if input.shape[0] == 2: + return torch.tensor([[-input[0] / input[1]]]) + + n = input.shape[0] - 1 + + output = torch.zeros((n, n), dtype=input.dtype) + + scale = 1.0 / torch.sqrt(2 * torch.arange(n) + 1) + + shape = output.shape + + output = torch.reshape(output, [-1]) + + output[1 :: n + 1] = torch.arange(1, n) * scale[: n - 1] * scale[1:n] + + output[n :: n + 1] = torch.arange(1, n) * scale[: n - 1] * scale[1:n] + + output = torch.reshape(output, shape) + + output[:, -1] += -(input[:-1] / input[-1]) * (scale / scale[-1]) * (n / (2 * n - 1)) + + return output diff --git a/src/beignet/_legendre_polynomial_domain.py b/src/beignet/_legendre_polynomial_domain.py new file mode 100644 index 0000000000..e9a2c3e9e4 --- /dev/null +++ b/src/beignet/_legendre_polynomial_domain.py @@ -0,0 +1,3 @@ +import torch + +legendre_polynomial_domain = torch.tensor([-1.0, 1.0]) diff --git a/src/beignet/_legendre_polynomial_from_roots.py b/src/beignet/_legendre_polynomial_from_roots.py new file mode 100644 index 0000000000..5482ea8414 --- /dev/null +++ b/src/beignet/_legendre_polynomial_from_roots.py @@ -0,0 +1,85 @@ +import math + +import torch + +from ._linear_legendre_polynomial import linear_legendre_polynomial +from ._multiply_legendre_polynomial import multiply_legendre_polynomial + + +def legendre_polynomial_from_roots(input): + f = linear_legendre_polynomial + g = multiply_legendre_polynomial + if math.prod(input.shape) == 0: + return torch.ones([1]) + + input, _ = torch.sort(input) + + ys = [] + + for x in input: + a = torch.zeros(input.shape[0] + 1, dtype=x.dtype) + b = f(-x, 1) + + a = torch.atleast_1d(a) + b = torch.atleast_1d(b) + + dtype = torch.promote_types(a.dtype, b.dtype) + + a = a.to(dtype) + b = b.to(dtype) + + if a.shape[0] > b.shape[0]: + y = torch.concatenate( + [ + b, + torch.zeros( + a.shape[0] - b.shape[0], + dtype=b.dtype, + ), + ], + ) + + y = a + y + else: + y = torch.concatenate( + [ + a, + torch.zeros( + b.shape[0] - a.shape[0], + dtype=a.dtype, + ), + ] + ) + + y = b + y + + ys = [*ys, y] + + p = torch.stack(ys) + + m = p.shape[0] + + x = m, p + + while x[0] > 1: + m, r = divmod(x[0], 2) + + z = x[1] + + previous = torch.zeros([len(p), input.shape[0] + 1]) + + y = previous + + for i in range(0, m): + y[i] = g(z[i], z[i + m])[: input.shape[0] + 1] + + previous = y + + if r: + previous[0] = g(previous[0], z[2 * m])[: input.shape[0] + 1] + + x = m, previous + + _, output = x + + return output[0] diff --git a/src/beignet/_legendre_polynomial_one.py b/src/beignet/_legendre_polynomial_one.py new file mode 100644 index 0000000000..40901adf43 --- /dev/null +++ b/src/beignet/_legendre_polynomial_one.py @@ -0,0 +1,3 @@ +import torch + +legendre_polynomial_one = torch.tensor([1.0]) diff --git a/src/beignet/_legendre_polynomial_power.py b/src/beignet/_legendre_polynomial_power.py new file mode 100644 index 0000000000..f85b7ec4ab --- /dev/null +++ b/src/beignet/_legendre_polynomial_power.py @@ -0,0 +1,61 @@ +import torch +from torch import Tensor + +from ._multiply_legendre_polynomial import multiply_legendre_polynomial + + +def legendre_polynomial_power( + input: Tensor, + exponent: float | Tensor, + maximum_exponent: float | Tensor = 16.0, +) -> Tensor: + input = torch.atleast_1d(input) + _exponent = int(exponent) + if _exponent != exponent or _exponent < 0: + raise ValueError + if maximum_exponent is not None and _exponent > maximum_exponent: + raise ValueError + match _exponent: + case 0: + output = torch.tensor([1], dtype=input.dtype) + case 1: + output = input + case _: + output = torch.zeros(input.shape[0] * exponent, dtype=input.dtype) + + input = torch.atleast_1d(input) + output = torch.atleast_1d(output) + + dtype = torch.promote_types(input.dtype, output.dtype) + + input = input.to(dtype) + output = output.to(dtype) + + if output.shape[0] > input.shape[0]: + input = torch.concatenate( + [ + input, + torch.zeros( + output.shape[0] - input.shape[0], + dtype=input.dtype, + ), + ], + ) + + output = output + input + else: + output = torch.concatenate( + [ + output, + torch.zeros( + input.shape[0] - output.shape[0], + dtype=output.dtype, + ), + ] + ) + + output = input + output + + for _ in range(2, _exponent + 1): + output = multiply_legendre_polynomial(output, input, mode="same") + return output diff --git a/src/beignet/_legendre_polynomial_roots.py b/src/beignet/_legendre_polynomial_roots.py new file mode 100644 index 0000000000..cff5620a2b --- /dev/null +++ b/src/beignet/_legendre_polynomial_roots.py @@ -0,0 +1,25 @@ +import torch +from torch import Tensor + +from ._legendre_polynomial_companion import legendre_polynomial_companion + + +def legendre_polynomial_roots(input: Tensor) -> Tensor: + input = torch.atleast_1d(input) + + if input.shape[0] <= 1: + return torch.tensor([], dtype=input.dtype) + + if input.shape[0] == 2: + return torch.tensor([-input[0] / input[1]]) + + output = legendre_polynomial_companion(input) + + output = torch.flip(output, dims=[0]) + output = torch.flip(output, dims=[1]) + + output = torch.linalg.eigvals(output) + + output, _ = torch.sort(output.real) + + return output diff --git a/src/beignet/_legendre_polynomial_to_polynomial.py b/src/beignet/_legendre_polynomial_to_polynomial.py new file mode 100644 index 0000000000..e54e6e0f77 --- /dev/null +++ b/src/beignet/_legendre_polynomial_to_polynomial.py @@ -0,0 +1,47 @@ +import torch +from torch import Tensor + +from ._add_polynomial import add_polynomial +from ._multiply_polynomial_by_x import multiply_polynomial_by_x +from ._subtract_polynomial import subtract_polynomial + + +def legendre_polynomial_to_polynomial(input: Tensor) -> Tensor: + input = torch.atleast_1d(input) + + n = input.shape[0] + + if n < 3: + return input + + c0 = torch.zeros_like(input) + c0[0] = input[-2] + + c1 = torch.zeros_like(input) + c1[0] = input[-1] + + def body(k, c0c1): + i = n - 1 - k + + c0, c1 = c0c1 + + tmp = c0 + + c0 = subtract_polynomial(input[i - 2], c1 * (i - 1) / i) + + c1 = add_polynomial(tmp, multiply_polynomial_by_x(c1, "same") * (2 * i - 1) / i) + + return c0, c1 + + x = (c0, c1) + + for i in range(0, n - 2): + x = body(i, x) + + c0, c1 = x + + output = multiply_polynomial_by_x(c1, "same") + + output = add_polynomial(c0, output) + + return output diff --git a/src/beignet/_legendre_polynomial_vandermonde.py b/src/beignet/_legendre_polynomial_vandermonde.py new file mode 100644 index 0000000000..e9db5c6f01 --- /dev/null +++ b/src/beignet/_legendre_polynomial_vandermonde.py @@ -0,0 +1,30 @@ +import torch +from torch import Tensor + + +def legendre_polynomial_vandermonde(x: Tensor, degree: Tensor) -> Tensor: + if degree < 0: + raise ValueError + + x = torch.tensor(x) + x = torch.atleast_1d(x) + + dims = (degree + 1,) + x.shape + + dtype = torch.promote_types(x.dtype, torch.tensor(0.0).dtype) + + x = x.to(dtype) + + v = torch.empty(dims, dtype=dtype) + + v[0] = torch.ones_like(x) + + if degree > 0: + v[1] = x + + for index in range(2, degree + 1): + v[index] = ( + v[index - 1] * x * (2 * index - 1) - v[index - 2] * (index - 1) + ) / index + + return torch.moveaxis(v, 0, -1) diff --git a/src/beignet/_legendre_polynomial_vandermonde_2d.py b/src/beignet/_legendre_polynomial_vandermonde_2d.py new file mode 100644 index 0000000000..7b7e06841b --- /dev/null +++ b/src/beignet/_legendre_polynomial_vandermonde_2d.py @@ -0,0 +1,49 @@ +import functools +import operator + +import torch +from torch import Tensor + +from ._legendre_polynomial_vandermonde import legendre_polynomial_vandermonde + + +def legendre_polynomial_vandermonde_2d( + x: Tensor, + y: Tensor, + degree: Tensor, +) -> Tensor: + functions = ( + legendre_polynomial_vandermonde, + legendre_polynomial_vandermonde, + ) + + n = len(functions) + + if n != len([x, y]): + raise ValueError + + if n != len(degree): + raise ValueError + + if n == 0: + raise ValueError + + matrices = [] + + for i in range(n): + matrix = functions[i]((x, y)[i], degree[i]) + + matrices = [ + *matrices, + matrix[(..., *tuple(slice(None) if j == i else None for j in range(n)))], + ] + + vandermonde = functools.reduce( + operator.mul, + matrices, + ) + + return torch.reshape( + vandermonde, + [*vandermonde.shape[: -len(degree)], -1], + ) diff --git a/src/beignet/_legendre_polynomial_vandermonde_3d.py b/src/beignet/_legendre_polynomial_vandermonde_3d.py new file mode 100644 index 0000000000..c1e8a2e694 --- /dev/null +++ b/src/beignet/_legendre_polynomial_vandermonde_3d.py @@ -0,0 +1,51 @@ +import functools +import operator + +import torch +from torch import Tensor + +from ._legendre_polynomial_vandermonde import legendre_polynomial_vandermonde + + +def legendre_polynomial_vandermonde_3d( + x: Tensor, + y: Tensor, + z: Tensor, + degree: Tensor, +) -> Tensor: + functions = ( + legendre_polynomial_vandermonde, + legendre_polynomial_vandermonde, + legendre_polynomial_vandermonde, + ) + + n = len(functions) + + if n != len([x, y, z]): + raise ValueError + + if n != len(degree): + raise ValueError + + if n == 0: + raise ValueError + + matrices = [] + + for i in range(n): + matrix = functions[i]((x, y, z)[i], degree[i]) + + matrices = [ + *matrices, + matrix[(..., *tuple(slice(None) if j == i else None for j in range(n)))], + ] + + vandermonde = functools.reduce( + operator.mul, + matrices, + ) + + return torch.reshape( + vandermonde, + [*vandermonde.shape[: -len(degree)], -1], + ) diff --git a/src/beignet/_legendre_polynomial_weight.py b/src/beignet/_legendre_polynomial_weight.py new file mode 100644 index 0000000000..27a6c7e414 --- /dev/null +++ b/src/beignet/_legendre_polynomial_weight.py @@ -0,0 +1,6 @@ +import torch +from torch import Tensor + + +def legendre_polynomial_weight(x: Tensor) -> Tensor: + return torch.ones_like(x) diff --git a/src/beignet/_legendre_polynomial_x.py b/src/beignet/_legendre_polynomial_x.py new file mode 100644 index 0000000000..909275de9c --- /dev/null +++ b/src/beignet/_legendre_polynomial_x.py @@ -0,0 +1,3 @@ +import torch + +legendre_polynomial_x = torch.tensor([0.0, 1.0]) diff --git a/src/beignet/_legendre_polynomial_zero.py b/src/beignet/_legendre_polynomial_zero.py new file mode 100644 index 0000000000..4c4f45a6f9 --- /dev/null +++ b/src/beignet/_legendre_polynomial_zero.py @@ -0,0 +1,3 @@ +import torch + +legendre_polynomial_zero = torch.tensor([0.0]) diff --git a/src/beignet/_linear_chebyshev_polynomial.py b/src/beignet/_linear_chebyshev_polynomial.py new file mode 100644 index 0000000000..38ead4ad38 --- /dev/null +++ b/src/beignet/_linear_chebyshev_polynomial.py @@ -0,0 +1,6 @@ +import torch +from torch import Tensor + + +def linear_chebyshev_polynomial(input: float, other: float) -> Tensor: + return torch.tensor([input, other]) diff --git a/src/beignet/_linear_laguerre_polynomial.py b/src/beignet/_linear_laguerre_polynomial.py new file mode 100644 index 0000000000..03f321b225 --- /dev/null +++ b/src/beignet/_linear_laguerre_polynomial.py @@ -0,0 +1,6 @@ +import torch +from torch import Tensor + + +def linear_laguerre_polynomial(input: float, other: float) -> Tensor: + return torch.tensor([input + other, -other]) diff --git a/src/beignet/_linear_legendre_polynomial.py b/src/beignet/_linear_legendre_polynomial.py new file mode 100644 index 0000000000..5fa1cbce53 --- /dev/null +++ b/src/beignet/_linear_legendre_polynomial.py @@ -0,0 +1,6 @@ +import torch +from torch import Tensor + + +def linear_legendre_polynomial(input: float, other: float) -> Tensor: + return torch.tensor([input, other]) diff --git a/src/beignet/_linear_physicists_hermite_polynomial.py b/src/beignet/_linear_physicists_hermite_polynomial.py new file mode 100644 index 0000000000..5aae8a5383 --- /dev/null +++ b/src/beignet/_linear_physicists_hermite_polynomial.py @@ -0,0 +1,6 @@ +import torch +from torch import Tensor + + +def linear_physicists_hermite_polynomial(input: float, other: float) -> Tensor: + return torch.tensor([input, other / 2]) diff --git a/src/beignet/_linear_polynomial.py b/src/beignet/_linear_polynomial.py new file mode 100644 index 0000000000..a4545eaffc --- /dev/null +++ b/src/beignet/_linear_polynomial.py @@ -0,0 +1,6 @@ +import torch +from torch import Tensor + + +def linear_polynomial(input: float, other: float) -> Tensor: + return torch.tensor([input, other]) diff --git a/src/beignet/_linear_probabilists_hermite_polynomial.py b/src/beignet/_linear_probabilists_hermite_polynomial.py new file mode 100644 index 0000000000..bc493685f7 --- /dev/null +++ b/src/beignet/_linear_probabilists_hermite_polynomial.py @@ -0,0 +1,6 @@ +import torch +from torch import Tensor + + +def linear_probabilists_hermite_polynomial(input: float, other: float) -> Tensor: + return torch.tensor([input, other]) diff --git a/src/beignet/_multiply_chebyshev_polynomial.py b/src/beignet/_multiply_chebyshev_polynomial.py new file mode 100644 index 0000000000..b29818e543 --- /dev/null +++ b/src/beignet/_multiply_chebyshev_polynomial.py @@ -0,0 +1,60 @@ +import math +from typing import Literal + +import torch +import torchaudio.functional +from torch import Tensor + + +def multiply_chebyshev_polynomial( + input: Tensor, + other: Tensor, + mode: Literal["full", "same", "valid"] = "full", +) -> Tensor: + r""" + Returns the product of two polynomials. + + Parameters + ---------- + input : Tensor + Polynomial coefficients. + + other : Tensor + Polynomial coefficients. + + Returns + ------- + output : Tensor + Polynomial coefficients of the product. + """ + input = torch.atleast_1d(input) + other = torch.atleast_1d(other) + + dtype = torch.promote_types(input.dtype, other.dtype) + + input = input.to(dtype) + other = other.to(dtype) + + index = math.prod(input.shape) + output1 = torch.zeros(2 * index - 1, dtype=input.dtype) + output1[index - 1 :] = input / 2.0 + output1 = torch.flip(output1, dims=[0]) + output1 + a = output1 + + index1 = math.prod(other.shape) + output2 = torch.zeros(2 * index1 - 1, dtype=other.dtype) + output2[index1 - 1 :] = other / 2.0 + output2 = torch.flip(output2, dims=[0]) + output2 + b = output2 + + output = torchaudio.functional.convolve(a, b, mode=mode) + + n = (math.prod(output.shape) + 1) // 2 + c = output[n - 1 :] + c[1:n] = c[1:n] * 2.0 + output = c + + if mode == "same": + output = output[: max(input.shape[0], other.shape[0])] + + return output diff --git a/src/beignet/_multiply_chebyshev_polynomial_by_x.py b/src/beignet/_multiply_chebyshev_polynomial_by_x.py new file mode 100644 index 0000000000..4cabc407f1 --- /dev/null +++ b/src/beignet/_multiply_chebyshev_polynomial_by_x.py @@ -0,0 +1,25 @@ +from typing import Literal + +import torch +from torch import Tensor + + +def multiply_chebyshev_polynomial_by_x( + input: Tensor, + mode: Literal["full", "same", "valid"] = "full", +) -> Tensor: + input = torch.atleast_1d(input) + + output = torch.zeros(input.shape[0] + 1, dtype=input.dtype) + + output[1] = input[0] + + if input.shape[0] > 1: + output[2:] = input[1:] / 2 + + output[0:-2] = output[0:-2] + input[1:] / 2 + + if mode == "same": + output = output[: input.shape[0]] + + return output diff --git a/src/beignet/_multiply_laguerre_polynomial.py b/src/beignet/_multiply_laguerre_polynomial.py new file mode 100644 index 0000000000..6dcc5ce913 --- /dev/null +++ b/src/beignet/_multiply_laguerre_polynomial.py @@ -0,0 +1,82 @@ +from typing import Literal + +import torch +from torch import Tensor + +from ._add_laguerre_polynomial import add_laguerre_polynomial +from ._multiply_laguerre_polynomial_by_x import multiply_laguerre_polynomial_by_x +from ._subtract_laguerre_polynomial import subtract_laguerre_polynomial + + +def multiply_laguerre_polynomial( + input: Tensor, + other: Tensor, + mode: Literal["full", "same", "valid"] = "full", +) -> Tensor: + r""" + Returns the product of two polynomials. + + Parameters + ---------- + input : Tensor + Polynomial coefficients. + + other : Tensor + Polynomial coefficients. + + Returns + ------- + output : Tensor + Polynomial coefficients of the product. + """ + input = torch.atleast_1d(input) + other = torch.atleast_1d(other) + + dtype = torch.promote_types(input.dtype, other.dtype) + + input = input.to(dtype) + other = other.to(dtype) + + m, n = input.shape[0], other.shape[0] + + if m > n: + x, y = other, input + else: + x, y = input, other + + match x.shape[0]: + case 1: + a = add_laguerre_polynomial(torch.zeros(m + n - 1), x[0] * y) + b = torch.zeros(m + n - 1) + case 2: + a = add_laguerre_polynomial(torch.zeros(m + n - 1), x[0] * y) + b = add_laguerre_polynomial(torch.zeros(m + n - 1), x[1] * y) + case _: + size = x.shape[0] + + a = add_laguerre_polynomial(torch.zeros(m + n - 1), x[-2] * y) + b = add_laguerre_polynomial(torch.zeros(m + n - 1), x[-1] * y) + + for i in range(3, x.shape[0] + 1): + previous = a + + size = size - 1 + + a = subtract_laguerre_polynomial(x[-i] * y, (b * (size - 1.0)) / size) + b = add_laguerre_polynomial( + previous, + subtract_laguerre_polynomial( + (2.0 * size - 1.0) * b, + multiply_laguerre_polynomial_by_x(b, "same"), + ) + / size, + ) + + output = add_laguerre_polynomial( + a, subtract_laguerre_polynomial(b, multiply_laguerre_polynomial_by_x(b, "same")) + ) + + if mode == "same": + output = output[: max(m, n)] + + return output diff --git a/src/beignet/_multiply_laguerre_polynomial_by_x.py b/src/beignet/_multiply_laguerre_polynomial_by_x.py new file mode 100644 index 0000000000..07f59457b3 --- /dev/null +++ b/src/beignet/_multiply_laguerre_polynomial_by_x.py @@ -0,0 +1,29 @@ +from typing import Literal + +import torch +from torch import Tensor + + +def multiply_laguerre_polynomial_by_x( + input: Tensor, + mode: Literal["full", "same", "valid"] = "full", +) -> Tensor: + input = torch.atleast_1d(input) + + output = torch.zeros(input.shape[0] + 1, dtype=input.dtype) + + output[0] = +input[0] + output[1] = -input[0] + + i = torch.arange(1, input.shape[0]) + + output[i + 1] = -input[i] * (i + 1) + + output[i] = output[i] + input[i] * (2 * i + 1) + + output[i - 1] = output[i - 1] - input[i] * i + + if mode == "same": + output = output[: input.shape[0]] + + return output diff --git a/src/beignet/_multiply_legendre_polynomial.py b/src/beignet/_multiply_legendre_polynomial.py new file mode 100644 index 0000000000..2b4c121efb --- /dev/null +++ b/src/beignet/_multiply_legendre_polynomial.py @@ -0,0 +1,80 @@ +from typing import Literal + +import torch +from torch import Tensor + +from ._add_legendre_polynomial import add_legendre_polynomial +from ._multiply_legendre_polynomial_by_x import multiply_legendre_polynomial_by_x +from ._subtract_legendre_polynomial import subtract_legendre_polynomial + + +def multiply_legendre_polynomial( + input: Tensor, + other: Tensor, + mode: Literal["full", "same", "valid"] = "full", +) -> Tensor: + r""" + Returns the product of two polynomials. + + Parameters + ---------- + input : Tensor + Polynomial coefficients. + + other : Tensor + Polynomial coefficients. + + Returns + ------- + output : Tensor + Polynomial coefficients of the product. + """ + input = torch.atleast_1d(input) + other = torch.atleast_1d(other) + + dtype = torch.promote_types(input.dtype, other.dtype) + + input = input.to(dtype) + other = other.to(dtype) + + m, n = input.shape[0], other.shape[0] + + if m > n: + x, y = other, input + else: + x, y = input, other + + match x.shape[0]: + case 1: + a = add_legendre_polynomial(torch.zeros(m + n - 1), x[0] * y) + b = torch.zeros(m + n - 1) + case 2: + a = add_legendre_polynomial(torch.zeros(m + n - 1), x[0] * y) + b = add_legendre_polynomial(torch.zeros(m + n - 1), x[1] * y) + case _: + size = x.shape[0] + + a = add_legendre_polynomial(torch.zeros(m + n - 1), x[-2] * y) + b = add_legendre_polynomial(torch.zeros(m + n - 1), x[-1] * y) + + for index in range(3, x.shape[0] + 1): + previous = a + + size = size - 1 + + a = subtract_legendre_polynomial( + x[-index] * y, (b * (size - 1.0)) / size + ) + + b = add_legendre_polynomial( + previous, + (multiply_legendre_polynomial_by_x(b, "same") * (2.0 * size - 1.0)) + / size, + ) + + output = add_legendre_polynomial(a, multiply_legendre_polynomial_by_x(b, "same")) + + if mode == "same": + output = output[: max(m, n)] + + return output diff --git a/src/beignet/_multiply_legendre_polynomial_by_x.py b/src/beignet/_multiply_legendre_polynomial_by_x.py new file mode 100644 index 0000000000..548ac48091 --- /dev/null +++ b/src/beignet/_multiply_legendre_polynomial_by_x.py @@ -0,0 +1,24 @@ +from typing import Literal + +import torch +from torch import Tensor + + +def multiply_legendre_polynomial_by_x( + input: Tensor, mode: Literal["full", "same"] = "full" +) -> Tensor: + input = torch.atleast_1d(input) + + output = torch.zeros(input.shape[0] + 1, dtype=input.dtype) + output[1] = input[0] + + for index in range(1, input.shape[0]): + output[index + 1] = (input[index] * (index + 1)) / (index + index + 1) + output[index - 1] = output[index - 1] + (input[index] * (index + 0)) / ( + index + index + 1 + ) + + if mode == "same": + output = output[: input.shape[0]] + + return output diff --git a/src/beignet/_multiply_physicists_hermite_polynomial.py b/src/beignet/_multiply_physicists_hermite_polynomial.py new file mode 100644 index 0000000000..199c78b735 --- /dev/null +++ b/src/beignet/_multiply_physicists_hermite_polynomial.py @@ -0,0 +1,85 @@ +from typing import Literal + +import torch +from torch import Tensor + +from ._add_physicists_hermite_polynomial import add_physicists_hermite_polynomial +from ._multiply_physicists_hermite_polynomial_by_x import ( + multiply_physicists_hermite_polynomial_by_x, +) +from ._subtract_physicists_hermite_polynomial import ( + subtract_physicists_hermite_polynomial, +) + + +def multiply_physicists_hermite_polynomial( + input: Tensor, + other: Tensor, + mode: Literal["full", "same", "valid"] = "full", +) -> Tensor: + r""" + Returns the product of two polynomials. + + Parameters + ---------- + input : Tensor + Polynomial coefficients. + + other : Tensor + Polynomial coefficients. + + Returns + ------- + output : Tensor + Polynomial coefficients of the product. + """ + input = torch.atleast_1d(input) + other = torch.atleast_1d(other) + + dtype = torch.promote_types(input.dtype, other.dtype) + + input = input.to(dtype) + other = other.to(dtype) + + m, n = input.shape[0], other.shape[0] + + if m > n: + x, y = other, input + else: + x, y = input, other + + match x.shape[0]: + case 1: + a = add_physicists_hermite_polynomial(torch.zeros(m + n - 1), x[0] * y) + b = torch.zeros(m + n - 1) + case 2: + a = add_physicists_hermite_polynomial(torch.zeros(m + n - 1), x[0] * y) + b = add_physicists_hermite_polynomial(torch.zeros(m + n - 1), x[1] * y) + case _: + size = x.shape[0] + + a = add_physicists_hermite_polynomial(torch.zeros(m + n - 1), x[-2] * y) + b = add_physicists_hermite_polynomial(torch.zeros(m + n - 1), x[-1] * y) + + for i in range(3, x.shape[0] + 1): + previous = a + + size = size - 1 + + a = subtract_physicists_hermite_polynomial( + x[-i] * y, b * (2 * (size - 1.0)) + ) + + b = add_physicists_hermite_polynomial( + previous, + multiply_physicists_hermite_polynomial_by_x(b, "same") * 2.0, + ) + + output = add_physicists_hermite_polynomial( + a, multiply_physicists_hermite_polynomial_by_x(b, "same") * 2 + ) + + if mode == "same": + output = output[: max(m, n)] + + return output diff --git a/src/beignet/_multiply_physicists_hermite_polynomial_by_x.py b/src/beignet/_multiply_physicists_hermite_polynomial_by_x.py new file mode 100644 index 0000000000..d390cdce94 --- /dev/null +++ b/src/beignet/_multiply_physicists_hermite_polynomial_by_x.py @@ -0,0 +1,25 @@ +from typing import Literal + +import torch +from torch import Tensor + + +def multiply_physicists_hermite_polynomial_by_x( + input: Tensor, + mode: Literal["full", "same", "valid"] = "full", +) -> Tensor: + input = torch.atleast_1d(input) + + output = torch.zeros(input.shape[0] + 1, dtype=input.dtype) + + output[1] = input[0] / 2.0 + + i = torch.arange(1, input.shape[0]) + + output[i + 1] = input[i] / 2.0 + output[i - 1] = output[i - 1] + input[i] * i + + if mode == "same": + output = output[: input.shape[0]] + + return output diff --git a/src/beignet/_multiply_polynomial.py b/src/beignet/_multiply_polynomial.py new file mode 100644 index 0000000000..5159c9b1fb --- /dev/null +++ b/src/beignet/_multiply_polynomial.py @@ -0,0 +1,42 @@ +from typing import Literal + +import torch +import torchaudio.functional +from torch import Tensor + + +def multiply_polynomial( + input: Tensor, + other: Tensor, + mode: Literal["full", "same", "valid"] = "full", +) -> Tensor: + r""" + Returns the product of two polynomials. + + Parameters + ---------- + input : Tensor + Polynomial coefficients. + + other : Tensor + Polynomial coefficients. + + Returns + ------- + output : Tensor + Polynomial coefficients of the product. + """ + input = torch.atleast_1d(input) + other = torch.atleast_1d(other) + + dtype = torch.promote_types(input.dtype, other.dtype) + + input = input.to(dtype) + other = other.to(dtype) + + output = torchaudio.functional.convolve(input, other) + + if mode == "same": + output = output[: max(input.shape[0], other.shape[0])] + + return output diff --git a/src/beignet/_multiply_polynomial_by_x.py b/src/beignet/_multiply_polynomial_by_x.py new file mode 100644 index 0000000000..705b00f2b4 --- /dev/null +++ b/src/beignet/_multiply_polynomial_by_x.py @@ -0,0 +1,34 @@ +from typing import Literal + +import torch +from torch import Tensor + + +def multiply_polynomial_by_x( + input: Tensor, + mode: Literal["full", "same", "valid"] = "full", +) -> Tensor: + r""" + Parameters + ---------- + input : Tensor + Polynomial coefficients. + + mode : Literal["full", "same", "valid"] + + Returns + ------- + output : Tensor + Polynomial coefficients of the product of the polynomial and the + independent variable. + """ + input = torch.atleast_1d(input) + + output = torch.zeros(input.shape[0] + 1, dtype=input.dtype) + + output[1:] = input + + if mode == "same": + output = output[: input.shape[0]] + + return output diff --git a/src/beignet/_multiply_probabilists_hermite_polynomial.py b/src/beignet/_multiply_probabilists_hermite_polynomial.py new file mode 100644 index 0000000000..268f88595c --- /dev/null +++ b/src/beignet/_multiply_probabilists_hermite_polynomial.py @@ -0,0 +1,84 @@ +from typing import Literal + +import torch +from torch import Tensor + +from ._add_probabilists_hermite_polynomial import add_probabilists_hermite_polynomial +from ._multiply_probabilists_hermite_polynomial_by_x import ( + multiply_probabilists_hermite_polynomial_by_x, +) +from ._subtract_probabilists_hermite_polynomial import ( + subtract_probabilists_hermite_polynomial, +) + + +def multiply_probabilists_hermite_polynomial( + input: Tensor, + other: Tensor, + mode: Literal["full", "same", "valid"] = "full", +) -> Tensor: + r""" + Returns the product of two polynomials. + + Parameters + ---------- + input : Tensor + Polynomial coefficients. + + other : Tensor + Polynomial coefficients. + + Returns + ------- + output : Tensor + Polynomial coefficients of the product. + """ + input = torch.atleast_1d(input) + other = torch.atleast_1d(other) + + dtype = torch.promote_types(input.dtype, other.dtype) + + input = input.to(dtype) + other = other.to(dtype) + + m, n = input.shape[0], other.shape[0] + + if m > n: + x, y = other, input + else: + x, y = input, other + + match x.shape[0]: + case 1: + a = add_probabilists_hermite_polynomial(torch.zeros(m + n - 1), x[0] * y) + b = torch.zeros(m + n - 1) + case 2: + a = add_probabilists_hermite_polynomial(torch.zeros(m + n - 1), x[0] * y) + b = add_probabilists_hermite_polynomial(torch.zeros(m + n - 1), x[1] * y) + case _: + size = x.shape[0] + + a = add_probabilists_hermite_polynomial(torch.zeros(m + n - 1), x[-2] * y) + b = add_probabilists_hermite_polynomial(torch.zeros(m + n - 1), x[-1] * y) + + for i in range(3, x.shape[0] + 1): + previous = a + + size = size - 1 + + a = subtract_probabilists_hermite_polynomial( + x[-i] * y, b * (size - 1.0) + ) + + b = add_probabilists_hermite_polynomial( + previous, multiply_probabilists_hermite_polynomial_by_x(b, "same") + ) + + output = add_probabilists_hermite_polynomial( + a, multiply_probabilists_hermite_polynomial_by_x(b, "same") + ) + + if mode == "same": + output = output[: max(m, n)] + + return output diff --git a/src/beignet/_multiply_probabilists_hermite_polynomial_by_x.py b/src/beignet/_multiply_probabilists_hermite_polynomial_by_x.py new file mode 100644 index 0000000000..17962b3d27 --- /dev/null +++ b/src/beignet/_multiply_probabilists_hermite_polynomial_by_x.py @@ -0,0 +1,25 @@ +from typing import Literal + +import torch +from torch import Tensor + + +def multiply_probabilists_hermite_polynomial_by_x( + input: Tensor, + mode: Literal["full", "same", "valid"] = "full", +) -> Tensor: + input = torch.atleast_1d(input) + + output = torch.zeros(input.shape[0] + 1, dtype=input.dtype) + + output[1] = input[0] + + index = torch.arange(1, input.shape[0]) + + output[index + 1] = input[index] + output[index - 1] = output[index - 1] + input[index] * index + + if mode == "same": + output = output[: input.shape[0]] + + return output diff --git a/src/beignet/_physicists_hermite_polynomial_companion.py b/src/beignet/_physicists_hermite_polynomial_companion.py new file mode 100644 index 0000000000..a730dd6f2d --- /dev/null +++ b/src/beignet/_physicists_hermite_polynomial_companion.py @@ -0,0 +1,40 @@ +import torch +from torch import Tensor + + +def physicists_hermite_polynomial_companion(input: Tensor) -> Tensor: + input = torch.atleast_1d(input) + + if input.shape[0] < 2: + raise ValueError + + if input.shape[0] == 2: + return torch.tensor([[-0.5 * input[0] / input[1]]]) + + n = input.shape[0] - 1 + + output = torch.zeros((n, n), dtype=input.dtype) + + scale = torch.hstack( + [ + torch.tensor([1.0]), + 1.0 / torch.sqrt(2.0 * torch.arange(n - 1, 0, -1)), + ], + ) + + scale = torch.cumprod(scale, dim=0) + + scale = torch.flip(scale, dims=[0]) + + shp = output.shape + + output = torch.reshape(output, [-1]) + + output[1 :: n + 1] = torch.sqrt(0.5 * torch.arange(1, n)) + output[n :: n + 1] = torch.sqrt(0.5 * torch.arange(1, n)) + + output = torch.reshape(output, shp) + + output[:, -1] += -scale * input[:-1] / (2.0 * input[-1]) + + return output diff --git a/src/beignet/_physicists_hermite_polynomial_domain.py b/src/beignet/_physicists_hermite_polynomial_domain.py new file mode 100644 index 0000000000..5590fb9f77 --- /dev/null +++ b/src/beignet/_physicists_hermite_polynomial_domain.py @@ -0,0 +1,3 @@ +import torch + +physicists_hermite_polynomial_domain = torch.tensor([-1.0, 1.0]) diff --git a/src/beignet/_physicists_hermite_polynomial_from_roots.py b/src/beignet/_physicists_hermite_polynomial_from_roots.py new file mode 100644 index 0000000000..175f34f11f --- /dev/null +++ b/src/beignet/_physicists_hermite_polynomial_from_roots.py @@ -0,0 +1,87 @@ +import math + +import torch + +from ._linear_physicists_hermite_polynomial import linear_physicists_hermite_polynomial +from ._multiply_physicists_hermite_polynomial import ( + multiply_physicists_hermite_polynomial, +) + + +def physicists_hermite_polynomial_from_roots(input): + f = linear_physicists_hermite_polynomial + g = multiply_physicists_hermite_polynomial + if math.prod(input.shape) == 0: + return torch.ones([1]) + + input, _ = torch.sort(input) + + ys = [] + + for x in input: + a = torch.zeros(input.shape[0] + 1, dtype=x.dtype) + b = f(-x, 1) + + a = torch.atleast_1d(a) + b = torch.atleast_1d(b) + + dtype = torch.promote_types(a.dtype, b.dtype) + + a = a.to(dtype) + b = b.to(dtype) + + if a.shape[0] > b.shape[0]: + y = torch.concatenate( + [ + b, + torch.zeros( + a.shape[0] - b.shape[0], + dtype=b.dtype, + ), + ], + ) + + y = a + y + else: + y = torch.concatenate( + [ + a, + torch.zeros( + b.shape[0] - a.shape[0], + dtype=a.dtype, + ), + ] + ) + + y = b + y + + ys = [*ys, y] + + p = torch.stack(ys) + + m = p.shape[0] + + x = m, p + + while x[0] > 1: + m, r = divmod(x[0], 2) + + z = x[1] + + previous = torch.zeros([len(p), input.shape[0] + 1]) + + y = previous + + for i in range(0, m): + y[i] = g(z[i], z[i + m])[: input.shape[0] + 1] + + previous = y + + if r: + previous[0] = g(previous[0], z[2 * m])[: input.shape[0] + 1] + + x = m, previous + + _, output = x + + return output[0] diff --git a/src/beignet/_physicists_hermite_polynomial_one.py b/src/beignet/_physicists_hermite_polynomial_one.py new file mode 100644 index 0000000000..b760195d66 --- /dev/null +++ b/src/beignet/_physicists_hermite_polynomial_one.py @@ -0,0 +1,3 @@ +import torch + +physicists_hermite_polynomial_one = torch.tensor([1.0]) diff --git a/src/beignet/_physicists_hermite_polynomial_power.py b/src/beignet/_physicists_hermite_polynomial_power.py new file mode 100644 index 0000000000..d92f21ea24 --- /dev/null +++ b/src/beignet/_physicists_hermite_polynomial_power.py @@ -0,0 +1,65 @@ +import torch +from torch import Tensor + +from ._multiply_physicists_hermite_polynomial import ( + multiply_physicists_hermite_polynomial, +) + + +def physicists_hermite_polynomial_power( + input: Tensor, + exponent: float | Tensor, + maximum_exponent: float | Tensor = 16.0, +) -> Tensor: + input = torch.atleast_1d(input) + _exponent = int(exponent) + if _exponent != exponent or _exponent < 0: + raise ValueError + if maximum_exponent is not None and _exponent > maximum_exponent: + raise ValueError + match _exponent: + case 0: + output = torch.tensor([1], dtype=input.dtype) + case 1: + output = input + case _: + output = torch.zeros(input.shape[0] * exponent, dtype=input.dtype) + + input = torch.atleast_1d(input) + output = torch.atleast_1d(output) + + dtype = torch.promote_types(input.dtype, output.dtype) + + input = input.to(dtype) + output = output.to(dtype) + + if output.shape[0] > input.shape[0]: + input = torch.concatenate( + [ + input, + torch.zeros( + output.shape[0] - input.shape[0], + dtype=input.dtype, + ), + ], + ) + + output = output + input + else: + output = torch.concatenate( + [ + output, + torch.zeros( + input.shape[0] - output.shape[0], + dtype=output.dtype, + ), + ] + ) + + output = input + output + + for _ in range(2, _exponent + 1): + output = multiply_physicists_hermite_polynomial( + output, input, mode="same" + ) + return output diff --git a/src/beignet/_physicists_hermite_polynomial_roots.py b/src/beignet/_physicists_hermite_polynomial_roots.py new file mode 100644 index 0000000000..4cd94d51f9 --- /dev/null +++ b/src/beignet/_physicists_hermite_polynomial_roots.py @@ -0,0 +1,27 @@ +import torch +from torch import Tensor + +from ._physicists_hermite_polynomial_companion import ( + physicists_hermite_polynomial_companion, +) + + +def physicists_hermite_polynomial_roots(input: Tensor) -> Tensor: + input = torch.atleast_1d(input) + + if input.shape[0] <= 1: + return torch.tensor([], dtype=input.dtype) + + if input.shape[0] == 2: + return torch.tensor([-0.5 * input[0] / input[1]]) + + output = physicists_hermite_polynomial_companion(input) + + output = torch.flip(output, dims=[0]) + output = torch.flip(output, dims=[1]) + + output = torch.linalg.eigvals(output) + + output, _ = torch.sort(output.real) + + return output diff --git a/src/beignet/_physicists_hermite_polynomial_to_polynomial.py b/src/beignet/_physicists_hermite_polynomial_to_polynomial.py new file mode 100644 index 0000000000..179d7084ca --- /dev/null +++ b/src/beignet/_physicists_hermite_polynomial_to_polynomial.py @@ -0,0 +1,45 @@ +import torch +from torch import Tensor + +from ._add_polynomial import add_polynomial +from ._multiply_polynomial_by_x import multiply_polynomial_by_x +from ._subtract_polynomial import subtract_polynomial + + +def physicists_hermite_polynomial_to_polynomial(input: Tensor) -> Tensor: + input = torch.atleast_1d(input) + + n = input.shape[0] + + if n == 1: + return input + + if n == 2: + input[1] = input[1] * 2 + + return input + else: + c0 = torch.zeros_like(input) + c0[0] = input[-2] + + c1 = torch.zeros_like(input) + c1[0] = input[-1] + + def body(k, c0c1): + i = n - 1 - k + c0, c1 = c0c1 + tmp = c0 + c0 = subtract_polynomial(input[i - 2], c1 * (2 * (i - 1))) + c1 = add_polynomial(tmp, multiply_polynomial_by_x(c1, "same") * 2) + return c0, c1 + + x = (c0, c1) + + y = x + + for index in range(0, n - 2): + y = body(index, y) + + c0, c1 = y + + return add_polynomial(c0, multiply_polynomial_by_x(c1, "same") * 2) diff --git a/src/beignet/_physicists_hermite_polynomial_vandermonde.py b/src/beignet/_physicists_hermite_polynomial_vandermonde.py new file mode 100644 index 0000000000..e5bbf91430 --- /dev/null +++ b/src/beignet/_physicists_hermite_polynomial_vandermonde.py @@ -0,0 +1,25 @@ +import torch +from torch import Tensor + + +def physicists_hermite_polynomial_vandermonde( + x: Tensor, + degree: Tensor, +) -> Tensor: + if degree < 0: + raise ValueError + + x = torch.atleast_1d(x) + dims = (degree + 1,) + x.shape + dtyp = torch.promote_types(x.dtype, torch.tensor(0.0).dtype) + x = x.to(dtyp) + v = torch.empty(dims, dtype=dtyp) + v[0] = torch.ones_like(x) + + if degree > 0: + v[1] = x * 2 + + for index in range(2, degree + 1): + v[index] = v[index - 1] * x * 2 - v[index - 2] * (2 * (index - 1)) + + return torch.moveaxis(v, 0, -1) diff --git a/src/beignet/_physicists_hermite_polynomial_vandermonde_2d.py b/src/beignet/_physicists_hermite_polynomial_vandermonde_2d.py new file mode 100644 index 0000000000..80879afe28 --- /dev/null +++ b/src/beignet/_physicists_hermite_polynomial_vandermonde_2d.py @@ -0,0 +1,51 @@ +import functools +import operator + +import torch +from torch import Tensor + +from ._physicists_hermite_polynomial_vandermonde import ( + physicists_hermite_polynomial_vandermonde, +) + + +def physicists_hermite_polynomial_vandermonde_2d( + x: Tensor, + y: Tensor, + degree: Tensor, +) -> Tensor: + functions = ( + physicists_hermite_polynomial_vandermonde, + physicists_hermite_polynomial_vandermonde, + ) + + n = len(functions) + + if n != len([x, y]): + raise ValueError + + if n != len(degree): + raise ValueError + + if n == 0: + raise ValueError + + matrices = [] + + for i in range(n): + matrix = functions[i]((x, y)[i], degree[i]) + + matrices = [ + *matrices, + matrix[(..., *tuple(slice(None) if j == i else None for j in range(n)))], + ] + + vandermonde = functools.reduce( + operator.mul, + matrices, + ) + + return torch.reshape( + vandermonde, + [*vandermonde.shape[: -len(degree)], -1], + ) diff --git a/src/beignet/_physicists_hermite_polynomial_vandermonde_3d.py b/src/beignet/_physicists_hermite_polynomial_vandermonde_3d.py new file mode 100644 index 0000000000..d87b0137a5 --- /dev/null +++ b/src/beignet/_physicists_hermite_polynomial_vandermonde_3d.py @@ -0,0 +1,53 @@ +import functools +import operator + +import torch +from torch import Tensor + +from ._physicists_hermite_polynomial_vandermonde import ( + physicists_hermite_polynomial_vandermonde, +) + + +def physicists_hermite_polynomial_vandermonde_3d( + x: Tensor, + y: Tensor, + z: Tensor, + degree: Tensor, +) -> Tensor: + functions = ( + physicists_hermite_polynomial_vandermonde, + physicists_hermite_polynomial_vandermonde, + physicists_hermite_polynomial_vandermonde, + ) + + n = len(functions) + + if n != len([x, y, z]): + raise ValueError + + if n != len(degree): + raise ValueError + + if n == 0: + raise ValueError + + matrices = [] + + for i in range(n): + matrix = functions[i]((x, y, z)[i], degree[i]) + + matrices = [ + *matrices, + matrix[(..., *tuple(slice(None) if j == i else None for j in range(n)))], + ] + + vandermonde = functools.reduce( + operator.mul, + matrices, + ) + + return torch.reshape( + vandermonde, + [*vandermonde.shape[: -len(degree)], -1], + ) diff --git a/src/beignet/_physicists_hermite_polynomial_weight.py b/src/beignet/_physicists_hermite_polynomial_weight.py new file mode 100644 index 0000000000..af7884f90d --- /dev/null +++ b/src/beignet/_physicists_hermite_polynomial_weight.py @@ -0,0 +1,6 @@ +import torch +from torch import Tensor + + +def physicists_hermite_polynomial_weight(x: Tensor) -> Tensor: + return torch.exp(-(x**2)) diff --git a/src/beignet/_physicists_hermite_polynomial_x.py b/src/beignet/_physicists_hermite_polynomial_x.py new file mode 100644 index 0000000000..e2abfc4670 --- /dev/null +++ b/src/beignet/_physicists_hermite_polynomial_x.py @@ -0,0 +1,3 @@ +import torch + +physicists_hermite_polynomial_x = torch.tensor([0.0, 1.0 / 2.0]) diff --git a/src/beignet/_physicists_hermite_polynomial_zero.py b/src/beignet/_physicists_hermite_polynomial_zero.py new file mode 100644 index 0000000000..3e6b247b81 --- /dev/null +++ b/src/beignet/_physicists_hermite_polynomial_zero.py @@ -0,0 +1,3 @@ +import torch + +physicists_hermite_polynomial_zero = torch.tensor([0.0]) diff --git a/src/beignet/_polynomial_companion.py b/src/beignet/_polynomial_companion.py new file mode 100644 index 0000000000..1fbc30513f --- /dev/null +++ b/src/beignet/_polynomial_companion.py @@ -0,0 +1,35 @@ +import torch +from torch import Tensor + + +def polynomial_companion(input: Tensor) -> Tensor: + r""" + Parameters + ---------- + input : Tensor + Polynomial coefficients. + + Returns + ------- + output : Tensor, shape=(degree, degree) + Companion matrix. + """ + input = torch.atleast_1d(input) + + if input.shape[0] < 2: + raise ValueError + + if input.shape[0] == 2: + output = torch.tensor([[-input[0] / input[1]]]) + else: + n = input.shape[0] - 1 + + output = torch.reshape(torch.zeros([n, n], dtype=input.dtype), [-1]) + + output[n :: n + 1] = 1.0 + + output = torch.reshape(output, [n, n]) + + output[:, -1] = output[:, -1] + (-input[:-1] / input[-1]) + + return output diff --git a/src/beignet/_polynomial_domain.py b/src/beignet/_polynomial_domain.py new file mode 100644 index 0000000000..3482e01ab5 --- /dev/null +++ b/src/beignet/_polynomial_domain.py @@ -0,0 +1,3 @@ +import torch + +polynomial_domain = torch.tensor([-1.0, 1.0]) diff --git a/src/beignet/_polynomial_from_roots.py b/src/beignet/_polynomial_from_roots.py new file mode 100644 index 0000000000..f923f28b42 --- /dev/null +++ b/src/beignet/_polynomial_from_roots.py @@ -0,0 +1,97 @@ +import math + +import torch +from torch import Tensor + +from ._linear_polynomial import linear_polynomial +from ._multiply_polynomial import multiply_polynomial + + +def polynomial_from_roots(input: Tensor) -> Tensor: + r""" + Parameters + ---------- + input : Tensor + Roots. + + Returns + ------- + output : Tensor + Polynomial coefficients. + """ + f = linear_polynomial + g = multiply_polynomial + if math.prod(input.shape) == 0: + return torch.ones([1]) + + input, _ = torch.sort(input) + + ys = [] + + for x in input: + a = torch.zeros(input.shape[0] + 1, dtype=x.dtype) + b = f(-x, 1) + + a = torch.atleast_1d(a) + b = torch.atleast_1d(b) + + dtype = torch.promote_types(a.dtype, b.dtype) + + a = a.to(dtype) + b = b.to(dtype) + + if a.shape[0] > b.shape[0]: + y = torch.concatenate( + [ + b, + torch.zeros( + a.shape[0] - b.shape[0], + dtype=b.dtype, + ), + ], + ) + + y = a + y + else: + y = torch.concatenate( + [ + a, + torch.zeros( + b.shape[0] - a.shape[0], + dtype=a.dtype, + ), + ] + ) + + y = b + y + + ys = [*ys, y] + + p = torch.stack(ys) + + m = p.shape[0] + + x = m, p + + while x[0] > 1: + m, r = divmod(x[0], 2) + + z = x[1] + + previous = torch.zeros([len(p), input.shape[0] + 1]) + + y = previous + + for i in range(0, m): + y[i] = g(z[i], z[i + m])[: input.shape[0] + 1] + + previous = y + + if r: + previous[0] = g(previous[0], z[2 * m])[: input.shape[0] + 1] + + x = m, previous + + _, output = x + + return output[0] diff --git a/src/beignet/_polynomial_one.py b/src/beignet/_polynomial_one.py new file mode 100644 index 0000000000..f8f6211d6d --- /dev/null +++ b/src/beignet/_polynomial_one.py @@ -0,0 +1,3 @@ +import torch + +polynomial_one = torch.tensor([1.0]) diff --git a/src/beignet/_polynomial_power.py b/src/beignet/_polynomial_power.py new file mode 100644 index 0000000000..cc01747aa1 --- /dev/null +++ b/src/beignet/_polynomial_power.py @@ -0,0 +1,76 @@ +import torch +from torch import Tensor + +from ._multiply_polynomial import multiply_polynomial + + +def polynomial_power( + input: Tensor, + exponent: float | Tensor, + maximum_exponent: float | Tensor = 16.0, +) -> Tensor: + r""" + Parameters + ---------- + input : Tensor + Polynomial coefficients. + + exponent : float or Tensor + + maximum_exponent : float or Tensor, default=16.0 + + Returns + ------- + output : Tensor + Polynomial coefficients of the power. + """ + input = torch.atleast_1d(input) + _exponent = int(exponent) + if _exponent != exponent or _exponent < 0: + raise ValueError + if maximum_exponent is not None and _exponent > maximum_exponent: + raise ValueError + match _exponent: + case 0: + output = torch.tensor([1], dtype=input.dtype) + case 1: + output = input + case _: + output = torch.zeros(input.shape[0] * exponent, dtype=input.dtype) + + input = torch.atleast_1d(input) + output = torch.atleast_1d(output) + + dtype = torch.promote_types(input.dtype, output.dtype) + + input = input.to(dtype) + output = output.to(dtype) + + if output.shape[0] > input.shape[0]: + input = torch.concatenate( + [ + input, + torch.zeros( + output.shape[0] - input.shape[0], + dtype=input.dtype, + ), + ], + ) + + output = output + input + else: + output = torch.concatenate( + [ + output, + torch.zeros( + input.shape[0] - output.shape[0], + dtype=output.dtype, + ), + ] + ) + + output = input + output + + for _ in range(2, _exponent + 1): + output = multiply_polynomial(output, input, mode="same") + return output diff --git a/src/beignet/_polynomial_roots.py b/src/beignet/_polynomial_roots.py new file mode 100644 index 0000000000..e3d9269cb6 --- /dev/null +++ b/src/beignet/_polynomial_roots.py @@ -0,0 +1,48 @@ +import torch +from torch import Tensor + + +def polynomial_roots(input: Tensor) -> Tensor: + r""" + Parameters + ---------- + input : Tensor + Polynomial coefficients. + + Returns + ------- + output : Tensor + Roots. + """ + input = torch.atleast_1d(input) + + if input.shape[0] < 2: + return torch.tensor([], dtype=input.dtype) + + if input.shape[0] == 2: + return torch.tensor([-input[0] / input[1]]) + + if input.shape[0] < 2: + raise ValueError + + if input.shape[0] == 2: + output = torch.tensor([[-input[0] / input[1]]]) + else: + n = input.shape[0] - 1 + + output = torch.reshape(torch.zeros([n, n], dtype=input.dtype), [-1]) + + output[n :: n + 1] = 1.0 + + output = torch.reshape(output, [n, n]) + + output[:, -1] = output[:, -1] + (-input[:-1] / input[-1]) + + output = torch.flip(output, dims=[0]) + output = torch.flip(output, dims=[1]) + + output = torch.linalg.eigvals(output) + + output, _ = torch.sort(output.real) + + return output diff --git a/src/beignet/_polynomial_to_chebyshev_polynomial.py b/src/beignet/_polynomial_to_chebyshev_polynomial.py new file mode 100644 index 0000000000..8140243bd1 --- /dev/null +++ b/src/beignet/_polynomial_to_chebyshev_polynomial.py @@ -0,0 +1,18 @@ +import torch +from torch import Tensor + +from ._add_chebyshev_polynomial import add_chebyshev_polynomial +from ._multiply_chebyshev_polynomial_by_x import multiply_chebyshev_polynomial_by_x + + +def polynomial_to_chebyshev_polynomial(input: Tensor) -> Tensor: + input = torch.atleast_1d(input) + + output = torch.zeros_like(input) + + for i in range(0, input.shape[0] - 1 + 1): + output = multiply_chebyshev_polynomial_by_x(output, mode="same") + + output = add_chebyshev_polynomial(output, input[input.shape[0] - 1 - i]) + + return output diff --git a/src/beignet/_polynomial_to_laguerre_polynomial.py b/src/beignet/_polynomial_to_laguerre_polynomial.py new file mode 100644 index 0000000000..0d8046f9c5 --- /dev/null +++ b/src/beignet/_polynomial_to_laguerre_polynomial.py @@ -0,0 +1,18 @@ +import torch +from torch import Tensor + +from ._add_laguerre_polynomial import add_laguerre_polynomial +from ._multiply_laguerre_polynomial_by_x import multiply_laguerre_polynomial_by_x + + +def polynomial_to_laguerre_polynomial(input: Tensor) -> Tensor: + input = torch.atleast_1d(input) + + output = torch.zeros_like(input) + + for i in range(0, input.shape[0]): + output = multiply_laguerre_polynomial_by_x(output, mode="same") + + output = add_laguerre_polynomial(output, torch.flip(input, dims=[0])[i]) + + return output diff --git a/src/beignet/_polynomial_to_legendre_polynomial.py b/src/beignet/_polynomial_to_legendre_polynomial.py new file mode 100644 index 0000000000..8268b051d0 --- /dev/null +++ b/src/beignet/_polynomial_to_legendre_polynomial.py @@ -0,0 +1,18 @@ +import torch +from torch import Tensor + +from ._add_legendre_polynomial import add_legendre_polynomial +from ._multiply_legendre_polynomial_by_x import multiply_legendre_polynomial_by_x + + +def polynomial_to_legendre_polynomial(input: Tensor) -> Tensor: + input = torch.atleast_1d(input) + + output = torch.zeros_like(input) + + for i in range(0, input.shape[0] - 1 + 1): + output = multiply_legendre_polynomial_by_x(output, mode="same") + + output = add_legendre_polynomial(output, input[input.shape[0] - 1 - i]) + + return output diff --git a/src/beignet/_polynomial_to_physicists_hermite_polynomial.py b/src/beignet/_polynomial_to_physicists_hermite_polynomial.py new file mode 100644 index 0000000000..b894ff7307 --- /dev/null +++ b/src/beignet/_polynomial_to_physicists_hermite_polynomial.py @@ -0,0 +1,22 @@ +import torch +from torch import Tensor + +from ._add_physicists_hermite_polynomial import add_physicists_hermite_polynomial +from ._multiply_physicists_hermite_polynomial_by_x import ( + multiply_physicists_hermite_polynomial_by_x, +) + + +def polynomial_to_physicists_hermite_polynomial(input: Tensor) -> Tensor: + input = torch.atleast_1d(input) + + output = torch.zeros_like(input) + + for index in range(0, input.shape[0] - 1 + 1): + output = multiply_physicists_hermite_polynomial_by_x(output, mode="same") + + output = add_physicists_hermite_polynomial( + output, input[input.shape[0] - 1 - index] + ) + + return output diff --git a/src/beignet/_polynomial_to_probabilists_hermite_polynomial.py b/src/beignet/_polynomial_to_probabilists_hermite_polynomial.py new file mode 100644 index 0000000000..9c4d6168a4 --- /dev/null +++ b/src/beignet/_polynomial_to_probabilists_hermite_polynomial.py @@ -0,0 +1,22 @@ +import torch +from torch import Tensor + +from ._add_probabilists_hermite_polynomial import add_probabilists_hermite_polynomial +from ._multiply_probabilists_hermite_polynomial_by_x import ( + multiply_probabilists_hermite_polynomial_by_x, +) + + +def polynomial_to_probabilists_hermite_polynomial(input: Tensor) -> Tensor: + input = torch.atleast_1d(input) + + output = torch.zeros_like(input) + + for i in range(0, input.shape[0] - 1 + 1): + output = multiply_probabilists_hermite_polynomial_by_x(output, mode="same") + + output = add_probabilists_hermite_polynomial( + output, input[input.shape[0] - 1 - i] + ) + + return output diff --git a/src/beignet/_polynomial_vandermonde.py b/src/beignet/_polynomial_vandermonde.py new file mode 100644 index 0000000000..4318aedf8d --- /dev/null +++ b/src/beignet/_polynomial_vandermonde.py @@ -0,0 +1,33 @@ +import torch +from torch import Tensor + + +def polynomial_vandermonde(input: Tensor, degree: Tensor) -> Tensor: + r""" + Parameters + ---------- + input : Tensor + + degree : Tensor + + Returns + ------- + output : Tensor + """ + if degree < 0: + raise ValueError + + degree = int(degree) + + input = torch.atleast_1d(input) + + output = torch.empty([degree + 1, *input.shape], dtype=input.dtype) + + output[0] = torch.ones_like(input) + + for i in range(1, degree + 1): + output[i] = output[i - 1] * input + + output = torch.moveaxis(output, 0, -1) + + return output diff --git a/src/beignet/_polynomial_vandermonde_2d.py b/src/beignet/_polynomial_vandermonde_2d.py new file mode 100644 index 0000000000..bdec450056 --- /dev/null +++ b/src/beignet/_polynomial_vandermonde_2d.py @@ -0,0 +1,58 @@ +import functools +import operator + +import torch +from torch import Tensor + +from ._polynomial_vandermonde import polynomial_vandermonde + + +def polynomial_vandermonde_2d(x: Tensor, y: Tensor, degree: Tensor) -> Tensor: + r""" + Parameters + ---------- + x : Tensor + + y : Tensor + + degree : Tensor + + Returns + ------- + output : Tensor + """ + functions = ( + polynomial_vandermonde, + polynomial_vandermonde, + ) + + n = len(functions) + + if n != len([x, y]): + raise ValueError + + if n != len(degree): + raise ValueError + + if n == 0: + raise ValueError + + matrices = [] + + for i in range(n): + matrix = functions[i]((x, y)[i], degree[i]) + + matrices = [ + *matrices, + matrix[(..., *tuple(slice(None) if j == i else None for j in range(n)))], + ] + + vandermonde = functools.reduce( + operator.mul, + matrices, + ) + + return torch.reshape( + vandermonde, + [*vandermonde.shape[: -len(degree)], -1], + ) diff --git a/src/beignet/_polynomial_vandermonde_3d.py b/src/beignet/_polynomial_vandermonde_3d.py new file mode 100644 index 0000000000..690a791131 --- /dev/null +++ b/src/beignet/_polynomial_vandermonde_3d.py @@ -0,0 +1,63 @@ +import functools +import operator + +import torch +from torch import Tensor + +from ._polynomial_vandermonde import polynomial_vandermonde + + +def polynomial_vandermonde_3d( + x: Tensor, y: Tensor, z: Tensor, degree: Tensor +) -> Tensor: + r""" + Parameters + ---------- + x : Tensor + + y : Tensor + + z : Tensor + + degree : Tensor + + Returns + ------- + output : Tensor + """ + vandermonde_functions = ( + polynomial_vandermonde, + polynomial_vandermonde, + polynomial_vandermonde, + ) + + n = len(vandermonde_functions) + + if n != len([x, y, z]): + raise ValueError + + if n != len(degree): + raise ValueError + + if n == 0: + raise ValueError + + matrices = [] + + for i in range(n): + matrix = vandermonde_functions[i]((x, y, z)[i], degree[i]) + + matrices = [ + *matrices, + matrix[(..., *tuple(slice(None) if j == i else None for j in range(n)))], + ] + + vandermonde = functools.reduce( + operator.mul, + matrices, + ) + + return torch.reshape( + vandermonde, + [*vandermonde.shape[: -len(degree)], -1], + ) diff --git a/src/beignet/_polynomial_x.py b/src/beignet/_polynomial_x.py new file mode 100644 index 0000000000..6ace7faf7f --- /dev/null +++ b/src/beignet/_polynomial_x.py @@ -0,0 +1,3 @@ +import torch + +polynomial_x = torch.tensor([0.0, 1.0]) diff --git a/src/beignet/_polynomial_zero.py b/src/beignet/_polynomial_zero.py new file mode 100644 index 0000000000..745c63dd68 --- /dev/null +++ b/src/beignet/_polynomial_zero.py @@ -0,0 +1,3 @@ +import torch + +polynomial_zero = torch.tensor([0.0]) diff --git a/src/beignet/_probabilists_hermite_polynomial_companion.py b/src/beignet/_probabilists_hermite_polynomial_companion.py new file mode 100644 index 0000000000..390c46f9cf --- /dev/null +++ b/src/beignet/_probabilists_hermite_polynomial_companion.py @@ -0,0 +1,39 @@ +import torch +from torch import Tensor + + +def probabilists_hermite_polynomial_companion(input: Tensor) -> Tensor: + input = torch.atleast_1d(input) + + if input.shape[0] < 2: + raise ValueError + + if input.shape[0] == 2: + return torch.tensor([[-input[0] / input[1]]]) + + n = input.shape[0] - 1 + + output = torch.zeros([n, n], dtype=input.dtype) + + scale = torch.hstack( + [ + torch.tensor([1.0]), + 1.0 / torch.sqrt(torch.arange(n - 1, 0, -1)), + ], + ) + + scale = torch.cumprod(scale, dim=0) + scale = torch.flip(scale, dims=[0]) + + shape = output.shape + + output = torch.reshape(output, [-1]) + + output[1 :: n + 1] = torch.sqrt(torch.arange(1, n)) + output[n :: n + 1] = torch.sqrt(torch.arange(1, n)) + + output = torch.reshape(output, shape) + + output[:, -1] += -scale * input[:-1] / input[-1] + + return output diff --git a/src/beignet/_probabilists_hermite_polynomial_domain.py b/src/beignet/_probabilists_hermite_polynomial_domain.py new file mode 100644 index 0000000000..a146072cdf --- /dev/null +++ b/src/beignet/_probabilists_hermite_polynomial_domain.py @@ -0,0 +1,3 @@ +import torch + +probabilists_hermite_polynomial_domain = torch.tensor([-1.0, 1.0]) diff --git a/src/beignet/_probabilists_hermite_polynomial_from_roots.py b/src/beignet/_probabilists_hermite_polynomial_from_roots.py new file mode 100644 index 0000000000..3ec8ee0df1 --- /dev/null +++ b/src/beignet/_probabilists_hermite_polynomial_from_roots.py @@ -0,0 +1,90 @@ +import math + +import torch +from torch import Tensor + +from ._linear_probabilists_hermite_polynomial import ( + linear_probabilists_hermite_polynomial, +) +from ._multiply_probabilists_hermite_polynomial import ( + multiply_probabilists_hermite_polynomial, +) + + +def probabilists_hermite_polynomial_from_roots(input: Tensor) -> Tensor: + f = linear_probabilists_hermite_polynomial + g = multiply_probabilists_hermite_polynomial + if math.prod(input.shape) == 0: + return torch.ones([1]) + + input, _ = torch.sort(input) + + ys = [] + + for x in input: + a = torch.zeros(input.shape[0] + 1, dtype=x.dtype) + b = f(-x, 1) + + a = torch.atleast_1d(a) + b = torch.atleast_1d(b) + + dtype = torch.promote_types(a.dtype, b.dtype) + + a = a.to(dtype) + b = b.to(dtype) + + if a.shape[0] > b.shape[0]: + y = torch.concatenate( + [ + b, + torch.zeros( + a.shape[0] - b.shape[0], + dtype=b.dtype, + ), + ], + ) + + y = a + y + else: + y = torch.concatenate( + [ + a, + torch.zeros( + b.shape[0] - a.shape[0], + dtype=a.dtype, + ), + ] + ) + + y = b + y + + ys = [*ys, y] + + p = torch.stack(ys) + + m = p.shape[0] + + x = m, p + + while x[0] > 1: + m, r = divmod(x[0], 2) + + z = x[1] + + previous = torch.zeros([len(p), input.shape[0] + 1]) + + y = previous + + for i in range(0, m): + y[i] = g(z[i], z[i + m])[: input.shape[0] + 1] + + previous = y + + if r: + previous[0] = g(previous[0], z[2 * m])[: input.shape[0] + 1] + + x = m, previous + + _, output = x + + return output[0] diff --git a/src/beignet/_probabilists_hermite_polynomial_one.py b/src/beignet/_probabilists_hermite_polynomial_one.py new file mode 100644 index 0000000000..13c91bda67 --- /dev/null +++ b/src/beignet/_probabilists_hermite_polynomial_one.py @@ -0,0 +1,3 @@ +import torch + +probabilists_hermite_polynomial_one = torch.tensor([1.0]) diff --git a/src/beignet/_probabilists_hermite_polynomial_power.py b/src/beignet/_probabilists_hermite_polynomial_power.py new file mode 100644 index 0000000000..e170300ba1 --- /dev/null +++ b/src/beignet/_probabilists_hermite_polynomial_power.py @@ -0,0 +1,65 @@ +import torch +from torch import Tensor + +from ._multiply_probabilists_hermite_polynomial import ( + multiply_probabilists_hermite_polynomial, +) + + +def probabilists_hermite_polynomial_power( + input: Tensor, + exponent: float | Tensor, + maximum_exponent: float | Tensor = 16.0, +) -> Tensor: + input = torch.atleast_1d(input) + _exponent = int(exponent) + if _exponent != exponent or _exponent < 0: + raise ValueError + if maximum_exponent is not None and _exponent > maximum_exponent: + raise ValueError + match _exponent: + case 0: + output = torch.tensor([1], dtype=input.dtype) + case 1: + output = input + case _: + output = torch.zeros(input.shape[0] * exponent, dtype=input.dtype) + + input = torch.atleast_1d(input) + output = torch.atleast_1d(output) + + dtype = torch.promote_types(input.dtype, output.dtype) + + input = input.to(dtype) + output = output.to(dtype) + + if output.shape[0] > input.shape[0]: + input = torch.concatenate( + [ + input, + torch.zeros( + output.shape[0] - input.shape[0], + dtype=input.dtype, + ), + ], + ) + + output = output + input + else: + output = torch.concatenate( + [ + output, + torch.zeros( + input.shape[0] - output.shape[0], + dtype=output.dtype, + ), + ] + ) + + output = input + output + + for _ in range(2, _exponent + 1): + output = multiply_probabilists_hermite_polynomial( + output, input, mode="same" + ) + return output diff --git a/src/beignet/_probabilists_hermite_polynomial_roots.py b/src/beignet/_probabilists_hermite_polynomial_roots.py new file mode 100644 index 0000000000..88277e707b --- /dev/null +++ b/src/beignet/_probabilists_hermite_polynomial_roots.py @@ -0,0 +1,27 @@ +import torch +from torch import Tensor + +from ._probabilists_hermite_polynomial_companion import ( + probabilists_hermite_polynomial_companion, +) + + +def probabilists_hermite_polynomial_roots(input: Tensor) -> Tensor: + input = torch.atleast_1d(input) + + if input.shape[0] <= 1: + return torch.tensor([], dtype=input.dtype) + + if input.shape[0] == 2: + return torch.tensor([-input[0] / input[1]]) + + output = probabilists_hermite_polynomial_companion(input) + + output = torch.flip(output, dims=[0]) + output = torch.flip(output, dims=[1]) + + output = torch.linalg.eigvals(output) + + output, _ = torch.sort(output.real) + + return output diff --git a/src/beignet/_probabilists_hermite_polynomial_to_polynomial.py b/src/beignet/_probabilists_hermite_polynomial_to_polynomial.py new file mode 100644 index 0000000000..0ec138e7e6 --- /dev/null +++ b/src/beignet/_probabilists_hermite_polynomial_to_polynomial.py @@ -0,0 +1,48 @@ +import torch +from torch import Tensor + +from ._add_polynomial import add_polynomial +from ._multiply_polynomial_by_x import multiply_polynomial_by_x +from ._subtract_polynomial import subtract_polynomial + + +def probabilists_hermite_polynomial_to_polynomial(input: Tensor) -> Tensor: + input = torch.atleast_1d(input) + + n = input.shape[0] + + if n == 1: + return input + + if n == 2: + return input + else: + c0 = torch.zeros_like(input) + c0[0] = input[-2] + + c1 = torch.zeros_like(input) + c1[0] = input[-1] + + def body(k, c0c1): + i = n - 1 - k + + c0, c1 = c0c1 + + tmp = c0 + + c0 = subtract_polynomial(input[i - 2], c1 * (i - 1)) + + c1 = add_polynomial(tmp, multiply_polynomial_by_x(c1, "same")) + + return c0, c1 + + b = n - 2 + x = (c0, c1) + y = x + + for index in range(0, b): + y = body(index, y) + + c0, c1 = y + + return add_polynomial(c0, multiply_polynomial_by_x(c1, "same")) diff --git a/src/beignet/_probabilists_hermite_polynomial_vandermonde.py b/src/beignet/_probabilists_hermite_polynomial_vandermonde.py new file mode 100644 index 0000000000..b529db0798 --- /dev/null +++ b/src/beignet/_probabilists_hermite_polynomial_vandermonde.py @@ -0,0 +1,22 @@ +import torch +from torch import Tensor + + +def probabilists_hermite_polynomial_vandermonde(x: Tensor, degree: Tensor) -> Tensor: + if degree < 0: + raise ValueError + + x = torch.atleast_1d(x) + dims = (degree + 1,) + x.shape + dtyp = torch.promote_types(x.dtype, torch.tensor(0.0).dtype) + x = x.to(dtyp) + v = torch.empty(dims, dtype=dtyp) + v[0] = torch.ones_like(x) + + if degree > 0: + v[1] = x + + for index in range(2, degree + 1): + v[index] = v[index - 1] * x - v[index - 2] * (index - 1) + + return torch.moveaxis(v, 0, -1) diff --git a/src/beignet/_probabilists_hermite_polynomial_vandermonde_2d.py b/src/beignet/_probabilists_hermite_polynomial_vandermonde_2d.py new file mode 100644 index 0000000000..4dc4dd2cce --- /dev/null +++ b/src/beignet/_probabilists_hermite_polynomial_vandermonde_2d.py @@ -0,0 +1,51 @@ +import functools +import operator + +import torch +from torch import Tensor + +from ._probabilists_hermite_polynomial_vandermonde import ( + probabilists_hermite_polynomial_vandermonde, +) + + +def probabilists_hermite_polynomial_vandermonde_2d( + x: Tensor, + y: Tensor, + degree: Tensor, +) -> Tensor: + functions = ( + probabilists_hermite_polynomial_vandermonde, + probabilists_hermite_polynomial_vandermonde, + ) + + n = len(functions) + + if n != len([x, y]): + raise ValueError + + if n != len(degree): + raise ValueError + + if n == 0: + raise ValueError + + matrices = [] + + for i in range(n): + matrix = functions[i]((x, y)[i], degree[i]) + + matrices = [ + *matrices, + matrix[(..., *tuple(slice(None) if j == i else None for j in range(n)))], + ] + + vandermonde = functools.reduce( + operator.mul, + matrices, + ) + + return torch.reshape( + vandermonde, + [*vandermonde.shape[: -len(degree)], -1], + ) diff --git a/src/beignet/_probabilists_hermite_polynomial_vandermonde_3d.py b/src/beignet/_probabilists_hermite_polynomial_vandermonde_3d.py new file mode 100644 index 0000000000..fad7394ab6 --- /dev/null +++ b/src/beignet/_probabilists_hermite_polynomial_vandermonde_3d.py @@ -0,0 +1,53 @@ +import functools +import operator + +import torch +from torch import Tensor + +from ._probabilists_hermite_polynomial_vandermonde import ( + probabilists_hermite_polynomial_vandermonde, +) + + +def probabilists_hermite_polynomial_vandermonde_3d( + x: Tensor, + y: Tensor, + z: Tensor, + degree: Tensor, +) -> Tensor: + functions = ( + probabilists_hermite_polynomial_vandermonde, + probabilists_hermite_polynomial_vandermonde, + probabilists_hermite_polynomial_vandermonde, + ) + + n = len(functions) + + if n != len([x, y, z]): + raise ValueError + + if n != len(degree): + raise ValueError + + if n == 0: + raise ValueError + + matrices = [] + + for i in range(n): + matrix = functions[i]((x, y, z)[i], degree[i]) + + matrices = [ + *matrices, + matrix[(..., *tuple(slice(None) if j == i else None for j in range(n)))], + ] + + vandermonde = functools.reduce( + operator.mul, + matrices, + ) + + return torch.reshape( + vandermonde, + [*vandermonde.shape[: -len(degree)], -1], + ) diff --git a/src/beignet/_probabilists_hermite_polynomial_weight.py b/src/beignet/_probabilists_hermite_polynomial_weight.py new file mode 100644 index 0000000000..253949a0ff --- /dev/null +++ b/src/beignet/_probabilists_hermite_polynomial_weight.py @@ -0,0 +1,6 @@ +import torch +from torch import Tensor + + +def probabilists_hermite_polynomial_weight(x: Tensor) -> Tensor: + return torch.exp(-0.5 * x**2) diff --git a/src/beignet/_probabilists_hermite_polynomial_x.py b/src/beignet/_probabilists_hermite_polynomial_x.py new file mode 100644 index 0000000000..a1b77a534e --- /dev/null +++ b/src/beignet/_probabilists_hermite_polynomial_x.py @@ -0,0 +1,3 @@ +import torch + +probabilists_hermite_polynomial_x = torch.tensor([0.0, 1.0]) diff --git a/src/beignet/_probabilists_hermite_polynomial_zero.py b/src/beignet/_probabilists_hermite_polynomial_zero.py new file mode 100644 index 0000000000..b1c9202f5d --- /dev/null +++ b/src/beignet/_probabilists_hermite_polynomial_zero.py @@ -0,0 +1,3 @@ +import torch + +probabilists_hermite_polynomial_zero = torch.tensor([0.0]) diff --git a/src/beignet/_subtract_chebyshev_polynomial.py b/src/beignet/_subtract_chebyshev_polynomial.py new file mode 100644 index 0000000000..07fa2d55cd --- /dev/null +++ b/src/beignet/_subtract_chebyshev_polynomial.py @@ -0,0 +1,53 @@ +import torch +from torch import Tensor + + +def subtract_chebyshev_polynomial(input: Tensor, other: Tensor) -> Tensor: + r""" + Returns the difference of two polynomials. + + Parameters + ---------- + input : Tensor + Polynomial coefficients. + + other : Tensor + Polynomial coefficients. + + Returns + ------- + output : Tensor + Polynomial coefficients of the difference. + """ + input = torch.atleast_1d(input) + other = torch.atleast_1d(other) + + dtype = torch.promote_types(input.dtype, other.dtype) + + input = input.to(dtype) + other = other.to(dtype) + + if input.shape[0] > other.shape[0]: + output = -other + + output = torch.concatenate( + [ + output, + torch.zeros( + input.shape[0] - other.shape[0], + dtype=other.dtype, + ), + ], + ) + output = input + output + else: + output = -other + + output = torch.concatenate( + [ + output[: input.shape[0]] + input, + output[input.shape[0] :], + ], + ) + + return output diff --git a/src/beignet/_subtract_laguerre_polynomial.py b/src/beignet/_subtract_laguerre_polynomial.py new file mode 100644 index 0000000000..edda044c48 --- /dev/null +++ b/src/beignet/_subtract_laguerre_polynomial.py @@ -0,0 +1,53 @@ +import torch +from torch import Tensor + + +def subtract_laguerre_polynomial(input: Tensor, other: Tensor) -> Tensor: + r""" + Returns the difference of two polynomials. + + Parameters + ---------- + input : Tensor + Polynomial coefficients. + + other : Tensor + Polynomial coefficients. + + Returns + ------- + output : Tensor + Polynomial coefficients of the difference. + """ + input = torch.atleast_1d(input) + other = torch.atleast_1d(other) + + dtype = torch.promote_types(input.dtype, other.dtype) + + input = input.to(dtype) + other = other.to(dtype) + + if input.shape[0] > other.shape[0]: + output = -other + + output = torch.concatenate( + [ + output, + torch.zeros( + input.shape[0] - other.shape[0], + dtype=other.dtype, + ), + ], + ) + output = input + output + else: + output = -other + + output = torch.concatenate( + [ + output[: input.shape[0]] + input, + output[input.shape[0] :], + ], + ) + + return output diff --git a/src/beignet/_subtract_legendre_polynomial.py b/src/beignet/_subtract_legendre_polynomial.py new file mode 100644 index 0000000000..b1d95ce31e --- /dev/null +++ b/src/beignet/_subtract_legendre_polynomial.py @@ -0,0 +1,53 @@ +import torch +from torch import Tensor + + +def subtract_legendre_polynomial(input: Tensor, other: Tensor) -> Tensor: + r""" + Returns the difference of two polynomials. + + Parameters + ---------- + input : Tensor + Polynomial coefficients. + + other : Tensor + Polynomial coefficients. + + Returns + ------- + output : Tensor + Polynomial coefficients of the difference. + """ + input = torch.atleast_1d(input) + other = torch.atleast_1d(other) + + dtype = torch.promote_types(input.dtype, other.dtype) + + input = input.to(dtype) + other = other.to(dtype) + + if input.shape[0] > other.shape[0]: + output = -other + + output = torch.concatenate( + [ + output, + torch.zeros( + input.shape[0] - other.shape[0], + dtype=other.dtype, + ), + ], + ) + output = input + output + else: + output = -other + + output = torch.concatenate( + [ + output[: input.shape[0]] + input, + output[input.shape[0] :], + ], + ) + + return output diff --git a/src/beignet/_subtract_physicists_hermite_polynomial.py b/src/beignet/_subtract_physicists_hermite_polynomial.py new file mode 100644 index 0000000000..977b5b543b --- /dev/null +++ b/src/beignet/_subtract_physicists_hermite_polynomial.py @@ -0,0 +1,56 @@ +import torch +from torch import Tensor + + +def subtract_physicists_hermite_polynomial( + input: Tensor, + other: Tensor, +) -> Tensor: + r""" + Returns the difference of two polynomials. + + Parameters + ---------- + input : Tensor + Polynomial coefficients. + + other : Tensor + Polynomial coefficients. + + Returns + ------- + output : Tensor + Polynomial coefficients of the difference. + """ + input = torch.atleast_1d(input) + other = torch.atleast_1d(other) + + dtype = torch.promote_types(input.dtype, other.dtype) + + input = input.to(dtype) + other = other.to(dtype) + + if input.shape[0] > other.shape[0]: + output = -other + + output = torch.concatenate( + [ + output, + torch.zeros( + input.shape[0] - other.shape[0], + dtype=other.dtype, + ), + ], + ) + output = input + output + else: + output = -other + + output = torch.concatenate( + [ + output[: input.shape[0]] + input, + output[input.shape[0] :], + ], + ) + + return output diff --git a/src/beignet/_subtract_polynomial.py b/src/beignet/_subtract_polynomial.py new file mode 100644 index 0000000000..5e3af22172 --- /dev/null +++ b/src/beignet/_subtract_polynomial.py @@ -0,0 +1,53 @@ +import torch +from torch import Tensor + + +def subtract_polynomial(input: Tensor, other: Tensor) -> Tensor: + r""" + Returns the difference of two polynomials. + + Parameters + ---------- + input : Tensor + Polynomial coefficients. + + other : Tensor + Polynomial coefficients. + + Returns + ------- + output : Tensor + Polynomial coefficients of the difference. + """ + input = torch.atleast_1d(input) + other = torch.atleast_1d(other) + + dtype = torch.promote_types(input.dtype, other.dtype) + + input = input.to(dtype) + other = other.to(dtype) + + if input.shape[0] > other.shape[0]: + output = -other + + output = torch.concatenate( + [ + output, + torch.zeros( + input.shape[0] - other.shape[0], + dtype=other.dtype, + ), + ], + ) + output = input + output + else: + output = -other + + output = torch.concatenate( + [ + output[: input.shape[0]] + input, + output[input.shape[0] :], + ], + ) + + return output diff --git a/src/beignet/_subtract_probabilists_hermite_polynomial.py b/src/beignet/_subtract_probabilists_hermite_polynomial.py new file mode 100644 index 0000000000..9050321bde --- /dev/null +++ b/src/beignet/_subtract_probabilists_hermite_polynomial.py @@ -0,0 +1,56 @@ +import torch +from torch import Tensor + + +def subtract_probabilists_hermite_polynomial( + input: Tensor, + other: Tensor, +) -> Tensor: + r""" + Returns the difference of two polynomials. + + Parameters + ---------- + input : Tensor + Polynomial coefficients. + + other : Tensor + Polynomial coefficients. + + Returns + ------- + output : Tensor + Polynomial coefficients of the difference. + """ + input = torch.atleast_1d(input) + other = torch.atleast_1d(other) + + dtype = torch.promote_types(input.dtype, other.dtype) + + input = input.to(dtype) + other = other.to(dtype) + + if input.shape[0] > other.shape[0]: + output = -other + + output = torch.concatenate( + [ + output, + torch.zeros( + input.shape[0] - other.shape[0], + dtype=other.dtype, + ), + ], + ) + output = input + output + else: + output = -other + + output = torch.concatenate( + [ + output[: input.shape[0]] + input, + output[input.shape[0] :], + ], + ) + + return output diff --git a/src/beignet/_trim_chebyshev_polynomial_coefficients.py b/src/beignet/_trim_chebyshev_polynomial_coefficients.py new file mode 100644 index 0000000000..01db83a6ba --- /dev/null +++ b/src/beignet/_trim_chebyshev_polynomial_coefficients.py @@ -0,0 +1,21 @@ +import torch +from torch import Tensor + + +def trim_chebyshev_polynomial_coefficients( + input: Tensor, + tol: float = 0.0, +) -> Tensor: + if tol < 0: + raise ValueError + + input = torch.atleast_1d(input) + + indices = torch.nonzero(torch.abs(input) > tol) + + if indices.shape[0] == 0: + output = input[:1] * 0 + else: + output = input[: indices[-1] + 1] + + return output diff --git a/src/beignet/_trim_laguerre_polynomial_coefficients.py b/src/beignet/_trim_laguerre_polynomial_coefficients.py new file mode 100644 index 0000000000..6251c3a4c5 --- /dev/null +++ b/src/beignet/_trim_laguerre_polynomial_coefficients.py @@ -0,0 +1,21 @@ +import torch +from torch import Tensor + + +def trim_laguerre_polynomial_coefficients( + input: Tensor, + tol: float = 0.0, +) -> Tensor: + if tol < 0: + raise ValueError + + input = torch.atleast_1d(input) + + indices = torch.nonzero(torch.abs(input) > tol) + + if indices.shape[0] == 0: + output = input[:1] * 0 + else: + output = input[: indices[-1] + 1] + + return output diff --git a/src/beignet/_trim_legendre_polynomial_coefficients.py b/src/beignet/_trim_legendre_polynomial_coefficients.py new file mode 100644 index 0000000000..298b4db1b7 --- /dev/null +++ b/src/beignet/_trim_legendre_polynomial_coefficients.py @@ -0,0 +1,21 @@ +import torch +from torch import Tensor + + +def trim_legendre_polynomial_coefficients( + input: Tensor, + tol: float = 0.0, +) -> Tensor: + if tol < 0: + raise ValueError + + input = torch.atleast_1d(input) + + indices = torch.nonzero(torch.abs(input) > tol) + + if indices.shape[0] == 0: + output = input[:1] * 0 + else: + output = input[: indices[-1] + 1] + + return output diff --git a/src/beignet/_trim_physicists_hermite_polynomial_coefficients.py b/src/beignet/_trim_physicists_hermite_polynomial_coefficients.py new file mode 100644 index 0000000000..ac8f25a560 --- /dev/null +++ b/src/beignet/_trim_physicists_hermite_polynomial_coefficients.py @@ -0,0 +1,21 @@ +import torch +from torch import Tensor + + +def trim_physicists_hermite_polynomial_coefficients( + input: Tensor, + tol: float = 0.0, +) -> Tensor: + if tol < 0: + raise ValueError + + input = torch.atleast_1d(input) + + indices = torch.nonzero(torch.abs(input) > tol) + + if indices.shape[0] == 0: + output = input[:1] * 0 + else: + output = input[: indices[-1] + 1] + + return output diff --git a/src/beignet/_trim_polynomial_coefficients.py b/src/beignet/_trim_polynomial_coefficients.py new file mode 100644 index 0000000000..235a4b55ab --- /dev/null +++ b/src/beignet/_trim_polynomial_coefficients.py @@ -0,0 +1,21 @@ +import torch +from torch import Tensor + + +def trim_polynomial_coefficients( + input: Tensor, + tol: float = 0.0, +) -> Tensor: + if tol < 0: + raise ValueError + + input = torch.atleast_1d(input) + + indices = torch.nonzero(torch.abs(input) > tol) + + if indices.shape[0] == 0: + output = input[:1] * 0 + else: + output = input[: indices[-1] + 1] + + return output diff --git a/src/beignet/_trim_probabilists_hermite_polynomial_coefficients.py b/src/beignet/_trim_probabilists_hermite_polynomial_coefficients.py new file mode 100644 index 0000000000..d2edec6f72 --- /dev/null +++ b/src/beignet/_trim_probabilists_hermite_polynomial_coefficients.py @@ -0,0 +1,21 @@ +import torch +from torch import Tensor + + +def trim_probabilists_hermite_polynomial_coefficients( + input: Tensor, + tol: float = 0.0, +) -> Tensor: + if tol < 0: + raise ValueError + + input = torch.atleast_1d(input) + + indices = torch.nonzero(torch.abs(input) > tol) + + if indices.shape[0] == 0: + output = input[:1] * 0 + else: + output = input[: indices[-1] + 1] + + return output diff --git a/tests/beignet/func/test__space.py b/tests/beignet/func/test__space.py index e91eaf6b44..ab211dd253 100644 --- a/tests/beignet/func/test__space.py +++ b/tests/beignet/func/test__space.py @@ -1,144 +1,147 @@ -import functools -from typing import Callable - -import beignet.func -import hypothesis -import hypothesis.strategies -import torch.testing -from torch import Tensor - - -def map_product(fn: Callable) -> Callable: - return torch.vmap( - torch.vmap( - fn, - in_dims=(0, None), - out_dims=0, - ), - in_dims=(None, 0), - out_dims=0, - ) - - -@hypothesis.strategies.composite -def _strategy(function): - dtype = function( - hypothesis.strategies.sampled_from( - [ - torch.float32, - torch.float64, - ], - ), - ) - - maximum_size = function( - hypothesis.strategies.floats( - min_value=1.0, - max_value=8.0, - ), - ) - - particles = function( - hypothesis.strategies.integers( - min_value=16, - max_value=32, - ), - ) - - spatial_dimension = function( - hypothesis.strategies.integers( - min_value=1, - max_value=3, - ), - ) - - return ( - dtype, - torch.rand([particles, spatial_dimension], dtype=dtype), - particles, - torch.rand([spatial_dimension], dtype=dtype) * maximum_size, - spatial_dimension, - ) - - -@hypothesis.given(_strategy()) -@hypothesis.settings(deadline=None) -def test_space(data): - dtype, input, particles, size, spatial_dimension = data - - displacement_fn, shift_fn = beignet.func.space(size, parallelepiped=False) - - ( - parallelepiped_displacement_fn, - parallelepiped_shift_fn, - ) = beignet.func.space( - torch.diag(size), - ) - - standardized_input = input * size - - displacement_fn = map_product(displacement_fn) - - parallelepiped_displacement_fn = map_product( - parallelepiped_displacement_fn, - ) - - torch.testing.assert_close( - displacement_fn( - standardized_input, - standardized_input, - ), - parallelepiped_displacement_fn( - input, - input, - ), - ) - - displacement = torch.randn([particles, spatial_dimension], dtype=dtype) - - torch.testing.assert_close( - shift_fn(standardized_input, displacement), - parallelepiped_shift_fn(input, displacement) * size, - ) - - def f(input: Tensor) -> Tensor: - return torch.sum(displacement_fn(input, input) ** 2) - - def g(input: Tensor) -> Tensor: - return torch.sum(parallelepiped_displacement_fn(input, input) ** 2) - - torch.testing.assert_close( - torch.func.grad(f)(standardized_input), - torch.func.grad(g)(input), - rtol=0.0001, - atol=0.0001, - ) - - size_a = 10.0 * torch.rand([]) - size_b = 10.0 * torch.rand([], dtype=dtype) - - transform_a = 0.5 * torch.randn([spatial_dimension, spatial_dimension]) - transform_b = 0.5 * torch.randn([spatial_dimension, spatial_dimension], dtype=dtype) - - transform_a = size_a * (torch.eye(spatial_dimension) + transform_a) - transform_b = size_b * (torch.eye(spatial_dimension) + transform_b) - - displacement_fn_a, shift_fn_a = beignet.func.space(transform_a) - displacement_fn_b, shift_fn_b = beignet.func.space(transform_b) - - displacement = torch.randn([particles, spatial_dimension], dtype=dtype) - - torch.testing.assert_close( - map_product( - functools.partial( - displacement_fn_a, - transform=transform_b, - ), - )(input, input), - map_product(displacement_fn_b)(input, input), - ) - - torch.testing.assert_close( - shift_fn_a(input, displacement, transform=transform_b), - shift_fn_b(input, displacement), - ) +# import functools +# from typing import Callable +# +# import beignet.func +# import hypothesis +# import hypothesis.strategies +# import torch.testing +# from torch import Tensor +# +# +# def map_product(fn: Callable) -> Callable: +# return torch.vmap( +# torch.vmap( +# fn, +# in_dims=(0, None), +# out_dims=0, +# ), +# in_dims=(None, 0), +# out_dims=0, +# ) +# +# +# @hypothesis.strategies.composite +# def _strategy(function): +# dtype = function( +# hypothesis.strategies.sampled_from( +# [ +# torch.float32, +# torch.float64, +# ], +# ), +# ) +# +# maximum_size = function( +# hypothesis.strategies.floats( +# min_value=1.0, +# max_value=8.0, +# ), +# ) +# +# particles = function( +# hypothesis.strategies.integers( +# min_value=16, +# max_value=32, +# ), +# ) +# +# spatial_dimension = function( +# hypothesis.strategies.integers( +# min_value=1, +# max_value=3, +# ), +# ) +# +# return ( +# dtype, +# torch.rand([particles, spatial_dimension], dtype=dtype), +# particles, +# torch.rand([spatial_dimension], dtype=dtype) * maximum_size, +# spatial_dimension, +# ) +# +# +# @hypothesis.given(_strategy()) +# @hypothesis.settings(deadline=None) +# def test_space(data): +# dtype, input, particles, size, spatial_dimension = data +# +# displacement_fn, shift_fn = beignet.func.space(size, parallelepiped=False) +# +# ( +# parallelepiped_displacement_fn, +# parallelepiped_shift_fn, +# ) = beignet.func.space( +# torch.diag(size), +# ) +# +# standardized_input = input * size +# +# displacement_fn = map_product(displacement_fn) +# +# parallelepiped_displacement_fn = map_product( +# parallelepiped_displacement_fn, +# ) +# +# torch.testing.assert_close( +# displacement_fn( +# standardized_input, +# standardized_input, +# ), +# parallelepiped_displacement_fn( +# input, +# input, +# ), +# ) +# +# displacement = torch.randn([particles, spatial_dimension], dtype=dtype) +# +# torch.testing.assert_close( +# shift_fn(standardized_input, displacement), +# parallelepiped_shift_fn(input, displacement) * size, +# ) +# +# def f(input: Tensor) -> Tensor: +# return torch.sum(displacement_fn(input, input) ** 2) +# +# def g(input: Tensor) -> Tensor: +# return torch.sum(parallelepiped_displacement_fn(input, input) ** 2) +# +# torch.testing.assert_close( +# torch.func.grad(f)(standardized_input), +# torch.func.grad(g)(input), +# rtol=0.0001, +# atol=0.0001, +# ) +# +# size_a = 10.0 * torch.rand([]) +# size_b = 10.0 * torch.rand([], dtype=dtype) +# +# transform_a = 0.5 * torch.randn([spatial_dimension, spatial_dimension]) +# transform_b = 0.5 * torch.randn( +# [spatial_dimension, spatial_dimension], +# dtype=dtype, +# ) +# +# transform_a = size_a * (torch.eye(spatial_dimension) + transform_a) +# transform_b = size_b * (torch.eye(spatial_dimension) + transform_b) +# +# displacement_fn_a, shift_fn_a = beignet.func.space(transform_a) +# displacement_fn_b, shift_fn_b = beignet.func.space(transform_b) +# +# displacement = torch.randn([particles, spatial_dimension], dtype=dtype) +# +# torch.testing.assert_close( +# map_product( +# functools.partial( +# displacement_fn_a, +# transform=transform_b, +# ), +# )(input, input), +# map_product(displacement_fn_b)(input, input), +# ) +# +# torch.testing.assert_close( +# shift_fn_a(input, displacement, transform=transform_b), +# shift_fn_b(input, displacement), +# ) diff --git a/tests/beignet/special/test__dawson_integral_f.py b/tests/beignet/special/test__dawson_integral_f.py index 69e14bb9da..7da53e350c 100644 --- a/tests/beignet/special/test__dawson_integral_f.py +++ b/tests/beignet/special/test__dawson_integral_f.py @@ -1,55 +1,55 @@ -import beignet.special -import hypothesis -import hypothesis.strategies -import scipy -import torch - - -@hypothesis.strategies.composite -def _strategy(function): - x, y = torch.meshgrid( - torch.linspace( - function( - hypothesis.strategies.floats( - min_value=-10, - max_value=-10, - ), - ), - function( - hypothesis.strategies.floats( - min_value=10, - max_value=10, - ), - ), - steps=128, - dtype=torch.float64, - ), - torch.linspace( - function( - hypothesis.strategies.floats( - min_value=-10, - max_value=-10, - ), - ), - function( - hypothesis.strategies.floats( - min_value=10, - max_value=10, - ), - ), - steps=128, - dtype=torch.float64, - ), - indexing="xy", - ) - - input = x + 1.0j * y - - return input, scipy.special.dawsn(input) - - -@hypothesis.given(_strategy()) -def test_dawson_integral_f(data): - input, output = data - - torch.testing.assert_close(beignet.special.dawson_integral_f(input), output) +# import beignet.special +# import hypothesis +# import hypothesis.strategies +# import scipy +# import torch +# +# +# @hypothesis.strategies.composite +# def _strategy(function): +# x, y = torch.meshgrid( +# torch.linspace( +# function( +# hypothesis.strategies.floats( +# min_value=-10, +# max_value=-10, +# ), +# ), +# function( +# hypothesis.strategies.floats( +# min_value=10, +# max_value=10, +# ), +# ), +# steps=128, +# dtype=torch.float64, +# ), +# torch.linspace( +# function( +# hypothesis.strategies.floats( +# min_value=-10, +# max_value=-10, +# ), +# ), +# function( +# hypothesis.strategies.floats( +# min_value=10, +# max_value=10, +# ), +# ), +# steps=128, +# dtype=torch.float64, +# ), +# indexing="xy", +# ) +# +# input = x + 1.0j * y +# +# return input, scipy.special.dawsn(input) +# +# +# @hypothesis.given(_strategy()) +# def test_dawson_integral_f(data): +# input, output = data +# +# torch.testing.assert_close(beignet.special.dawson_integral_f(input), output) diff --git a/tests/beignet/test__add_chebyshev_polynomial.py b/tests/beignet/test__add_chebyshev_polynomial.py new file mode 100644 index 0000000000..6872f092eb --- /dev/null +++ b/tests/beignet/test__add_chebyshev_polynomial.py @@ -0,0 +1,25 @@ +import beignet +import torch + + +def test_add_chebyshev_polynomial(): + for j in range(5): + for k in range(5): + target = torch.zeros(max(j, k) + 1) + + target[j] = target[j] + 1 + target[k] = target[k] + 1 + + torch.testing.assert_close( + beignet.trim_chebyshev_polynomial_coefficients( + beignet.add_chebyshev_polynomial( + torch.tensor([0.0] * j + [1.0]), + torch.tensor([0.0] * k + [1.0]), + ), + tol=0.000001, + ), + beignet.trim_chebyshev_polynomial_coefficients( + target, + tol=0.000001, + ), + ) diff --git a/tests/beignet/test__add_laguerre_polynomial.py b/tests/beignet/test__add_laguerre_polynomial.py new file mode 100644 index 0000000000..748424e79e --- /dev/null +++ b/tests/beignet/test__add_laguerre_polynomial.py @@ -0,0 +1,25 @@ +import beignet +import torch + + +def test_add_laguerre_polynomial(): + for i in range(5): + for j in range(5): + target = torch.zeros(max(i, j) + 1) + + target[i] = target[i] + 1 + target[j] = target[j] + 1 + + torch.testing.assert_close( + beignet.trim_laguerre_polynomial_coefficients( + beignet.add_laguerre_polynomial( + torch.tensor([0.0] * i + [1.0]), + torch.tensor([0.0] * j + [1.0]), + ), + tol=0.000001, + ), + beignet.trim_laguerre_polynomial_coefficients( + target, + tol=0.000001, + ), + ) diff --git a/tests/beignet/test__add_legendre_polynomial.py b/tests/beignet/test__add_legendre_polynomial.py new file mode 100644 index 0000000000..131cd28422 --- /dev/null +++ b/tests/beignet/test__add_legendre_polynomial.py @@ -0,0 +1,25 @@ +import beignet +import torch + + +def test_add_legendre_polynomial(): + for i in range(5): + for j in range(5): + target = torch.zeros(max(i, j) + 1) + + target[i] = target[i] + 1 + target[j] = target[j] + 1 + + torch.testing.assert_close( + beignet.trim_legendre_polynomial_coefficients( + beignet.add_legendre_polynomial( + torch.tensor([0.0] * i + [1.0]), + torch.tensor([0.0] * j + [1.0]), + ), + tol=0.000001, + ), + beignet.trim_legendre_polynomial_coefficients( + target, + tol=0.000001, + ), + ) diff --git a/tests/beignet/test__add_physicists_hermite_polynomial.py b/tests/beignet/test__add_physicists_hermite_polynomial.py new file mode 100644 index 0000000000..20013dfac2 --- /dev/null +++ b/tests/beignet/test__add_physicists_hermite_polynomial.py @@ -0,0 +1,25 @@ +import beignet +import torch + + +def test_add_physicists_hermite_polynomial(): + for j in range(5): + for k in range(5): + target = torch.zeros(max(j, k) + 1) + + target[j] = target[j] + 1 + target[k] = target[k] + 1 + + torch.testing.assert_close( + beignet.trim_physicists_hermite_polynomial_coefficients( + beignet.add_physicists_hermite_polynomial( + torch.tensor([0.0] * j + [1.0]), + torch.tensor([0.0] * k + [1.0]), + ), + tol=0.000001, + ), + beignet.trim_physicists_hermite_polynomial_coefficients( + target, + tol=0.000001, + ), + ) diff --git a/tests/beignet/test__add_polynomial.py b/tests/beignet/test__add_polynomial.py new file mode 100644 index 0000000000..1a526d042a --- /dev/null +++ b/tests/beignet/test__add_polynomial.py @@ -0,0 +1,25 @@ +import beignet +import torch + + +def test_add_polynomial(): + for i in range(5): + for j in range(5): + target = torch.zeros(max(i, j) + 1) + + target[i] = target[i] + 1 + target[j] = target[j] + 1 + + torch.testing.assert_close( + beignet.trim_polynomial_coefficients( + beignet.add_polynomial( + torch.tensor([0.0] * i + [1.0]), + torch.tensor([0.0] * j + [1.0]), + ), + tol=0.000001, + ), + beignet.trim_polynomial_coefficients( + target, + tol=0.000001, + ), + ) diff --git a/tests/beignet/test__add_probabilists_hermite_polynomial.py b/tests/beignet/test__add_probabilists_hermite_polynomial.py new file mode 100644 index 0000000000..fd5c66fe57 --- /dev/null +++ b/tests/beignet/test__add_probabilists_hermite_polynomial.py @@ -0,0 +1,25 @@ +import beignet +import torch + + +def test_add_probabilists_hermite_polynomial(): + for j in range(5): + for k in range(5): + target = torch.zeros(max(j, k) + 1) + + target[j] = target[j] + 1 + target[k] = target[k] + 1 + + torch.testing.assert_close( + beignet.trim_probabilists_hermite_polynomial_coefficients( + beignet.add_probabilists_hermite_polynomial( + torch.tensor([0.0] * j + [1.0]), + torch.tensor([0.0] * k + [1.0]), + ), + tol=0.000001, + ), + beignet.trim_probabilists_hermite_polynomial_coefficients( + target, + tol=0.000001, + ), + ) diff --git a/tests/beignet/test__apply_transform.py b/tests/beignet/test__apply_transform.py index 7811aebdba..44fdacf487 100644 --- a/tests/beignet/test__apply_transform.py +++ b/tests/beignet/test__apply_transform.py @@ -1,21 +1,21 @@ -import torch -import torch.func -from beignet import apply_transform -from torch import Tensor - - -def test_apply_transform(): - input = torch.randn([32, 3]) - - transform = torch.randn([3, 3]) - - def f(r: Tensor) -> Tensor: - return torch.sum(r**2) - - def g(r: Tensor, t: Tensor) -> Tensor: - return torch.sum(apply_transform(r, t) ** 2) - - torch.testing.assert_close( - torch.func.grad(f)(apply_transform(input, transform)), - torch.func.grad(g, 0)(input, transform), - ) +# import torch +# import torch.func +# from beignet import apply_transform +# from torch import Tensor +# +# +# def test_apply_transform(): +# input = torch.randn([32, 3]) +# +# transform = torch.randn([3, 3]) +# +# def f(r: Tensor) -> Tensor: +# return torch.sum(r**2) +# +# def g(r: Tensor, t: Tensor) -> Tensor: +# return torch.sum(apply_transform(r, t) ** 2) +# +# torch.testing.assert_close( +# torch.func.grad(f)(apply_transform(input, transform)), +# torch.func.grad(g, 0)(input, transform), +# ) diff --git a/tests/beignet/test__chebyshev_extrema.py b/tests/beignet/test__chebyshev_extrema.py new file mode 100644 index 0000000000..c17cf3ff0a --- /dev/null +++ b/tests/beignet/test__chebyshev_extrema.py @@ -0,0 +1,31 @@ +import beignet +import pytest +import torch + + +def test_chebyshev_extrema(): + with pytest.raises(ValueError): + beignet.chebyshev_extrema(1.5) + + with pytest.raises(ValueError): + beignet.chebyshev_extrema(1) + + torch.testing.assert_close( + beignet.chebyshev_extrema(2), + torch.tensor([-1.0, 1.0]), + ) + + torch.testing.assert_close( + beignet.chebyshev_extrema(3), + torch.tensor([-1.0, 0.0, 1.0]), + ) + + torch.testing.assert_close( + beignet.chebyshev_extrema(4), + torch.tensor([-1.0, -0.5, 0.5, 1.0]), + ) + + torch.testing.assert_close( + beignet.chebyshev_extrema(5), + torch.tensor([-1.0, -0.707106781187, 0, 0.707106781187, 1.0]), + ) diff --git a/tests/beignet/test__chebyshev_gauss_quadrature.py b/tests/beignet/test__chebyshev_gauss_quadrature.py new file mode 100644 index 0000000000..440914634c --- /dev/null +++ b/tests/beignet/test__chebyshev_gauss_quadrature.py @@ -0,0 +1,27 @@ +import math + +import beignet +import torch + + +def test_chebyshev_gauss_quadrature(): + output, weight = beignet.chebyshev_gauss_quadrature(100) + + output = beignet.chebyshev_polynomial_vandermonde( + output, + degree=torch.tensor([99]), + ) + + u = (output.T * weight) @ output + + v = 1 / torch.sqrt(u.diagonal()) + + torch.testing.assert_close( + v[:, None] * u * v, + torch.eye(100), + ) + + torch.testing.assert_close( + torch.sum(weight), + torch.tensor(math.pi), + ) diff --git a/tests/beignet/test__chebyshev_interpolation.py b/tests/beignet/test__chebyshev_interpolation.py new file mode 100644 index 0000000000..374a419141 --- /dev/null +++ b/tests/beignet/test__chebyshev_interpolation.py @@ -0,0 +1,32 @@ +import beignet +import pytest +import torch + + +def test_chebyshev_interpolation(): + def f(x): + return x * (x - 1) * (x - 2) + + with pytest.raises(ValueError): + beignet.chebyshev_interpolation(f, -1) + + for i in range(1, 5): + assert beignet.chebyshev_interpolation(f, i).shape == (i + 1,) + + def powx(x, p): + return x**p + + x = torch.linspace(-1, 1, 10) + + for i in range(0, 10): + for j in range(0, i + 1): + c = beignet.chebyshev_interpolation( + powx, + i, + j, + ) + + torch.testing.assert_close( + beignet.evaluate_chebyshev_polynomial(x, c), + powx(x, j), + ) diff --git a/tests/beignet/test__chebyshev_polynomial_companion.py b/tests/beignet/test__chebyshev_polynomial_companion.py new file mode 100644 index 0000000000..e76b585ec9 --- /dev/null +++ b/tests/beignet/test__chebyshev_polynomial_companion.py @@ -0,0 +1,28 @@ +import beignet +import pytest +import torch + + +def test_chebyshev_polynomial_companion(): + with pytest.raises(ValueError): + beignet.chebyshev_polynomial_companion( + torch.tensor([]), + ) + + with pytest.raises(ValueError): + beignet.chebyshev_polynomial_companion( + torch.tensor([1.0]), + ) + + for index in range(1, 5): + output = beignet.chebyshev_polynomial_companion( + torch.tensor([0.0] * index + [1.0]), + ) + + assert output.shape == (index, index) + + output = beignet.chebyshev_polynomial_companion( + torch.tensor([1.0, 2.0]), + ) + + assert output[0, 0] == -0.5 diff --git a/tests/beignet/test__chebyshev_polynomial_domain.py b/tests/beignet/test__chebyshev_polynomial_domain.py new file mode 100644 index 0000000000..84bdb329cf --- /dev/null +++ b/tests/beignet/test__chebyshev_polynomial_domain.py @@ -0,0 +1,10 @@ +import beignet +import torch + + +def test_chebyshev_polynomial_domain(): + torch.testing.assert_close( + beignet.chebyshev_polynomial_domain, + torch.tensor([-1.0, 1.0]), + check_dtype=False, + ) diff --git a/tests/beignet/test__chebyshev_polynomial_from_roots.py b/tests/beignet/test__chebyshev_polynomial_from_roots.py new file mode 100644 index 0000000000..a35416d9a4 --- /dev/null +++ b/tests/beignet/test__chebyshev_polynomial_from_roots.py @@ -0,0 +1,34 @@ +import math + +import beignet +import torch + + +def test_chebyshev_polynomial_from_roots(): + torch.testing.assert_close( + beignet.trim_chebyshev_polynomial_coefficients( + beignet.chebyshev_polynomial_from_roots( + torch.tensor([]), + ), + tol=0.000001, + ), + torch.tensor([1.0]), + ) + + for index in range(1, 5): + input = beignet.chebyshev_polynomial_from_roots( + torch.cos(torch.linspace(-math.pi, 0.0, 2 * index + 1)[1::2]), + ) + + input = input * 2 ** (index - 1) + + torch.testing.assert_close( + beignet.trim_chebyshev_polynomial_coefficients( + input, + tol=0.000001, + ), + beignet.trim_chebyshev_polynomial_coefficients( + torch.tensor([0.0] * index + [1.0]), + tol=0.000001, + ), + ) diff --git a/tests/beignet/test__chebyshev_polynomial_one.py b/tests/beignet/test__chebyshev_polynomial_one.py new file mode 100644 index 0000000000..ba7dccd159 --- /dev/null +++ b/tests/beignet/test__chebyshev_polynomial_one.py @@ -0,0 +1,10 @@ +import beignet +import torch + + +def test_chebyshev_polynomial_one(): + torch.testing.assert_close( + beignet.chebyshev_polynomial_one, + torch.tensor([1.0]), + check_dtype=False, + ) diff --git a/tests/beignet/test__chebyshev_polynomial_power.py b/tests/beignet/test__chebyshev_polynomial_power.py new file mode 100644 index 0000000000..d3e90f5f0d --- /dev/null +++ b/tests/beignet/test__chebyshev_polynomial_power.py @@ -0,0 +1,26 @@ +import functools + +import beignet +import torch + + +def test_chebyshev_polynomial_power(): + for j in range(5): + for k in range(5): + torch.testing.assert_close( + beignet.trim_chebyshev_polynomial_coefficients( + beignet.chebyshev_polynomial_power( + torch.arange(0.0, j + 1), + k, + ), + tol=0.000001, + ), + beignet.trim_chebyshev_polynomial_coefficients( + functools.reduce( + beignet.multiply_chebyshev_polynomial, + [torch.arange(0.0, j + 1)] * k, + torch.tensor([1.0]), + ), + tol=0.000001, + ), + ) diff --git a/tests/beignet/test__chebyshev_polynomial_roots.py b/tests/beignet/test__chebyshev_polynomial_roots.py new file mode 100644 index 0000000000..aa581a314b --- /dev/null +++ b/tests/beignet/test__chebyshev_polynomial_roots.py @@ -0,0 +1,34 @@ +import beignet +import torch + + +def test_chebyshev_polynomial_roots(): + torch.testing.assert_close( + beignet.chebyshev_polynomial_roots( + torch.tensor([1.0]), + ), + torch.tensor([]), + ) + + torch.testing.assert_close( + beignet.chebyshev_polynomial_roots( + torch.tensor([1.0, 2.0]), + ), + torch.tensor([-0.5]), + ) + + for i in range(2, 5): + torch.testing.assert_close( + beignet.trim_chebyshev_polynomial_coefficients( + beignet.chebyshev_polynomial_roots( + beignet.chebyshev_polynomial_from_roots( + torch.linspace(-1, 1, i), + ) + ), + tol=0.000001, + ), + beignet.trim_chebyshev_polynomial_coefficients( + torch.linspace(-1, 1, i), + tol=0.000001, + ), + ) diff --git a/tests/beignet/test__chebyshev_polynomial_vandermonde.py b/tests/beignet/test__chebyshev_polynomial_vandermonde.py new file mode 100644 index 0000000000..38546a1641 --- /dev/null +++ b/tests/beignet/test__chebyshev_polynomial_vandermonde.py @@ -0,0 +1,36 @@ +import beignet +import torch + + +def test_chebyshev_polynomial_vandermonde(): + v = beignet.chebyshev_polynomial_vandermonde( + torch.arange(3), + degree=torch.tensor([3]), + ) + + assert v.shape == (3, 4) + + for i in range(4): + torch.testing.assert_close( + v[..., i], + beignet.evaluate_chebyshev_polynomial( + torch.arange(3), + torch.tensor([0.0] * i + [1.0]), + ), + ) + + v = beignet.chebyshev_polynomial_vandermonde( + torch.tensor([[1.0, 2.0], [3.0, 4.0], [5.0, 6.0]]), + degree=torch.tensor([3]), + ) + + assert v.shape == (3, 2, 4) + + for i in range(4): + torch.testing.assert_close( + v[..., i], + beignet.evaluate_chebyshev_polynomial( + torch.tensor([[1.0, 2.0], [3.0, 4.0], [5.0, 6.0]]), + torch.tensor([0.0] * i + [1.0]), + ), + ) diff --git a/tests/beignet/test__chebyshev_polynomial_vandermonde_2d.py b/tests/beignet/test__chebyshev_polynomial_vandermonde_2d.py new file mode 100644 index 0000000000..5e56e82367 --- /dev/null +++ b/tests/beignet/test__chebyshev_polynomial_vandermonde_2d.py @@ -0,0 +1,31 @@ +import beignet +import torch + + +def test_chebyshev_polynomial_vandermonde_2d(): + a, b, c = torch.rand(3, 5) * 2 - 1 + + coefficients = torch.rand(2, 3) + + output = beignet.chebyshev_polynomial_vandermonde_2d( + a, + b, + degree=torch.tensor([1, 2]), + ) + + torch.testing.assert_close( + output @ torch.ravel(coefficients), + beignet.evaluate_chebyshev_polynomial_2d( + a, + b, + coefficients, + ), + ) + + van = beignet.chebyshev_polynomial_vandermonde_2d( + a, + b, + degree=torch.tensor([1, 2]), + ) + + assert van.shape == (5, 6) diff --git a/tests/beignet/test__chebyshev_polynomial_vandermonde_3d.py b/tests/beignet/test__chebyshev_polynomial_vandermonde_3d.py new file mode 100644 index 0000000000..d72247d0be --- /dev/null +++ b/tests/beignet/test__chebyshev_polynomial_vandermonde_3d.py @@ -0,0 +1,34 @@ +import beignet +import torch + + +def test_chebyshev_polynomial_vandermonde_3d(): + a, b, c = torch.rand(3, 5) * 2 - 1 + + coefficients = torch.rand(2, 3, 4) + + output = beignet.chebyshev_polynomial_vandermonde_3d( + a, + b, + c, + degree=torch.tensor([1, 2, 3]), + ) + + torch.testing.assert_close( + output @ torch.ravel(coefficients), + beignet.evaluate_chebyshev_polynomial_3d( + a, + b, + c, + coefficients, + ), + ) + + output = beignet.chebyshev_polynomial_vandermonde_3d( + a, + b, + c, + degree=torch.tensor([1, 2, 3]), + ) + + assert output.shape == (5, 24) diff --git a/tests/beignet/test__chebyshev_polynomial_weight.py b/tests/beignet/test__chebyshev_polynomial_weight.py new file mode 100644 index 0000000000..b7111afd29 --- /dev/null +++ b/tests/beignet/test__chebyshev_polynomial_weight.py @@ -0,0 +1,11 @@ +import beignet +import torch + + +def test_chebyshev_polynomial_weight(): + x = torch.linspace(-1, 1, 11)[1:-1] + + torch.testing.assert_close( + beignet.chebyshev_polynomial_weight(x), + 1.0 / (torch.sqrt(1 + x) * torch.sqrt(1 - x)), + ) diff --git a/tests/beignet/test__chebyshev_polynomial_x.py b/tests/beignet/test__chebyshev_polynomial_x.py new file mode 100644 index 0000000000..9fdb362d19 --- /dev/null +++ b/tests/beignet/test__chebyshev_polynomial_x.py @@ -0,0 +1,10 @@ +import beignet +import torch + + +def test_chebyshev_polynomial_x(): + torch.testing.assert_close( + beignet.chebyshev_polynomial_x, + torch.tensor([0.0, 1.0]), + check_dtype=False, + ) diff --git a/tests/beignet/test__chebyshev_polynomial_zero.py b/tests/beignet/test__chebyshev_polynomial_zero.py new file mode 100644 index 0000000000..a066c1f345 --- /dev/null +++ b/tests/beignet/test__chebyshev_polynomial_zero.py @@ -0,0 +1,10 @@ +import beignet +import torch + + +def test_chebyshev_polynomial_zero(): + torch.testing.assert_close( + beignet.chebyshev_polynomial_zero, + torch.tensor([0.0]), + check_dtype=False, + ) diff --git a/tests/beignet/test__chebyshev_zeros.py b/tests/beignet/test__chebyshev_zeros.py new file mode 100644 index 0000000000..33bf04067a --- /dev/null +++ b/tests/beignet/test__chebyshev_zeros.py @@ -0,0 +1,28 @@ +import beignet +import pytest +import torch + + +def test_chebyshev_zeros(): + with pytest.raises(ValueError): + beignet.chebyshev_zeros(0) + + torch.testing.assert_close( + beignet.chebyshev_zeros(1), + torch.tensor([0.0]), + ) + + torch.testing.assert_close( + beignet.chebyshev_zeros(2), + torch.tensor([-0.70710678118654746, 0.70710678118654746]), + ) + + torch.testing.assert_close( + beignet.chebyshev_zeros(3), + torch.tensor([-0.86602540378443871, 0, 0.86602540378443871]), + ) + + torch.testing.assert_close( + beignet.chebyshev_zeros(4), + torch.tensor([-0.9238795325, -0.3826834323, 0.3826834323, 0.9238795325]), + ) diff --git a/tests/beignet/test__differentiate_chebyshev_polynomial.py b/tests/beignet/test__differentiate_chebyshev_polynomial.py new file mode 100644 index 0000000000..3800fdbb41 --- /dev/null +++ b/tests/beignet/test__differentiate_chebyshev_polynomial.py @@ -0,0 +1,91 @@ +import beignet +import pytest +import torch + + +def test_differentiate_chebyshev_polynomial(): + with pytest.raises(TypeError): + beignet.differentiate_chebyshev_polynomial( + torch.tensor([0.0]), + torch.tensor([0.5]), + ) + + with pytest.raises(ValueError): + beignet.differentiate_chebyshev_polynomial( + torch.tensor([0.0]), + order=torch.tensor([-1.0]), + ) + + for i in range(5): + torch.testing.assert_close( + beignet.trim_chebyshev_polynomial_coefficients( + beignet.differentiate_chebyshev_polynomial( + torch.tensor([0.0] * i + [1.0]), + order=torch.tensor([0.0]), + ), + tol=0.000001, + ), + beignet.trim_chebyshev_polynomial_coefficients( + torch.tensor([0.0] * i + [1.0]), + tol=0.000001, + ), + ) + + # for i in range(5): + # for j in range(2, 5): + # torch.testing.assert_close( + # beignet.chebtrim( + # beignet.chebder( + # beignet.chebint( + # torch.tensor([0.0] * i + [1.0]), order=j + # ), + # order=j, + # ), + # tol=0.000001, + # ), + # beignet.chebtrim( + # torch.tensor([0.0] * i + [1.0]), + # tol=0.000001, + # ), + # ) + + # for i in range(5): + # for j in range(2, 5): + # torch.testing.assert_close( + # beignet.chebtrim( + # beignet.chebder( + # beignet.chebint( + # torch.tensor([0.0] * i + [1.0]), + # order=j, + # scale=2.0, + # ), + # order=j, + # scale=0.5, + # ), + # tol=0.000001, + # ), + # beignet.chebtrim( + # torch.tensor([0.0] * i + [1.0]), + # tol=0.000001, + # ), + # ) + + input = torch.rand(3, 4) + + torch.testing.assert_close( + beignet.differentiate_chebyshev_polynomial( + input, + axis=0, + ), + torch.vstack( + [beignet.differentiate_chebyshev_polynomial(c) for c in input.T] + ).T, + ) + + torch.testing.assert_close( + beignet.differentiate_chebyshev_polynomial( + input, + axis=1, + ), + torch.vstack([beignet.differentiate_chebyshev_polynomial(c) for c in input]), + ) diff --git a/tests/beignet/test__differentiate_laguerre_polynomial.py b/tests/beignet/test__differentiate_laguerre_polynomial.py new file mode 100644 index 0000000000..19aa48ddb0 --- /dev/null +++ b/tests/beignet/test__differentiate_laguerre_polynomial.py @@ -0,0 +1,87 @@ +# import beignet +# import pytest +# import torch +# +# +# def test_differentiate_laguerre_polynomial(): +# with pytest.raises(TypeError): +# beignet.differentiate_laguerre_polynomial( +# torch.tensor([0]), +# order=0.5, +# ) +# +# with pytest.raises(ValueError): +# beignet.differentiate_laguerre_polynomial( +# torch.tensor([0]), +# order=-1, +# ) +# +# for i in range(5): +# torch.testing.assert_close( +# beignet.trim_laguerre_polynomial_coefficients( +# beignet.differentiate_laguerre_polynomial( +# torch.tensor([0.0] * i + [1.0]), +# order=0, +# ), +# tol=0.000001, +# ), +# beignet.trim_laguerre_polynomial_coefficients( +# torch.tensor([0.0] * i + [1.0]), +# tol=0.000001, +# ), +# ) +# +# for i in range(5): +# for j in range(2, 5): +# torch.testing.assert_close( +# beignet.trim_laguerre_polynomial_coefficients( +# beignet.differentiate_laguerre_polynomial( +# beignet.integrate_laguerre_polynomial( +# torch.tensor([0.0] * i + [1.0]), +# order=j, +# ), +# order=j, +# ), +# tol=0.000001, +# ), +# beignet.trim_laguerre_polynomial_coefficients( +# torch.tensor([0.0] * i + [1.0]), +# tol=0.000001, +# ), +# ) +# +# for i in range(5): +# for j in range(2, 5): +# torch.testing.assert_close( +# beignet.trim_laguerre_polynomial_coefficients( +# beignet.differentiate_laguerre_polynomial( +# beignet.integrate_laguerre_polynomial( +# torch.tensor([0.0] * i + [1.0]), +# order=j, +# scale=2, +# ), +# order=j, +# scale=0.5, +# ), +# tol=0.000001, +# ), +# beignet.trim_laguerre_polynomial_coefficients( +# torch.tensor([0.0] * i + [1.0]), +# tol=0.000001, +# ), +# ) +# +# # c2d = torch.rand(3, 4) +# +# # torch.testing.assert_close( +# # beignet.lagder(c2d, axis=0), +# # torch.vstack([beignet.lagder(c) for c in c2d.T]).T, +# # ) +# +# # torch.testing.assert_close( +# # beignet.lagder( +# # c2d, +# # axis=1, +# # ), +# # torch.vstack([beignet.lagder(c) for c in c2d]), +# # ) diff --git a/tests/beignet/test__differentiate_legendre_polynomial.py b/tests/beignet/test__differentiate_legendre_polynomial.py new file mode 100644 index 0000000000..f2786aa046 --- /dev/null +++ b/tests/beignet/test__differentiate_legendre_polynomial.py @@ -0,0 +1,118 @@ +import beignet +import pytest +import torch + + +def test_differentiate_legendre_polynomial(): + with pytest.raises(TypeError): + beignet.differentiate_legendre_polynomial( + torch.tensor([0.0]), + order=0.5, + ) + + with pytest.raises(ValueError): + beignet.differentiate_legendre_polynomial( + torch.tensor([0.0]), + order=-1, + ) + + for i in range(5): + torch.testing.assert_close( + beignet.trim_legendre_polynomial_coefficients( + beignet.differentiate_legendre_polynomial( + torch.tensor([0.0] * i + [1.0]), + order=0, + ), + tol=0.000001, + ), + beignet.trim_legendre_polynomial_coefficients( + torch.tensor([0.0] * i + [1.0]), + tol=0.000001, + ), + ) + + for i in range(5): + for j in range(2, 5): + torch.testing.assert_close( + beignet.trim_legendre_polynomial_coefficients( + beignet.differentiate_legendre_polynomial( + beignet.integrate_legendre_polynomial( + torch.tensor([0.0] * i + [1.0]), + order=j, + ), + order=j, + ), + tol=0.000001, + ), + beignet.trim_legendre_polynomial_coefficients( + torch.tensor([0.0] * i + [1.0]), + tol=0.000001, + ), + ) + + for i in range(5): + for j in range(2, 5): + torch.testing.assert_close( + beignet.trim_legendre_polynomial_coefficients( + beignet.differentiate_legendre_polynomial( + beignet.integrate_legendre_polynomial( + torch.tensor([0.0] * i + [1.0]), + order=j, + scale=2, + ), + order=j, + scale=0.5, + ), + tol=0.000001, + ), + beignet.trim_legendre_polynomial_coefficients( + torch.tensor([0.0] * i + [1.0]), + tol=0.000001, + ), + ) + + coefficients = torch.rand(3, 4) + + target = [] + + for input in coefficients.T: + target = [ + *target, + beignet.differentiate_legendre_polynomial( + input, + ), + ] + + torch.testing.assert_close( + beignet.differentiate_legendre_polynomial( + coefficients, + axis=0, + ), + torch.vstack(target).T, + ) + + target = [] + + for input in coefficients: + target = [ + *target, + beignet.differentiate_legendre_polynomial( + input, + ), + ] + + # torch.testing.assert_close( + # beignet.legder( + # coefficients, + # axis=1, + # ), + # torch.vstack(target), + # ) + + torch.testing.assert_close( + beignet.differentiate_legendre_polynomial( + torch.tensor([1.0, 2.0, 3.0, 4.0]), + order=4, + ), + torch.tensor([0.0]), + ) diff --git a/tests/beignet/test__differentiate_physicists_hermite_polynomial.py b/tests/beignet/test__differentiate_physicists_hermite_polynomial.py new file mode 100644 index 0000000000..250498add6 --- /dev/null +++ b/tests/beignet/test__differentiate_physicists_hermite_polynomial.py @@ -0,0 +1,85 @@ +import beignet +import pytest +import torch + + +def test_differentiate_physicists_hermite_polynomial(): + with pytest.raises(TypeError): + beignet.differentiate_physicists_hermite_polynomial(torch.tensor([0]), 0.5) + + with pytest.raises(ValueError): + beignet.differentiate_physicists_hermite_polynomial(torch.tensor([0]), -1) + + for i in range(5): + torch.testing.assert_close( + beignet.trim_physicists_hermite_polynomial_coefficients( + beignet.differentiate_physicists_hermite_polynomial( + torch.tensor([0.0] * i + [1.0]), + order=0, + ), + tol=0.000001, + ), + beignet.trim_physicists_hermite_polynomial_coefficients( + torch.tensor([0.0] * i + [1.0]), + tol=0.000001, + ), + ) + + for i in range(5): + for j in range(2, 5): + torch.testing.assert_close( + beignet.trim_physicists_hermite_polynomial_coefficients( + beignet.differentiate_physicists_hermite_polynomial( + beignet.integrate_physicists_hermite_polynomial( + torch.tensor([0.0] * i + [1.0]), + order=j, + ), + order=j, + ), + tol=0.000001, + ), + beignet.trim_physicists_hermite_polynomial_coefficients( + torch.tensor([0.0] * i + [1.0]), + tol=0.000001, + ), + ) + + for i in range(5): + for j in range(2, 5): + torch.testing.assert_close( + beignet.trim_physicists_hermite_polynomial_coefficients( + beignet.differentiate_physicists_hermite_polynomial( + beignet.integrate_physicists_hermite_polynomial( + torch.tensor([0.0] * i + [1.0]), + order=j, + scale=2, + ), + order=j, + scale=0.5, + ), + tol=0.000001, + ), + beignet.trim_physicists_hermite_polynomial_coefficients( + torch.tensor([0.0] * i + [1.0]), + tol=0.000001, + ), + ) + + c2d = torch.rand(3, 4) + + torch.testing.assert_close( + beignet.differentiate_physicists_hermite_polynomial(c2d, axis=0), + torch.vstack( + [beignet.differentiate_physicists_hermite_polynomial(c) for c in c2d.T] + ).T, + ) + + torch.testing.assert_close( + beignet.differentiate_physicists_hermite_polynomial( + c2d, + axis=1, + ), + torch.vstack( + [beignet.differentiate_physicists_hermite_polynomial(c) for c in c2d] + ), + ) diff --git a/tests/beignet/test__differentiate_probabilists_hermite_polynomial.py b/tests/beignet/test__differentiate_probabilists_hermite_polynomial.py new file mode 100644 index 0000000000..f5c027a14d --- /dev/null +++ b/tests/beignet/test__differentiate_probabilists_hermite_polynomial.py @@ -0,0 +1,90 @@ +import beignet +import pytest +import torch + + +def test_differentiate_probabilists_hermite_polynomial(): + pytest.raises( + TypeError, + beignet.differentiate_probabilists_hermite_polynomial, + torch.tensor([0]), + 0.5, + ) + pytest.raises( + ValueError, + beignet.differentiate_probabilists_hermite_polynomial, + torch.tensor([0]), + -1, + ) + + for i in range(5): + torch.testing.assert_close( + beignet.trim_probabilists_hermite_polynomial_coefficients( + beignet.differentiate_probabilists_hermite_polynomial( + torch.tensor([0.0] * i + [1.0]), order=0 + ), + tol=0.000001, + ), + beignet.trim_probabilists_hermite_polynomial_coefficients( + torch.tensor([0.0] * i + [1.0]), + tol=0.000001, + ), + ) + + for i in range(5): + for j in range(2, 5): + torch.testing.assert_close( + beignet.trim_probabilists_hermite_polynomial_coefficients( + beignet.differentiate_probabilists_hermite_polynomial( + beignet.integrate_probabilists_hermite_polynomial( + torch.tensor([0.0] * i + [1.0]), order=j + ), + order=j, + ), + tol=0.000001, + ), + beignet.trim_probabilists_hermite_polynomial_coefficients( + torch.tensor([0.0] * i + [1.0]), + tol=0.000001, + ), + ) + + for i in range(5): + for j in range(2, 5): + torch.testing.assert_close( + beignet.trim_probabilists_hermite_polynomial_coefficients( + beignet.differentiate_probabilists_hermite_polynomial( + beignet.integrate_probabilists_hermite_polynomial( + torch.tensor([0.0] * i + [1.0]), + order=j, + scale=2, + ), + order=j, + scale=0.5, + ), + tol=0.000001, + ), + beignet.trim_probabilists_hermite_polynomial_coefficients( + torch.tensor([0.0] * i + [1.0]), + tol=0.000001, + ), + ) + + c2d = torch.rand(3, 4) + + torch.testing.assert_close( + beignet.differentiate_probabilists_hermite_polynomial(c2d, axis=0), + torch.vstack( + [beignet.differentiate_probabilists_hermite_polynomial(c) for c in c2d.T] + ).T, + ) + + torch.testing.assert_close( + beignet.differentiate_probabilists_hermite_polynomial( + c2d, + axis=1, + ), + torch.vstack( + [beignet.differentiate_probabilists_hermite_polynomial(c) for c in c2d] + ), + ) diff --git a/tests/beignet/test__divide_chebyshev_polynomial.py b/tests/beignet/test__divide_chebyshev_polynomial.py new file mode 100644 index 0000000000..cd91d0a858 --- /dev/null +++ b/tests/beignet/test__divide_chebyshev_polynomial.py @@ -0,0 +1,37 @@ +import beignet +import torch + + +def test_divide_chebyshev_polynomial(): + for j in range(5): + for k in range(5): + input = torch.tensor([0.0] * j + [1.0]) + other = torch.tensor([0.0] * k + [1.0]) + + quotient, remainder = beignet.divide_chebyshev_polynomial( + beignet.add_chebyshev_polynomial( + input, + other, + ), + input, + ) + + torch.testing.assert_close( + beignet.trim_chebyshev_polynomial_coefficients( + beignet.add_chebyshev_polynomial( + beignet.multiply_chebyshev_polynomial( + quotient, + input, + ), + remainder, + ), + tol=0.000001, + ), + beignet.trim_chebyshev_polynomial_coefficients( + beignet.add_chebyshev_polynomial( + input, + other, + ), + tol=0.000001, + ), + ) diff --git a/tests/beignet/test__divide_laguerre_polynomial.py b/tests/beignet/test__divide_laguerre_polynomial.py new file mode 100644 index 0000000000..c185a916a5 --- /dev/null +++ b/tests/beignet/test__divide_laguerre_polynomial.py @@ -0,0 +1,34 @@ +import beignet +import torch + + +def test_divide_laguerre_polynomial(): + for i in range(5): + for j in range(5): + quotient, remainder = beignet.divide_laguerre_polynomial( + beignet.add_laguerre_polynomial( + torch.tensor([0.0] * i + [1.0]), + torch.tensor([0.0] * j + [1.0]), + ), + torch.tensor([0.0] * i + [1.0]), + ) + + torch.testing.assert_close( + beignet.trim_laguerre_polynomial_coefficients( + beignet.add_laguerre_polynomial( + beignet.multiply_laguerre_polynomial( + quotient, + torch.tensor([0.0] * i + [1.0]), + ), + remainder, + ), + tol=0.000001, + ), + beignet.trim_laguerre_polynomial_coefficients( + beignet.add_laguerre_polynomial( + torch.tensor([0.0] * i + [1.0]), + torch.tensor([0.0] * j + [1.0]), + ), + tol=0.000001, + ), + ) diff --git a/tests/beignet/test__divide_legendre_polynomial.py b/tests/beignet/test__divide_legendre_polynomial.py new file mode 100644 index 0000000000..58c890d8ab --- /dev/null +++ b/tests/beignet/test__divide_legendre_polynomial.py @@ -0,0 +1,34 @@ +import beignet +import torch + + +def test_divide_legendre_polynomial(): + for i in range(5): + for j in range(5): + quotient, remainder = beignet.divide_legendre_polynomial( + beignet.add_legendre_polynomial( + torch.tensor([0.0] * i + [1.0]), + torch.tensor([0.0] * j + [1.0]), + ), + torch.tensor([0.0] * i + [1.0]), + ) + + torch.testing.assert_close( + beignet.trim_legendre_polynomial_coefficients( + beignet.add_legendre_polynomial( + beignet.multiply_legendre_polynomial( + quotient, + torch.tensor([0.0] * i + [1.0]), + ), + remainder, + ), + tol=0.000001, + ), + beignet.trim_legendre_polynomial_coefficients( + beignet.add_legendre_polynomial( + torch.tensor([0.0] * i + [1.0]), + torch.tensor([0.0] * j + [1.0]), + ), + tol=0.000001, + ), + ) diff --git a/tests/beignet/test__divide_physicists_hermite_polynomial.py b/tests/beignet/test__divide_physicists_hermite_polynomial.py new file mode 100644 index 0000000000..ef12c9a763 --- /dev/null +++ b/tests/beignet/test__divide_physicists_hermite_polynomial.py @@ -0,0 +1,37 @@ +import beignet +import torch + + +def test_divide_physicists_hermite_polynomial(): + for j in range(5): + for k in range(5): + input = torch.tensor([0.0] * j + [1.0]) + other = torch.tensor([0.0] * k + [1.0]) + + quotient, remainder = beignet.divide_physicists_hermite_polynomial( + beignet.add_physicists_hermite_polynomial( + input, + other, + ), + input, + ) + + torch.testing.assert_close( + beignet.trim_physicists_hermite_polynomial_coefficients( + beignet.add_physicists_hermite_polynomial( + beignet.multiply_physicists_hermite_polynomial( + quotient, + input, + ), + remainder, + ), + tol=0.000001, + ), + beignet.trim_physicists_hermite_polynomial_coefficients( + beignet.add_physicists_hermite_polynomial( + input, + other, + ), + tol=0.000001, + ), + ) diff --git a/tests/beignet/test__divide_polynomial.py b/tests/beignet/test__divide_polynomial.py new file mode 100644 index 0000000000..2f406783b2 --- /dev/null +++ b/tests/beignet/test__divide_polynomial.py @@ -0,0 +1,67 @@ +import beignet +import torch + + +def test_divide_polynomial(): + quotient, remainder = beignet.divide_polynomial( + torch.tensor([2.0]), + torch.tensor([2.0]), + ) + + torch.testing.assert_close( + quotient, + torch.tensor([1.0]), + ) + + torch.testing.assert_close( + remainder, + torch.tensor([0.0]), + ) + + quotient, remainder = beignet.divide_polynomial( + torch.tensor([2.0, 2.0]), + torch.tensor([2.0]), + ) + + torch.testing.assert_close( + quotient, + torch.tensor([1.0, 1.0]), + ) + + torch.testing.assert_close( + remainder, + torch.tensor([0.0]), + ) + + for j in range(5): + for k in range(5): + input = torch.tensor([0.0] * j + [1.0, 2.0]) + other = torch.tensor([0.0] * k + [1.0, 2.0]) + + quotient, remainder = beignet.divide_polynomial( + beignet.add_polynomial( + input, + other, + ), + input, + ) + + torch.testing.assert_close( + beignet.trim_polynomial_coefficients( + beignet.add_polynomial( + beignet.multiply_polynomial( + quotient, + input, + ), + remainder, + ), + tol=0.000001, + ), + beignet.trim_polynomial_coefficients( + beignet.add_polynomial( + input, + other, + ), + tol=0.000001, + ), + ) diff --git a/tests/beignet/test__divide_probabilists_hermite_polynomial.py b/tests/beignet/test__divide_probabilists_hermite_polynomial.py new file mode 100644 index 0000000000..91af2b76f2 --- /dev/null +++ b/tests/beignet/test__divide_probabilists_hermite_polynomial.py @@ -0,0 +1,37 @@ +import beignet +import torch + + +def test_divide_probabilists_hermite_polynomial(): + for j in range(5): + for k in range(5): + input = torch.tensor([0.0] * j + [1.0]) + other = torch.tensor([0.0] * k + [1.0]) + + quotient, remainder = beignet.divide_probabilists_hermite_polynomial( + beignet.add_probabilists_hermite_polynomial( + input, + other, + ), + input, + ) + + torch.testing.assert_close( + beignet.trim_probabilists_hermite_polynomial_coefficients( + beignet.add_probabilists_hermite_polynomial( + beignet.multiply_probabilists_hermite_polynomial( + quotient, + input, + ), + remainder, + ), + tol=0.000001, + ), + beignet.trim_probabilists_hermite_polynomial_coefficients( + beignet.add_probabilists_hermite_polynomial( + input, + other, + ), + tol=0.000001, + ), + ) diff --git a/tests/beignet/test__evaluate_chebyshev_polynomial.py b/tests/beignet/test__evaluate_chebyshev_polynomial.py new file mode 100644 index 0000000000..d2156ea3cf --- /dev/null +++ b/tests/beignet/test__evaluate_chebyshev_polynomial.py @@ -0,0 +1,72 @@ +import math + +import beignet +import torch + + +def test_evaluate_chebyshev_polynomial(): + chebcoefficients = [ + torch.tensor([1]), + torch.tensor([0, 1]), + torch.tensor([-1, 0, 2]), + torch.tensor([0, -3, 0, 4]), + torch.tensor([1, 0, -8, 0, 8]), + torch.tensor([0, 5, 0, -20, 0, 16]), + torch.tensor([-1, 0, 18, 0, -48, 0, 32]), + torch.tensor([0, -7, 0, 56, 0, -112, 0, 64]), + torch.tensor([1, 0, -32, 0, 160, 0, -256, 0, 128]), + torch.tensor([0, 9, 0, -120, 0, 432, 0, -576, 0, 256]), + ] + + output = beignet.evaluate_chebyshev_polynomial( + torch.tensor([]), + torch.tensor([1.0]), + ) + + assert math.prod(output.shape) == 0 + + ys = [] + + for coefficient in chebcoefficients: + ys = [ + *ys, + beignet.evaluate_polynomial( + torch.linspace(-1, 1, 50), + coefficient, + ), + ] + + for index in range(10): + torch.testing.assert_close( + beignet.evaluate_chebyshev_polynomial( + torch.linspace(-1, 1, 50), + torch.tensor([0.0] * index + [1.0]), + ), + torch.tensor(ys[index]), + ) + + for index in range(3): + shape = (2,) * index + + input = torch.zeros(shape) + + output = beignet.evaluate_chebyshev_polynomial( + input, + torch.tensor([1.0]), + ) + + assert output.shape == shape + + output = beignet.evaluate_chebyshev_polynomial( + input, + torch.tensor([1.0, 0.0]), + ) + + assert output.shape == shape + + output = beignet.evaluate_chebyshev_polynomial( + input, + torch.tensor([1.0, 0.0, 0.0]), + ) + + assert output.shape == shape diff --git a/tests/beignet/test__evaluate_chebyshev_polynomial_2d.py b/tests/beignet/test__evaluate_chebyshev_polynomial_2d.py new file mode 100644 index 0000000000..9d32c4c52d --- /dev/null +++ b/tests/beignet/test__evaluate_chebyshev_polynomial_2d.py @@ -0,0 +1,50 @@ +import beignet +import pytest +import torch + + +def test_evaluate_chebyshev_polynomial_2d(): + input = torch.rand(3, 5) * 2 - 1 + + a, b, c = input + + x, y, z = beignet.evaluate_polynomial( + input, + torch.tensor([1.0, 2.0, 3.0]), + ) + + with pytest.raises(ValueError): + beignet.evaluate_chebyshev_polynomial_2d( + a, + b[:2], + torch.einsum( + "i,j->ij", + torch.tensor([2.5, 2.0, 1.5]), + torch.tensor([2.5, 2.0, 1.5]), + ), + ) + + torch.testing.assert_close( + beignet.evaluate_chebyshev_polynomial_2d( + a, + b, + torch.einsum( + "i,j->ij", + torch.tensor([2.5, 2.0, 1.5]), + torch.tensor([2.5, 2.0, 1.5]), + ), + ), + x * y, + ) + + output = beignet.evaluate_chebyshev_polynomial_2d( + torch.ones([2, 3]), + torch.ones([2, 3]), + torch.einsum( + "i,j->ij", + torch.tensor([2.5, 2.0, 1.5]), + torch.tensor([2.5, 2.0, 1.5]), + ), + ) + + assert output.shape == (2, 3) diff --git a/tests/beignet/test__evaluate_chebyshev_polynomial_3d.py b/tests/beignet/test__evaluate_chebyshev_polynomial_3d.py new file mode 100644 index 0000000000..91c778b981 --- /dev/null +++ b/tests/beignet/test__evaluate_chebyshev_polynomial_3d.py @@ -0,0 +1,56 @@ +import beignet +import pytest +import torch + + +def test_evaluate_chebyshev_polynomial_3d(): + input = torch.rand(3, 5) * 2 - 1 + + a, b, c = input + + x, y, z = beignet.evaluate_polynomial( + input, + torch.tensor([1.0, 2.0, 3.0]), + ) + + with pytest.raises(ValueError): + beignet.evaluate_chebyshev_polynomial_3d( + a, + b, + c[:2], + torch.einsum( + "i,j,k->ijk", + torch.tensor([2.5, 2.0, 1.5]), + torch.tensor([2.5, 2.0, 1.5]), + torch.tensor([2.5, 2.0, 1.5]), + ), + ) + + torch.testing.assert_close( + beignet.evaluate_chebyshev_polynomial_3d( + a, + b, + c, + torch.einsum( + "i,j,k->ijk", + torch.tensor([2.5, 2.0, 1.5]), + torch.tensor([2.5, 2.0, 1.5]), + torch.tensor([2.5, 2.0, 1.5]), + ), + ), + x * y * z, + ) + + output = beignet.evaluate_chebyshev_polynomial_3d( + torch.ones([2, 3]), + torch.ones([2, 3]), + torch.ones([2, 3]), + torch.einsum( + "i,j,k->ijk", + torch.tensor([2.5, 2.0, 1.5]), + torch.tensor([2.5, 2.0, 1.5]), + torch.tensor([2.5, 2.0, 1.5]), + ), + ) + + assert output.shape == (2, 3) diff --git a/tests/beignet/test__evaluate_chebyshev_polynomial_cartesian_2d.py b/tests/beignet/test__evaluate_chebyshev_polynomial_cartesian_2d.py new file mode 100644 index 0000000000..3db4b7edb9 --- /dev/null +++ b/tests/beignet/test__evaluate_chebyshev_polynomial_cartesian_2d.py @@ -0,0 +1,42 @@ +import beignet +import torch + + +def test_evaluate_chebyshev_polynomial_cartesian_2d(): + input = torch.rand(3, 5) * 2 - 1 + + a, b, c = input + + x, y, z = beignet.evaluate_polynomial( + input, + torch.tensor([1.0, 2.0, 3.0]), + ) + + torch.testing.assert_close( + beignet.evaluate_chebyshev_polynomial_cartesian_2d( + a, + b, + torch.einsum( + "i,j->ij", + torch.tensor([2.5, 2.0, 1.5]), + torch.tensor([2.5, 2.0, 1.5]), + ), + ), + torch.einsum( + "i,j->ij", + x, + y, + ), + ) + + output = beignet.evaluate_chebyshev_polynomial_cartesian_2d( + torch.ones([2, 3]), + torch.ones([2, 3]), + torch.einsum( + "i,j->ij", + torch.tensor([2.5, 2.0, 1.5]), + torch.tensor([2.5, 2.0, 1.5]), + ), + ) + + assert output.shape == (2, 3) * 2 diff --git a/tests/beignet/test__evaluate_chebyshev_polynomial_cartesian_3d.py b/tests/beignet/test__evaluate_chebyshev_polynomial_cartesian_3d.py new file mode 100644 index 0000000000..b45b9f6356 --- /dev/null +++ b/tests/beignet/test__evaluate_chebyshev_polynomial_cartesian_3d.py @@ -0,0 +1,47 @@ +import beignet +import torch + + +def test_evaluate_chebyshev_polynomial_cartesian_3d(): + input = torch.rand(3, 5) * 2 - 1 + + a, b, c = input + + x, y, z = beignet.evaluate_polynomial( + input, + torch.tensor([1.0, 2.0, 3.0]), + ) + + torch.testing.assert_close( + beignet.evaluate_chebyshev_polynomial_cartesian_3d( + a, + b, + c, + torch.einsum( + "i,j,k->ijk", + torch.tensor([2.5, 2.0, 1.5]), + torch.tensor([2.5, 2.0, 1.5]), + torch.tensor([2.5, 2.0, 1.5]), + ), + ), + torch.einsum( + "i,j,k->ijk", + x, + y, + z, + ), + ) + + output = beignet.evaluate_chebyshev_polynomial_cartesian_3d( + torch.ones([2, 3]), + torch.ones([2, 3]), + torch.ones([2, 3]), + torch.einsum( + "i,j,k->ijk", + torch.tensor([2.5, 2.0, 1.5]), + torch.tensor([2.5, 2.0, 1.5]), + torch.tensor([2.5, 2.0, 1.5]), + ), + ) + + assert output.shape == (2, 3) * 3 diff --git a/tests/beignet/test__evaluate_laguerre_polynomial.py b/tests/beignet/test__evaluate_laguerre_polynomial.py new file mode 100644 index 0000000000..08aaffa1bc --- /dev/null +++ b/tests/beignet/test__evaluate_laguerre_polynomial.py @@ -0,0 +1,71 @@ +import math + +import beignet +import torch + + +def test_evaluate_laguerre_polynomial(): + coefficients = [ + torch.tensor([1]) / 1, + torch.tensor([1, -1]) / 1, + torch.tensor([2, -4, 1]) / 2, + torch.tensor([6, -18, 9, -1]) / 6, + torch.tensor([24, -96, 72, -16, 1]) / 24, + torch.tensor([120, -600, 600, -200, 25, -1]) / 120, + torch.tensor([720, -4320, 5400, -2400, 450, -36, 1]) / 720, + ] + + output = beignet.evaluate_laguerre_polynomial( + torch.tensor([]), + torch.tensor([1.0]), + ) + + assert math.prod(output.shape) == 0 + + ys = [] + + input = torch.linspace(-1, 1, 50) + + for coefficient in coefficients: + ys = [ + *ys, + beignet.evaluate_polynomial( + input, + coefficient, + ), + ] + + for i in range(7): + torch.testing.assert_close( + beignet.evaluate_laguerre_polynomial( + input, + torch.tensor([0.0] * i + [1.0]), + ), + torch.tensor(torch.tensor(ys[i])), + ) + + for index in range(3): + shape = (2,) * index + + input = torch.zeros(shape) + + output = beignet.evaluate_laguerre_polynomial( + input, + torch.tensor([1.0]), + ) + + assert output.shape == shape + + output = beignet.evaluate_laguerre_polynomial( + input, + torch.tensor([1.0, 0.0]), + ) + + assert output.shape == shape + + output = beignet.evaluate_laguerre_polynomial( + input, + torch.tensor([1.0, 0.0, 0.0]), + ) + + assert output.shape == shape diff --git a/tests/beignet/test__evaluate_laguerre_polynomial_2d.py b/tests/beignet/test__evaluate_laguerre_polynomial_2d.py new file mode 100644 index 0000000000..38dd609504 --- /dev/null +++ b/tests/beignet/test__evaluate_laguerre_polynomial_2d.py @@ -0,0 +1,48 @@ +import beignet +import pytest +import torch + + +def test_evaluate_laguerre_polynomial_2d(): + input = torch.rand(3, 5) * 2 - 1 + + a, b, c = input + + x, y, z = beignet.evaluate_polynomial( + input, + torch.tensor([1.0, 2.0, 3.0]), + ) + + with pytest.raises(ValueError): + beignet.evaluate_laguerre_polynomial_2d( + a, + b[:2], + torch.einsum( + "i,j->ij", + torch.tensor([9.0, -14.0, 6.0]), + torch.tensor([9.0, -14.0, 6.0]), + ), + ) + + torch.testing.assert_close( + beignet.evaluate_laguerre_polynomial_2d( + a, + b, + torch.einsum( + "i,j->ij", + torch.tensor([9.0, -14.0, 6.0]), + torch.tensor([9.0, -14.0, 6.0]), + ), + ), + x * y, + ) + + output = beignet.evaluate_laguerre_polynomial_2d( + torch.ones([2, 3]), + torch.ones([2, 3]), + torch.einsum( + "i,j->ij", torch.tensor([9.0, -14.0, 6.0]), torch.tensor([9.0, -14.0, 6.0]) + ), + ) + + assert output.shape == (2, 3) diff --git a/tests/beignet/test__evaluate_laguerre_polynomial_3d.py b/tests/beignet/test__evaluate_laguerre_polynomial_3d.py new file mode 100644 index 0000000000..22f37116b6 --- /dev/null +++ b/tests/beignet/test__evaluate_laguerre_polynomial_3d.py @@ -0,0 +1,56 @@ +import beignet +import pytest +import torch + + +def test_evaluate_laguerre_polynomial_3d(): + input = torch.rand(3, 5) * 2 - 1 + + a, b, c = input + + x, y, z = beignet.evaluate_polynomial( + input, + torch.tensor([1.0, 2.0, 3.0]), + ) + + with pytest.raises(ValueError): + beignet.evaluate_laguerre_polynomial_3d( + a, + b, + c[:2], + torch.einsum( + "i,j,k->ijk", + torch.tensor([9.0, -14.0, 6.0]), + torch.tensor([9.0, -14.0, 6.0]), + torch.tensor([9.0, -14.0, 6.0]), + ), + ) + + torch.testing.assert_close( + beignet.evaluate_laguerre_polynomial_3d( + a, + b, + c, + torch.einsum( + "i,j,k->ijk", + torch.tensor([9.0, -14.0, 6.0]), + torch.tensor([9.0, -14.0, 6.0]), + torch.tensor([9.0, -14.0, 6.0]), + ), + ), + x * y * z, + ) + + output = beignet.evaluate_laguerre_polynomial_3d( + torch.ones([2, 3]), + torch.ones([2, 3]), + torch.ones([2, 3]), + torch.einsum( + "i,j,k->ijk", + torch.tensor([9.0, -14.0, 6.0]), + torch.tensor([9.0, -14.0, 6.0]), + torch.tensor([9.0, -14.0, 6.0]), + ), + ) + + assert output.shape == (2, 3) diff --git a/tests/beignet/test__evaluate_laguerre_polynomial_cartesian_2d.py b/tests/beignet/test__evaluate_laguerre_polynomial_cartesian_2d.py new file mode 100644 index 0000000000..62a814ce1c --- /dev/null +++ b/tests/beignet/test__evaluate_laguerre_polynomial_cartesian_2d.py @@ -0,0 +1,30 @@ +import beignet +import torch + + +def test_evaluate_laguerre_polynomial_cartesian_2d(): + c1d = torch.tensor([9.0, -14.0, 6.0]) + c2d = torch.einsum("i,j->ij", c1d, c1d) + + x = torch.rand(3, 5) * 2 - 1 + a, b, x3 = x + y1, y2, y3 = beignet.evaluate_polynomial(x, torch.tensor([1.0, 2.0, 3.0])) + + torch.testing.assert_close( + beignet.evaluate_laguerre_polynomial_cartesian_2d( + a, + b, + c2d, + ), + torch.einsum("i,j->ij", y1, y2), + ) + + z = torch.ones([2, 3]) + assert ( + beignet.evaluate_laguerre_polynomial_cartesian_2d( + z, + z, + c2d, + ).shape + == (2, 3) * 2 + ) diff --git a/tests/beignet/test__evaluate_laguerre_polynomial_cartesian_3d.py b/tests/beignet/test__evaluate_laguerre_polynomial_cartesian_3d.py new file mode 100644 index 0000000000..3598d2db27 --- /dev/null +++ b/tests/beignet/test__evaluate_laguerre_polynomial_cartesian_3d.py @@ -0,0 +1,24 @@ +import beignet +import torch + + +def test_evaluate_laguerre_polynomial_cartesian_3d(): + c1d = torch.tensor([9.0, -14.0, 6.0]) + c3d = torch.einsum("i,j,k->ijk", c1d, c1d, c1d) + + x = torch.rand(3, 5) * 2 - 1 + y = beignet.evaluate_polynomial(x, torch.tensor([1.0, 2.0, 3.0])) + + a, b, x3 = x + y1, y2, y3 = y + + target = torch.einsum("i,j,k->ijk", y1, y2, y3) + torch.testing.assert_close( + beignet.evaluate_laguerre_polynomial_cartesian_3d(a, b, x3, c3d), target + ) + + z = torch.ones([2, 3]) + assert ( + beignet.evaluate_laguerre_polynomial_cartesian_3d(z, z, z, c3d).shape + == (2, 3) * 3 + ) diff --git a/tests/beignet/test__evaluate_legendre_polynomial.py b/tests/beignet/test__evaluate_legendre_polynomial.py new file mode 100644 index 0000000000..93ef723ccd --- /dev/null +++ b/tests/beignet/test__evaluate_legendre_polynomial.py @@ -0,0 +1,72 @@ +import math + +import beignet +import torch + + +def test_evaluate_legendre_polynomial(): + coefficients = [ + torch.tensor([1]), + torch.tensor([0, 1]), + torch.tensor([-1, 0, 3]) / 2, + torch.tensor([0, -3, 0, 5]) / 2, + torch.tensor([3, 0, -30, 0, 35]) / 8, + torch.tensor([0, 15, 0, -70, 0, 63]) / 8, + torch.tensor([-5, 0, 105, 0, -315, 0, 231]) / 16, + torch.tensor([0, -35, 0, 315, 0, -693, 0, 429]) / 16, + torch.tensor([35, 0, -1260, 0, 6930, 0, -12012, 0, 6435]) / 128, + torch.tensor([0, 315, 0, -4620, 0, 18018, 0, -25740, 0, 12155]) / 128, + ] + + output = beignet.evaluate_legendre_polynomial( + torch.tensor([]), + torch.tensor([1.0]), + ) + + assert math.prod(output.shape) == 0 + + ys = [] + + for coefficient in coefficients: + ys = [ + *ys, + beignet.evaluate_polynomial( + torch.linspace(-1, 1, 50), + coefficient, + ), + ] + + for i in range(10): + torch.testing.assert_close( + beignet.evaluate_legendre_polynomial( + torch.linspace(-1, 1, 50), + torch.tensor([0.0] * i + [1.0]), + ), + torch.tensor(ys[i]), + ) + + for index in range(3): + shape = (2,) * index + + input = torch.zeros(shape) + + output = beignet.evaluate_legendre_polynomial( + input, + torch.tensor([1.0]), + ) + + assert output.shape == shape + + output = beignet.evaluate_legendre_polynomial( + input, + torch.tensor([1.0, 0.0]), + ) + + assert output.shape == shape + + output = beignet.evaluate_legendre_polynomial( + input, + torch.tensor([1.0, 0.0, 0.0]), + ) + + assert output.shape == shape diff --git a/tests/beignet/test__evaluate_legendre_polynomial_2d.py b/tests/beignet/test__evaluate_legendre_polynomial_2d.py new file mode 100644 index 0000000000..752318d5d7 --- /dev/null +++ b/tests/beignet/test__evaluate_legendre_polynomial_2d.py @@ -0,0 +1,51 @@ +import beignet +import pytest +import torch + + +def test_evaluate_legendre_polynomial_2d(): + input = torch.rand(3, 5) * 2 - 1 + + a, b, c = input + + x, y, z = beignet.evaluate_polynomial( + input, + torch.tensor([1.0, 2.0, 3.0]), + ) + + pytest.raises( + ValueError, + beignet.evaluate_legendre_polynomial_2d, + a, + b[:2], + torch.einsum( + "i,j->ij", + torch.tensor([2.0, 2.0, 2.0]), + torch.tensor([2.0, 2.0, 2.0]), + ), + ) + + torch.testing.assert_close( + beignet.evaluate_legendre_polynomial_2d( + a, + b, + torch.einsum( + "i,j->ij", + torch.tensor([2.0, 2.0, 2.0]), + torch.tensor([2.0, 2.0, 2.0]), + ), + ), + x * y, + ) + + output = beignet.evaluate_legendre_polynomial_2d( + torch.ones([2, 3]), + torch.ones([2, 3]), + torch.einsum( + "i,j->ij", + torch.tensor([2.0, 2.0, 2.0]), + torch.tensor([2.0, 2.0, 2.0]), + ), + ) + + assert output.shape == (2, 3) diff --git a/tests/beignet/test__evaluate_legendre_polynomial_3d.py b/tests/beignet/test__evaluate_legendre_polynomial_3d.py new file mode 100644 index 0000000000..d64758f762 --- /dev/null +++ b/tests/beignet/test__evaluate_legendre_polynomial_3d.py @@ -0,0 +1,36 @@ +import beignet +import torch + + +def test_evaluate_legendre_polynomial_3d(): + a, b, c = torch.rand(3, 5) * 2 - 1 + + coefficients = torch.rand(2, 3, 4) + + target = beignet.evaluate_legendre_polynomial_3d( + a, + b, + c, + coefficients, + ) + + output = beignet.legendre_polynomial_vandermonde_3d( + a, + b, + c, + degree=torch.tensor([1, 2, 3]), + ) + + torch.testing.assert_close( + output @ torch.ravel(coefficients), + target, + ) + + output = beignet.legendre_polynomial_vandermonde_3d( + a, + b, + c, + degree=torch.tensor([1, 2, 3]), + ) + + assert output.shape == (5, 24) diff --git a/tests/beignet/test__evaluate_legendre_polynomial_cartesian_2d.py b/tests/beignet/test__evaluate_legendre_polynomial_cartesian_2d.py new file mode 100644 index 0000000000..d0a45cf951 --- /dev/null +++ b/tests/beignet/test__evaluate_legendre_polynomial_cartesian_2d.py @@ -0,0 +1,42 @@ +import beignet +import torch + + +def test_evaluate_legendre_polynomial_cartesian_2d(): + input = torch.rand(3, 5) * 2 - 1 + + a, b, c = input + + x, y, z = beignet.evaluate_polynomial( + input, + torch.tensor([1.0, 2.0, 3.0]), + ) + + torch.testing.assert_close( + beignet.evaluate_legendre_polynomial_cartesian_2d( + a, + b, + torch.einsum( + "i,j->ij", + torch.tensor([2.0, 2.0, 2.0]), + torch.tensor([2.0, 2.0, 2.0]), + ), + ), + torch.einsum( + "i,j->ij", + x, + y, + ), + ) + + output = beignet.evaluate_legendre_polynomial_cartesian_2d( + torch.ones([2, 3]), + torch.ones([2, 3]), + torch.einsum( + "i,j->ij", + torch.tensor([2.0, 2.0, 2.0]), + torch.tensor([2.0, 2.0, 2.0]), + ), + ) + + assert output.shape == (2, 3) * 2 diff --git a/tests/beignet/test__evaluate_legendre_polynomial_cartesian_3d.py b/tests/beignet/test__evaluate_legendre_polynomial_cartesian_3d.py new file mode 100644 index 0000000000..4a78a012ff --- /dev/null +++ b/tests/beignet/test__evaluate_legendre_polynomial_cartesian_3d.py @@ -0,0 +1,47 @@ +import beignet +import torch + + +def test_evaluate_legendre_polynomial_cartesian_3d(): + input = torch.rand(3, 5) * 2 - 1 + + a, b, c = input + + x, y, z = beignet.evaluate_polynomial( + input, + torch.tensor([1.0, 2.0, 3.0]), + ) + + torch.testing.assert_close( + beignet.evaluate_legendre_polynomial_cartesian_3d( + a, + b, + c, + torch.einsum( + "i,j,k->ijk", + torch.tensor([2.0, 2.0, 2.0]), + torch.tensor([2.0, 2.0, 2.0]), + torch.tensor([2.0, 2.0, 2.0]), + ), + ), + torch.einsum( + "i,j,k->ijk", + x, + y, + z, + ), + ) + + output = beignet.evaluate_legendre_polynomial_cartesian_3d( + torch.ones([2, 3]), + torch.ones([2, 3]), + torch.ones([2, 3]), + torch.einsum( + "i,j,k->ijk", + torch.tensor([2.0, 2.0, 2.0]), + torch.tensor([2.0, 2.0, 2.0]), + torch.tensor([2.0, 2.0, 2.0]), + ), + ) + + assert output.shape == (2, 3) * 3 diff --git a/tests/beignet/test__evaluate_physicists_hermite_polynomial.py b/tests/beignet/test__evaluate_physicists_hermite_polynomial.py new file mode 100644 index 0000000000..fdeb516fee --- /dev/null +++ b/tests/beignet/test__evaluate_physicists_hermite_polynomial.py @@ -0,0 +1,74 @@ +import math + +import beignet +import torch + + +def test_evaluate_physicists_hermite_polynomial(): + coefficients = [ + torch.tensor([1]), + torch.tensor([0, 2]), + torch.tensor([-2, 0, 4]), + torch.tensor([0, -12, 0, 8]), + torch.tensor([12, 0, -48, 0, 16]), + torch.tensor([0, 120, 0, -160, 0, 32]), + torch.tensor([-120, 0, 720, 0, -480, 0, 64]), + torch.tensor([0, -1680, 0, 3360, 0, -1344, 0, 128]), + torch.tensor([1680, 0, -13440, 0, 13440, 0, -3584, 0, 256]), + torch.tensor([0, 30240, 0, -80640, 0, 48384, 0, -9216, 0, 512]), + ] + + output = beignet.evaluate_physicists_hermite_polynomial( + torch.tensor([]), + torch.tensor([1.0]), + ) + + assert math.prod(output.shape) == 0 + + ys = [] + + input = torch.linspace(-1, 1, 50) + + for coefficient in coefficients: + ys = [ + *ys, + beignet.evaluate_polynomial( + input, + coefficient, + ), + ] + + for index in range(10): + torch.testing.assert_close( + beignet.evaluate_physicists_hermite_polynomial( + input, + torch.tensor([0.0] * index + [1.0]), + ), + ys[index], + ) + + for index in range(3): + shape = (2,) * index + + input = torch.zeros(shape) + + output = beignet.evaluate_physicists_hermite_polynomial( + input, + torch.tensor([1.0]), + ) + + assert output.shape == shape + + output = beignet.evaluate_physicists_hermite_polynomial( + input, + torch.tensor([1.0, 0.0]), + ) + + assert output.shape == shape + + output = beignet.evaluate_physicists_hermite_polynomial( + input, + torch.tensor([1.0, 0.0, 0.0]), + ) + + assert output.shape == shape diff --git a/tests/beignet/test__evaluate_physicists_hermite_polynomial_2d.py b/tests/beignet/test__evaluate_physicists_hermite_polynomial_2d.py new file mode 100644 index 0000000000..848118f39f --- /dev/null +++ b/tests/beignet/test__evaluate_physicists_hermite_polynomial_2d.py @@ -0,0 +1,50 @@ +import beignet +import pytest +import torch + + +def test_evaluate_physicists_hermite_polynomial_2d(): + input = torch.rand(3, 5) * 2 - 1 + + a, b, c = input + + x, y, z = beignet.evaluate_polynomial( + input, + torch.tensor([1.0, 2.0, 3.0]), + ) + + with pytest.raises(ValueError): + beignet.evaluate_physicists_hermite_polynomial_2d( + a, + b[:2], + torch.einsum( + "i,j->ij", + torch.tensor([2.5, 1.0, 0.75]), + torch.tensor([2.5, 1.0, 0.75]), + ), + ) + + torch.testing.assert_close( + beignet.evaluate_physicists_hermite_polynomial_2d( + a, + b, + torch.einsum( + "i,j->ij", + torch.tensor([2.5, 1.0, 0.75]), + torch.tensor([2.5, 1.0, 0.75]), + ), + ), + x * y, + ) + + output = beignet.evaluate_physicists_hermite_polynomial_2d( + torch.ones([2, 3]), + torch.ones([2, 3]), + torch.einsum( + "i,j->ij", + torch.tensor([2.5, 1.0, 0.75]), + torch.tensor([2.5, 1.0, 0.75]), + ), + ) + + assert output.shape == (2, 3) diff --git a/tests/beignet/test__evaluate_physicists_hermite_polynomial_3d.py b/tests/beignet/test__evaluate_physicists_hermite_polynomial_3d.py new file mode 100644 index 0000000000..576237b963 --- /dev/null +++ b/tests/beignet/test__evaluate_physicists_hermite_polynomial_3d.py @@ -0,0 +1,53 @@ +import beignet +import pytest +import torch + + +def test_evaluate_physicists_hermite_polynomial_3d(): + input = torch.rand(3, 5) * 2 - 1 + + a, b, c = input + + x, y, z = beignet.evaluate_polynomial(input, torch.tensor([1.0, 2.0, 3.0])) + + with pytest.raises(ValueError): + beignet.evaluate_physicists_hermite_polynomial_3d( + a, + b, + c[:2], + torch.einsum( + "i,j,k->ijk", + torch.tensor([2.5, 1.0, 0.75]), + torch.tensor([2.5, 1.0, 0.75]), + torch.tensor([2.5, 1.0, 0.75]), + ), + ) + + torch.testing.assert_close( + beignet.evaluate_physicists_hermite_polynomial_3d( + a, + b, + c, + torch.einsum( + "i,j,k->ijk", + torch.tensor([2.5, 1.0, 0.75]), + torch.tensor([2.5, 1.0, 0.75]), + torch.tensor([2.5, 1.0, 0.75]), + ), + ), + x * y * z, + ) + + output = beignet.evaluate_physicists_hermite_polynomial_3d( + torch.ones([2, 3]), + torch.ones([2, 3]), + torch.ones([2, 3]), + torch.einsum( + "i,j,k->ijk", + torch.tensor([2.5, 1.0, 0.75]), + torch.tensor([2.5, 1.0, 0.75]), + torch.tensor([2.5, 1.0, 0.75]), + ), + ) + + assert output.shape == (2, 3) diff --git a/tests/beignet/test__evaluate_physicists_hermite_polynomial_cartesian_2d.py b/tests/beignet/test__evaluate_physicists_hermite_polynomial_cartesian_2d.py new file mode 100644 index 0000000000..a37342e687 --- /dev/null +++ b/tests/beignet/test__evaluate_physicists_hermite_polynomial_cartesian_2d.py @@ -0,0 +1,31 @@ +import beignet +import torch + + +def test_evaluate_physicists_hermite_polynomial_cartesian_2d(): + c1d = torch.tensor([2.5, 1.0, 0.75]) + c2d = torch.einsum("i,j->ij", c1d, c1d) + + x = torch.rand(3, 5) * 2 - 1 + a, b, x3 = x + y1, y2, y3 = beignet.evaluate_polynomial(x, torch.tensor([1.0, 2.0, 3.0])) + + target = torch.einsum("i,j->ij", y1, y2) + torch.testing.assert_close( + beignet.evaluate_physicists_hermite_polynomial_cartesian_2d( + a, + b, + c2d, + ), + target, + ) + + z = torch.ones([2, 3]) + assert ( + beignet.evaluate_physicists_hermite_polynomial_cartesian_2d( + z, + z, + c2d, + ).shape + == (2, 3) * 2 + ) diff --git a/tests/beignet/test__evaluate_physicists_hermite_polynomial_cartesian_3d.py b/tests/beignet/test__evaluate_physicists_hermite_polynomial_cartesian_3d.py new file mode 100644 index 0000000000..58d0a3ff73 --- /dev/null +++ b/tests/beignet/test__evaluate_physicists_hermite_polynomial_cartesian_3d.py @@ -0,0 +1,38 @@ +import beignet +import torch + + +def test_evaluate_physicists_hermite_polynomial_cartesian_3d(): + c1d = torch.tensor([2.5, 1.0, 0.75]) + c3d = torch.einsum( + "i,j,k->ijk", + c1d, + c1d, + c1d, + ) + + x = torch.rand(3, 5) * 2 - 1 + a, b, x3 = x + y1, y2, y3 = beignet.evaluate_polynomial(x, torch.tensor([1.0, 2.0, 3.0])) + + torch.testing.assert_close( + beignet.evaluate_physicists_hermite_polynomial_cartesian_3d( + a, + b, + x3, + c3d, + ), + torch.einsum( + "i,j,k->ijk", + y1, + y2, + y3, + ), + ) + + z = torch.ones([2, 3]) + + assert ( + beignet.evaluate_physicists_hermite_polynomial_cartesian_3d(z, z, z, c3d).shape + == (2, 3) * 3 + ) diff --git a/tests/beignet/test__evaluate_polynomial.py b/tests/beignet/test__evaluate_polynomial.py new file mode 100644 index 0000000000..a03fe76abd --- /dev/null +++ b/tests/beignet/test__evaluate_polynomial.py @@ -0,0 +1,66 @@ +import math + +import beignet +import torch + + +def test_evaluate_polynomial(): + output = beignet.evaluate_polynomial( + torch.tensor([]), + torch.tensor([1.0]), + ) + + assert math.prod(output.shape) == 0 + + y = [] + + input = torch.linspace(-1, 1, 50) + + for index in range(5): + y = [ + *y, + input**index, + ] + + for index in range(5): + torch.testing.assert_close( + beignet.evaluate_polynomial( + input, + torch.tensor([0.0] * index + [1.0]), + ), + y[index], + ) + + torch.testing.assert_close( + beignet.evaluate_polynomial( + input, + torch.tensor([0, -1, 0, 1]), + ), + input * (input**2 - 1), + ) + + for index in range(3): + shape = (2,) * index + + input = torch.zeros(shape) + + output = beignet.evaluate_polynomial( + input, + torch.tensor([1.0]), + ) + + assert output.shape == shape + + output = beignet.evaluate_polynomial( + input, + torch.tensor([1.0, 0.0]), + ) + + assert output.shape == shape + + output = beignet.evaluate_polynomial( + input, + torch.tensor([1.0, 0.0, 0.0]), + ) + + assert output.shape == shape diff --git a/tests/beignet/test__evaluate_polynomial_2d.py b/tests/beignet/test__evaluate_polynomial_2d.py new file mode 100644 index 0000000000..a824228dac --- /dev/null +++ b/tests/beignet/test__evaluate_polynomial_2d.py @@ -0,0 +1,38 @@ +import beignet +import torch + + +def test_evaluate_polynomial_2d(): + input = torch.rand(3, 5) * 2 - 1 + + a, b, c = input + + x, y, z = beignet.evaluate_polynomial( + input, + torch.tensor([1.0, 2.0, 3.0]), + ) + + torch.testing.assert_close( + beignet.evaluate_polynomial_2d( + a, + b, + torch.einsum( + "i,j->ij", + torch.tensor([1.0, 2.0, 3.0]), + torch.tensor([1.0, 2.0, 3.0]), + ), + ), + x * y, + ) + + output = beignet.evaluate_polynomial_2d( + torch.ones([2, 3]), + torch.ones([2, 3]), + torch.einsum( + "i,j->ij", + torch.tensor([1.0, 2.0, 3.0]), + torch.tensor([1.0, 2.0, 3.0]), + ), + ) + + assert output.shape == (2, 3) diff --git a/tests/beignet/test__evaluate_polynomial_3d.py b/tests/beignet/test__evaluate_polynomial_3d.py new file mode 100644 index 0000000000..b6a4da533c --- /dev/null +++ b/tests/beignet/test__evaluate_polynomial_3d.py @@ -0,0 +1,42 @@ +import beignet +import torch + + +def test_evaluate_polynomial_3d(): + input = torch.rand(3, 5) * 2 - 1 + + a, b, c = input + + x, y, z = beignet.evaluate_polynomial( + input, + torch.tensor([1.0, 2.0, 3.0]), + ) + + torch.testing.assert_close( + beignet.evaluate_polynomial_3d( + a, + b, + c, + torch.einsum( + "i,j,k->ijk", + torch.tensor([1.0, 2.0, 3.0]), + torch.tensor([1.0, 2.0, 3.0]), + torch.tensor([1.0, 2.0, 3.0]), + ), + ), + x * y * z, + ) + + output = beignet.evaluate_polynomial_3d( + torch.ones([2, 3]), + torch.ones([2, 3]), + torch.ones([2, 3]), + torch.einsum( + "i,j,k->ijk", + torch.tensor([1.0, 2.0, 3.0]), + torch.tensor([1.0, 2.0, 3.0]), + torch.tensor([1.0, 2.0, 3.0]), + ), + ) + + assert output.shape == (2, 3) diff --git a/tests/beignet/test__evaluate_polynomial_cartesian_2d.py b/tests/beignet/test__evaluate_polynomial_cartesian_2d.py new file mode 100644 index 0000000000..eaec049d39 --- /dev/null +++ b/tests/beignet/test__evaluate_polynomial_cartesian_2d.py @@ -0,0 +1,42 @@ +import beignet +import torch + + +def test_evaluate_polynomial_cartesian_2d(): + x = torch.rand(3, 5) * 2 - 1 + + a, b, x3 = x + + y1, y2, y3 = beignet.evaluate_polynomial( + x, + torch.tensor([1.0, 2.0, 3.0]), + ) + + torch.testing.assert_close( + beignet.evaluate_polynomial_cartesian_2d( + a, + b, + torch.einsum( + "i,j->ij", + torch.tensor([1.0, 2.0, 3.0]), + torch.tensor([1.0, 2.0, 3.0]), + ), + ), + torch.einsum( + "i,j->ij", + y1, + y2, + ), + ) + + output = beignet.evaluate_polynomial_cartesian_2d( + torch.ones([2, 3]), + torch.ones([2, 3]), + torch.einsum( + "i,j->ij", + torch.tensor([1.0, 2.0, 3.0]), + torch.tensor([1.0, 2.0, 3.0]), + ), + ) + + assert output.shape == (2, 3) * 2 diff --git a/tests/beignet/test__evaluate_polynomial_cartesian_3d.py b/tests/beignet/test__evaluate_polynomial_cartesian_3d.py new file mode 100644 index 0000000000..e553c1772d --- /dev/null +++ b/tests/beignet/test__evaluate_polynomial_cartesian_3d.py @@ -0,0 +1,48 @@ +import beignet +import torch + + +def test_evaluate_polynomial_cartesian_3d(): + x = torch.rand(3, 5) * 2 - 1 + + y = beignet.evaluate_polynomial( + x, + torch.tensor([1.0, 2.0, 3.0]), + ) + + a, b, x3 = x + y1, y2, y3 = y + + torch.testing.assert_close( + beignet.evaluate_polynomial_cartesian_3d( + a, + b, + x3, + torch.einsum( + "i,j,k->ijk", + torch.tensor([1.0, 2.0, 3.0]), + torch.tensor([1.0, 2.0, 3.0]), + torch.tensor([1.0, 2.0, 3.0]), + ), + ), + torch.einsum( + "i,j,k->ijk", + y1, + y2, + y3, + ), + ) + + output = beignet.evaluate_polynomial_cartesian_3d( + torch.ones([2, 3]), + torch.ones([2, 3]), + torch.ones([2, 3]), + torch.einsum( + "i,j,k->ijk", + torch.tensor([1.0, 2.0, 3.0]), + torch.tensor([1.0, 2.0, 3.0]), + torch.tensor([1.0, 2.0, 3.0]), + ), + ) + + assert output.shape == (2, 3) * 3 diff --git a/tests/beignet/test__evaluate_polynomial_from_roots.py b/tests/beignet/test__evaluate_polynomial_from_roots.py new file mode 100644 index 0000000000..a35a68f0da --- /dev/null +++ b/tests/beignet/test__evaluate_polynomial_from_roots.py @@ -0,0 +1,155 @@ +import math + +import beignet +import pytest +import torch + + +def test_evaluate_polynomial_from_roots(): + with pytest.raises(ValueError): + beignet.evaluate_polynomial_from_roots( + torch.tensor([1.0]), + torch.tensor([1.0]), + tensor=False, + ) + + output = beignet.evaluate_polynomial_from_roots( + torch.tensor([]), + torch.tensor([1.0]), + ) + + assert math.prod(output.shape) == 0 + + assert output.shape == (0,) + + output = beignet.evaluate_polynomial_from_roots( + torch.tensor([]), + torch.tensor([[1.0] * 5]), + ) + + assert math.prod(output.shape) == 0 + + assert output.shape == (5, 0) + + torch.testing.assert_close( + beignet.evaluate_polynomial_from_roots( + torch.tensor([1.0]), + torch.tensor([1.0]), + ), + torch.tensor([0.0]), + ) + + output = beignet.evaluate_polynomial_from_roots( + torch.tensor([1.0]), + torch.ones([3, 3]), + ) + + assert output.shape == (3, 1) + + input = torch.linspace(-1, 1, 50) + + evaluations = [] + + for i in range(5): + evaluations = [*evaluations, input**i] + + for i in range(1, 5): + target = evaluations[i] + + torch.testing.assert_close( + beignet.evaluate_polynomial_from_roots( + input, + torch.tensor([0.0] * i), + ), + target, + ) + + torch.testing.assert_close( + beignet.evaluate_polynomial_from_roots( + input, + torch.tensor([-1.0, 0.0, 1.0]), + ), + input * (input - 1.0) * (input + 1.0), + ) + + for i in range(3): + shape = (2,) * i + + input = torch.zeros(shape) + + output = beignet.evaluate_polynomial_from_roots( + input, + torch.tensor([1.0]), + ) + + assert output.shape == shape + + output = beignet.evaluate_polynomial_from_roots( + input, + torch.tensor([1.0, 0.0]), + ) + + assert output.shape == shape + + output = beignet.evaluate_polynomial_from_roots( + input, + torch.tensor([1.0, 0.0, 0.0]), + ) + + assert output.shape == shape + + ptest = torch.tensor([15.0, 2.0, -16.0, -2.0, 1.0]) + + r = beignet.polynomial_roots(ptest) + + torch.testing.assert_close( + beignet.evaluate_polynomial( + input, + ptest, + ), + beignet.evaluate_polynomial_from_roots( + input, + r, + ), + ) + + x = torch.arange(-3, 2) + + r = torch.randint(-5, 5, (3, 5)).to(torch.float64) + + target = torch.empty(r.shape[1:]) + + for j in range(math.prod(target.shape)): + target[j] = beignet.evaluate_polynomial_from_roots( + x[j], + r[:, j], + ) + + torch.testing.assert_close( + beignet.evaluate_polynomial_from_roots( + x, + r, + tensor=False, + ), + target, + ) + + x = torch.vstack([x, 2 * x]) + + target = torch.empty(r.shape[1:] + x.shape) + + for j in range(r.shape[1]): + for k in range(x.shape[0]): + target[j, k, :] = beignet.evaluate_polynomial_from_roots( + x[k], + r[:, j], + ) + + torch.testing.assert_close( + beignet.evaluate_polynomial_from_roots( + x, + r, + tensor=True, + ), + target, + ) diff --git a/tests/beignet/test__evaluate_probabilists_hermite_polynomial.py b/tests/beignet/test__evaluate_probabilists_hermite_polynomial.py new file mode 100644 index 0000000000..f0cd86381a --- /dev/null +++ b/tests/beignet/test__evaluate_probabilists_hermite_polynomial.py @@ -0,0 +1,72 @@ +import math + +import beignet +import torch + + +def test_evaluate_probabilists_hermite_polynomial(): + coefficients = [ + torch.tensor([1]), + torch.tensor([0, 1]), + torch.tensor([-1, 0, 1]), + torch.tensor([0, -3, 0, 1]), + torch.tensor([3, 0, -6, 0, 1]), + torch.tensor([0, 15, 0, -10, 0, 1]), + torch.tensor([-15, 0, 45, 0, -15, 0, 1]), + torch.tensor([0, -105, 0, 105, 0, -21, 0, 1]), + torch.tensor([105, 0, -420, 0, 210, 0, -28, 0, 1]), + torch.tensor([0, 945, 0, -1260, 0, 378, 0, -36, 0, 1]), + ] + + output = beignet.evaluate_probabilists_hermite_polynomial( + torch.tensor([]), + torch.tensor([1.0]), + ) + + assert math.prod(output.shape) == 0 + + ys = [] + + for coefficient in coefficients: + ys = [ + *ys, + beignet.evaluate_polynomial( + torch.linspace(-1, 1, 50), + coefficient, + ), + ] + + for i in range(10): + torch.testing.assert_close( + beignet.evaluate_probabilists_hermite_polynomial( + torch.linspace(-1, 1, 50), + torch.tensor([0.0] * i + [1.0]), + ), + ys[i], + ) + + for index in range(3): + shape = (2,) * index + + input = torch.zeros(shape) + + output = beignet.evaluate_probabilists_hermite_polynomial( + input, + torch.tensor([1.0]), + ) + + assert output.shape == shape + + output = beignet.evaluate_probabilists_hermite_polynomial( + input, + torch.tensor([1.0, 0.0]), + ) + + assert output.shape == shape + + output = beignet.evaluate_probabilists_hermite_polynomial( + input, + torch.tensor([1.0, 0.0, 0.0]), + ) + + assert output.shape == shape diff --git a/tests/beignet/test__evaluate_probabilists_hermite_polynomial_2d.py b/tests/beignet/test__evaluate_probabilists_hermite_polynomial_2d.py new file mode 100644 index 0000000000..0d87e566bf --- /dev/null +++ b/tests/beignet/test__evaluate_probabilists_hermite_polynomial_2d.py @@ -0,0 +1,50 @@ +import beignet +import pytest +import torch + + +def test_evaluate_probabilists_hermite_polynomial_2d(): + input = torch.rand(3, 5) * 2 - 1 + + a, b, c = input + + x, y, z = beignet.evaluate_polynomial( + input, + torch.tensor([1.0, 2.0, 3.0]), + ) + + with pytest.raises(ValueError): + beignet.evaluate_probabilists_hermite_polynomial_2d( + a, + b[:2], + torch.einsum( + "i,j->ij", + torch.tensor([4.0, 2.0, 3.0]), + torch.tensor([4.0, 2.0, 3.0]), + ), + ) + + torch.testing.assert_close( + beignet.evaluate_probabilists_hermite_polynomial_2d( + a, + b, + torch.einsum( + "i,j->ij", + torch.tensor([4.0, 2.0, 3.0]), + torch.tensor([4.0, 2.0, 3.0]), + ), + ), + x * y, + ) + + output = beignet.evaluate_probabilists_hermite_polynomial_2d( + torch.ones([2, 3]), + torch.ones([2, 3]), + torch.einsum( + "i,j->ij", + torch.tensor([4.0, 2.0, 3.0]), + torch.tensor([4.0, 2.0, 3.0]), + ), + ) + + assert output.shape == (2, 3) diff --git a/tests/beignet/test__evaluate_probabilists_hermite_polynomial_3d.py b/tests/beignet/test__evaluate_probabilists_hermite_polynomial_3d.py new file mode 100644 index 0000000000..135f4d91d8 --- /dev/null +++ b/tests/beignet/test__evaluate_probabilists_hermite_polynomial_3d.py @@ -0,0 +1,56 @@ +import beignet +import pytest +import torch + + +def test_evaluate_probabilists_hermite_polynomial_3d(): + input = torch.rand(3, 5) * 2 - 1 + + a, b, c = input + + x, y, z = beignet.evaluate_polynomial( + input, + torch.tensor([1.0, 2.0, 3.0]), + ) + + with pytest.raises(ValueError): + beignet.evaluate_probabilists_hermite_polynomial_3d( + a, + b, + c[:2], + torch.einsum( + "i,j,k->ijk", + torch.tensor([4.0, 2.0, 3.0]), + torch.tensor([4.0, 2.0, 3.0]), + torch.tensor([4.0, 2.0, 3.0]), + ), + ) + + torch.testing.assert_close( + beignet.evaluate_probabilists_hermite_polynomial_3d( + a, + b, + c, + torch.einsum( + "i,j,k->ijk", + torch.tensor([4.0, 2.0, 3.0]), + torch.tensor([4.0, 2.0, 3.0]), + torch.tensor([4.0, 2.0, 3.0]), + ), + ), + x * y * z, + ) + + output = beignet.evaluate_probabilists_hermite_polynomial_3d( + torch.ones([2, 3]), + torch.ones([2, 3]), + torch.ones([2, 3]), + torch.einsum( + "i,j,k->ijk", + torch.tensor([4.0, 2.0, 3.0]), + torch.tensor([4.0, 2.0, 3.0]), + torch.tensor([4.0, 2.0, 3.0]), + ), + ) + + assert output.shape == (2, 3) diff --git a/tests/beignet/test__evaluate_probabilists_hermite_polynomial_cartersian_2d.py b/tests/beignet/test__evaluate_probabilists_hermite_polynomial_cartersian_2d.py new file mode 100644 index 0000000000..4ded1ab12e --- /dev/null +++ b/tests/beignet/test__evaluate_probabilists_hermite_polynomial_cartersian_2d.py @@ -0,0 +1,42 @@ +import beignet +import torch + + +def test_evaluate_probabilists_hermite_polynomial_cartersian_2d(): + input = torch.rand(3, 5) * 2 - 1 + + a, b, c = input + + x, y, z = beignet.evaluate_polynomial( + input, + torch.tensor([1.0, 2.0, 3.0]), + ) + + torch.testing.assert_close( + beignet.evaluate_probabilists_hermite_polynomial_cartersian_2d( + a, + b, + torch.einsum( + "i,j->ij", + torch.tensor([4.0, 2.0, 3.0]), + torch.tensor([4.0, 2.0, 3.0]), + ), + ), + torch.einsum( + "i,j->ij", + x, + y, + ), + ) + + output = beignet.evaluate_probabilists_hermite_polynomial_cartersian_2d( + torch.ones([2, 3]), + torch.ones([2, 3]), + torch.einsum( + "i,j->ij", + torch.tensor([4.0, 2.0, 3.0]), + torch.tensor([4.0, 2.0, 3.0]), + ), + ) + + assert output.shape == (2, 3) * 2 diff --git a/tests/beignet/test__evaluate_probabilists_hermite_polynomial_cartersian_3d.py b/tests/beignet/test__evaluate_probabilists_hermite_polynomial_cartersian_3d.py new file mode 100644 index 0000000000..f4bc7ef5a5 --- /dev/null +++ b/tests/beignet/test__evaluate_probabilists_hermite_polynomial_cartersian_3d.py @@ -0,0 +1,22 @@ +import beignet +import torch + + +def test_evaluate_probabilists_hermite_polynomial_cartersian_3d(): + c1d = torch.tensor([4.0, 2.0, 3.0]) + c3d = torch.einsum("i,j,k->ijk", c1d, c1d, c1d) + + x = torch.rand(3, 5) * 2 - 1 + y = beignet.evaluate_polynomial(x, torch.tensor([1.0, 2.0, 3.0])) + + a, b, x3 = x + y1, y2, y3 = y + + torch.testing.assert_close( + beignet.evaluate_probabilists_hermite_polynomial_cartersian_3d(a, b, x3, c3d), + torch.einsum("i,j,k->ijk", y1, y2, y3), + ) + + z = torch.ones([2, 3]) + res = beignet.evaluate_probabilists_hermite_polynomial_cartersian_3d(z, z, z, c3d) + assert res.shape == (2, 3) * 3 diff --git a/tests/beignet/test__fit_chebyshev_polynomial.py b/tests/beignet/test__fit_chebyshev_polynomial.py new file mode 100644 index 0000000000..58083c0624 --- /dev/null +++ b/tests/beignet/test__fit_chebyshev_polynomial.py @@ -0,0 +1,255 @@ +import beignet +import torch + + +def test_fit_chebyshev_polynomial(): + def f(x): + return x * (x - 1) * (x - 2) + + def g(x): + return x**4 + x**2 + 1 + + input = torch.linspace(0, 2, 50) + + other = f(input) + + torch.testing.assert_close( + beignet.evaluate_chebyshev_polynomial( + input, + beignet.fit_chebyshev_polynomial( + input, + other, + degree=3, + ), + ), + other, + ) + + torch.testing.assert_close( + beignet.evaluate_chebyshev_polynomial( + input, + beignet.fit_chebyshev_polynomial( + input, + other, + degree=torch.tensor([0, 1, 2, 3]), + ), + ), + other, + ) + + torch.testing.assert_close( + beignet.evaluate_chebyshev_polynomial( + input, + beignet.fit_chebyshev_polynomial( + input, + other, + degree=4, + ), + ), + other, + ) + + torch.testing.assert_close( + beignet.evaluate_chebyshev_polynomial( + input, + beignet.fit_chebyshev_polynomial( + input, + other, + degree=torch.tensor([0, 1, 2, 3, 4]), + ), + ), + other, + ) + + torch.testing.assert_close( + beignet.evaluate_chebyshev_polynomial( + input, + beignet.fit_chebyshev_polynomial( + input, + other, + degree=torch.tensor([2, 3, 4, 1, 0]), + ), + ), + other, + ) + + # torch.testing.assert_close( + # beignet.chebfit( + # input, + # torch.stack([other, other]).T, + # degree=4, + # ), + # torch.stack( + # [ + # beignet.chebfit( + # input, + # other, + # degree=torch.tensor([0, 1, 2, 3]), + # ), + # beignet.chebfit( + # input, + # other, + # degree=torch.tensor([0, 1, 2, 3]), + # ), + # ] + # ).T, + # ) + + torch.testing.assert_close( + beignet.fit_chebyshev_polynomial( + input, + torch.stack([other, other]).T, + degree=torch.tensor([0, 1, 2, 3]), + ), + torch.stack( + [ + beignet.fit_chebyshev_polynomial( + input, + other, + degree=torch.tensor([0, 1, 2, 3]), + ), + beignet.fit_chebyshev_polynomial( + input, + other, + degree=torch.tensor([0, 1, 2, 3]), + ), + ] + ).T, + ) + + weight = torch.zeros_like(input) + + weight[1::2] = 1.0 + + torch.testing.assert_close( + beignet.fit_chebyshev_polynomial( + input, + other, + degree=3, + weight=weight, + ), + beignet.fit_chebyshev_polynomial( + input, + other, + degree=torch.tensor([0, 1, 2, 3]), + ), + ) + + torch.testing.assert_close( + beignet.fit_chebyshev_polynomial( + input, + other, + degree=torch.tensor([0, 1, 2, 3]), + weight=weight, + ), + beignet.fit_chebyshev_polynomial( + input, + other, + degree=torch.tensor([0, 1, 2, 3]), + ), + ) + + torch.testing.assert_close( + beignet.fit_chebyshev_polynomial( + input, + torch.stack([other, other]).T, + degree=3, + weight=weight, + ), + torch.stack( + [ + beignet.fit_chebyshev_polynomial( + input, + other, + degree=torch.tensor([0, 1, 2, 3]), + ), + beignet.fit_chebyshev_polynomial( + input, + other, + degree=torch.tensor([0, 1, 2, 3]), + ), + ] + ).T, + ) + + torch.testing.assert_close( + beignet.fit_chebyshev_polynomial( + input, + torch.stack([other, other]).T, + degree=torch.tensor([0, 1, 2, 3]), + weight=weight, + ), + torch.stack( + [ + beignet.fit_chebyshev_polynomial( + input, + other, + degree=torch.tensor([0, 1, 2, 3]), + ), + beignet.fit_chebyshev_polynomial( + input, + other, + degree=torch.tensor([0, 1, 2, 3]), + ), + ], + ).T, + ) + + # torch.testing.assert_close( + # beignet.chebfit( + # torch.tensor([1, 1j, -1, -1j]), + # torch.tensor([1, 1j, -1, -1j]), + # degree=torch.tensor([1]), + # ), + # torch.tensor([0, 1]), + # ) + + # torch.testing.assert_close( + # beignet.chebfit( + # torch.tensor([1, 1j, -1, -1j]), + # torch.tensor([1, 1j, -1, -1j]), + # degree=torch.tensor([0, 1]), + # ), + # torch.tensor([0, 1]), + # ) + + input = torch.linspace(-1, 1, 50) + + other = g(input) + + torch.testing.assert_close( + beignet.evaluate_chebyshev_polynomial( + input, + beignet.fit_chebyshev_polynomial( + input, + other, + degree=4, + ), + ), + other, + ) + + torch.testing.assert_close( + beignet.evaluate_chebyshev_polynomial( + input, + beignet.fit_chebyshev_polynomial( + input, + other, + degree=torch.tensor([0, 2, 4]), + ), + ), + other, + ) + + torch.testing.assert_close( + beignet.fit_chebyshev_polynomial( + input, + other, + degree=4, + ), + beignet.fit_chebyshev_polynomial( + input, + other, + degree=torch.tensor([0, 2, 4]), + ), + ) diff --git a/tests/beignet/test__fit_laguerre_polynomial.py b/tests/beignet/test__fit_laguerre_polynomial.py new file mode 100644 index 0000000000..78dc0deb20 --- /dev/null +++ b/tests/beignet/test__fit_laguerre_polynomial.py @@ -0,0 +1,199 @@ +import beignet +import torch + + +def test_fit_laguerre_polynomial(): + def f(x): + return x * (x - 1) * (x - 2) + + input = torch.linspace(0, 2, 50) + + other = f(input) + + torch.testing.assert_close( + beignet.evaluate_laguerre_polynomial( + input, + beignet.fit_laguerre_polynomial( + input, + other, + degree=3, + ), + ), + other, + ) + + torch.testing.assert_close( + beignet.evaluate_laguerre_polynomial( + input, + beignet.fit_laguerre_polynomial( + input, + other, + degree=torch.tensor([0, 1, 2, 3]), + ), + ), + other, + ) + + torch.testing.assert_close( + beignet.evaluate_laguerre_polynomial( + input, + beignet.fit_laguerre_polynomial( + input, + other, + degree=4, + ), + ), + other, + ) + + torch.testing.assert_close( + beignet.evaluate_laguerre_polynomial( + input, + beignet.fit_laguerre_polynomial( + input, + other, + degree=torch.tensor([0, 1, 2, 3, 4]), + ), + ), + other, + ) + + torch.testing.assert_close( + beignet.fit_laguerre_polynomial( + input, + torch.stack([other, other]).T, + degree=3, + ), + torch.stack( + [ + beignet.fit_laguerre_polynomial( + input, + other, + degree=torch.tensor([0, 1, 2, 3]), + ), + beignet.fit_laguerre_polynomial( + input, + other, + degree=torch.tensor([0, 1, 2, 3]), + ), + ] + ).T, + ) + + torch.testing.assert_close( + beignet.fit_laguerre_polynomial( + input, + torch.stack([other, other]).T, + degree=torch.tensor([0, 1, 2, 3]), + ), + torch.stack( + [ + beignet.fit_laguerre_polynomial( + input, + other, + degree=torch.tensor([0, 1, 2, 3]), + ), + beignet.fit_laguerre_polynomial( + input, + other, + degree=torch.tensor([0, 1, 2, 3]), + ), + ] + ).T, + ) + + weight = torch.zeros_like(input) + + weight[1::2] = 1.0 + + torch.testing.assert_close( + beignet.fit_laguerre_polynomial( + input, + other, + degree=3, + weight=weight, + ), + beignet.fit_laguerre_polynomial( + input, + other, + degree=torch.tensor([0, 1, 2, 3]), + ), + ) + + torch.testing.assert_close( + beignet.fit_laguerre_polynomial( + input, + other, + degree=torch.tensor([0, 1, 2, 3]), + weight=weight, + ), + beignet.fit_laguerre_polynomial( + input, + other, + degree=torch.tensor([0, 1, 2, 3]), + ), + ) + + torch.testing.assert_close( + beignet.fit_laguerre_polynomial( + input, + torch.stack([other, other]).T, + degree=3, + weight=weight, + ), + torch.stack( + [ + beignet.fit_laguerre_polynomial( + input, + other, + degree=torch.tensor([0, 1, 2, 3]), + ), + beignet.fit_laguerre_polynomial( + input, + other, + degree=torch.tensor([0, 1, 2, 3]), + ), + ], + ).T, + ) + + torch.testing.assert_close( + beignet.fit_laguerre_polynomial( + input, + torch.stack([other, other]).T, + degree=torch.tensor([0, 1, 2, 3]), + weight=weight, + ), + torch.stack( + [ + beignet.fit_laguerre_polynomial( + input, + other, + degree=torch.tensor([0, 1, 2, 3]), + ), + beignet.fit_laguerre_polynomial( + input, + other, + degree=torch.tensor([0, 1, 2, 3]), + ), + ] + ).T, + ) + + # torch.testing.assert_close( + # beignet.lagfit( + # torch.tensor([1, 1j, -1, -1j]), + # torch.tensor([1, 1j, -1, -1j]), + # degree=torch.tensor([1]), + # ), + # torch.tensor([1, -1]), + # ) + + # torch.testing.assert_close( + # beignet.lagfit( + # torch.tensor([1, 1j, -1, -1j]), + # torch.tensor([1, 1j, -1, -1j]), + # degree=torch.tensor([0, 1]), + # ), + # torch.tensor([1, -1]), + # ) diff --git a/tests/beignet/test__fit_legendre_polynomial.py b/tests/beignet/test__fit_legendre_polynomial.py new file mode 100644 index 0000000000..3766ea454d --- /dev/null +++ b/tests/beignet/test__fit_legendre_polynomial.py @@ -0,0 +1,271 @@ +import beignet +import torch + + +def test_fit_legendre_polynomial(): + def f(x): + return x * (x - 1) * (x - 2) + + def g(x): + return x**4 + x**2 + 1 + + input = torch.linspace(0, 2, 50) + + other = f(input) + + torch.testing.assert_close( + beignet.evaluate_legendre_polynomial( + input, + beignet.fit_legendre_polynomial( + input, + other, + degree=3, + ), + ), + other, + ) + + torch.testing.assert_close( + beignet.evaluate_legendre_polynomial( + input, + beignet.fit_legendre_polynomial( + input, + other, + degree=torch.tensor([0, 1, 2, 3]), + ), + ), + other, + ) + + torch.testing.assert_close( + beignet.evaluate_legendre_polynomial( + input, + beignet.fit_legendre_polynomial( + input, + other, + degree=4, + ), + ), + other, + ) + + torch.testing.assert_close( + beignet.evaluate_legendre_polynomial( + input, + beignet.fit_legendre_polynomial( + input, + other, + degree=torch.tensor([0, 1, 2, 3, 4]), + ), + ), + other, + ) + + torch.testing.assert_close( + beignet.evaluate_legendre_polynomial( + input, + beignet.fit_legendre_polynomial( + input, + other, + degree=torch.tensor([2, 3, 4, 1, 0]), + ), + ), + other, + ) + + torch.testing.assert_close( + beignet.fit_legendre_polynomial( + input, + torch.stack([other, other]).T, + degree=3, + ), + torch.stack( + [ + ( + beignet.fit_legendre_polynomial( + input, + other, + degree=torch.tensor([0, 1, 2, 3]), + ) + ), + ( + beignet.fit_legendre_polynomial( + input, + other, + degree=torch.tensor([0, 1, 2, 3]), + ) + ), + ] + ).T, + ) + + torch.testing.assert_close( + beignet.fit_legendre_polynomial( + input, + torch.stack([other, other]).T, + degree=torch.tensor([0, 1, 2, 3]), + ), + torch.stack( + [ + ( + beignet.fit_legendre_polynomial( + input, + other, + degree=torch.tensor([0, 1, 2, 3]), + ) + ), + ( + beignet.fit_legendre_polynomial( + input, + other, + degree=torch.tensor([0, 1, 2, 3]), + ) + ), + ] + ).T, + ) + + weight = torch.zeros_like(input) + + weight[1::2] = 1.0 + + torch.testing.assert_close( + beignet.fit_legendre_polynomial( + input, + other, + degree=3, + weight=weight, + ), + beignet.fit_legendre_polynomial( + input, + other, + degree=torch.tensor([0, 1, 2, 3]), + ), + ) + + torch.testing.assert_close( + beignet.fit_legendre_polynomial( + input, + other, + degree=torch.tensor([0, 1, 2, 3]), + weight=weight, + ), + beignet.fit_legendre_polynomial( + input, + other, + degree=torch.tensor([0, 1, 2, 3]), + ), + ) + + torch.testing.assert_close( + beignet.fit_legendre_polynomial( + input, + torch.stack([other, other]).T, + degree=3, + weight=weight, + ), + torch.stack( + [ + ( + beignet.fit_legendre_polynomial( + input, + other, + degree=torch.tensor([0, 1, 2, 3]), + ) + ), + ( + beignet.fit_legendre_polynomial( + input, + other, + degree=torch.tensor([0, 1, 2, 3]), + ) + ), + ] + ).T, + ) + + torch.testing.assert_close( + beignet.fit_legendre_polynomial( + input, + torch.stack([other, other]).T, + degree=torch.tensor([0, 1, 2, 3]), + weight=weight, + ), + torch.stack( + [ + ( + beignet.fit_legendre_polynomial( + input, + other, + degree=torch.tensor([0, 1, 2, 3]), + ) + ), + ( + beignet.fit_legendre_polynomial( + input, + other, + degree=torch.tensor([0, 1, 2, 3]), + ) + ), + ] + ).T, + ) + + # torch.testing.assert_close( + # beignet.legfit( + # torch.tensor([1, 1j, -1, -1j]), + # torch.tensor([1, 1j, -1, -1j]), + # degree=torch.tensor([1]), + # ), + # torch.tensor([0, 1]), + # ) + + # torch.testing.assert_close( + # beignet.legfit( + # torch.tensor([1, 1j, -1, -1j]), + # torch.tensor([1, 1j, -1, -1j]), + # degree=torch.tensor([0, 1]), + # ), + # torch.tensor([0, 1]), + # ) + + input = torch.linspace(-1, 1, 50) + + other = g(input) + + torch.testing.assert_close( + beignet.evaluate_legendre_polynomial( + input, + beignet.fit_legendre_polynomial( + input, + other, + degree=4, + ), + ), + other, + ) + + torch.testing.assert_close( + beignet.evaluate_legendre_polynomial( + input, + beignet.fit_legendre_polynomial( + input, + other, + degree=torch.tensor([0, 2, 4]), + ), + ), + other, + ) + + torch.testing.assert_close( + beignet.fit_legendre_polynomial( + input, + other, + degree=4, + ), + beignet.fit_legendre_polynomial( + input, + other, + degree=torch.tensor([0, 2, 4]), + ), + ) diff --git a/tests/beignet/test__fit_physicists_hermite_polynomial.py b/tests/beignet/test__fit_physicists_hermite_polynomial.py new file mode 100644 index 0000000000..ba1a331624 --- /dev/null +++ b/tests/beignet/test__fit_physicists_hermite_polynomial.py @@ -0,0 +1,271 @@ +import beignet +import torch + + +def test_fit_physicists_hermite_polynomial(): + def f(x): + return x * (x - 1) * (x - 2) + + def g(x): + return x**4 + x**2 + 1 + + input = torch.linspace(0, 2, 50) + + other = f(input) + + torch.testing.assert_close( + beignet.evaluate_physicists_hermite_polynomial( + input, + beignet.fit_physicists_hermite_polynomial( + input, + other, + degree=3, + ), + ), + other, + ) + + torch.testing.assert_close( + beignet.evaluate_physicists_hermite_polynomial( + input, + beignet.fit_physicists_hermite_polynomial( + input, + other, + degree=torch.tensor([0, 1, 2, 3]), + ), + ), + other, + ) + + torch.testing.assert_close( + beignet.evaluate_physicists_hermite_polynomial( + input, + beignet.fit_physicists_hermite_polynomial( + input, + other, + degree=4, + ), + ), + other, + ) + + torch.testing.assert_close( + beignet.evaluate_physicists_hermite_polynomial( + input, + beignet.fit_physicists_hermite_polynomial( + input, + other, + degree=torch.tensor([0, 1, 2, 3, 4]), + ), + ), + other, + ) + + torch.testing.assert_close( + beignet.evaluate_physicists_hermite_polynomial( + input, + beignet.fit_physicists_hermite_polynomial( + input, + other, + degree=torch.tensor([2, 3, 4, 1, 0]), + ), + ), + other, + ) + + torch.testing.assert_close( + beignet.fit_physicists_hermite_polynomial( + input, + torch.stack([other, other]).T, + degree=3, + ), + torch.stack( + [ + ( + beignet.fit_physicists_hermite_polynomial( + input, + other, + degree=torch.tensor([0, 1, 2, 3]), + ) + ), + ( + beignet.fit_physicists_hermite_polynomial( + input, + other, + degree=torch.tensor([0, 1, 2, 3]), + ) + ), + ], + ).T, + ) + + torch.testing.assert_close( + beignet.fit_physicists_hermite_polynomial( + input, + torch.stack([other, other]).T, + degree=torch.tensor([0, 1, 2, 3]), + ), + torch.stack( + [ + ( + beignet.fit_physicists_hermite_polynomial( + input, + other, + degree=torch.tensor([0, 1, 2, 3]), + ) + ), + ( + beignet.fit_physicists_hermite_polynomial( + input, + other, + degree=torch.tensor([0, 1, 2, 3]), + ) + ), + ] + ).T, + ) + + weight = torch.zeros_like(input) + + weight[1::2] = 1.0 + + torch.testing.assert_close( + beignet.fit_physicists_hermite_polynomial( + input, + other, + degree=3, + weight=weight, + ), + beignet.fit_physicists_hermite_polynomial( + input, + other, + degree=torch.tensor([0, 1, 2, 3]), + ), + ) + + torch.testing.assert_close( + beignet.fit_physicists_hermite_polynomial( + input, + other, + degree=torch.tensor([0, 1, 2, 3]), + weight=weight, + ), + beignet.fit_physicists_hermite_polynomial( + input, + other, + degree=torch.tensor([0, 1, 2, 3]), + ), + ) + + torch.testing.assert_close( + beignet.fit_physicists_hermite_polynomial( + input, + torch.stack([other, other]).T, + degree=3, + weight=weight, + ), + torch.stack( + [ + ( + beignet.fit_physicists_hermite_polynomial( + input, + other, + degree=torch.tensor([0, 1, 2, 3]), + ) + ), + ( + beignet.fit_physicists_hermite_polynomial( + input, + other, + degree=torch.tensor([0, 1, 2, 3]), + ) + ), + ] + ).T, + ) + + torch.testing.assert_close( + beignet.fit_physicists_hermite_polynomial( + input, + torch.stack([other, other]).T, + degree=torch.tensor([0, 1, 2, 3]), + weight=weight, + ), + torch.stack( + [ + ( + beignet.fit_physicists_hermite_polynomial( + input, + other, + degree=torch.tensor([0, 1, 2, 3]), + ) + ), + ( + beignet.fit_physicists_hermite_polynomial( + input, + other, + degree=torch.tensor([0, 1, 2, 3]), + ) + ), + ] + ).T, + ) + + # torch.testing.assert_close( + # beignet.hermfit( + # torch.tensor([1, 1j, -1, -1j]), + # torch.tensor([1, 1j, -1, -1j]), + # degree=1, + # ), + # torch.tensor([0.0j, 0.5j]), + # ) + + # torch.testing.assert_close( + # beignet.hermfit( + # torch.tensor([1, 1j, -1, -1j]), + # torch.tensor([1, 1j, -1, -1j]), + # degree=torch.tensor([0, 1]), + # ), + # torch.tensor([0, 0.5]), + # ) + + input = torch.linspace(-1, 1, 50) + + other = g(input) + + torch.testing.assert_close( + beignet.evaluate_physicists_hermite_polynomial( + input, + beignet.fit_physicists_hermite_polynomial( + input, + other, + degree=4, + ), + ), + other, + ) + + torch.testing.assert_close( + beignet.evaluate_physicists_hermite_polynomial( + input, + beignet.fit_physicists_hermite_polynomial( + input, + other, + degree=torch.tensor([0, 2, 4]), + ), + ), + other, + ) + + torch.testing.assert_close( + beignet.fit_physicists_hermite_polynomial( + input, + other, + degree=4, + ), + beignet.fit_physicists_hermite_polynomial( + input, + other, + degree=torch.tensor([0, 2, 4]), + ), + ) diff --git a/tests/beignet/test__fit_polynomial.py b/tests/beignet/test__fit_polynomial.py new file mode 100644 index 0000000000..7f1fcb4d32 --- /dev/null +++ b/tests/beignet/test__fit_polynomial.py @@ -0,0 +1,244 @@ +import beignet +import torch +from torch import Tensor + + +def test_fit_polynomial(): + def f(x: Tensor) -> Tensor: + return x * (x - 1) * (x - 2) + + def g(x: Tensor) -> Tensor: + return x**4 + x**2 + 1 + + input = torch.linspace(0, 2, 50) + + other = f(input) + + torch.testing.assert_close( + beignet.evaluate_polynomial( + input, + beignet.fit_polynomial( + input, + other, + degree=3, + ), + ), + other, + ) + + torch.testing.assert_close( + beignet.evaluate_polynomial( + input, + beignet.fit_polynomial( + input, + other, + degree=torch.tensor([0, 1, 2, 3]), + ), + ), + other, + ) + + torch.testing.assert_close( + beignet.evaluate_polynomial( + input, + beignet.fit_polynomial( + input, + other, + degree=4, + ), + ), + other, + ) + + torch.testing.assert_close( + beignet.evaluate_polynomial( + input, + beignet.fit_polynomial( + input, + other, + degree=torch.tensor([0, 1, 2, 3, 4]), + ), + ), + other, + ) + + torch.testing.assert_close( + beignet.fit_polynomial( + input, + torch.stack([other, other]).T, + degree=3, + ), + torch.stack( + [ + beignet.fit_polynomial( + input, + other, + degree=torch.tensor([0, 1, 2, 3]), + ), + beignet.fit_polynomial( + input, + other, + degree=torch.tensor([0, 1, 2, 3]), + ), + ] + ).T, + ) + + torch.testing.assert_close( + beignet.fit_polynomial( + input, + torch.stack([other, other]).T, + degree=torch.tensor([0, 1, 2, 3]), + ), + torch.stack( + [ + beignet.fit_polynomial( + input, + other, + degree=torch.tensor([0, 1, 2, 3]), + ), + beignet.fit_polynomial( + input, + other, + degree=torch.tensor([0, 1, 2, 3]), + ), + ] + ).T, + ) + + weight = torch.zeros_like(input) + + weight[1::2] = 1.0 + + # torch.testing.assert_close( + # beignet.polyfit( + # input, + # other.at[0::2].set(0), + # degree=3, + # weight=weight, + # ), + # beignet.polyfit( + # input, + # other, + # degree=torch.tensor([0, 1, 2, 3]), + # ), + # ) + # + # torch.testing.assert_close( + # beignet.polyfit( + # input, + # other.at[0::2].set(0), + # degree=torch.tensor([0, 1, 2, 3]), + # weight=weight, + # ), + # beignet.polyfit( + # input, + # other, + # degree=torch.tensor([0, 1, 2, 3]), + # ), + # ) + # + # torch.testing.assert_close( + # beignet.polyfit( + # input, + # torch.tensor([other.at[0::2].set(0), other.at[0::2].set(0)]).T, + # degree=3, + # weight=weight, + # ), + # torch.tensor( + # [ + # beignet.polyfit( + # input, + # other, + # degree=torch.tensor([0, 1, 2, 3]), + # ), + # beignet.polyfit( + # input, + # other, + # degree=torch.tensor([0, 1, 2, 3]), + # ), + # ] + # ).T, + # ) + # + # torch.testing.assert_close( + # beignet.polyfit( + # input, + # torch.tensor([other.at[0::2].set(0), other.at[0::2].set(0)]).T, + # degree=torch.tensor([0, 1, 2, 3]), + # weight=weight, + # ), + # torch.tensor( + # [ + # beignet.polyfit( + # input, + # other, + # degree=torch.tensor([0, 1, 2, 3]), + # ), + # beignet.polyfit( + # input, + # other, + # degree=torch.tensor([0, 1, 2, 3]), + # ), + # ] + # ).T, + # ) + # + # torch.testing.assert_close( + # beignet.polyfit( + # torch.tensor([1, 1j, -1, -1j]), + # torch.tensor([1, 1j, -1, -1j]), + # 1, + # ), + # torch.tensor([0, 1]), + # ) + # + # torch.testing.assert_close( + # beignet.polyfit( + # torch.tensor([1, 1j, -1, -0 - 1j]), + # torch.tensor([1, 1j, -1, -0 - 1j]), + # (0, 1), + # ), + # torch.tensor([0, 1]), + # ) + # + # input = torch.linspace(-1, 1, 50) + # + # other = g(input) + # + # torch.testing.assert_close( + # beignet.polyval( + # input, + # beignet.polyfit( + # input, + # other, + # degree=torch.tensor([4]), + # ), + # ), + # other, + # ) + # + # torch.testing.assert_close( + # beignet.polyval( + # input, + # beignet.polyfit( + # input, + # other, + # degree=torch.tensor([0, 2, 4]), + # ), + # ), + # other, + # ) + # + # torch.testing.assert_close( + # beignet.polyfit( + # input, + # other, + # degree=torch.tensor([4]), + # ), + # beignet.polyfit( + # input, + # other, + # degree=torch.tensor([0, 2, 4]), + # ), + # ) diff --git a/tests/beignet/test__fit_probabilists_hermite_polynomial.py b/tests/beignet/test__fit_probabilists_hermite_polynomial.py new file mode 100644 index 0000000000..d7f7e3277b --- /dev/null +++ b/tests/beignet/test__fit_probabilists_hermite_polynomial.py @@ -0,0 +1,271 @@ +import beignet +import torch + + +def test_fit_probabilists_hermite_polynomial(): + def f(x): + return x * (x - 1) * (x - 2) + + def g(x): + return x**4 + x**2 + 1 + + input = torch.linspace(0, 2, 50) + + other = f(input) + + torch.testing.assert_close( + beignet.evaluate_probabilists_hermite_polynomial( + input, + beignet.fit_probabilists_hermite_polynomial( + input, + other, + degree=3, + ), + ), + other, + ) + + torch.testing.assert_close( + beignet.evaluate_probabilists_hermite_polynomial( + input, + beignet.fit_probabilists_hermite_polynomial( + input, + other, + degree=torch.tensor([0, 1, 2, 3]), + ), + ), + other, + ) + + torch.testing.assert_close( + beignet.evaluate_probabilists_hermite_polynomial( + input, + beignet.fit_probabilists_hermite_polynomial( + input, + other, + degree=4, + ), + ), + other, + ) + + torch.testing.assert_close( + beignet.evaluate_probabilists_hermite_polynomial( + input, + beignet.fit_probabilists_hermite_polynomial( + input, + other, + degree=torch.tensor([0, 1, 2, 3, 4]), + ), + ), + other, + ) + + torch.testing.assert_close( + beignet.evaluate_probabilists_hermite_polynomial( + input, + beignet.fit_probabilists_hermite_polynomial( + input, + other, + degree=torch.tensor([2, 3, 4, 1, 0]), + ), + ), + other, + ) + + torch.testing.assert_close( + beignet.fit_probabilists_hermite_polynomial( + input, + torch.stack([other, other]).T, + degree=3, + ), + torch.stack( + [ + ( + beignet.fit_probabilists_hermite_polynomial( + input, + other, + degree=torch.tensor([0, 1, 2, 3]), + ) + ), + ( + beignet.fit_probabilists_hermite_polynomial( + input, + other, + degree=torch.tensor([0, 1, 2, 3]), + ) + ), + ] + ).T, + ) + + torch.testing.assert_close( + beignet.fit_probabilists_hermite_polynomial( + input, + torch.stack([other, other]).T, + degree=torch.tensor([0, 1, 2, 3]), + ), + torch.stack( + [ + ( + beignet.fit_probabilists_hermite_polynomial( + input, + other, + degree=torch.tensor([0, 1, 2, 3]), + ) + ), + ( + beignet.fit_probabilists_hermite_polynomial( + input, + other, + degree=torch.tensor([0, 1, 2, 3]), + ) + ), + ] + ).T, + ) + + weight = torch.zeros_like(input) + + weight[1::2] = 1.0 + + torch.testing.assert_close( + beignet.fit_probabilists_hermite_polynomial( + input, + other, + degree=3, + weight=weight, + ), + beignet.fit_probabilists_hermite_polynomial( + input, + other, + degree=torch.tensor([0, 1, 2, 3]), + ), + ) + + torch.testing.assert_close( + beignet.fit_probabilists_hermite_polynomial( + input, + other, + degree=torch.tensor([0, 1, 2, 3]), + weight=weight, + ), + beignet.fit_probabilists_hermite_polynomial( + input, + other, + degree=torch.tensor([0, 1, 2, 3]), + ), + ) + + torch.testing.assert_close( + beignet.fit_probabilists_hermite_polynomial( + input, + torch.stack([other, other]).T, + degree=3, + weight=weight, + ), + torch.stack( + [ + ( + beignet.fit_probabilists_hermite_polynomial( + input, + other, + degree=torch.tensor([0, 1, 2, 3]), + ) + ), + ( + beignet.fit_probabilists_hermite_polynomial( + input, + other, + degree=torch.tensor([0, 1, 2, 3]), + ) + ), + ] + ).T, + ) + + torch.testing.assert_close( + beignet.fit_probabilists_hermite_polynomial( + input, + torch.stack([other, other]).T, + degree=torch.tensor([0, 1, 2, 3]), + weight=weight, + ), + torch.stack( + [ + ( + beignet.fit_probabilists_hermite_polynomial( + input, + other, + degree=torch.tensor([0, 1, 2, 3]), + ) + ), + ( + beignet.fit_probabilists_hermite_polynomial( + input, + other, + degree=torch.tensor([0, 1, 2, 3]), + ) + ), + ] + ).T, + ) + + # torch.testing.assert_close( + # beignet.hermefit( + # torch.tensor([1, 1j, -1, -1j]), + # torch.tensor([1, 1j, -1, -1j]), + # degree=torch.tensor([1]), + # ), + # torch.tensor([0, 1]), + # ) + + # torch.testing.assert_close( + # beignet.hermefit( + # torch.tensor([1, 1j, -1, -1j]), + # torch.tensor([1, 1j, -1, -1j]), + # degree=torch.tensor([0, 1]), + # ), + # torch.tensor([0, 1]), + # ) + + input = torch.linspace(-1, 1, 50) + + other = g(input) + + torch.testing.assert_close( + beignet.evaluate_probabilists_hermite_polynomial( + input, + beignet.fit_probabilists_hermite_polynomial( + input, + other, + degree=4, + ), + ), + other, + ) + + torch.testing.assert_close( + beignet.evaluate_probabilists_hermite_polynomial( + input, + beignet.fit_probabilists_hermite_polynomial( + input, + other, + degree=torch.tensor([0, 2, 4]), + ), + ), + other, + ) + + torch.testing.assert_close( + beignet.fit_probabilists_hermite_polynomial( + input, + other, + degree=4, + ), + beignet.fit_probabilists_hermite_polynomial( + input, + other, + degree=torch.tensor([0, 2, 4]), + ), + ) diff --git a/tests/beignet/test__gauss_laguerre_quadrature.py b/tests/beignet/test__gauss_laguerre_quadrature.py new file mode 100644 index 0000000000..7271bc8bb7 --- /dev/null +++ b/tests/beignet/test__gauss_laguerre_quadrature.py @@ -0,0 +1,18 @@ +# import beignet +# import torch +# +# +# def test_gauss_laguerre_quadrature(): +# x, w = beignet.gauss_laguerre_quadrature(100) +# +# v = beignet.lagvander(x, 99) +# vv = (v.T * w) @ v +# vd = 1 / torch.sqrt(vv.diagonal()) +# vv = vd[:, None] * vv * vd +# torch.testing.assert_close( +# vv, +# torch.eye(100), +# ) +# +# target = 1.0 +# torch.testing.assert_close(w.sum(), target) diff --git a/tests/beignet/test__gauss_legendre_quadrature.py b/tests/beignet/test__gauss_legendre_quadrature.py new file mode 100644 index 0000000000..992e00423f --- /dev/null +++ b/tests/beignet/test__gauss_legendre_quadrature.py @@ -0,0 +1,23 @@ +# import beignet +# import torch +# +# +# def test_gauss_legendre_quadrature(): +# x, w = beignet.gauss_legendre_quadrature(100) +# +# v = beignet.legvander( +# x, +# degree=torch.tensor([99]), +# ) +# +# vv = (v.T * w) @ v +# +# vd = 1 / torch.sqrt(vv.diagonal()) +# vv = vd[:, None] * vv * vd +# +# torch.testing.assert_close( +# vv, +# torch.eye(100), +# ) +# +# torch.testing.assert_close(w.sum(), 2.0) diff --git a/tests/beignet/test__gauss_physicists_hermite_polynomial_quadrature.py b/tests/beignet/test__gauss_physicists_hermite_polynomial_quadrature.py new file mode 100644 index 0000000000..1f4b5fb823 --- /dev/null +++ b/tests/beignet/test__gauss_physicists_hermite_polynomial_quadrature.py @@ -0,0 +1,22 @@ +import math + +import beignet +import torch + + +def test_gauss_physicists_hermite_polynomial_quadrature(): + x, w = beignet.gauss_physicists_hermite_polynomial_quadrature(100) + + v = beignet.physicists_hermite_polynomial_vandermonde(x, 99) + vv = (v.T * w) @ v + vd = 1 / torch.sqrt(vv.diagonal()) + vv = vd[:, None] * vv * vd + torch.testing.assert_close( + vv, + torch.eye(100), + ) + + torch.testing.assert_close( + w.sum(), + torch.tensor(math.sqrt(math.pi)), + ) diff --git a/tests/beignet/test__gauss_probabilists_hermite_polynomial_quadrature.py b/tests/beignet/test__gauss_probabilists_hermite_polynomial_quadrature.py new file mode 100644 index 0000000000..a2a9179904 --- /dev/null +++ b/tests/beignet/test__gauss_probabilists_hermite_polynomial_quadrature.py @@ -0,0 +1,20 @@ +import math + +import beignet +import torch + + +def test_gauss_probabilists_hermite_polynomial_quadrature(): + x, w = beignet.gauss_probabilists_hermite_polynomial_quadrature(100) + + v = beignet.probabilists_hermite_polynomial_vandermonde(x, 99) + vv = (v.T * w) @ v + vd = 1 / torch.sqrt(vv.diagonal()) + vv = vd[:, None] * vv * vd + torch.testing.assert_close(vv, torch.eye(100)) + + target = math.sqrt(2 * math.pi) + torch.testing.assert_close( + w.sum(), + torch.tensor(target), + ) diff --git a/tests/beignet/test__integrate_chebyshev_polynomial.py b/tests/beignet/test__integrate_chebyshev_polynomial.py new file mode 100644 index 0000000000..8f525ab049 --- /dev/null +++ b/tests/beignet/test__integrate_chebyshev_polynomial.py @@ -0,0 +1,240 @@ +import beignet +import pytest +import torch + + +def test_integrate_chebyshev_polynomial(): + with pytest.raises(TypeError): + beignet.integrate_chebyshev_polynomial( + torch.tensor([0]), + order=0.5, + ) + + with pytest.raises(ValueError): + beignet.integrate_chebyshev_polynomial( + torch.tensor([0]), + order=-1, + ) + + with pytest.raises(ValueError): + beignet.integrate_chebyshev_polynomial( + torch.tensor([0.0]), + order=1, + k=torch.tensor([0.0, 0.0]), + ) + + with pytest.raises(TypeError): + beignet.integrate_chebyshev_polynomial( + torch.tensor([0]), + axis=0.5, + ) + + for i in range(2, 5): + torch.testing.assert_close( + beignet.trim_chebyshev_polynomial_coefficients( + beignet.integrate_chebyshev_polynomial( + torch.tensor([0.0]), + order=i, + k=torch.tensor([0.0] * (i - 2) + [1.0]), + ), + tol=0.000001, + ), + torch.tensor([0.0, 1.0]), + ) + + for i in range(5): + torch.testing.assert_close( + beignet.trim_chebyshev_polynomial_coefficients( + beignet.chebyshev_polynomial_to_polynomial( + beignet.integrate_chebyshev_polynomial( + beignet.polynomial_to_chebyshev_polynomial( + torch.tensor([0.0] * i + [1.0]), + ), + order=1, + k=[i], + ), + ), + tol=0.000001, + ), + beignet.trim_chebyshev_polynomial_coefficients( + torch.tensor([i] + [0] * i + [1 / (i + 1)]), + tol=0.000001, + ), + ) + + for i in range(5): + torch.testing.assert_close( + beignet.evaluate_chebyshev_polynomial( + torch.tensor([-1]), + beignet.integrate_chebyshev_polynomial( + beignet.polynomial_to_chebyshev_polynomial( + torch.tensor([0.0] * i + [1.0]), + ), + order=1, + k=[i], + lower_bound=-1, + ), + ), + torch.tensor([i], dtype=torch.get_default_dtype()), + ) + + for i in range(5): + torch.testing.assert_close( + beignet.trim_chebyshev_polynomial_coefficients( + beignet.chebyshev_polynomial_to_polynomial( + beignet.integrate_chebyshev_polynomial( + beignet.polynomial_to_chebyshev_polynomial( + torch.tensor([0.0] * i + [1.0]), + ), + order=1, + k=[i], + scale=2, + ) + ), + tol=0.000001, + ), + beignet.trim_chebyshev_polynomial_coefficients( + torch.tensor([i] + [0] * i + [2 / (i + 1)]), + tol=0.000001, + ), + ) + + for i in range(5): + for j in range(2, 5): + input = torch.tensor([0.0] * i + [1.0]) + target = input[:] + + for _ in range(j): + target = beignet.integrate_chebyshev_polynomial( + target, + order=1, + ) + + torch.testing.assert_close( + beignet.trim_chebyshev_polynomial_coefficients( + beignet.integrate_chebyshev_polynomial( + input, + order=j, + ), + tol=0.000001, + ), + beignet.trim_chebyshev_polynomial_coefficients( + target, + tol=0.000001, + ), + ) + + for i in range(5): + for j in range(2, 5): + input = torch.tensor([0.0] * i + [1.0]) + + target = input[:] + + for k in range(j): + target = beignet.integrate_chebyshev_polynomial( + target, + order=1, + k=[k], + ) + + torch.testing.assert_close( + beignet.trim_chebyshev_polynomial_coefficients( + beignet.integrate_chebyshev_polynomial( + input, + order=j, + k=list(range(j)), + ), + tol=0.000001, + ), + beignet.trim_chebyshev_polynomial_coefficients( + target, + tol=0.000001, + ), + ) + + for i in range(5): + for j in range(2, 5): + input = torch.tensor([0.0] * i + [1.0]) + + target = input[:] + + for k in range(j): + target = beignet.integrate_chebyshev_polynomial( + target, + order=1, + k=[k], + lower_bound=-1, + ) + + torch.testing.assert_close( + beignet.trim_chebyshev_polynomial_coefficients( + beignet.integrate_chebyshev_polynomial( + input, + order=j, + k=list(range(j)), + lower_bound=-1, + ), + tol=0.000001, + ), + beignet.trim_chebyshev_polynomial_coefficients( + target, + tol=0.000001, + ), + ) + + for i in range(5): + for j in range(2, 5): + input = torch.tensor([0.0] * i + [1.0]) + + target = input[:] + + for k in range(j): + target = beignet.integrate_chebyshev_polynomial( + target, + order=1, + k=[k], + scale=2, + ) + + torch.testing.assert_close( + beignet.trim_chebyshev_polynomial_coefficients( + beignet.integrate_chebyshev_polynomial( + input, + order=j, + k=list(range(j)), + scale=2, + ), + tol=0.000001, + ), + beignet.trim_chebyshev_polynomial_coefficients( + target, + tol=0.000001, + ), + ) + + c2d = torch.rand(3, 4) + + torch.testing.assert_close( + beignet.integrate_chebyshev_polynomial( + c2d, + axis=0, + ), + torch.vstack([beignet.integrate_chebyshev_polynomial(c) for c in c2d.T]).T, + ) + + # torch.testing.assert_close( + # beignet.chebint( + # c2d, + # axis=1, + # ), + # torch.vstack([beignet.chebint(c) for c in c2d]), + # ) + + # torch.testing.assert_close( + # beignet.chebint( + # c2d, + # k=3, + # axis=1, + # ), + # torch.vstack([beignet.chebint(c, k=3) for c in c2d]), + # ) diff --git a/tests/beignet/test__integrate_laguerre_polynomial.py b/tests/beignet/test__integrate_laguerre_polynomial.py new file mode 100644 index 0000000000..4d4ea45d7d --- /dev/null +++ b/tests/beignet/test__integrate_laguerre_polynomial.py @@ -0,0 +1,245 @@ +# import beignet +# import pytest +# import torch +# +# +# def test_integrate_laguerre_polynomial(): +# with pytest.raises(TypeError): +# beignet.integrate_laguerre_polynomial( +# torch.tensor([0]), +# 0.5, +# ) +# +# with pytest.raises(ValueError): +# beignet.integrate_laguerre_polynomial( +# torch.tensor([0]), +# -1, +# ) +# +# with pytest.raises(ValueError): +# beignet.integrate_laguerre_polynomial( +# torch.tensor([0]), +# 1, +# torch.tensor([0, 0]), +# ) +# +# with pytest.raises(ValueError): +# beignet.integrate_laguerre_polynomial( +# torch.tensor([0]), +# lower_bound=[0], +# ) +# +# with pytest.raises(ValueError): +# beignet.integrate_laguerre_polynomial( +# torch.tensor([0]), +# scale=[0], +# ) +# +# with pytest.raises(TypeError): +# beignet.integrate_laguerre_polynomial( +# torch.tensor([0]), +# axis=0.5, +# ) +# +# for i in range(2, 5): +# torch.testing.assert_close( +# beignet.trim_laguerre_polynomial_coefficients( +# beignet.integrate_laguerre_polynomial( +# torch.tensor([0.0]), +# order=i, +# k=([0.0] * (i - 2) + [1.0]), +# ), +# tol=0.000001, +# ), +# torch.tensor([1.0, -1.0]), +# ) +# +# for i in range(5): +# torch.testing.assert_close( +# beignet.trim_laguerre_polynomial_coefficients( +# beignet.laguerre_polynomial_to_polynomial( +# beignet.integrate_laguerre_polynomial( +# beignet.polynomial_to_laguerre_polynomial( +# torch.tensor([0.0] * i + [1.0]), +# ), +# order=1, +# k=[i], +# ), +# ), +# tol=0.000001, +# ), +# beignet.trim_laguerre_polynomial_coefficients( +# torch.tensor([i] + [0.0] * i + [1.0 / (i + 1.0)]), +# tol=0.000001, +# ), +# ) +# +# for i in range(5): +# torch.testing.assert_close( +# beignet.evaluate_laguerre_polynomial( +# torch.tensor([-1.0]), +# beignet.integrate_laguerre_polynomial( +# beignet.polynomial_to_laguerre_polynomial( +# torch.tensor([0.0] * i + [1.0]), +# ), +# order=1, +# k=[i], +# lower_bound=-1, +# ), +# ), +# torch.tensor([i], dtype=torch.get_default_dtype()), +# ) +# +# for i in range(5): +# torch.testing.assert_close( +# beignet.trim_laguerre_polynomial_coefficients( +# beignet.laguerre_polynomial_to_polynomial( +# beignet.integrate_laguerre_polynomial( +# beignet.polynomial_to_laguerre_polynomial( +# torch.tensor([0.0] * i + [1.0]), +# ), +# order=1, +# k=[i], +# scale=2, +# ), +# ), +# tol=0.000001, +# ), +# beignet.trim_laguerre_polynomial_coefficients( +# torch.tensor([i] + [0.0] * i + [2.0 / (i + 1)]), +# tol=0.000001, +# ), +# ) +# +# for i in range(5): +# for j in range(2, 5): +# target = torch.tensor([0.0] * i + [1.0])[:] +# +# for _ in range(j): +# target = beignet.integrate_laguerre_polynomial( +# target, +# order=1, +# ) +# +# torch.testing.assert_close( +# beignet.trim_laguerre_polynomial_coefficients( +# beignet.integrate_laguerre_polynomial( +# torch.tensor([0.0] * i + [1.0]), +# order=j, +# ), +# tol=0.000001, +# ), +# beignet.trim_laguerre_polynomial_coefficients( +# target, +# tol=0.000001, +# ), +# ) +# +# for i in range(5): +# for j in range(2, 5): +# target = torch.tensor([0.0] * i + [1.0])[:] +# +# for k in range(j): +# target = beignet.integrate_laguerre_polynomial( +# target, +# order=1, +# k=[k], +# ) +# +# torch.testing.assert_close( +# beignet.trim_laguerre_polynomial_coefficients( +# beignet.integrate_laguerre_polynomial( +# torch.tensor([0.0] * i + [1.0]), +# order=j, +# k=list(range(j)), +# ), +# tol=0.000001, +# ), +# beignet.trim_laguerre_polynomial_coefficients( +# target, +# tol=0.000001, +# ), +# ) +# +# for i in range(5): +# for j in range(2, 5): +# target = torch.tensor([0.0] * i + [1.0])[:] +# +# for k in range(j): +# target = beignet.integrate_laguerre_polynomial( +# target, +# order=1, +# k=[k], +# lower_bound=-1, +# ) +# +# torch.testing.assert_close( +# beignet.trim_laguerre_polynomial_coefficients( +# beignet.integrate_laguerre_polynomial( +# torch.tensor([0.0] * i + [1.0]), +# order=j, +# k=list(range(j)), +# lower_bound=-1, +# ), +# tol=0.000001, +# ), +# beignet.trim_laguerre_polynomial_coefficients( +# target, +# tol=0.000001, +# ), +# ) +# +# for i in range(5): +# for j in range(2, 5): +# target = torch.tensor([0.0] * i + [1.0])[:] +# +# for k in range(j): +# target = beignet.integrate_laguerre_polynomial( +# target, +# order=1, +# k=[k], +# scale=2, +# ) +# +# torch.testing.assert_close( +# beignet.trim_laguerre_polynomial_coefficients( +# beignet.integrate_laguerre_polynomial( +# torch.tensor([0.0] * i + [1.0]), +# order=j, +# k=list(range(j)), +# scale=2, +# ), +# tol=0.000001, +# ), +# beignet.trim_laguerre_polynomial_coefficients( +# target, +# tol=0.000001, +# ), +# ) +# +# c2d = torch.rand(3, 4) +# +# torch.testing.assert_close( +# beignet.integrate_laguerre_polynomial( +# c2d, +# axis=0, +# ), +# torch.vstack([beignet.integrate_laguerre_polynomial(c) for c in c2d.T]).T, +# ) +# +# torch.testing.assert_close( +# beignet.integrate_laguerre_polynomial( +# c2d, +# axis=1, +# ), +# torch.vstack([beignet.integrate_laguerre_polynomial(c) for c in c2d]), +# ) +# +# torch.testing.assert_close( +# beignet.integrate_laguerre_polynomial( +# c2d, +# k=3, +# axis=1, +# ), +# torch.vstack([beignet.integrate_laguerre_polynomial(c, k=3) for c in c2d]), +# ) diff --git a/tests/beignet/test__integrate_legendre_polynomial.py b/tests/beignet/test__integrate_legendre_polynomial.py new file mode 100644 index 0000000000..42bf104ea3 --- /dev/null +++ b/tests/beignet/test__integrate_legendre_polynomial.py @@ -0,0 +1,259 @@ +import beignet +import pytest +import torch + + +def test_integrate_legendre_polynomial(): + with pytest.raises(TypeError): + beignet.integrate_legendre_polynomial( + torch.tensor([0]), + 0.5, + ) + + with pytest.raises(ValueError): + beignet.integrate_legendre_polynomial( + torch.tensor([0]), + -1, + ) + + with pytest.raises(ValueError): + beignet.integrate_legendre_polynomial( + torch.tensor([0]), + 1, + torch.tensor([0, 0]), + ) + + with pytest.raises(ValueError): + beignet.integrate_legendre_polynomial( + torch.tensor([0]), + lower_bound=[0], + ) + + with pytest.raises(ValueError): + beignet.integrate_legendre_polynomial( + torch.tensor([0]), + scale=[0], + ) + + with pytest.raises(TypeError): + beignet.integrate_legendre_polynomial( + torch.tensor([0]), + axis=0.5, + ) + + for i in range(2, 5): + output = beignet.integrate_legendre_polynomial( + torch.tensor([0.0]), + order=i, + k=[0.0] * (i - 2) + [1.0], + ) + torch.testing.assert_close( + beignet.trim_legendre_polynomial_coefficients( + output, + tol=0.000001, + ), + torch.tensor([0.0, 1.0]), + ) + + for i in range(5): + torch.testing.assert_close( + beignet.trim_legendre_polynomial_coefficients( + beignet.legendre_polynomial_to_polynomial( + beignet.integrate_legendre_polynomial( + beignet.polynomial_to_legendre_polynomial( + torch.tensor([0.0] * i + [1.0]), + ), + order=1, + k=[i], + ) + ), + tol=0.000001, + ), + beignet.trim_legendre_polynomial_coefficients( + torch.tensor([i] + [0.0] * i + [1 / (i + 1)]), + tol=0.000001, + ), + ) + + for i in range(5): + torch.testing.assert_close( + beignet.evaluate_legendre_polynomial( + torch.tensor([-1]), + beignet.integrate_legendre_polynomial( + beignet.polynomial_to_legendre_polynomial( + torch.tensor([0.0] * i + [1.0]), + ), + order=1, + k=[i], + lower_bound=-1, + ), + ), + torch.tensor([i], dtype=torch.get_default_dtype()), + ) + + for i in range(5): + torch.testing.assert_close( + beignet.trim_legendre_polynomial_coefficients( + beignet.legendre_polynomial_to_polynomial( + beignet.integrate_legendre_polynomial( + beignet.polynomial_to_legendre_polynomial( + torch.tensor([0.0] * i + [1.0]), + ), + order=1, + k=[i], + scale=2, + ) + ), + tol=0.000001, + ), + beignet.trim_legendre_polynomial_coefficients( + torch.tensor([i] + [0.0] * i + [2 / (i + 1)]), + tol=0.000001, + ), + ) + + for i in range(5): + for j in range(2, 5): + target = torch.tensor([0.0] * i + [1.0])[:] + + for _ in range(j): + target = beignet.integrate_legendre_polynomial( + target, + order=1, + ) + + torch.testing.assert_close( + beignet.trim_legendre_polynomial_coefficients( + beignet.integrate_legendre_polynomial( + torch.tensor([0.0] * i + [1.0]), + order=j, + ), + tol=0.000001, + ), + beignet.trim_legendre_polynomial_coefficients( + target, + tol=0.000001, + ), + ) + + for i in range(5): + for j in range(2, 5): + target = torch.tensor([0.0] * i + [1.0])[:] + + for k in range(j): + target = beignet.integrate_legendre_polynomial( + target, + order=1, + k=[k], + ) + + torch.testing.assert_close( + beignet.trim_legendre_polynomial_coefficients( + beignet.integrate_legendre_polynomial( + torch.tensor([0.0] * i + [1.0]), + order=j, + k=list(range(j)), + ), + tol=0.000001, + ), + beignet.trim_legendre_polynomial_coefficients( + target, + tol=0.000001, + ), + ) + + for i in range(5): + for j in range(2, 5): + target = torch.tensor([0.0] * i + [1.0])[:] + + for k in range(j): + target = beignet.integrate_legendre_polynomial( + target, + order=1, + k=[k], + lower_bound=-1, + ) + + torch.testing.assert_close( + beignet.trim_legendre_polynomial_coefficients( + beignet.integrate_legendre_polynomial( + torch.tensor([0.0] * i + [1.0]), + order=j, + k=list(range(j)), + lower_bound=-1, + ), + tol=0.000001, + ), + beignet.trim_legendre_polynomial_coefficients( + target, + tol=0.000001, + ), + ) + + for i in range(5): + for j in range(2, 5): + target = torch.tensor([0.0] * i + [1.0])[:] + + for k in range(j): + target = beignet.integrate_legendre_polynomial( + target, + order=1, + k=[k], + scale=2, + ) + + torch.testing.assert_close( + beignet.trim_legendre_polynomial_coefficients( + beignet.integrate_legendre_polynomial( + torch.tensor([0.0] * i + [1.0]), + order=j, + k=list(range(j)), + scale=2, + ), + tol=0.000001, + ), + beignet.trim_legendre_polynomial_coefficients( + target, + tol=0.000001, + ), + ) + + c2d = torch.rand(3, 4) + + torch.testing.assert_close( + beignet.integrate_legendre_polynomial(c2d, axis=0), + torch.vstack([beignet.integrate_legendre_polynomial(c) for c in c2d.T]).T, + ) + + target = [beignet.integrate_legendre_polynomial(c) for c in c2d] + + target = torch.vstack(target) + + torch.testing.assert_close( + beignet.integrate_legendre_polynomial( + c2d, + axis=1, + ), + target, + ) + + target = [beignet.integrate_legendre_polynomial(c, k=3) for c in c2d] + + target = torch.vstack(target) + + torch.testing.assert_close( + beignet.integrate_legendre_polynomial( + c2d, + k=3, + axis=1, + ), + target, + ) + + torch.testing.assert_close( + beignet.integrate_legendre_polynomial( + torch.tensor([1, 2, 3]), + order=0, + ), + torch.tensor([1, 2, 3]), + ) diff --git a/tests/beignet/test__integrate_physicists_hermite_polynomial.py b/tests/beignet/test__integrate_physicists_hermite_polynomial.py new file mode 100644 index 0000000000..b8d981054b --- /dev/null +++ b/tests/beignet/test__integrate_physicists_hermite_polynomial.py @@ -0,0 +1,257 @@ +import beignet +import pytest +import torch + + +def test_integrate_physicists_hermite_polynomial(): + with pytest.raises(TypeError): + beignet.integrate_physicists_hermite_polynomial( + torch.tensor([0.0]), + order=0.5, + ) + + with pytest.raises(ValueError): + beignet.integrate_physicists_hermite_polynomial( + torch.tensor([0]), + order=-1, + ) + + with pytest.raises(ValueError): + beignet.integrate_physicists_hermite_polynomial( + torch.tensor([0]), + order=1, + k=torch.tensor([0, 0]), + ) + + with pytest.raises(ValueError): + beignet.integrate_physicists_hermite_polynomial( + torch.tensor([0]), + lower_bound=[0], + ) + + with pytest.raises(ValueError): + beignet.integrate_physicists_hermite_polynomial( + torch.tensor([0]), + scale=[0], + ) + + with pytest.raises(TypeError): + beignet.integrate_physicists_hermite_polynomial( + torch.tensor([0]), + axis=0.5, + ) + + for i in range(2, 5): + torch.testing.assert_close( + beignet.trim_physicists_hermite_polynomial_coefficients( + beignet.integrate_physicists_hermite_polynomial( + torch.tensor([0.0]), + order=i, + k=([0.0] * (i - 2) + [1.0]), + ), + tol=0.000001, + ), + torch.tensor([0.0, 0.5]), + ) + + for i in range(5): + torch.testing.assert_close( + beignet.trim_physicists_hermite_polynomial_coefficients( + beignet.physicists_hermite_polynomial_to_polynomial( + beignet.integrate_physicists_hermite_polynomial( + beignet.polynomial_to_physicists_hermite_polynomial( + torch.tensor([0.0] * i + [1.0]), + ), + order=1, + k=[i], + ) + ), + tol=0.000001, + ), + beignet.trim_physicists_hermite_polynomial_coefficients( + torch.tensor([i] + [0.0] * i + [1.0 / (i + 1)]), + tol=0.000001, + ), + ) + + for i in range(5): + torch.testing.assert_close( + beignet.evaluate_physicists_hermite_polynomial( + torch.tensor([-1.0]), + beignet.integrate_physicists_hermite_polynomial( + beignet.polynomial_to_physicists_hermite_polynomial( + torch.tensor([0.0] * i + [1.0]), + ), + order=1, + k=[i], + lower_bound=-1, + ), + ), + torch.tensor([i], dtype=torch.get_default_dtype()), + ) + + for i in range(5): + torch.testing.assert_close( + beignet.trim_physicists_hermite_polynomial_coefficients( + beignet.physicists_hermite_polynomial_to_polynomial( + beignet.integrate_physicists_hermite_polynomial( + beignet.polynomial_to_physicists_hermite_polynomial( + torch.tensor([0.0] * i + [1.0]), + ), + order=1, + k=[i], + scale=2, + ), + ), + tol=0.000001, + ), + beignet.trim_physicists_hermite_polynomial_coefficients( + torch.tensor([i] + [0.0] * i + [2.0 / (i + 1.0)]), + tol=0.000001, + ), + ) + + for i in range(5): + for j in range(2, 5): + target = torch.tensor([0.0] * i + [1.0])[:] + + for _ in range(j): + target = beignet.integrate_physicists_hermite_polynomial( + target, + order=1, + ) + + torch.testing.assert_close( + beignet.trim_physicists_hermite_polynomial_coefficients( + beignet.integrate_physicists_hermite_polynomial( + torch.tensor([0.0] * i + [1.0]), + order=j, + ), + tol=0.000001, + ), + beignet.trim_physicists_hermite_polynomial_coefficients( + target, + tol=0.000001, + ), + ) + + for i in range(5): + for j in range(2, 5): + pol = torch.tensor([0.0] * i + [1.0]) + + target = pol[:] + + for k in range(j): + target = beignet.integrate_physicists_hermite_polynomial( + target, order=1, k=[k] + ) + + torch.testing.assert_close( + beignet.trim_physicists_hermite_polynomial_coefficients( + beignet.integrate_physicists_hermite_polynomial( + pol, + order=j, + k=list(range(j)), + ), + tol=0.000001, + ), + beignet.trim_physicists_hermite_polynomial_coefficients( + target, + tol=0.000001, + ), + ) + + for i in range(5): + for j in range(2, 5): + pol = torch.tensor([0.0] * i + [1.0]) + target = pol[:] + for k in range(j): + target = beignet.integrate_physicists_hermite_polynomial( + target, + order=1, + k=[k], + lower_bound=-1, + ) + + torch.testing.assert_close( + beignet.trim_physicists_hermite_polynomial_coefficients( + beignet.integrate_physicists_hermite_polynomial( + pol, + order=j, + k=list(range(j)), + lower_bound=-1, + ), + tol=0.000001, + ), + beignet.trim_physicists_hermite_polynomial_coefficients( + target, + tol=0.000001, + ), + ) + + for i in range(5): + for j in range(2, 5): + pol = torch.tensor([0.0] * i + [1.0]) + target = pol[:] + for k in range(j): + target = beignet.integrate_physicists_hermite_polynomial( + target, + order=1, + k=[k], + scale=2, + ) + + # torch.testing.assert_close( + # beignet.hermtrim( + # beignet.hermint( + # pol, + # order=j, + # k=list(range(j)), + # scale=2, + # ), + # tol=0.000001, + # ), + # beignet.hermtrim( + # target, + # tol=0.000001, + # ), + # ) + + c2d = torch.rand(3, 4) + + target = torch.vstack( + [beignet.integrate_physicists_hermite_polynomial(c) for c in c2d.T] + ).T + + torch.testing.assert_close( + beignet.integrate_physicists_hermite_polynomial( + c2d, + axis=0, + ), + target, + ) + + target = torch.vstack( + [beignet.integrate_physicists_hermite_polynomial(c) for c in c2d] + ) + + torch.testing.assert_close( + beignet.integrate_physicists_hermite_polynomial( + c2d, + axis=1, + ), + target, + ) + + target = torch.vstack( + [beignet.integrate_physicists_hermite_polynomial(c, k=3) for c in c2d] + ) + + torch.testing.assert_close( + beignet.integrate_physicists_hermite_polynomial( + c2d, + k=3, + axis=1, + ), + target, + ) diff --git a/tests/beignet/test__integrate_polynomial.py b/tests/beignet/test__integrate_polynomial.py new file mode 100644 index 0000000000..bb4ad0c81a --- /dev/null +++ b/tests/beignet/test__integrate_polynomial.py @@ -0,0 +1,222 @@ +import beignet +import pytest +import torch + + +def test_integrate_polynomial(): + with pytest.raises(TypeError): + beignet.integrate_polynomial( + torch.tensor([0.0]), + order=0.5, + ) + + with pytest.raises(ValueError): + beignet.integrate_polynomial( + torch.tensor([0.0]), + order=-1, + ) + + with pytest.raises(ValueError): + beignet.integrate_polynomial( + torch.tensor([0.0]), + order=1, + k=[0, 0], + ) + + with pytest.raises(ValueError): + beignet.integrate_polynomial( + torch.tensor([0.0]), + lower_bound=[0], + ) + + with pytest.raises(ValueError): + beignet.integrate_polynomial( + torch.tensor([0.0]), + scale=[0], + ) + + with pytest.raises(TypeError): + beignet.integrate_polynomial( + torch.tensor([0.0]), + axis=0.5, + ) + + for i in range(2, 5): + torch.testing.assert_close( + beignet.trim_polynomial_coefficients( + beignet.integrate_polynomial( + torch.tensor([0.0]), + order=i, + k=[0.0] * (i - 2) + [1.0], + ), + ), + torch.tensor([0.0, 1.0]), + ) + + for i in range(5): + torch.testing.assert_close( + beignet.trim_polynomial_coefficients( + beignet.integrate_polynomial( + torch.tensor([0.0] * i + [1.0]), + order=1, + k=[i], + ), + ), + beignet.trim_polynomial_coefficients( + torch.tensor([i] + [0.0] * i + [1.0 / (i + 1.0)]), + ), + ) + + for i in range(5): + torch.testing.assert_close( + beignet.evaluate_polynomial( + torch.tensor([-1.0]), + beignet.integrate_polynomial( + torch.tensor([0.0] * i + [1.0]), + order=1, + k=[i], + lower_bound=-1, + ), + ), + torch.tensor([i], dtype=torch.get_default_dtype()), + ) + + for i in range(5): + torch.testing.assert_close( + beignet.trim_polynomial_coefficients( + beignet.integrate_polynomial( + torch.tensor([0.0] * i + [1.0]), + order=1, + k=[i], + scale=2, + ), + ), + beignet.trim_polynomial_coefficients( + torch.tensor([i] + [0.0] * i + [2.0 / (i + 1.0)]), + ), + ) + + for i in range(5): + for j in range(2, 5): + target = torch.tensor([0.0] * i + [1.0])[:] + + for _ in range(j): + target = beignet.integrate_polynomial( + target, + order=1, + ) + + torch.testing.assert_close( + beignet.trim_polynomial_coefficients( + beignet.integrate_polynomial( + torch.tensor([0.0] * i + [1.0]), + order=j, + ), + ), + beignet.trim_polynomial_coefficients( + target, + ), + ) + + for i in range(5): + for j in range(2, 5): + target = torch.tensor([0.0] * i + [1.0])[:] + + for k in range(j): + target = beignet.integrate_polynomial( + target, + order=1, + k=[k], + ) + + torch.testing.assert_close( + beignet.trim_polynomial_coefficients( + beignet.integrate_polynomial( + torch.tensor([0.0] * i + [1.0]), + order=j, + k=list(range(j)), + ), + ), + beignet.trim_polynomial_coefficients( + target, + ), + ) + + for i in range(5): + for j in range(2, 5): + target = torch.tensor([0.0] * i + [1.0])[:] + + for k in range(j): + target = beignet.integrate_polynomial( + target, + order=1, + k=[k], + lower_bound=-1, + ) + + torch.testing.assert_close( + beignet.trim_polynomial_coefficients( + beignet.integrate_polynomial( + torch.tensor([0.0] * i + [1.0]), + order=j, + k=list(range(j)), + lower_bound=-1, + ), + ), + beignet.trim_polynomial_coefficients( + target, + ), + ) + + for i in range(5): + for j in range(2, 5): + target = torch.tensor([0.0] * i + [1.0])[:] + + for k in range(j): + target = beignet.integrate_polynomial( + target, + order=1, + k=[k], + scale=2, + ) + + torch.testing.assert_close( + beignet.trim_polynomial_coefficients( + beignet.integrate_polynomial( + torch.tensor([0.0] * i + [1.0]), + order=j, + k=list(range(j)), + scale=2, + ), + ), + beignet.trim_polynomial_coefficients( + target, + ), + ) + + c2d = torch.rand(3, 6) + + torch.testing.assert_close( + beignet.integrate_polynomial( + c2d, + dim=0, + ), + torch.vstack([beignet.integrate_polynomial(c) for c in c2d.T]).T, + ) + + torch.testing.assert_close( + beignet.integrate_polynomial( + c2d, + dim=1, + ), + torch.vstack([beignet.integrate_polynomial(c) for c in c2d]), + ) + + torch.testing.assert_close( + beignet.integrate_polynomial( + c2d, + k=3, + dim=1, + ), + torch.vstack([beignet.integrate_polynomial(c, k=3) for c in c2d]), + ) diff --git a/tests/beignet/test__integrate_probabilists_hermite_polynomial.py b/tests/beignet/test__integrate_probabilists_hermite_polynomial.py new file mode 100644 index 0000000000..67a492ce0d --- /dev/null +++ b/tests/beignet/test__integrate_probabilists_hermite_polynomial.py @@ -0,0 +1,251 @@ +import beignet +import pytest +import torch + + +def test_integrate_probabilists_hermite_polynomial(): + pytest.raises( + TypeError, + beignet.integrate_probabilists_hermite_polynomial, + torch.tensor([0]), + 0.5, + ) + pytest.raises( + ValueError, + beignet.integrate_probabilists_hermite_polynomial, + torch.tensor([0]), + -1, + ) + pytest.raises( + ValueError, + beignet.integrate_probabilists_hermite_polynomial, + torch.tensor([0]), + 1, + [0, 0], + ) + pytest.raises( + ValueError, + beignet.integrate_probabilists_hermite_polynomial, + torch.tensor([0]), + lower_bound=[0], + ) + pytest.raises( + ValueError, + beignet.integrate_probabilists_hermite_polynomial, + torch.tensor([0]), + scale=[0], + ) + pytest.raises( + TypeError, + beignet.integrate_probabilists_hermite_polynomial, + torch.tensor([0]), + axis=0.5, + ) + + for i in range(2, 5): + torch.testing.assert_close( + beignet.trim_probabilists_hermite_polynomial_coefficients( + beignet.integrate_probabilists_hermite_polynomial( + torch.tensor([0.0]), + order=i, + k=([0.0] * (i - 2) + [1.0]), + ), + tol=0.000001, + ), + torch.tensor([0.0, 1.0]), + ) + + for i in range(5): + torch.testing.assert_close( + beignet.trim_probabilists_hermite_polynomial_coefficients( + beignet.probabilists_hermite_polynomial_to_polynomial( + beignet.integrate_probabilists_hermite_polynomial( + beignet.polynomial_to_probabilists_hermite_polynomial( + torch.tensor([0.0] * i + [1.0]), + ), + order=1, + k=[i], + ), + ), + tol=0.000001, + ), + beignet.trim_probabilists_hermite_polynomial_coefficients( + torch.tensor([i] + [0.0] * i + [1.0 / (i + 1.0)]), + tol=0.000001, + ), + ) + + for i in range(5): + torch.testing.assert_close( + beignet.evaluate_probabilists_hermite_polynomial( + torch.tensor([-1]), + beignet.integrate_probabilists_hermite_polynomial( + beignet.polynomial_to_probabilists_hermite_polynomial( + torch.tensor([0.0] * i + [1.0]), + ), + order=1, + k=[i], + lower_bound=-1, + ), + ), + torch.tensor([i], dtype=torch.get_default_dtype()), + ) + + for i in range(5): + torch.testing.assert_close( + beignet.trim_probabilists_hermite_polynomial_coefficients( + beignet.probabilists_hermite_polynomial_to_polynomial( + beignet.integrate_probabilists_hermite_polynomial( + beignet.polynomial_to_probabilists_hermite_polynomial( + torch.tensor([0.0] * i + [1.0]), + ), + order=1, + k=[i], + scale=2, + ), + ), + tol=0.000001, + ), + beignet.trim_probabilists_hermite_polynomial_coefficients( + torch.tensor([i] + [0.0] * i + [2.0 / (i + 1.0)]), + tol=0.000001, + ), + ) + + for i in range(5): + for j in range(2, 5): + target = torch.tensor([0.0] * i + [1.0])[:] + + for _ in range(j): + target = beignet.integrate_probabilists_hermite_polynomial( + target, + order=1, + ) + + torch.testing.assert_close( + beignet.trim_probabilists_hermite_polynomial_coefficients( + beignet.integrate_probabilists_hermite_polynomial( + torch.tensor([0.0] * i + [1.0]), + order=j, + ), + tol=0.000001, + ), + beignet.trim_probabilists_hermite_polynomial_coefficients( + target, + tol=0.000001, + ), + ) + + for i in range(5): + for j in range(2, 5): + target = torch.tensor([0.0] * i + [1.0])[:] + for k in range(j): + target = beignet.integrate_probabilists_hermite_polynomial( + target, + order=1, + k=[k], + ) + + torch.testing.assert_close( + beignet.trim_probabilists_hermite_polynomial_coefficients( + beignet.integrate_probabilists_hermite_polynomial( + torch.tensor([0.0] * i + [1.0]), + order=j, + k=list(range(j)), + ), + tol=0.000001, + ), + beignet.trim_probabilists_hermite_polynomial_coefficients( + target, + tol=0.000001, + ), + ) + + for i in range(5): + for j in range(2, 5): + target = torch.tensor([0.0] * i + [1.0])[:] + + for k in range(j): + target = beignet.integrate_probabilists_hermite_polynomial( + target, + order=1, + k=[k], + lower_bound=-1, + ) + + torch.testing.assert_close( + beignet.trim_probabilists_hermite_polynomial_coefficients( + beignet.integrate_probabilists_hermite_polynomial( + torch.tensor([0.0] * i + [1.0]), + order=j, + k=list(range(j)), + lower_bound=-1, + ), + tol=0.000001, + ), + beignet.trim_probabilists_hermite_polynomial_coefficients( + target, + tol=0.000001, + ), + ) + + for i in range(5): + for j in range(2, 5): + target = torch.tensor([0.0] * i + [1.0])[:] + + for k in range(j): + target = beignet.integrate_probabilists_hermite_polynomial( + target, + order=1, + k=[k], + scale=2, + ) + + torch.testing.assert_close( + beignet.trim_probabilists_hermite_polynomial_coefficients( + beignet.integrate_probabilists_hermite_polynomial( + torch.tensor([0.0] * i + [1.0]), + order=j, + k=list(range(j)), + scale=2, + ), + tol=0.000001, + ), + beignet.trim_probabilists_hermite_polynomial_coefficients( + target, + tol=0.000001, + ), + ) + + c2d = torch.rand(3, 4) + + torch.testing.assert_close( + beignet.integrate_probabilists_hermite_polynomial( + c2d, + axis=0, + ), + torch.vstack( + [beignet.integrate_probabilists_hermite_polynomial(c) for c in c2d.T] + ).T, + ) + + torch.testing.assert_close( + beignet.integrate_probabilists_hermite_polynomial( + c2d, + axis=1, + ), + torch.vstack( + [beignet.integrate_probabilists_hermite_polynomial(c) for c in c2d] + ), + ) + + torch.testing.assert_close( + beignet.integrate_probabilists_hermite_polynomial( + c2d, + k=3, + axis=1, + ), + torch.vstack( + [beignet.integrate_probabilists_hermite_polynomial(c, k=3) for c in c2d] + ), + ) diff --git a/tests/beignet/test__laguerre_polynomial_companion.py b/tests/beignet/test__laguerre_polynomial_companion.py new file mode 100644 index 0000000000..97573f0755 --- /dev/null +++ b/tests/beignet/test__laguerre_polynomial_companion.py @@ -0,0 +1,28 @@ +import beignet +import pytest +import torch + + +def test_laguerre_polynomial_companion(): + with pytest.raises(ValueError): + beignet.laguerre_polynomial_companion( + torch.tensor([]), + ) + + with pytest.raises(ValueError): + beignet.laguerre_polynomial_companion( + torch.tensor([1.0]), + ) + + for index in range(1, 5): + output = beignet.laguerre_polynomial_companion( + torch.tensor([0.0] * index + [1.0]), + ) + + assert output.shape == (index, index) + + output = beignet.laguerre_polynomial_companion( + torch.tensor([1.0, 2.0]), + ) + + assert output[0, 0] == 1.5 diff --git a/tests/beignet/test__laguerre_polynomial_domain.py b/tests/beignet/test__laguerre_polynomial_domain.py new file mode 100644 index 0000000000..8ac3bfa56c --- /dev/null +++ b/tests/beignet/test__laguerre_polynomial_domain.py @@ -0,0 +1,10 @@ +import beignet +import torch + + +def test_laguerre_polynomial_domain(): + torch.testing.assert_close( + beignet.laguerre_polynomial_domain, + torch.tensor([0.0, 1.0]), + check_dtype=False, + ) diff --git a/tests/beignet/test__laguerre_polynomial_from_roots.py b/tests/beignet/test__laguerre_polynomial_from_roots.py new file mode 100644 index 0000000000..32536b3c3f --- /dev/null +++ b/tests/beignet/test__laguerre_polynomial_from_roots.py @@ -0,0 +1,44 @@ +import beignet +import torch + + +def test_laguerre_polynomial_from_roots(): + torch.testing.assert_close( + beignet.trim_laguerre_polynomial_coefficients( + beignet.laguerre_polynomial_from_roots( + torch.tensor([]), + ), + tol=0.000001, + ), + torch.tensor([1.0]), + ) + + # for i in range(1, 5): + # roots = torch.linspace(-math.pi, 0, 2 * i + 1) + # + # roots = roots[1::2] + # + # roots = torch.cos(roots) + # + # output = beignet.lag2poly( + # beignet.lagfromroots( + # roots, + # ), + # ) + # + # torch.testing.assert_close( + # output, + # torch.tensor([1.0]), + # ) + # + # output = beignet.lagval( + # roots, + # beignet.lagfromroots( + # roots, + # ), + # ) + # + # torch.testing.assert_close( + # output, + # torch.tensor([0.0]), + # ) diff --git a/tests/beignet/test__laguerre_polynomial_one.py b/tests/beignet/test__laguerre_polynomial_one.py new file mode 100644 index 0000000000..48ef608b1b --- /dev/null +++ b/tests/beignet/test__laguerre_polynomial_one.py @@ -0,0 +1,10 @@ +import beignet +import torch + + +def test_laguerre_polynomial_one(): + torch.testing.assert_close( + beignet.laguerre_polynomial_one, + torch.tensor([1.0]), + check_dtype=False, + ) diff --git a/tests/beignet/test__laguerre_polynomial_power.py b/tests/beignet/test__laguerre_polynomial_power.py new file mode 100644 index 0000000000..da9c5756d6 --- /dev/null +++ b/tests/beignet/test__laguerre_polynomial_power.py @@ -0,0 +1,26 @@ +import functools + +import beignet +import torch + + +def test_laguerre_polynomial_power(): + for i in range(5): + for j in range(5): + torch.testing.assert_close( + beignet.trim_laguerre_polynomial_coefficients( + beignet.laguerre_polynomial_power( + torch.arange(0.0, i + 1), + j, + ), + tol=0.000001, + ), + beignet.trim_laguerre_polynomial_coefficients( + functools.reduce( + beignet.multiply_laguerre_polynomial, + [torch.arange(0.0, i + 1)] * j, + torch.tensor([1.0]), + ), + tol=0.000001, + ), + ) diff --git a/tests/beignet/test__laguerre_polynomial_roots.py b/tests/beignet/test__laguerre_polynomial_roots.py new file mode 100644 index 0000000000..af062e20dc --- /dev/null +++ b/tests/beignet/test__laguerre_polynomial_roots.py @@ -0,0 +1,34 @@ +import beignet +import torch + + +def test_laguerre_polynomial_roots(): + torch.testing.assert_close( + beignet.laguerre_polynomial_roots( + torch.tensor([1.0]), + ), + torch.tensor([]), + ) + + torch.testing.assert_close( + beignet.laguerre_polynomial_roots( + torch.tensor([0.0, 1.0]), + ), + torch.tensor([1.0]), + ) + + for index in range(2, 5): + torch.testing.assert_close( + beignet.trim_laguerre_polynomial_coefficients( + beignet.laguerre_polynomial_roots( + beignet.laguerre_polynomial_from_roots( + torch.linspace(0, 3, index), + ), + ), + tol=0.000001, + ), + beignet.trim_laguerre_polynomial_coefficients( + torch.linspace(0, 3, index), + tol=0.000001, + ), + ) diff --git a/tests/beignet/test__laguerre_polynomial_to_polynomial.py b/tests/beignet/test__laguerre_polynomial_to_polynomial.py new file mode 100644 index 0000000000..8824ee585d --- /dev/null +++ b/tests/beignet/test__laguerre_polynomial_to_polynomial.py @@ -0,0 +1,22 @@ +import beignet +import torch + + +def test_laguerre_polynomial_to_polynomial(): + coefficients = [ + torch.tensor([1.0]) / 1, + torch.tensor([1.0, -1]) / 1, + torch.tensor([2.0, -4, 1]) / 2, + torch.tensor([6.0, -18, 9, -1]) / 6, + torch.tensor([24.0, -96, 72, -16, 1]) / 24, + torch.tensor([120.0, -600, 600, -200, 25, -1]) / 120, + torch.tensor([720.0, -4320, 5400, -2400, 450, -36, 1]) / 720, + ] + + for index in range(7): + torch.testing.assert_close( + beignet.laguerre_polynomial_to_polynomial( + torch.tensor([0.0] * index + [1.0]), + ), + coefficients[index], + ) diff --git a/tests/beignet/test__laguerre_polynomial_vandermonde.py b/tests/beignet/test__laguerre_polynomial_vandermonde.py new file mode 100644 index 0000000000..da9b4d0c0c --- /dev/null +++ b/tests/beignet/test__laguerre_polynomial_vandermonde.py @@ -0,0 +1,34 @@ +import beignet +import torch + + +def test_laguerre_polynomial_vandermonde(): + x = torch.arange(3) + + v = beignet.laguerre_polynomial_vandermonde(x, 3) + + assert v.shape == (3, 4) + + for i in range(4): + torch.testing.assert_close( + v[..., i], + beignet.evaluate_laguerre_polynomial( + x, + torch.tensor([0.0] * i + [1.0]), + ), + ) + + x = torch.tensor([[1.0, 2.0], [3.0, 4.0], [5.0, 6.0]]) + + v = beignet.laguerre_polynomial_vandermonde(x, 3) + + assert v.shape == (3, 2, 4) + + for i in range(4): + torch.testing.assert_close( + v[..., i], + beignet.evaluate_laguerre_polynomial( + x, + torch.tensor([0.0] * i + [1.0]), + ), + ) diff --git a/tests/beignet/test__laguerre_polynomial_vandermonde_2d.py b/tests/beignet/test__laguerre_polynomial_vandermonde_2d.py new file mode 100644 index 0000000000..ed2fdcb699 --- /dev/null +++ b/tests/beignet/test__laguerre_polynomial_vandermonde_2d.py @@ -0,0 +1,27 @@ +import beignet +import torch + + +def test_laguerre_polynomial_vandermonde_2d(): + a, b, c = torch.rand(3, 5) * 2 - 1 + + coefficients = torch.rand(2, 3) + + output = beignet.laguerre_polynomial_vandermonde_2d( + a, + b, + torch.tensor([1, 2]), + ) + + torch.testing.assert_close( + output @ torch.ravel(coefficients), + beignet.evaluate_laguerre_polynomial_2d(a, b, coefficients), + ) + + output = beignet.laguerre_polynomial_vandermonde_2d( + a, + b, + torch.tensor([1, 2]), + ) + + assert output.shape == (5, 6) diff --git a/tests/beignet/test__laguerre_polynomial_vandermonde_3d.py b/tests/beignet/test__laguerre_polynomial_vandermonde_3d.py new file mode 100644 index 0000000000..1d86e86b33 --- /dev/null +++ b/tests/beignet/test__laguerre_polynomial_vandermonde_3d.py @@ -0,0 +1,33 @@ +import beignet +import torch + + +def test_laguerre_polynomial_vandermonde_3d(): + a, b, c = torch.rand(3, 5) * 2 - 1 + + coefficients = torch.rand(2, 3, 4) + + output = beignet.laguerre_polynomial_vandermonde_3d( + a, + b, + c, + degree=torch.tensor([1, 2, 3]), + ) + torch.testing.assert_close( + output @ torch.ravel(coefficients), + beignet.evaluate_laguerre_polynomial_3d( + a, + b, + c, + coefficients, + ), + ) + + output = beignet.laguerre_polynomial_vandermonde_3d( + a, + b, + c, + degree=torch.tensor([1, 2, 3]), + ) + + assert output.shape == (5, 24) diff --git a/tests/beignet/test__laguerre_polynomial_weight.py b/tests/beignet/test__laguerre_polynomial_weight.py new file mode 100644 index 0000000000..7d7bca8917 --- /dev/null +++ b/tests/beignet/test__laguerre_polynomial_weight.py @@ -0,0 +1,11 @@ +# import beignet +# import torch +# +# +# def test_laguerre_polynomial_weight(): +# torch.testing.assert_close( +# beignet.laguerre_polynomial_weight( +# torch.linspace(0, 10, 11), +# ), +# torch.exp(-torch.linspace(0, 10, 11)), +# ) diff --git a/tests/beignet/test__laguerre_polynomial_x.py b/tests/beignet/test__laguerre_polynomial_x.py new file mode 100644 index 0000000000..ef4871b109 --- /dev/null +++ b/tests/beignet/test__laguerre_polynomial_x.py @@ -0,0 +1,10 @@ +import beignet +import torch + + +def test_laguerre_polynomial_x(): + torch.testing.assert_close( + beignet.laguerre_polynomial_x, + torch.tensor([1.0, -1.0]), + check_dtype=False, + ) diff --git a/tests/beignet/test__laguerre_polynomial_zero.py b/tests/beignet/test__laguerre_polynomial_zero.py new file mode 100644 index 0000000000..d3abaf610c --- /dev/null +++ b/tests/beignet/test__laguerre_polynomial_zero.py @@ -0,0 +1,10 @@ +import beignet +import torch + + +def test_laguerre_polynomial_zero(): + torch.testing.assert_close( + beignet.laguerre_polynomial_zero, + torch.tensor([0.0]), + check_dtype=False, + ) diff --git a/tests/beignet/test__legendre_polynomial_companion.py b/tests/beignet/test__legendre_polynomial_companion.py new file mode 100644 index 0000000000..bee23fed33 --- /dev/null +++ b/tests/beignet/test__legendre_polynomial_companion.py @@ -0,0 +1,20 @@ +import beignet +import pytest +import torch + + +def test_legendre_polynomial_companion(): + with pytest.raises(ValueError): + beignet.legendre_polynomial_companion(torch.tensor([])) + + with pytest.raises(ValueError): + beignet.legendre_polynomial_companion(torch.tensor([1])) + + for index in range(1, 5): + output = beignet.legendre_polynomial_companion( + torch.tensor([0.0] * index + [1.0]), + ) + + assert output.shape == (index, index) + + assert beignet.legendre_polynomial_companion(torch.tensor([1, 2]))[0, 0] == -0.5 diff --git a/tests/beignet/test__legendre_polynomial_domain.py b/tests/beignet/test__legendre_polynomial_domain.py new file mode 100644 index 0000000000..e4983e95c2 --- /dev/null +++ b/tests/beignet/test__legendre_polynomial_domain.py @@ -0,0 +1,10 @@ +import beignet +import torch + + +def test_legendre_polynomial_domain(): + torch.testing.assert_close( + beignet.legendre_polynomial_domain, + torch.tensor([-1.0, 1.0]), + check_dtype=False, + ) diff --git a/tests/beignet/test__legendre_polynomial_from_roots.py b/tests/beignet/test__legendre_polynomial_from_roots.py new file mode 100644 index 0000000000..915f2ac63d --- /dev/null +++ b/tests/beignet/test__legendre_polynomial_from_roots.py @@ -0,0 +1,52 @@ +import math + +import beignet +import torch + + +def test_legendre_polynomial_from_roots(): + torch.testing.assert_close( + beignet.trim_legendre_polynomial_coefficients( + beignet.legendre_polynomial_from_roots( + torch.tensor([]), + ), + tol=0.000001, + ), + torch.tensor([1.0]), + ) + + for index in range(1, 5): + input = torch.linspace(-math.pi, 0, 2 * index + 1)[1::2] + + output = beignet.legendre_polynomial_from_roots( + torch.cos( + input, + ), + ) + + assert output.shape[-1] == index + 1 + + # torch.testing.assert_close( + # beignet.leg2poly( + # beignet.legfromroots( + # torch.cos( + # input, + # ), + # ) + # )[-1], + # torch.tensor([1.0]), + # ) + + # torch.testing.assert_close( + # beignet.legval( + # torch.cos( + # input, + # ), + # beignet.legfromroots( + # torch.cos( + # input, + # ), + # ), + # ), + # torch.tensor([0.0]), + # ) diff --git a/tests/beignet/test__legendre_polynomial_one.py b/tests/beignet/test__legendre_polynomial_one.py new file mode 100644 index 0000000000..9f153ebd61 --- /dev/null +++ b/tests/beignet/test__legendre_polynomial_one.py @@ -0,0 +1,10 @@ +import beignet +import torch + + +def test_legendre_polynomial_one(): + torch.testing.assert_close( + beignet.legendre_polynomial_one, + torch.tensor([1.0]), + check_dtype=False, + ) diff --git a/tests/beignet/test__legendre_polynomial_power.py b/tests/beignet/test__legendre_polynomial_power.py new file mode 100644 index 0000000000..d1f3c05706 --- /dev/null +++ b/tests/beignet/test__legendre_polynomial_power.py @@ -0,0 +1,26 @@ +import functools + +import beignet +import torch + + +def test_legendre_polynomial_power(): + for i in range(5): + for j in range(5): + torch.testing.assert_close( + beignet.trim_legendre_polynomial_coefficients( + beignet.legendre_polynomial_power( + torch.arange(0.0, i + 1), + j, + ), + tol=0.000001, + ), + beignet.trim_legendre_polynomial_coefficients( + functools.reduce( + beignet.multiply_legendre_polynomial, + [torch.arange(0.0, i + 1)] * j, + torch.tensor([1.0]), + ), + tol=0.000001, + ), + ) diff --git a/tests/beignet/test__legendre_polynomial_roots.py b/tests/beignet/test__legendre_polynomial_roots.py new file mode 100644 index 0000000000..94fc165601 --- /dev/null +++ b/tests/beignet/test__legendre_polynomial_roots.py @@ -0,0 +1,32 @@ +import beignet +import torch + + +def test_legendre_polynomial_roots(): + torch.testing.assert_close( + beignet.legendre_polynomial_roots( + torch.tensor([1.0]), + ), + torch.tensor([]), + ) + + torch.testing.assert_close( + beignet.legendre_polynomial_roots(torch.tensor([1.0, 2.0])), + torch.tensor([-0.5]), + ) + + for index in range(2, 5): + torch.testing.assert_close( + beignet.trim_legendre_polynomial_coefficients( + beignet.legendre_polynomial_roots( + beignet.legendre_polynomial_from_roots( + torch.linspace(-1, 1, index), + ), + ), + tol=0.000001, + ), + beignet.trim_legendre_polynomial_coefficients( + torch.linspace(-1, 1, index), + tol=0.000001, + ), + ) diff --git a/tests/beignet/test__legendre_polynomial_to_polynomial.py b/tests/beignet/test__legendre_polynomial_to_polynomial.py new file mode 100644 index 0000000000..8b429ad2d8 --- /dev/null +++ b/tests/beignet/test__legendre_polynomial_to_polynomial.py @@ -0,0 +1,25 @@ +import beignet +import torch + + +def test_legendre_polynomial_to_polynomial(): + coefficients = [ + torch.tensor([1.0]), + torch.tensor([0.0, 1.0]), + torch.tensor([-1.0, 0.0, 3.0]) / 2.0, + torch.tensor([0.0, -3.0, 0.0, 5.0]) / 2.0, + torch.tensor([3.0, 0.0, -30, 0, 35]) / 8, + torch.tensor([0.0, 15.0, 0, -70, 0, 63]) / 8, + torch.tensor([-5.0, 0.0, 105, 0, -315, 0, 231]) / 16, + torch.tensor([0.0, -35.0, 0, 315, 0, -693, 0, 429]) / 16, + torch.tensor([35.0, 0.0, -1260, 0, 6930, 0, -12012, 0, 6435]) / 128, + torch.tensor([0.0, 315.0, 0, -4620, 0, 18018, 0, -25740, 0, 12155]) / 128, + ] + + for index in range(10): + torch.testing.assert_close( + beignet.legendre_polynomial_to_polynomial( + torch.tensor([0.0] * index + [1.0]), + ), + coefficients[index], + ) diff --git a/tests/beignet/test__legendre_polynomial_vandermonde.py b/tests/beignet/test__legendre_polynomial_vandermonde.py new file mode 100644 index 0000000000..6d940528a3 --- /dev/null +++ b/tests/beignet/test__legendre_polynomial_vandermonde.py @@ -0,0 +1,47 @@ +import beignet +import pytest +import torch + + +def test_legendre_polynomial_vandermonde(): + x = torch.arange(3) + + v = beignet.legendre_polynomial_vandermonde( + x, + degree=3, + ) + + assert v.shape == (3, 4) + + for index in range(4): + torch.testing.assert_close( + v[..., index], + beignet.evaluate_legendre_polynomial( + x, + torch.tensor([0.0] * index + [1.0]), + ), + ) + + x = torch.tensor([[1.0, 2.0], [3.0, 4.0], [5.0, 6.0]]) + + v = beignet.legendre_polynomial_vandermonde( + x, + degree=3, + ) + + assert v.shape == (3, 2, 4) + + for index in range(4): + torch.testing.assert_close( + v[..., index], + beignet.evaluate_legendre_polynomial( + x, + torch.tensor([0.0] * index + [1.0]), + ), + ) + + with pytest.raises(ValueError): + beignet.legendre_polynomial_vandermonde( + torch.tensor([1, 2, 3]), + -1, + ) diff --git a/tests/beignet/test__legendre_polynomial_vandermonde_2d.py b/tests/beignet/test__legendre_polynomial_vandermonde_2d.py new file mode 100644 index 0000000000..89cb4d8379 --- /dev/null +++ b/tests/beignet/test__legendre_polynomial_vandermonde_2d.py @@ -0,0 +1,30 @@ +import beignet +import torch + + +def test_legendre_polynomial_vandermonde_2d(): + a, b, x3 = torch.rand(3, 5) * 2 - 1 + + coefficients = torch.rand(2, 3) + + output = beignet.legendre_polynomial_vandermonde_2d( + a, + b, + degree=torch.tensor([1, 2]), + ) + torch.testing.assert_close( + output @ torch.ravel(coefficients), + beignet.evaluate_legendre_polynomial_2d( + a, + b, + coefficients, + ), + ) + + output = beignet.legendre_polynomial_vandermonde_2d( + a, + b, + degree=torch.tensor([1, 2]), + ) + + assert output.shape == (5, 6) diff --git a/tests/beignet/test__legendre_polynomial_weight.py b/tests/beignet/test__legendre_polynomial_weight.py new file mode 100644 index 0000000000..06c5dd9dc1 --- /dev/null +++ b/tests/beignet/test__legendre_polynomial_weight.py @@ -0,0 +1,11 @@ +# import beignet +# import torch +# +# +# def test_legendre_polynomial_weight(): +# torch.testing.assert_close( +# beignet.legendre_polynomial_weight( +# torch.linspace(-1, 1, 11), +# ), +# torch.tensor([1.0]), +# ) diff --git a/tests/beignet/test__legendre_polynomial_x.py b/tests/beignet/test__legendre_polynomial_x.py new file mode 100644 index 0000000000..62f5dbb548 --- /dev/null +++ b/tests/beignet/test__legendre_polynomial_x.py @@ -0,0 +1,10 @@ +import beignet +import torch + + +def test_legendre_polynomial_x(): + torch.testing.assert_close( + beignet.legendre_polynomial_x, + torch.tensor([0.0, 1.0]), + check_dtype=False, + ) diff --git a/tests/beignet/test__legendre_polynomial_zero.py b/tests/beignet/test__legendre_polynomial_zero.py new file mode 100644 index 0000000000..73df136f33 --- /dev/null +++ b/tests/beignet/test__legendre_polynomial_zero.py @@ -0,0 +1,10 @@ +import beignet +import torch + + +def test_legendre_polynomial_zero(): + torch.testing.assert_close( + beignet.legendre_polynomial_zero, + torch.tensor([0.0]), + check_dtype=False, + ) diff --git a/tests/beignet/test__linear_chebyshev_polynomial.py b/tests/beignet/test__linear_chebyshev_polynomial.py new file mode 100644 index 0000000000..290e8c0cd9 --- /dev/null +++ b/tests/beignet/test__linear_chebyshev_polynomial.py @@ -0,0 +1,9 @@ +import beignet +import torch + + +def test_linear_chebyshev_polynomial(): + torch.testing.assert_close( + beignet.linear_chebyshev_polynomial(3.0, 4.0), + torch.tensor([3.0, 4.0]), + ) diff --git a/tests/beignet/test__linear_legendre_polynomial.py b/tests/beignet/test__linear_legendre_polynomial.py new file mode 100644 index 0000000000..052e097c97 --- /dev/null +++ b/tests/beignet/test__linear_legendre_polynomial.py @@ -0,0 +1,17 @@ +import beignet +import torch + + +def test_linear_legendre_polynomial(): + torch.testing.assert_close( + beignet.linear_legendre_polynomial(3.0, 4.0), + torch.tensor([3.0, 4.0]), + ) + + torch.testing.assert_close( + beignet.trim_legendre_polynomial_coefficients( + beignet.linear_legendre_polynomial(3.0, 0.0), + tol=0.000001, + ), + torch.tensor([3.0]), + ) diff --git a/tests/beignet/test__linear_physicists_hermite_polynomial.py b/tests/beignet/test__linear_physicists_hermite_polynomial.py new file mode 100644 index 0000000000..0a1a1c5f05 --- /dev/null +++ b/tests/beignet/test__linear_physicists_hermite_polynomial.py @@ -0,0 +1,9 @@ +import beignet +import torch + + +def test_linear_physicists_hermite_polynomial(): + torch.testing.assert_close( + beignet.linear_physicists_hermite_polynomial(3, 4), + torch.tensor([3.0, 2.0]), + ) diff --git a/tests/beignet/test__linear_polynomial.py b/tests/beignet/test__linear_polynomial.py new file mode 100644 index 0000000000..45d6580644 --- /dev/null +++ b/tests/beignet/test__linear_polynomial.py @@ -0,0 +1,14 @@ +import beignet +import torch + + +def test_linear_polynomial(): + torch.testing.assert_close( + beignet.linear_polynomial(3.0, 4.0), + torch.tensor([3.0, 4.0]), + ) + + torch.testing.assert_close( + beignet.linear_polynomial(3.0, 0.0), + torch.tensor([3.0, 0.0]), + ) diff --git a/tests/beignet/test__linear_probabilists_hermite_polynomial.py b/tests/beignet/test__linear_probabilists_hermite_polynomial.py new file mode 100644 index 0000000000..fc03535123 --- /dev/null +++ b/tests/beignet/test__linear_probabilists_hermite_polynomial.py @@ -0,0 +1,9 @@ +import beignet +import torch + + +def test_linear_probabilists_hermite_polynomial(): + torch.testing.assert_close( + beignet.linear_probabilists_hermite_polynomial(3.0, 4.0), + torch.tensor([3.0, 4.0]), + ) diff --git a/tests/beignet/test__multiply_chebyshev_polynomial.py b/tests/beignet/test__multiply_chebyshev_polynomial.py new file mode 100644 index 0000000000..23b65b0d63 --- /dev/null +++ b/tests/beignet/test__multiply_chebyshev_polynomial.py @@ -0,0 +1,28 @@ +import beignet +import torch + + +def test_multiply_chebyshev_polynomial(): + for j in range(5): + for k in range(5): + target = torch.zeros(j + k + 1) + + target[abs(j + k)] = target[abs(j + k)] + 0.5 + target[abs(j - k)] = target[abs(j - k)] + 0.5 + + input = torch.tensor([0.0] * j + [1.0]) + other = torch.tensor([0.0] * k + [1.0]) + + torch.testing.assert_close( + beignet.trim_chebyshev_polynomial_coefficients( + beignet.multiply_chebyshev_polynomial( + input, + other, + ), + tol=0.000001, + ), + beignet.trim_chebyshev_polynomial_coefficients( + target, + tol=0.000001, + ), + ) diff --git a/tests/beignet/test__multiply_chebyshev_polynomial_by_x.py b/tests/beignet/test__multiply_chebyshev_polynomial_by_x.py new file mode 100644 index 0000000000..775788fc01 --- /dev/null +++ b/tests/beignet/test__multiply_chebyshev_polynomial_by_x.py @@ -0,0 +1,35 @@ +import beignet +import torch + + +def test_multiply_chebyshev_polynomial_by_x(): + torch.testing.assert_close( + beignet.trim_chebyshev_polynomial_coefficients( + beignet.multiply_chebyshev_polynomial_by_x( + torch.tensor([0.0]), + ), + tol=0.000001, + ), + torch.tensor([0.0]), + ) + + torch.testing.assert_close( + beignet.trim_chebyshev_polynomial_coefficients( + beignet.multiply_chebyshev_polynomial_by_x( + torch.tensor([1.0]), + ), + tol=0.000001, + ), + torch.tensor([0.0, 1.0]), + ) + + for index in range(1, 5): + torch.testing.assert_close( + beignet.trim_chebyshev_polynomial_coefficients( + beignet.multiply_chebyshev_polynomial_by_x( + torch.tensor([0.0] * index + [1.0]), + ), + tol=0.000001, + ), + torch.tensor([0.0] * (index - 1) + [0.5, 0, 0.5]), + ) diff --git a/tests/beignet/test__multiply_laguerre_polynomial.py b/tests/beignet/test__multiply_laguerre_polynomial.py new file mode 100644 index 0000000000..f9fdcc46d3 --- /dev/null +++ b/tests/beignet/test__multiply_laguerre_polynomial.py @@ -0,0 +1,40 @@ +import beignet +import torch + +torch.set_default_dtype(torch.float64) + + +def test_multiply_laguerre_polynomial(): + for i in range(5): + input = torch.linspace(-3, 3, 100) + + a = beignet.evaluate_laguerre_polynomial( + input, + torch.tensor([0.0] * i + [1.0]), + ) + + for j in range(5): + b = beignet.evaluate_laguerre_polynomial( + input, + torch.tensor([0.0] * j + [1.0]), + ) + + torch.testing.assert_close( + beignet.evaluate_laguerre_polynomial( + input, + beignet.trim_laguerre_polynomial_coefficients( + beignet.multiply_laguerre_polynomial( + torch.tensor([0.0] * i + [1.0]), + torch.tensor([0.0] * j + [1.0]), + ), + ), + ), + a * b, + ) + + +def test_lagline(): + torch.testing.assert_close( + beignet.linear_laguerre_polynomial(3.0, 4.0), + torch.tensor([7.0, -4.0]), + ) diff --git a/tests/beignet/test__multiply_laguerre_polynomial_by_x.py b/tests/beignet/test__multiply_laguerre_polynomial_by_x.py new file mode 100644 index 0000000000..da0bf29623 --- /dev/null +++ b/tests/beignet/test__multiply_laguerre_polynomial_by_x.py @@ -0,0 +1,40 @@ +import beignet +import torch + + +def test_multiply_laguerre_polynomial_by_x(): + torch.testing.assert_close( + beignet.trim_laguerre_polynomial_coefficients( + beignet.multiply_laguerre_polynomial_by_x( + torch.tensor([0.0]), + ), + tol=0.000001, + ), + torch.tensor([0.0]), + ) + + torch.testing.assert_close( + beignet.trim_laguerre_polynomial_coefficients( + beignet.multiply_laguerre_polynomial_by_x( + torch.tensor([1.0]), + ), + tol=0.000001, + ), + torch.tensor([1.0, -1.0]), + ) + + for index in range(1, 5): + torch.testing.assert_close( + beignet.trim_laguerre_polynomial_coefficients( + beignet.multiply_laguerre_polynomial_by_x( + torch.tensor([0.0] * index + [1.0]), + ), + tol=0.000001, + ), + beignet.trim_laguerre_polynomial_coefficients( + torch.tensor( + [0.0] * (index - 1) + [-index, 2.0 * index + 1.0, -(index + 1.0)] + ), + tol=0.000001, + ), + ) diff --git a/tests/beignet/test__multiply_legendre_polynomial.py b/tests/beignet/test__multiply_legendre_polynomial.py new file mode 100644 index 0000000000..c85fecd238 --- /dev/null +++ b/tests/beignet/test__multiply_legendre_polynomial.py @@ -0,0 +1,29 @@ +import beignet +import torch + + +def test_multiply_legendre_polynomial(): + for i in range(5): + input = torch.linspace(-1, 1, 100) + + a = beignet.evaluate_legendre_polynomial( + input, + torch.tensor([0.0] * i + [1.0]), + ) + + for j in range(5): + b = beignet.evaluate_legendre_polynomial( + input, + torch.tensor([0.0] * j + [1.0]), + ) + + torch.testing.assert_close( + beignet.evaluate_legendre_polynomial( + input, + beignet.multiply_legendre_polynomial( + torch.tensor([0.0] * i + [1.0]), + torch.tensor([0.0] * j + [1.0]), + ), + ), + a * b, + ) diff --git a/tests/beignet/test__multiply_legendre_polynomial_by_x.py b/tests/beignet/test__multiply_legendre_polynomial_by_x.py new file mode 100644 index 0000000000..764d393947 --- /dev/null +++ b/tests/beignet/test__multiply_legendre_polynomial_by_x.py @@ -0,0 +1,35 @@ +import beignet +import torch + + +def test_multiply_legendre_polynomial_by_x(): + torch.testing.assert_close( + beignet.trim_legendre_polynomial_coefficients( + beignet.multiply_legendre_polynomial_by_x( + torch.tensor([0.0]), + ), + tol=0.000001, + ), + torch.tensor([0.0]), + ) + + torch.testing.assert_close( + beignet.trim_legendre_polynomial_coefficients( + beignet.multiply_legendre_polynomial_by_x( + torch.tensor([1.0]), + ), + tol=0.000001, + ), + torch.tensor([0.0, 1.0]), + ) + + for i in range(1, 5): + torch.testing.assert_close( + beignet.trim_legendre_polynomial_coefficients( + beignet.multiply_legendre_polynomial_by_x( + torch.tensor([0.0] * i + [1.0]), + ), + tol=0.000001, + ), + torch.tensor([0] * (i - 1) + [i / (2 * i + 1), 0, (i + 1) / (2 * i + 1)]), + ) diff --git a/tests/beignet/test__multiply_physicists_hermite_polynomial.py b/tests/beignet/test__multiply_physicists_hermite_polynomial.py new file mode 100644 index 0000000000..ce40c4781f --- /dev/null +++ b/tests/beignet/test__multiply_physicists_hermite_polynomial.py @@ -0,0 +1,29 @@ +import beignet +import torch + + +def test_multiply_physicists_hermite_polynomial(): + for i in range(5): + input = torch.linspace(-3, 3, 100) + + val1 = beignet.evaluate_physicists_hermite_polynomial( + input, + torch.tensor([0.0] * i + [1.0]), + ) + + for j in range(5): + val2 = beignet.evaluate_physicists_hermite_polynomial( + input, + torch.tensor([0.0] * j + [1.0]), + ) + + torch.testing.assert_close( + beignet.evaluate_physicists_hermite_polynomial( + input, + beignet.multiply_physicists_hermite_polynomial( + torch.tensor([0.0] * i + [1.0]), + torch.tensor([0.0] * j + [1.0]), + ), + ), + val1 * val2, + ) diff --git a/tests/beignet/test__multiply_physicists_hermite_polynomial_by_x.py b/tests/beignet/test__multiply_physicists_hermite_polynomial_by_x.py new file mode 100644 index 0000000000..e21252c1b4 --- /dev/null +++ b/tests/beignet/test__multiply_physicists_hermite_polynomial_by_x.py @@ -0,0 +1,29 @@ +import beignet +import torch + + +def test_multiply_physicists_hermite_polynomial_by_x(): + torch.testing.assert_close( + beignet.trim_physicists_hermite_polynomial_coefficients( + beignet.multiply_physicists_hermite_polynomial_by_x( + torch.tensor([0.0]), + ), + tol=0.000001, + ), + torch.tensor([0.0]), + ) + + torch.testing.assert_close( + beignet.multiply_physicists_hermite_polynomial_by_x( + torch.tensor([1.0]), + ), + torch.tensor([0.0, 0.5]), + ) + + for i in range(1, 5): + torch.testing.assert_close( + beignet.multiply_physicists_hermite_polynomial_by_x( + torch.tensor([0.0] * i + [1.0]), + ), + torch.tensor([0.0] * (i - 1) + [i, 0.0, 0.5]), + ) diff --git a/tests/beignet/test__multiply_polynomial.py b/tests/beignet/test__multiply_polynomial.py new file mode 100644 index 0000000000..7b5a20d5bd --- /dev/null +++ b/tests/beignet/test__multiply_polynomial.py @@ -0,0 +1,24 @@ +import beignet +import torch + + +def test_multiply_polynomial(): + for j in range(5): + for k in range(5): + target = torch.zeros(j + k + 1) + + target[j + k] = target[j + k] + 1 + + torch.testing.assert_close( + beignet.trim_polynomial_coefficients( + beignet.multiply_polynomial( + torch.tensor([0.0] * j + [1.0]), + torch.tensor([0.0] * k + [1.0]), + ), + tol=0.000001, + ), + beignet.trim_polynomial_coefficients( + target, + tol=0.000001, + ), + ) diff --git a/tests/beignet/test__multiply_polynomial_by_x.py b/tests/beignet/test__multiply_polynomial_by_x.py new file mode 100644 index 0000000000..304d40da40 --- /dev/null +++ b/tests/beignet/test__multiply_polynomial_by_x.py @@ -0,0 +1,26 @@ +import beignet +import torch + + +def test_multiply_polynomial_by_x(): + torch.testing.assert_close( + beignet.multiply_polynomial_by_x( + torch.tensor([0.0]), + ), + torch.tensor([0.0, 0.0]), + ) + + torch.testing.assert_close( + beignet.multiply_polynomial_by_x( + torch.tensor([1.0]), + ), + torch.tensor([0.0, 1.0]), + ) + + for i in range(1, 5): + torch.testing.assert_close( + beignet.multiply_polynomial_by_x( + torch.tensor([0.0] * i + [1.0]), + ), + torch.tensor([0.0] * (i + 1) + [1.0]), + ) diff --git a/tests/beignet/test__multiply_probabilists_hermite_polynomial.py b/tests/beignet/test__multiply_probabilists_hermite_polynomial.py new file mode 100644 index 0000000000..012512fc24 --- /dev/null +++ b/tests/beignet/test__multiply_probabilists_hermite_polynomial.py @@ -0,0 +1,29 @@ +import beignet +import torch + + +def test_multiply_probabilists_hermite_polynomial(): + for index in range(5): + input = torch.linspace(-3, 3, 100) + + val1 = beignet.evaluate_probabilists_hermite_polynomial( + input, + torch.tensor([0.0] * index + [1.0]), + ) + + for k in range(5): + val2 = beignet.evaluate_probabilists_hermite_polynomial( + input, + torch.tensor([0.0] * k + [1.0]), + ) + + torch.testing.assert_close( + beignet.evaluate_probabilists_hermite_polynomial( + input, + beignet.multiply_probabilists_hermite_polynomial( + torch.tensor([0.0] * index + [1.0]), + torch.tensor([0.0] * k + [1.0]), + ), + ), + val1 * val2, + ) diff --git a/tests/beignet/test__multiply_probabilists_hermite_polynomial_by_x.py b/tests/beignet/test__multiply_probabilists_hermite_polynomial_by_x.py new file mode 100644 index 0000000000..15c04a22d9 --- /dev/null +++ b/tests/beignet/test__multiply_probabilists_hermite_polynomial_by_x.py @@ -0,0 +1,34 @@ +import beignet +import torch + + +def test_multiply_probabilists_hermite_polynomial_by_x(): + torch.testing.assert_close( + beignet.trim_probabilists_hermite_polynomial_coefficients( + beignet.multiply_probabilists_hermite_polynomial_by_x( + torch.tensor([0.0]), + ), + tol=0.000001, + ), + torch.tensor([0.0]), + ) + torch.testing.assert_close( + beignet.trim_probabilists_hermite_polynomial_coefficients( + beignet.multiply_probabilists_hermite_polynomial_by_x( + torch.tensor([1.0]), + ), + tol=0.000001, + ), + torch.tensor([0.0, 1.0]), + ) + + for index in range(1, 5): + torch.testing.assert_close( + beignet.trim_probabilists_hermite_polynomial_coefficients( + beignet.multiply_probabilists_hermite_polynomial_by_x( + torch.tensor([0.0] * index + [1.0]), + ), + tol=0.000001, + ), + torch.tensor([0] * (index - 1) + [index, 0.0, 1.0]), + ) diff --git a/tests/beignet/test__physicists_hermite_polynomial_companion.py b/tests/beignet/test__physicists_hermite_polynomial_companion.py new file mode 100644 index 0000000000..10eb95ba93 --- /dev/null +++ b/tests/beignet/test__physicists_hermite_polynomial_companion.py @@ -0,0 +1,28 @@ +import beignet +import pytest +import torch + + +def test_physicists_hermite_polynomial_companion(): + with pytest.raises(ValueError): + beignet.physicists_hermite_polynomial_companion( + torch.tensor([]), + ) + + with pytest.raises(ValueError): + beignet.physicists_hermite_polynomial_companion( + torch.tensor([1.0]), + ) + + for index in range(1, 5): + output = beignet.physicists_hermite_polynomial_companion( + torch.tensor([0.0] * index + [1.0]), + ) + + assert output.shape == (index, index) + + output = beignet.physicists_hermite_polynomial_companion( + torch.tensor([1.0, 2.0]), + ) + + assert output[0, 0] == -0.25 diff --git a/tests/beignet/test__physicists_hermite_polynomial_domain.py b/tests/beignet/test__physicists_hermite_polynomial_domain.py new file mode 100644 index 0000000000..6ab06f2810 --- /dev/null +++ b/tests/beignet/test__physicists_hermite_polynomial_domain.py @@ -0,0 +1,10 @@ +import beignet +import torch + + +def test_physicists_hermite_polynomial_domain(): + torch.testing.assert_close( + beignet.physicists_hermite_polynomial_domain, + torch.tensor([-1.0, 1.0]), + check_dtype=False, + ) diff --git a/tests/beignet/test__physicists_hermite_polynomial_from_roots.py b/tests/beignet/test__physicists_hermite_polynomial_from_roots.py new file mode 100644 index 0000000000..f5fd6cf43c --- /dev/null +++ b/tests/beignet/test__physicists_hermite_polynomial_from_roots.py @@ -0,0 +1,37 @@ +import beignet +import torch + + +def test_physicists_hermite_polynomial_from_roots(): + torch.testing.assert_close( + beignet.trim_physicists_hermite_polynomial_coefficients( + beignet.physicists_hermite_polynomial_from_roots( + torch.tensor([]), + ), + tol=0.000001, + ), + torch.tensor([1.0]), + ) + + # for i in range(1, 5): + # roots = torch.cos(torch.linspace(-math.pi, 0, 2 * i + 1)[1::2]) + # target = 0 + # + # torch.testing.assert_close( + # beignet.herm2poly( + # beignet.hermfromroots( + # roots, + # ), + # )[-1], + # torch.tensor([1.0]), + # ) + # + # torch.testing.assert_close( + # beignet.hermval( + # roots, + # beignet.hermfromroots( + # roots, + # ), + # ), + # target, + # ) diff --git a/tests/beignet/test__physicists_hermite_polynomial_one.py b/tests/beignet/test__physicists_hermite_polynomial_one.py new file mode 100644 index 0000000000..31fb060c74 --- /dev/null +++ b/tests/beignet/test__physicists_hermite_polynomial_one.py @@ -0,0 +1,10 @@ +import beignet +import torch + + +def test_physicists_hermite_polynomial_one(): + torch.testing.assert_close( + beignet.physicists_hermite_polynomial_one, + torch.tensor([1.0]), + check_dtype=False, + ) diff --git a/tests/beignet/test__physicists_hermite_polynomial_power.py b/tests/beignet/test__physicists_hermite_polynomial_power.py new file mode 100644 index 0000000000..6985b59251 --- /dev/null +++ b/tests/beignet/test__physicists_hermite_polynomial_power.py @@ -0,0 +1,26 @@ +import functools + +import beignet +import torch + + +def test_physicists_hermite_polynomial_power(): + for i in range(5): + for j in range(5): + torch.testing.assert_close( + beignet.trim_physicists_hermite_polynomial_coefficients( + beignet.physicists_hermite_polynomial_power( + torch.arange(0.0, i + 1), + j, + ), + tol=0.000001, + ), + beignet.trim_physicists_hermite_polynomial_coefficients( + functools.reduce( + beignet.multiply_physicists_hermite_polynomial, + [torch.arange(0.0, i + 1)] * j, + torch.tensor([1.0]), + ), + tol=0.000001, + ), + ) diff --git a/tests/beignet/test__physicists_hermite_polynomial_roots.py b/tests/beignet/test__physicists_hermite_polynomial_roots.py new file mode 100644 index 0000000000..688bfbae83 --- /dev/null +++ b/tests/beignet/test__physicists_hermite_polynomial_roots.py @@ -0,0 +1,36 @@ +import beignet +import torch + + +def test_physicists_hermite_polynomial_roots(): + torch.testing.assert_close( + beignet.physicists_hermite_polynomial_roots( + torch.tensor([1.0]), + ), + torch.tensor([]), + ) + + torch.testing.assert_close( + beignet.physicists_hermite_polynomial_roots( + torch.tensor([1.0, 1.0]), + ), + torch.tensor([-0.5]), + ) + + for i in range(2, 5): + input = torch.linspace(-1, 1, i) + + torch.testing.assert_close( + beignet.trim_physicists_hermite_polynomial_coefficients( + beignet.physicists_hermite_polynomial_roots( + beignet.physicists_hermite_polynomial_from_roots( + input, + ), + ), + tol=0.000001, + ), + beignet.trim_physicists_hermite_polynomial_coefficients( + input, + tol=0.000001, + ), + ) diff --git a/tests/beignet/test__physicists_hermite_polynomial_to_polynomial.py b/tests/beignet/test__physicists_hermite_polynomial_to_polynomial.py new file mode 100644 index 0000000000..3b61cc5c63 --- /dev/null +++ b/tests/beignet/test__physicists_hermite_polynomial_to_polynomial.py @@ -0,0 +1,25 @@ +import beignet +import torch + + +def test_physicists_hermite_polynomial_to_polynomial(): + coefficients = [ + torch.tensor([1.0]), + torch.tensor([0.0, 2]), + torch.tensor([-2.0, 0, 4]), + torch.tensor([0.0, -12, 0, 8]), + torch.tensor([12.0, 0, -48, 0, 16]), + torch.tensor([0.0, 120, 0, -160, 0, 32]), + torch.tensor([-120.0, 0, 720, 0, -480, 0, 64]), + torch.tensor([0.0, -1680, 0, 3360, 0, -1344, 0, 128]), + torch.tensor([1680.0, 0, -13440, 0, 13440, 0, -3584, 0, 256]), + torch.tensor([0.0, 30240, 0, -80640, 0, 48384, 0, -9216, 0, 512]), + ] + + for index in range(10): + torch.testing.assert_close( + beignet.physicists_hermite_polynomial_to_polynomial( + torch.tensor([0.0] * index + [1.0]), + ), + coefficients[index], + ) diff --git a/tests/beignet/test__physicists_hermite_polynomial_vandermonde.py b/tests/beignet/test__physicists_hermite_polynomial_vandermonde.py new file mode 100644 index 0000000000..46e82097c6 --- /dev/null +++ b/tests/beignet/test__physicists_hermite_polynomial_vandermonde.py @@ -0,0 +1,38 @@ +import beignet +import torch + + +def test_physicists_hermite_polynomial_vandermonde(): + x = torch.arange(3) + + output = beignet.physicists_hermite_polynomial_vandermonde( + x, + degree=3, + ) + + assert output.shape == (3, 4) + + for index in range(4): + torch.testing.assert_close( + output[..., index], + beignet.evaluate_physicists_hermite_polynomial( + x, + torch.tensor([0.0] * index + [1.0]), + ), + ) + + output = beignet.physicists_hermite_polynomial_vandermonde( + torch.tensor([[1.0, 2.0], [3.0, 4.0], [5.0, 6.0]]), + degree=3, + ) + + assert output.shape == (3, 2, 4) + + for index in range(4): + torch.testing.assert_close( + output[..., index], + beignet.evaluate_physicists_hermite_polynomial( + torch.tensor([[1.0, 2.0], [3.0, 4.0], [5.0, 6.0]]), + torch.tensor([0.0] * index + [1.0]), + ), + ) diff --git a/tests/beignet/test__physicists_hermite_polynomial_vandermonde_2d.py b/tests/beignet/test__physicists_hermite_polynomial_vandermonde_2d.py new file mode 100644 index 0000000000..d2323fab01 --- /dev/null +++ b/tests/beignet/test__physicists_hermite_polynomial_vandermonde_2d.py @@ -0,0 +1,31 @@ +import beignet +import torch + + +def test_physicists_hermite_polynomial_vandermonde_2d(): + a, b, c = torch.rand(3, 5) * 2 - 1 + + coefficients = torch.rand(2, 3) + + output = beignet.physicists_hermite_polynomial_vandermonde_2d( + a, + b, + degree=torch.tensor([1, 2]), + ) + + torch.testing.assert_close( + output @ torch.ravel(coefficients), + beignet.evaluate_physicists_hermite_polynomial_2d( + a, + b, + coefficients, + ), + ) + + output = beignet.physicists_hermite_polynomial_vandermonde_2d( + a, + b, + degree=torch.tensor([1, 2]), + ) + + assert output.shape == (5, 6) diff --git a/tests/beignet/test__physicists_hermite_polynomial_vandermonde_3d.py b/tests/beignet/test__physicists_hermite_polynomial_vandermonde_3d.py new file mode 100644 index 0000000000..17642b0920 --- /dev/null +++ b/tests/beignet/test__physicists_hermite_polynomial_vandermonde_3d.py @@ -0,0 +1,29 @@ +import beignet +import torch + + +def test_physicists_hermite_polynomial_vandermonde_3d(): + a, b, x3 = torch.rand(3, 5) * 2 - 1 + + coefficients = torch.rand(2, 3, 4) + + output = beignet.physicists_hermite_polynomial_vandermonde_3d( + a, + b, + x3, + degree=torch.tensor([1, 2, 3]), + ) + + torch.testing.assert_close( + output @ torch.ravel(coefficients), + beignet.evaluate_physicists_hermite_polynomial_3d(a, b, x3, coefficients), + ) + + output = beignet.physicists_hermite_polynomial_vandermonde_3d( + a, + b, + x3, + degree=torch.tensor([1, 2, 3]), + ) + + assert output.shape == (5, 24) diff --git a/tests/beignet/test__physicists_hermite_polynomial_weight.py b/tests/beignet/test__physicists_hermite_polynomial_weight.py new file mode 100644 index 0000000000..c66c0ffa1d --- /dev/null +++ b/tests/beignet/test__physicists_hermite_polynomial_weight.py @@ -0,0 +1,9 @@ +import beignet +import torch + + +def test_physicists_hermite_polynomial_weight(): + torch.testing.assert_close( + beignet.physicists_hermite_polynomial_weight(torch.linspace(-5, 5, 11)), + torch.exp(-(torch.linspace(-5, 5, 11) ** 2)), + ) diff --git a/tests/beignet/test__physicists_hermite_polynomial_x.py b/tests/beignet/test__physicists_hermite_polynomial_x.py new file mode 100644 index 0000000000..cce9911bc6 --- /dev/null +++ b/tests/beignet/test__physicists_hermite_polynomial_x.py @@ -0,0 +1,10 @@ +import beignet +import torch + + +def test_physicists_hermite_polynomial_x(): + torch.testing.assert_close( + beignet.physicists_hermite_polynomial_x, + torch.tensor([0, 0.5]), + check_dtype=False, + ) diff --git a/tests/beignet/test__physicists_hermite_polynomial_zero.py b/tests/beignet/test__physicists_hermite_polynomial_zero.py new file mode 100644 index 0000000000..16a68efbaf --- /dev/null +++ b/tests/beignet/test__physicists_hermite_polynomial_zero.py @@ -0,0 +1,10 @@ +import beignet +import torch + + +def test_physicists_hermite_polynomial_zero(): + torch.testing.assert_close( + beignet.physicists_hermite_polynomial_zero, + torch.tensor([0.0]), + check_dtype=False, + ) diff --git a/tests/beignet/test__polynomial_companion.py b/tests/beignet/test__polynomial_companion.py new file mode 100644 index 0000000000..e36a2a9a61 --- /dev/null +++ b/tests/beignet/test__polynomial_companion.py @@ -0,0 +1,24 @@ +import beignet +import pytest +import torch + + +def test_polynomial_companion(): + with pytest.raises(ValueError): + beignet.polynomial_companion(torch.tensor([])) + + with pytest.raises(ValueError): + beignet.polynomial_companion(torch.tensor([1])) + + for i in range(1, 5): + output = beignet.polynomial_companion( + torch.tensor([0.0] * i + [1.0]), + ) + + assert output.shape == (i, i) + + output = beignet.polynomial_companion( + torch.tensor([1, 2]), + ) + + assert output[0, 0] == -0.5 diff --git a/tests/beignet/test__polynomial_domain.py b/tests/beignet/test__polynomial_domain.py new file mode 100644 index 0000000000..b663d8d7fb --- /dev/null +++ b/tests/beignet/test__polynomial_domain.py @@ -0,0 +1,10 @@ +import beignet +import torch + + +def test_polynomial_domain(): + torch.testing.assert_close( + beignet.polynomial_domain, + torch.tensor([-1.0, 1.0]), + check_dtype=False, + ) diff --git a/tests/beignet/test__polynomial_from_roots.py b/tests/beignet/test__polynomial_from_roots.py new file mode 100644 index 0000000000..5ca8697d83 --- /dev/null +++ b/tests/beignet/test__polynomial_from_roots.py @@ -0,0 +1,49 @@ +import math + +import beignet +import torch + + +def test_polynomial_from_roots(): + coefficients = [ + torch.tensor([1.0]), + torch.tensor([0.0, 1]), + torch.tensor([-1.0, 0, 2]), + torch.tensor([0.0, -3, 0, 4]), + torch.tensor([1.0, 0, -8, 0, 8]), + torch.tensor([0.0, 5, 0, -20, 0, 16]), + torch.tensor([-1.0, 0, 18, 0, -48, 0, 32]), + torch.tensor([0.0, -7, 0, 56, 0, -112, 0, 64]), + torch.tensor([1.0, 0, -32, 0, 160, 0, -256, 0, 128]), + torch.tensor([0.0, 9, 0, -120, 0, 432, 0, -576, 0, 256]), + ] + + torch.testing.assert_close( + beignet.trim_polynomial_coefficients( + beignet.polynomial_from_roots( + torch.tensor([]), + ), + tol=0.000001, + ), + torch.tensor([1.0]), + ) + + for index in range(1, 5): + input = torch.linspace(-math.pi, 0.0, 2 * index + 1) + + input = input[1::2] + + input = torch.cos(input) + + output = beignet.polynomial_from_roots(input) * 2 ** (index - 1) + + torch.testing.assert_close( + beignet.trim_polynomial_coefficients( + output, + tol=0.000001, + ), + beignet.trim_polynomial_coefficients( + coefficients[index], + tol=0.000001, + ), + ) diff --git a/tests/beignet/test__polynomial_one.py b/tests/beignet/test__polynomial_one.py new file mode 100644 index 0000000000..dc23507b6d --- /dev/null +++ b/tests/beignet/test__polynomial_one.py @@ -0,0 +1,10 @@ +import beignet +import torch + + +def test_polynomial_one(): + torch.testing.assert_close( + beignet.polynomial_one, + torch.tensor([1.0]), + check_dtype=False, + ) diff --git a/tests/beignet/test__polynomial_power.py b/tests/beignet/test__polynomial_power.py new file mode 100644 index 0000000000..85d237ab6c --- /dev/null +++ b/tests/beignet/test__polynomial_power.py @@ -0,0 +1,26 @@ +import functools + +import beignet +import torch + + +def test_polynomial_power(): + for i in range(5): + for j in range(5): + torch.testing.assert_close( + beignet.trim_polynomial_coefficients( + beignet.polynomial_power( + torch.arange(0.0, i + 1), + j, + ), + tol=0.000001, + ), + beignet.trim_polynomial_coefficients( + functools.reduce( + beignet.multiply_polynomial, + [torch.arange(0.0, i + 1)] * j, + torch.tensor([1.0]), + ), + tol=0.000001, + ), + ) diff --git a/tests/beignet/test__polynomial_roots.py b/tests/beignet/test__polynomial_roots.py new file mode 100644 index 0000000000..36c1500a00 --- /dev/null +++ b/tests/beignet/test__polynomial_roots.py @@ -0,0 +1,32 @@ +import beignet +import torch + + +def test_polynomial_roots(): + torch.testing.assert_close( + beignet.polynomial_roots(torch.tensor([1.0])), + torch.tensor([]), + ) + + torch.testing.assert_close( + beignet.polynomial_roots(torch.tensor([1.0, 2.0])), + torch.tensor([-0.5]), + ) + + for index in range(2, 5): + input = torch.linspace(-1, 1, index) + + torch.testing.assert_close( + beignet.trim_polynomial_coefficients( + beignet.polynomial_roots( + beignet.polynomial_from_roots( + input, + ), + ), + tol=0.000001, + ), + beignet.trim_polynomial_coefficients( + input, + tol=0.000001, + ), + ) diff --git a/tests/beignet/test__polynomial_to_chebyshev_polynomial.py b/tests/beignet/test__polynomial_to_chebyshev_polynomial.py new file mode 100644 index 0000000000..51ed63851e --- /dev/null +++ b/tests/beignet/test__polynomial_to_chebyshev_polynomial.py @@ -0,0 +1,25 @@ +import beignet +import torch + + +def test_polynomial_to_chebyshev_polynomial(): + coefficients = [ + torch.tensor([1.0]), + torch.tensor([0.0, 1]), + torch.tensor([-1.0, 0, 2]), + torch.tensor([0.0, -3, 0, 4]), + torch.tensor([1.0, 0, -8, 0, 8]), + torch.tensor([0.0, 5, 0, -20, 0, 16]), + torch.tensor([-1.0, 0, 18, 0, -48, 0, 32]), + torch.tensor([0.0, -7, 0, 56, 0, -112, 0, 64]), + torch.tensor([1.0, 0, -32, 0, 160, 0, -256, 0, 128]), + torch.tensor([0.0, 9, 0, -120, 0, 432, 0, -576, 0, 256]), + ] + + for index in range(10): + torch.testing.assert_close( + beignet.polynomial_to_chebyshev_polynomial( + coefficients[index], + ), + torch.tensor([0.0] * index + [1.0]), + ) diff --git a/tests/beignet/test__polynomial_to_laguerre_polynomial.py b/tests/beignet/test__polynomial_to_laguerre_polynomial.py new file mode 100644 index 0000000000..80b2026dfc --- /dev/null +++ b/tests/beignet/test__polynomial_to_laguerre_polynomial.py @@ -0,0 +1,22 @@ +import beignet +import torch + + +def test_polynomial_to_laguerre_polynomial(): + coefficients = [ + torch.tensor([1.0]) / 1.0, + torch.tensor([1.0, -1.0]) / 1.0, + torch.tensor([2.0, -4.0, 1.0]) / 2.0, + torch.tensor([6.0, -18.0, 9.0, -1.0]) / 6.0, + torch.tensor([24.0, -96.0, 72.0, -16.0, 1.0]) / 24.0, + torch.tensor([120.0, -600.0, 600.0, -200.0, 25.0, -1.0]) / 120.0, + torch.tensor([720.0, -4320.0, 5400.0, -2400.0, 450.0, -36.0, 1.0]) / 720.0, + ] + + for index in range(7): + torch.testing.assert_close( + beignet.polynomial_to_laguerre_polynomial( + coefficients[index], + ), + torch.tensor([0.0] * index + [1.0]), + ) diff --git a/tests/beignet/test__polynomial_to_legendre_polynomial.py b/tests/beignet/test__polynomial_to_legendre_polynomial.py new file mode 100644 index 0000000000..18061bc3f3 --- /dev/null +++ b/tests/beignet/test__polynomial_to_legendre_polynomial.py @@ -0,0 +1,25 @@ +import beignet +import torch + + +def test_polynomial_to_legendre_polynomial(): + coefficients = [ + torch.tensor([1.0]), + torch.tensor([0.0, 1]), + torch.tensor([-1.0, 0, 3]) / 2, + torch.tensor([0.0, -3, 0, 5]) / 2, + torch.tensor([3.0, 0, -30, 0, 35]) / 8, + torch.tensor([0.0, 15, 0, -70, 0, 63]) / 8, + torch.tensor([-5.0, 0, 105, 0, -315, 0, 231]) / 16, + torch.tensor([0.0, -35, 0, 315, 0, -693, 0, 429]) / 16, + torch.tensor([35.0, 0, -1260, 0, 6930, 0, -12012, 0, 6435]) / 128, + torch.tensor([0.0, 315, 0, -4620, 0, 18018, 0, -25740, 0, 12155]) / 128, + ] + + for index in range(10): + torch.testing.assert_close( + beignet.polynomial_to_legendre_polynomial( + coefficients[index], + ), + torch.tensor([0.0] * index + [1.0]), + ) diff --git a/tests/beignet/test__polynomial_to_physicists_hermite_polynomial.py b/tests/beignet/test__polynomial_to_physicists_hermite_polynomial.py new file mode 100644 index 0000000000..6ffe55718f --- /dev/null +++ b/tests/beignet/test__polynomial_to_physicists_hermite_polynomial.py @@ -0,0 +1,28 @@ +import beignet +import torch + + +def test_polynomial_to_physicists_hermite_polynomial(): + coefficients = [ + torch.tensor([1.0]), + torch.tensor([0.0, 2]), + torch.tensor([-2.0, 0, 4]), + torch.tensor([0.0, -12, 0, 8]), + torch.tensor([12.0, 0, -48, 0, 16]), + torch.tensor([0.0, 120, 0, -160, 0, 32]), + torch.tensor([-120.0, 0, 720, 0, -480, 0, 64]), + torch.tensor([0.0, -1680, 0, 3360, 0, -1344, 0, 128]), + torch.tensor([1680.0, 0, -13440, 0, 13440, 0, -3584, 0, 256]), + torch.tensor([0.0, 30240, 0, -80640, 0, 48384, 0, -9216, 0, 512]), + ] + + for index in range(10): + torch.testing.assert_close( + beignet.trim_physicists_hermite_polynomial_coefficients( + beignet.polynomial_to_physicists_hermite_polynomial( + coefficients[index], + ), + tol=0.000001, + ), + torch.tensor([0.0] * index + [1.0]), + ) diff --git a/tests/beignet/test__polynomial_to_probabilists_hermite_polynomial.py b/tests/beignet/test__polynomial_to_probabilists_hermite_polynomial.py new file mode 100644 index 0000000000..e8b98f09eb --- /dev/null +++ b/tests/beignet/test__polynomial_to_probabilists_hermite_polynomial.py @@ -0,0 +1,25 @@ +import beignet +import torch + + +def test_polynomial_to_probabilists_hermite_polynomial(): + coefficients = [ + torch.tensor([1.0]), + torch.tensor([0.0, 1]), + torch.tensor([-1.0, 0, 1]), + torch.tensor([0.0, -3, 0, 1]), + torch.tensor([3.0, 0, -6, 0, 1]), + torch.tensor([0.0, 15, 0, -10, 0, 1]), + torch.tensor([-15.0, 0, 45, 0, -15, 0, 1]), + torch.tensor([0.0, -105, 0, 105, 0, -21, 0, 1]), + torch.tensor([105.0, 0, -420, 0, 210, 0, -28, 0, 1]), + torch.tensor([0.0, 945, 0, -1260, 0, 378, 0, -36, 0, 1]), + ] + + for index in range(10): + torch.testing.assert_close( + beignet.polynomial_to_probabilists_hermite_polynomial( + coefficients[index], + ), + torch.tensor([0.0] * index + [1.0]), + ) diff --git a/tests/beignet/test__polynomial_vandermonde.py b/tests/beignet/test__polynomial_vandermonde.py new file mode 100644 index 0000000000..641fc34c1b --- /dev/null +++ b/tests/beignet/test__polynomial_vandermonde.py @@ -0,0 +1,43 @@ +import beignet +import pytest +import torch + + +def test_polynomial_vandermonde(): + output = beignet.polynomial_vandermonde( + torch.arange(3.0), + degree=torch.tensor([3]), + ) + + assert output.shape == (3, 4) + + for i in range(4): + torch.testing.assert_close( + output[..., i], + beignet.evaluate_polynomial( + torch.arange(3), + torch.tensor([0.0] * i + [1.0]), + ), + ) + + output = beignet.polynomial_vandermonde( + torch.tensor([[1.0, 2.0], [3.0, 4.0], [5.0, 6.0]]), + degree=torch.tensor([3]), + ) + + assert output.shape == (3, 2, 4) + + for i in range(4): + torch.testing.assert_close( + output[..., i], + beignet.evaluate_polynomial( + torch.tensor([[1.0, 2.0], [3.0, 4.0], [5.0, 6.0]]), + torch.tensor([0.0] * i + [1.0]), + ), + ) + + with pytest.raises(ValueError): + beignet.polynomial_vandermonde( + torch.arange(3), + degree=torch.tensor([-1]), + ) diff --git a/tests/beignet/test__polynomial_vandermonde_2d.py b/tests/beignet/test__polynomial_vandermonde_2d.py new file mode 100644 index 0000000000..bcc64759d8 --- /dev/null +++ b/tests/beignet/test__polynomial_vandermonde_2d.py @@ -0,0 +1,27 @@ +import beignet +import torch + + +def test_polynomial_vandermonde_2d(): + a, b, c = torch.rand(3, 5) * 2 - 1 + + coefficients = torch.rand(2, 3) + + output = beignet.polynomial_vandermonde_2d(a, b, degree=torch.tensor([1, 2])) + + torch.testing.assert_close( + output @ torch.ravel(coefficients), + beignet.evaluate_polynomial_2d( + a, + b, + coefficients, + ), + ) + + output = beignet.polynomial_vandermonde_2d( + a, + b, + degree=torch.tensor([1, 2]), + ) + + assert output.shape == (5, 6) diff --git a/tests/beignet/test__polynomial_vandermonde_3d.py b/tests/beignet/test__polynomial_vandermonde_3d.py new file mode 100644 index 0000000000..34615c4dd9 --- /dev/null +++ b/tests/beignet/test__polynomial_vandermonde_3d.py @@ -0,0 +1,34 @@ +import beignet +import torch + + +def test_polynomial_vandermonde_3d(): + a, b, c = torch.rand(3, 5) * 2 - 1 + + coefficients = torch.rand(2, 3, 4) + + output = beignet.polynomial_vandermonde_3d( + a, + b, + c, + degree=torch.tensor([1.0, 2.0, 3.0]), + ) + + torch.testing.assert_close( + output @ torch.ravel(coefficients), + beignet.evaluate_polynomial_3d( + a, + b, + c, + coefficients, + ), + ) + + output = beignet.polynomial_vandermonde_3d( + a, + b, + c, + degree=torch.tensor([1.0, 2.0, 3.0]), + ) + + assert output.shape == (5, 24) diff --git a/tests/beignet/test__polynomial_x.py b/tests/beignet/test__polynomial_x.py new file mode 100644 index 0000000000..09c3a7847f --- /dev/null +++ b/tests/beignet/test__polynomial_x.py @@ -0,0 +1,10 @@ +import beignet +import torch + + +def test_polynomial_x(): + torch.testing.assert_close( + beignet.polynomial_x, + torch.tensor([0.0, 1.0]), + check_dtype=False, + ) diff --git a/tests/beignet/test__polynomial_zero.py b/tests/beignet/test__polynomial_zero.py new file mode 100644 index 0000000000..e176d5f7a9 --- /dev/null +++ b/tests/beignet/test__polynomial_zero.py @@ -0,0 +1,10 @@ +import beignet +import torch + + +def test_polynomial_zero(): + torch.testing.assert_close( + beignet.polynomial_zero, + torch.tensor([0.0]), + check_dtype=False, + ) diff --git a/tests/beignet/test__probabilists_hermite_polynomial_companion.py b/tests/beignet/test__probabilists_hermite_polynomial_companion.py new file mode 100644 index 0000000000..aa405c35ad --- /dev/null +++ b/tests/beignet/test__probabilists_hermite_polynomial_companion.py @@ -0,0 +1,26 @@ +import beignet +import pytest +import torch + + +def test_probabilists_hermite_polynomial_companion(): + with pytest.raises(ValueError): + beignet.probabilists_hermite_polynomial_companion(torch.tensor([])) + + with pytest.raises(ValueError): + beignet.probabilists_hermite_polynomial_companion( + torch.tensor([1.0]), + ) + + for index in range(1, 5): + output = beignet.probabilists_hermite_polynomial_companion( + torch.tensor([0.0] * index + [1.0]), + ) + + assert output.shape == (index, index) + + output = beignet.probabilists_hermite_polynomial_companion( + torch.tensor([1.0, 2.0]), + ) + + assert output[0, 0] == -0.5 diff --git a/tests/beignet/test__probabilists_hermite_polynomial_domain.py b/tests/beignet/test__probabilists_hermite_polynomial_domain.py new file mode 100644 index 0000000000..aae362bc98 --- /dev/null +++ b/tests/beignet/test__probabilists_hermite_polynomial_domain.py @@ -0,0 +1,10 @@ +import beignet +import torch + + +def test_probabilists_hermite_polynomial_domain(): + torch.testing.assert_close( + beignet.probabilists_hermite_polynomial_domain, + torch.tensor([-1.0, 1.0]), + check_dtype=False, + ) diff --git a/tests/beignet/test__probabilists_hermite_polynomial_from_roots.py b/tests/beignet/test__probabilists_hermite_polynomial_from_roots.py new file mode 100644 index 0000000000..994f3324bd --- /dev/null +++ b/tests/beignet/test__probabilists_hermite_polynomial_from_roots.py @@ -0,0 +1,33 @@ +import math + +import beignet +import torch + + +def test_probabilists_hermite_polynomial_from_roots(): + torch.testing.assert_close( + beignet.trim_probabilists_hermite_polynomial_coefficients( + beignet.probabilists_hermite_polynomial_from_roots( + torch.tensor([]), + ), + tol=0.000001, + ), + torch.tensor([1.0]), + ) + + for i in range(1, 5): + roots = torch.cos(torch.linspace(-math.pi, 0, 2 * i + 1)[1::2]) + + pol = beignet.probabilists_hermite_polynomial_from_roots(roots) + + assert len(pol) == i + 1 + + torch.testing.assert_close( + beignet.probabilists_hermite_polynomial_to_polynomial(pol)[-1], + torch.tensor(1.0), + ) + + # torch.testing.assert_close( + # beignet.hermeval(roots, pol), + # torch.tensor([0.0]), + # ) diff --git a/tests/beignet/test__probabilists_hermite_polynomial_one.py b/tests/beignet/test__probabilists_hermite_polynomial_one.py new file mode 100644 index 0000000000..4fe799a601 --- /dev/null +++ b/tests/beignet/test__probabilists_hermite_polynomial_one.py @@ -0,0 +1,10 @@ +import beignet +import torch + + +def test_probabilists_hermite_polynomial_one(): + torch.testing.assert_close( + beignet.probabilists_hermite_polynomial_one, + torch.tensor([1.0]), + check_dtype=False, + ) diff --git a/tests/beignet/test__probabilists_hermite_polynomial_power.py b/tests/beignet/test__probabilists_hermite_polynomial_power.py new file mode 100644 index 0000000000..161c22351d --- /dev/null +++ b/tests/beignet/test__probabilists_hermite_polynomial_power.py @@ -0,0 +1,26 @@ +import functools + +import beignet +import torch + + +def test_probabilists_hermite_polynomial_power(): + for j in range(5): + for k in range(5): + torch.testing.assert_close( + beignet.trim_probabilists_hermite_polynomial_coefficients( + beignet.probabilists_hermite_polynomial_power( + torch.arange(0.0, j + 1), + k, + ), + tol=0.000001, + ), + beignet.trim_probabilists_hermite_polynomial_coefficients( + functools.reduce( + beignet.multiply_probabilists_hermite_polynomial, + [torch.arange(0.0, j + 1)] * k, + torch.tensor([1.0]), + ), + tol=0.000001, + ), + ) diff --git a/tests/beignet/test__probabilists_hermite_polynomial_roots.py b/tests/beignet/test__probabilists_hermite_polynomial_roots.py new file mode 100644 index 0000000000..a983241caa --- /dev/null +++ b/tests/beignet/test__probabilists_hermite_polynomial_roots.py @@ -0,0 +1,36 @@ +import beignet +import torch + + +def test_probabilists_hermite_polynomial_roots(): + torch.testing.assert_close( + beignet.probabilists_hermite_polynomial_roots( + torch.tensor([1.0]), + ), + torch.tensor([]), + ) + + torch.testing.assert_close( + beignet.probabilists_hermite_polynomial_roots( + torch.tensor([1.0, 1.0]), + ), + torch.tensor([-1.0]), + ) + + for index in range(2, 5): + input = torch.linspace(-1, 1, index) + + torch.testing.assert_close( + beignet.trim_probabilists_hermite_polynomial_coefficients( + beignet.probabilists_hermite_polynomial_roots( + beignet.probabilists_hermite_polynomial_from_roots( + input, + ) + ), + tol=0.000001, + ), + beignet.trim_probabilists_hermite_polynomial_coefficients( + input, + tol=0.000001, + ), + ) diff --git a/tests/beignet/test__probabilists_hermite_polynomial_to_polynomial.py b/tests/beignet/test__probabilists_hermite_polynomial_to_polynomial.py new file mode 100644 index 0000000000..30e42a2e28 --- /dev/null +++ b/tests/beignet/test__probabilists_hermite_polynomial_to_polynomial.py @@ -0,0 +1,25 @@ +import beignet +import torch + + +def test_probabilists_hermite_polynomial_to_polynomial(): + coefficients = [ + torch.tensor([1.0]), + torch.tensor([0.0, 1]), + torch.tensor([-1.0, 0, 1]), + torch.tensor([0.0, -3, 0, 1]), + torch.tensor([3.0, 0, -6, 0, 1]), + torch.tensor([0.0, 15, 0, -10, 0, 1]), + torch.tensor([-15.0, 0, 45, 0, -15, 0, 1]), + torch.tensor([0.0, -105, 0, 105, 0, -21, 0, 1]), + torch.tensor([105.0, 0, -420, 0, 210, 0, -28, 0, 1]), + torch.tensor([0.0, 945, 0, -1260, 0, 378, 0, -36, 0, 1]), + ] + + for index in range(10): + torch.testing.assert_close( + beignet.probabilists_hermite_polynomial_to_polynomial( + torch.tensor([0.0] * index + [1.0]), + ), + coefficients[index], + ) diff --git a/tests/beignet/test__probabilists_hermite_polynomial_vandermonde.py b/tests/beignet/test__probabilists_hermite_polynomial_vandermonde.py new file mode 100644 index 0000000000..39959edab7 --- /dev/null +++ b/tests/beignet/test__probabilists_hermite_polynomial_vandermonde.py @@ -0,0 +1,30 @@ +import beignet +import torch + + +def test_probabilists_hermite_polynomial_vandermonde(): + x = torch.arange(3) + v = beignet.probabilists_hermite_polynomial_vandermonde( + x, + 3, + ) + assert v.shape == (3, 4) + for i in range(4): + coefficients = torch.tensor([0.0] * i + [1.0]) + torch.testing.assert_close( + v[..., i], + beignet.evaluate_probabilists_hermite_polynomial(x, coefficients), + ) + + x = torch.tensor([[1.0, 2.0], [3.0, 4.0], [5.0, 6.0]]) + v = beignet.probabilists_hermite_polynomial_vandermonde( + x, + 3, + ) + assert v.shape == (3, 2, 4) + for i in range(4): + coefficients = torch.tensor([0.0] * i + [1.0]) + torch.testing.assert_close( + v[..., i], + beignet.evaluate_probabilists_hermite_polynomial(x, coefficients), + ) diff --git a/tests/beignet/test__probabilists_hermite_polynomial_vandermonde_2d.py b/tests/beignet/test__probabilists_hermite_polynomial_vandermonde_2d.py new file mode 100644 index 0000000000..bbbdfcde67 --- /dev/null +++ b/tests/beignet/test__probabilists_hermite_polynomial_vandermonde_2d.py @@ -0,0 +1,31 @@ +import beignet +import torch + + +def test_probabilists_hermite_polynomial_vandermonde_2d(): + a, b, c = torch.rand(3, 5) * 2 - 1 + + coefficients = torch.rand(2, 3) + + output = beignet.probabilists_hermite_polynomial_vandermonde_2d( + a, + b, + degree=torch.tensor([1, 2]), + ) + + torch.testing.assert_close( + output @ torch.ravel(coefficients), + beignet.evaluate_probabilists_hermite_polynomial_2d( + a, + b, + coefficients, + ), + ) + + output = beignet.probabilists_hermite_polynomial_vandermonde_2d( + a, + b, + degree=torch.tensor([1, 2]), + ) + + assert output.shape == (5, 6) diff --git a/tests/beignet/test__probabilists_hermite_polynomial_vandermonde_3d.py b/tests/beignet/test__probabilists_hermite_polynomial_vandermonde_3d.py new file mode 100644 index 0000000000..55faac9440 --- /dev/null +++ b/tests/beignet/test__probabilists_hermite_polynomial_vandermonde_3d.py @@ -0,0 +1,34 @@ +import beignet +import torch + + +def test_probabilists_hermite_polynomial_vandermonde_3d(): + a, b, c = torch.rand(3, 5) * 2 - 1 + + coefficients = torch.rand(2, 3, 4) + + output = beignet.probabilists_hermite_polynomial_vandermonde_3d( + a, + b, + c, + degree=torch.tensor([1, 2, 3]), + ) + + torch.testing.assert_close( + output @ torch.ravel(coefficients), + beignet.evaluate_probabilists_hermite_polynomial_3d( + a, + b, + c, + coefficients, + ), + ) + + output = beignet.probabilists_hermite_polynomial_vandermonde_3d( + a, + b, + c, + degree=torch.tensor([1, 2, 3]), + ) + + assert output.shape == (5, 24) diff --git a/tests/beignet/test__probabilists_hermite_polynomial_weight.py b/tests/beignet/test__probabilists_hermite_polynomial_weight.py new file mode 100644 index 0000000000..08b7a66378 --- /dev/null +++ b/tests/beignet/test__probabilists_hermite_polynomial_weight.py @@ -0,0 +1,11 @@ +import beignet +import torch + + +def test_probabilists_hermite_polynomial_weight(): + torch.testing.assert_close( + beignet.probabilists_hermite_polynomial_weight( + torch.linspace(-5, 5, 11), + ), + torch.exp(-0.5 * torch.linspace(-5, 5, 11) ** 2), + ) diff --git a/tests/beignet/test__probabilists_hermite_polynomial_x.py b/tests/beignet/test__probabilists_hermite_polynomial_x.py new file mode 100644 index 0000000000..6ffea002b3 --- /dev/null +++ b/tests/beignet/test__probabilists_hermite_polynomial_x.py @@ -0,0 +1,10 @@ +import beignet +import torch + + +def test_probabilists_hermite_polynomial_x(): + torch.testing.assert_close( + beignet.probabilists_hermite_polynomial_x, + torch.tensor([0.0, 1.0]), + check_dtype=False, + ) diff --git a/tests/beignet/test__probabilists_hermite_polynomial_zero.py b/tests/beignet/test__probabilists_hermite_polynomial_zero.py new file mode 100644 index 0000000000..b569e2c5fc --- /dev/null +++ b/tests/beignet/test__probabilists_hermite_polynomial_zero.py @@ -0,0 +1,10 @@ +import beignet +import torch + + +def test_probabilists_hermite_polynomial_zero(): + torch.testing.assert_close( + beignet.probabilists_hermite_polynomial_zero, + torch.tensor([0.0]), + check_dtype=False, + ) diff --git a/tests/beignet/test__quaternion_slerp.py b/tests/beignet/test__quaternion_slerp.py new file mode 100644 index 0000000000..a41f037a6e --- /dev/null +++ b/tests/beignet/test__quaternion_slerp.py @@ -0,0 +1,150 @@ +import beignet +import hypothesis.strategies +import numpy +import torch +from scipy.spatial.transform import Rotation, Slerp + +# def test_slerp(): +# # t = 0 +# torch.testing.assert_close( +# beignet.quaternion_slerp( +# torch.tensor([+0.00000]), +# torch.tensor([+0.00000, +1.00000]), +# torch.tensor( +# [ +# [+1.00000, +0.00000, +0.00000, +0.00000], +# [+0.00000, +1.00000, +0.00000, +0.00000], +# ] +# ), +# ), +# torch.tensor([[+1.00000, +0.00000, +0.00000, +0.00000]]), +# ) +# +# # t = 1 +# torch.testing.assert_close( +# beignet.quaternion_slerp( +# torch.tensor([+1.00000]), +# torch.tensor([+0.00000, +1.00000]), +# torch.tensor( +# [ +# [+1.00000, +0.00000, +0.00000, +0.00000], +# [+0.00000, +1.00000, +0.00000, +0.00000], +# ] +# ), +# ), +# torch.tensor([[+0.00000, +1.00000, +0.00000, +0.00000]]), +# ) +# +# # SMALL (ACUTE) ANGLE BETWEEN QUATERNIONS +# torch.testing.assert_close( +# beignet.quaternion_slerp( +# torch.tensor([+0.50000]), +# torch.tensor([+0.00000, +1.00000]), +# torch.tensor( +# [ +# [+1.00000, +0.00000, +0.00000, +0.00000], +# [+0.70710, +0.70710, +0.00000, +0.00000], +# ], +# ), +# ), +# torch.reshape( +# torch.tensor([+0.92388, +0.38268, +0.00000, +0.00000]), +# [1, -1], +# ), +# ) +# +# # LARGE (OBTUSE) ANGLE BETWEEN QUATERNIONS +# torch.testing.assert_close( +# beignet.quaternion_slerp( +# torch.tensor([+0.50000]), +# torch.tensor([+0.00000, +1.00000]), +# torch.tensor( +# [ +# [+1.00000, +0.00000, +0.00000, +0.00000], +# [-1.00000, +0.00000, +0.00000, +0.00000], +# ] +# ), +# ), +# torch.reshape( +# torch.tensor([+1.00000, +0.00000, +0.00000, +0.00000]), +# [1, -1], +# ), +# ) + + +@hypothesis.strategies.composite +def slerp_parameters(f): + n = f( + hypothesis.strategies.integers( + min_value=2, + max_value=8, + ), + ) + + times = numpy.sort( + f( + hypothesis.strategies.lists( + hypothesis.strategies.floats( + allow_infinity=False, + allow_nan=False, + ), + min_size=n, + max_size=n, + unique=True, + ), + ), + ) + + min_value = numpy.min(times) + max_value = numpy.max(times) + + input = numpy.sort( + f( + hypothesis.strategies.lists( + hypothesis.strategies.floats( + min_value=min_value, + max_value=max_value, + ), + min_size=1, + max_size=8, + unique=True, + ), + ), + ) + + rotations = f( + hypothesis.strategies.lists( + hypothesis.strategies.lists( + hypothesis.strategies.floats( + numpy.finfo(numpy.float32).eps, + 1.0, + ), + min_size=4, + max_size=4, + ), + min_size=n, + max_size=n, + ), + ) + + rotations = Rotation.from_quat(rotations) + + return [ + [ + torch.from_numpy(input), + torch.from_numpy(times), + torch.from_numpy(rotations.as_quat(canonical=True)), + ], + torch.from_numpy( + Slerp(times, rotations)(input).as_quat(canonical=True), + ), + ] + + +@hypothesis.given(slerp_parameters()) +def test_slerp_properties(data): + parameters, expected_rotations = data + + torch.testing.assert_close( + beignet.quaternion_slerp(*parameters), expected_rotations + ) diff --git a/tests/beignet/test__slerp.py b/tests/beignet/test__slerp.py deleted file mode 100644 index 3985fbe7e6..0000000000 --- a/tests/beignet/test__slerp.py +++ /dev/null @@ -1,151 +0,0 @@ -import beignet -import hypothesis.strategies -import numpy -import torch -from scipy.spatial.transform import Rotation, Slerp - - -def test_slerp(): - # t = 0 - torch.testing.assert_close( - beignet.quaternion_slerp( - torch.tensor([+0.00000]), - torch.tensor([+0.00000, +1.00000]), - torch.tensor( - [ - [+1.00000, +0.00000, +0.00000, +0.00000], - [+0.00000, +1.00000, +0.00000, +0.00000], - ] - ), - ), - torch.tensor([[+1.00000, +0.00000, +0.00000, +0.00000]]), - ) - - # t = 1 - torch.testing.assert_close( - beignet.quaternion_slerp( - torch.tensor([+1.00000]), - torch.tensor([+0.00000, +1.00000]), - torch.tensor( - [ - [+1.00000, +0.00000, +0.00000, +0.00000], - [+0.00000, +1.00000, +0.00000, +0.00000], - ] - ), - ), - torch.tensor([[+0.00000, +1.00000, +0.00000, +0.00000]]), - ) - - # SMALL (ACUTE) ANGLE BETWEEN QUATERNIONS - torch.testing.assert_close( - beignet.quaternion_slerp( - torch.tensor([+0.50000]), - torch.tensor([+0.00000, +1.00000]), - torch.tensor( - [ - [+1.00000, +0.00000, +0.00000, +0.00000], - [+0.70710, +0.70710, +0.00000, +0.00000], - ], - ), - ), - torch.reshape( - torch.tensor([+0.92388, +0.38268, +0.00000, +0.00000]), - [1, -1], - ), - ) - - # LARGE (OBTUSE) ANGLE BETWEEN QUATERNIONS - torch.testing.assert_close( - beignet.quaternion_slerp( - torch.tensor([+0.50000]), - torch.tensor([+0.00000, +1.00000]), - torch.tensor( - [ - [+1.00000, +0.00000, +0.00000, +0.00000], - [-1.00000, +0.00000, +0.00000, +0.00000], - ] - ), - ), - torch.reshape( - torch.tensor([+1.00000, +0.00000, +0.00000, +0.00000]), - [1, -1], - ), - ) - - -@hypothesis.strategies.composite -def slerp_parameters(f): - n = f( - hypothesis.strategies.integers( - min_value=2, - max_value=8, - ), - ) - - times = numpy.sort( - f( - hypothesis.strategies.lists( - hypothesis.strategies.floats( - allow_infinity=False, - allow_nan=False, - ), - min_size=n, - max_size=n, - unique=True, - ), - ), - ) - - min_value = numpy.min(times) - max_value = numpy.max(times) - - input = numpy.sort( - f( - hypothesis.strategies.lists( - hypothesis.strategies.floats( - min_value=min_value, - max_value=max_value, - ), - min_size=1, - max_size=8, - unique=True, - ), - ), - ) - - rotations = f( - hypothesis.strategies.lists( - hypothesis.strategies.lists( - hypothesis.strategies.floats( - numpy.finfo(numpy.float32).eps, - 1.0, - ), - min_size=4, - max_size=4, - ), - min_size=n, - max_size=n, - ), - ) - - rotations = Rotation.from_quat(rotations) - - return [ - [ - torch.from_numpy(input), - torch.from_numpy(times), - torch.from_numpy(rotations.as_quat(canonical=True)), - ], - torch.from_numpy( - Slerp(times, rotations)(input).as_quat(canonical=True), - ), - ] - - -@hypothesis.given(slerp_parameters()) -def test_slerp_properties(data): - parameters, expected_rotations = data - - torch.testing.assert_close( - beignet.quaternion_slerp(*parameters), expected_rotations - ) diff --git a/tests/beignet/test__subtract_chebyshev_polynomial.py b/tests/beignet/test__subtract_chebyshev_polynomial.py new file mode 100644 index 0000000000..a28db3ac31 --- /dev/null +++ b/tests/beignet/test__subtract_chebyshev_polynomial.py @@ -0,0 +1,28 @@ +import beignet +import torch + + +def test_subtract_chebyshev_polynomial(): + for j in range(5): + for k in range(5): + target = torch.zeros(max(j, k) + 1) + + target[j] = target[j] + 1 + target[k] = target[k] - 1 + + input = torch.tensor([0.0] * j + [1.0]) + other = torch.tensor([0.0] * k + [1.0]) + + torch.testing.assert_close( + beignet.trim_chebyshev_polynomial_coefficients( + beignet.subtract_chebyshev_polynomial( + input, + other, + ), + tol=0.000001, + ), + beignet.trim_chebyshev_polynomial_coefficients( + target, + tol=0.000001, + ), + ) diff --git a/tests/beignet/test__subtract_laguerre_polynomial.py b/tests/beignet/test__subtract_laguerre_polynomial.py new file mode 100644 index 0000000000..e117c62088 --- /dev/null +++ b/tests/beignet/test__subtract_laguerre_polynomial.py @@ -0,0 +1,25 @@ +import beignet +import torch + + +def test_subtract_laguerre_polynomial(): + for i in range(5): + for j in range(5): + target = torch.zeros(max(i, j) + 1) + + target[i] = target[i] + 1 + target[j] = target[j] - 1 + + torch.testing.assert_close( + beignet.trim_laguerre_polynomial_coefficients( + beignet.subtract_laguerre_polynomial( + torch.tensor([0.0] * i + [1.0]), + torch.tensor([0.0] * j + [1.0]), + ), + tol=0.000001, + ), + beignet.trim_laguerre_polynomial_coefficients( + target, + tol=0.000001, + ), + ) diff --git a/tests/beignet/test__subtract_legendre_polynomial.py b/tests/beignet/test__subtract_legendre_polynomial.py new file mode 100644 index 0000000000..ce110508f4 --- /dev/null +++ b/tests/beignet/test__subtract_legendre_polynomial.py @@ -0,0 +1,25 @@ +import beignet +import torch + + +def test_subtract_legendre_polynomial(): + for i in range(5): + for j in range(5): + target = torch.zeros(max(i, j) + 1) + + target[i] = target[i] + 1 + target[j] = target[j] - 1 + + torch.testing.assert_close( + beignet.trim_legendre_polynomial_coefficients( + beignet.subtract_legendre_polynomial( + torch.tensor([0.0] * i + [1.0]), + torch.tensor([0.0] * j + [1.0]), + ), + tol=0.000001, + ), + beignet.trim_legendre_polynomial_coefficients( + target, + tol=0.000001, + ), + ) diff --git a/tests/beignet/test__subtract_physicists_hermite_polynomial.py b/tests/beignet/test__subtract_physicists_hermite_polynomial.py new file mode 100644 index 0000000000..27274b31a5 --- /dev/null +++ b/tests/beignet/test__subtract_physicists_hermite_polynomial.py @@ -0,0 +1,25 @@ +import beignet +import torch + + +def test_subtract_physicists_hermite_polynomial(): + for i in range(5): + for j in range(5): + target = torch.zeros(max(i, j) + 1) + + target[i] = target[i] + 1 + target[j] = target[j] - 1 + + torch.testing.assert_close( + beignet.trim_physicists_hermite_polynomial_coefficients( + beignet.subtract_physicists_hermite_polynomial( + torch.tensor([0.0] * i + [1.0]), + torch.tensor([0.0] * j + [1.0]), + ), + tol=0.000001, + ), + beignet.trim_physicists_hermite_polynomial_coefficients( + target, + tol=0.000001, + ), + ) diff --git a/tests/beignet/test__subtract_polynomial.py b/tests/beignet/test__subtract_polynomial.py new file mode 100644 index 0000000000..5ab735dcef --- /dev/null +++ b/tests/beignet/test__subtract_polynomial.py @@ -0,0 +1,25 @@ +import beignet +import torch + + +def test_subtract_polynomial(): + for i in range(5): + for j in range(5): + target = torch.zeros(max(i, j) + 1) + + target[i] = target[i] + 1 + target[j] = target[j] - 1 + + torch.testing.assert_close( + beignet.trim_polynomial_coefficients( + beignet.subtract_polynomial( + torch.tensor([0.0] * i + [1.0]), + torch.tensor([0.0] * j + [1.0]), + ), + tol=0.000001, + ), + beignet.trim_polynomial_coefficients( + target, + tol=0.000001, + ), + ) diff --git a/tests/beignet/test__subtract_probabilists_hermite_polynomial.py b/tests/beignet/test__subtract_probabilists_hermite_polynomial.py new file mode 100644 index 0000000000..31f7d20844 --- /dev/null +++ b/tests/beignet/test__subtract_probabilists_hermite_polynomial.py @@ -0,0 +1,28 @@ +import beignet +import torch + + +def test_subtract_probabilists_hermite_polynomial(): + for j in range(5): + for k in range(5): + target = torch.zeros(max(j, k) + 1) + + target[j] = target[j] + 1 + target[k] = target[k] - 1 + + input = torch.tensor([0.0] * j + [1.0]) + other = torch.tensor([0.0] * k + [1.0]) + + torch.testing.assert_close( + beignet.trim_probabilists_hermite_polynomial_coefficients( + beignet.subtract_probabilists_hermite_polynomial( + input, + other, + ), + tol=0.000001, + ), + beignet.trim_probabilists_hermite_polynomial_coefficients( + target, + tol=0.000001, + ), + ) diff --git a/tests/beignet/test__trim_chebyshev_polynomial_coefficients.py b/tests/beignet/test__trim_chebyshev_polynomial_coefficients.py new file mode 100644 index 0000000000..346f1471df --- /dev/null +++ b/tests/beignet/test__trim_chebyshev_polynomial_coefficients.py @@ -0,0 +1,34 @@ +import beignet +import pytest +import torch + + +def test_trim_chebyshev_polynomial_coefficients(): + with pytest.raises(ValueError): + beignet.trim_chebyshev_polynomial_coefficients( + torch.tensor([2.0, -1.0, 1.0, 0.0]), + tol=-1, + ) + + torch.testing.assert_close( + beignet.trim_chebyshev_polynomial_coefficients( + torch.tensor([2.0, -1.0, 1.0, 0.0]), + ), + torch.tensor([2.0, -1.0, 1.0, 0.0])[:-1], + ) + + torch.testing.assert_close( + beignet.trim_chebyshev_polynomial_coefficients( + torch.tensor([2.0, -1.0, 1.0, 0.0]), + tol=1, + ), + torch.tensor([2.0, -1.0, 1.0, 0.0])[:-3], + ) + + torch.testing.assert_close( + beignet.trim_chebyshev_polynomial_coefficients( + torch.tensor([2.0, -1.0, 1.0, 0.0]), + tol=2, + ), + torch.tensor([0.0]), + ) diff --git a/tests/beignet/test__trim_laguerre_polynomial_coefficients.py b/tests/beignet/test__trim_laguerre_polynomial_coefficients.py new file mode 100644 index 0000000000..e8f6407cfb --- /dev/null +++ b/tests/beignet/test__trim_laguerre_polynomial_coefficients.py @@ -0,0 +1,34 @@ +import beignet +import pytest +import torch + + +def test_trim_laguerre_polynomial_coefficients(): + with pytest.raises(ValueError): + beignet.trim_laguerre_polynomial_coefficients( + torch.tensor([2.0, -1.0, 1.0, 0.0]), + tol=-1, + ) + + torch.testing.assert_close( + beignet.trim_laguerre_polynomial_coefficients( + torch.tensor([2.0, -1.0, 1.0, 0.0]), + ), + torch.tensor([2.0, -1.0, 1.0, 0.0])[:-1], + ) + + torch.testing.assert_close( + beignet.trim_laguerre_polynomial_coefficients( + torch.tensor([2.0, -1.0, 1.0, 0.0]), + tol=1, + ), + torch.tensor([2.0, -1.0, 1.0, 0.0])[:-3], + ) + + torch.testing.assert_close( + beignet.trim_laguerre_polynomial_coefficients( + torch.tensor([2.0, -1.0, 1.0, 0.0]), + tol=2, + ), + torch.tensor([0.0]), + ) diff --git a/tests/beignet/test__trim_legendre_polynomial_coefficients.py b/tests/beignet/test__trim_legendre_polynomial_coefficients.py new file mode 100644 index 0000000000..677f28e2bd --- /dev/null +++ b/tests/beignet/test__trim_legendre_polynomial_coefficients.py @@ -0,0 +1,34 @@ +import beignet +import pytest +import torch + + +def test_trim_legendre_polynomial_coefficients(): + with pytest.raises(ValueError): + beignet.trim_legendre_polynomial_coefficients( + torch.tensor([2.0, -1.0, 1.0, 0.0]), + tol=-1, + ) + + torch.testing.assert_close( + beignet.trim_legendre_polynomial_coefficients( + torch.tensor([2.0, -1.0, 1.0, 0.0]), + ), + torch.tensor([2.0, -1.0, 1.0, 0.0])[:-1], + ) + + torch.testing.assert_close( + beignet.trim_legendre_polynomial_coefficients( + torch.tensor([2.0, -1.0, 1.0, 0.0]), + tol=1, + ), + torch.tensor([2.0, -1.0, 1.0, 0.0])[:-3], + ) + + torch.testing.assert_close( + beignet.trim_legendre_polynomial_coefficients( + torch.tensor([2.0, -1.0, 1.0, 0.0]), + tol=2, + ), + torch.tensor([0.0]), + ) diff --git a/tests/beignet/test__trim_physicists_hermite_polynomial_coefficients.py b/tests/beignet/test__trim_physicists_hermite_polynomial_coefficients.py new file mode 100644 index 0000000000..7aeaf7fb15 --- /dev/null +++ b/tests/beignet/test__trim_physicists_hermite_polynomial_coefficients.py @@ -0,0 +1,34 @@ +import beignet +import pytest +import torch + + +def test_trim_physicists_hermite_polynomial_coefficients(): + with pytest.raises(ValueError): + beignet.trim_physicists_hermite_polynomial_coefficients( + torch.tensor([2.0, -1.0, 1.0, 0.0]), + tol=-1, + ) + + torch.testing.assert_close( + beignet.trim_physicists_hermite_polynomial_coefficients( + torch.tensor([2.0, -1.0, 1.0, 0.0]), + ), + torch.tensor([2.0, -1.0, 1.0, 0.0])[:-1], + ) + + torch.testing.assert_close( + beignet.trim_physicists_hermite_polynomial_coefficients( + torch.tensor([2.0, -1.0, 1.0, 0.0]), + tol=1, + ), + torch.tensor([2.0, -1.0, 1.0, 0.0])[:-3], + ) + + torch.testing.assert_close( + beignet.trim_physicists_hermite_polynomial_coefficients( + torch.tensor([2.0, -1.0, 1.0, 0.0]), + tol=2, + ), + torch.tensor([0.0]), + ) diff --git a/tests/beignet/test__trim_polynomial_coefficients.py b/tests/beignet/test__trim_polynomial_coefficients.py new file mode 100644 index 0000000000..3df46c1808 --- /dev/null +++ b/tests/beignet/test__trim_polynomial_coefficients.py @@ -0,0 +1,34 @@ +import beignet +import pytest +import torch + + +def test_trim_polynomial_coefficients(): + with pytest.raises(ValueError): + beignet.trim_polynomial_coefficients( + torch.tensor([2.0, -1.0, 1.0, 0.0]), + tol=-1, + ) + + torch.testing.assert_close( + beignet.trim_polynomial_coefficients( + torch.tensor([2.0, -1.0, 1.0, 0.0]), + ), + torch.tensor([2.0, -1.0, 1.0, 0.0])[:-1], + ) + + torch.testing.assert_close( + beignet.trim_polynomial_coefficients( + torch.tensor([2.0, -1.0, 1.0, 0.0]), + tol=1, + ), + torch.tensor([2.0, -1.0, 1.0, 0.0])[:-3], + ) + + torch.testing.assert_close( + beignet.trim_polynomial_coefficients( + torch.tensor([2.0, -1.0, 1.0, 0.0]), + tol=2, + ), + torch.tensor([0.0]), + ) diff --git a/tests/beignet/test__trim_probabilists_hermite_polynomial_coefficients.py b/tests/beignet/test__trim_probabilists_hermite_polynomial_coefficients.py new file mode 100644 index 0000000000..5e9c41faa6 --- /dev/null +++ b/tests/beignet/test__trim_probabilists_hermite_polynomial_coefficients.py @@ -0,0 +1,34 @@ +import beignet +import pytest +import torch + + +def test_trim_probabilists_hermite_polynomial_coefficients(): + with pytest.raises(ValueError): + beignet.trim_probabilists_hermite_polynomial_coefficients( + torch.tensor([2.0, -1.0, 1.0, 0.0]), + -1, + ) + + torch.testing.assert_close( + beignet.trim_probabilists_hermite_polynomial_coefficients( + torch.tensor([2.0, -1.0, 1.0, 0.0]), + ), + torch.tensor([2.0, -1.0, 1.0, 0.0])[:-1], + ) + + torch.testing.assert_close( + beignet.trim_probabilists_hermite_polynomial_coefficients( + torch.tensor([2.0, -1.0, 1.0, 0.0]), + 1, + ), + torch.tensor([2.0, -1.0, 1.0, 0.0])[:-3], + ) + + torch.testing.assert_close( + beignet.trim_probabilists_hermite_polynomial_coefficients( + torch.tensor([2.0, -1.0, 1.0, 0.0]), + 2, + ), + torch.tensor([0.0]), + )