1- #define FORCE_IMPORT_ARRAY
2- #define XTENSOR_USE_XSIMD
3-
1+ #define _USE_MATH_DEFINES
42#include < pybind11/pybind11.h>
5- #include < xtensor/xmath.hpp >
6- #include < xtensor/xarray.hpp >
7- #include < xtensor-python/pyarray .hpp>
8- #include < xtensor/xview.hpp >
3+ #include < pybind11/eigen.h >
4+ #include < Eigen/Core >
5+ #include < xsimd/xsimd .hpp>
6+ #include < cmath >
97
108namespace py = pybind11;
11- constexpr double FOUR_THIRDS_PI = 4.1887902 ;
12- constexpr double N_THREE_HALVES_SQRT_3 = -2.59807621 ;
13- constexpr double TWO_OVER_SQRT_THREE = 1.154700538 ;
14-
15- xt::pyarray<double > ge_41rt_inverse_distortion (const xt::pyarray<double >& inputs, const double rhoMax, const xt::pyarray<double >& params) {
16- auto radii = xt::sqrt (xt::sum (xt::square (inputs), {1 }));
17-
18- if (xt::amax (radii)() < 1e-10 ) {
19- return xt::zeros<double >({inputs.shape ()[0 ], inputs.shape ()[1 ]});
20- }
21-
22- auto inverted_radii = xt::pow (radii, -1 );
23- xt::pyarray<double > cosines = xt::view (inputs, xt::all (), 0 ) * inverted_radii;
24- auto cosine_double_angles = 2 * xt::square (cosines) - 1 ;
25- auto cosine_quadruple_angles = 2 * xt::square (cosine_double_angles) - 1 ;
26- auto sqrt_p_is = rhoMax / xt::sqrt (-params[0 ] * cosine_double_angles - params[1 ] * cosine_quadruple_angles - params[2 ]);
27- auto solutions = TWO_OVER_SQRT_THREE * sqrt_p_is * xt::cos (xt::acos (N_THREE_HALVES_SQRT_3 * radii / sqrt_p_is) / 3 + FOUR_THIRDS_PI);
28- xt::pyarray<double > results = xt::view (solutions, xt::all (), xt::newaxis ()) * inputs * xt::view (inverted_radii, xt::all (), xt::newaxis ());
29-
30- return results;
9+ const double FOUR_THIRDS_PI = M_PI * 4.0 / 3.0 ;
10+ const double N_THREE_HALVES_SQRT_3 = -3.0 / 2.0 * std::sqrt (3.0 );
11+ const double TWO_OVER_SQRT_THREE = 2.0 / std::sqrt(3.0 );
12+
13+ Eigen::ArrayXXd ge_41rt_inverse_distortion (const Eigen::ArrayXXd& inputs, const double rhoMax, const Eigen::ArrayXd& params) {
14+ Eigen::ArrayXd radii = inputs.matrix ().rowwise ().norm ();
15+ Eigen::ArrayXd inverted_radii = radii.cwiseInverse ();
16+ Eigen::ArrayXd cosines = inputs.col (0 ) * inverted_radii;
17+ Eigen::ArrayXd cosine_double_angles = 2 *cosines.square () - 1 ;
18+ Eigen::ArrayXd cosine_quadruple_angles = 2 *cosine_double_angles.square () - 1 ;
19+ Eigen::ArrayXd sqrt_p_is = rhoMax / (-params[0 ]*cosine_double_angles - params[1 ]*cosine_quadruple_angles - params[2 ]).sqrt ();
20+ Eigen::ArrayXd solutions = TWO_OVER_SQRT_THREE*sqrt_p_is*(acos (N_THREE_HALVES_SQRT_3*radii/sqrt_p_is)/3 + FOUR_THIRDS_PI).cos ();
21+ Eigen::ArrayXXd results = solutions.rowwise ().replicate (inputs.cols ()).array () * inputs * inverted_radii.rowwise ().replicate (inputs.cols ()).array ();
22+
23+ return results;
3124}
3225
3326PYBIND11_MODULE (inverse_distortion, m)
3427{
35- xt::import_numpy ();
3628 m.doc () = " HEXRD inverse distribution plugin" ;
3729
3830 m.def (" ge_41rt_inverse_distortion" , &ge_41rt_inverse_distortion, " Inverse distortion for ge_41rt" );
39- }
31+ }
0 commit comments