30#ifndef math_zernike_hpp
31#define math_zernike_hpp
42#include "../math/constants.hpp"
99template <
typename realT>
101 std::vector<realT> &c,
115 if( ( n - m ) % 2 > 0 )
121 int ul = 0.5 * ( n - m ) + 1;
125 for(
int k = 0; k < ul; ++k )
136extern template int zernikeRCoeffs<float>( std::vector<float> &c,
int n,
int m );
138extern template int zernikeRCoeffs<double>( std::vector<double> &c,
int n,
int m );
140extern template int zernikeRCoeffs<long double>( std::vector<long double> &c,
int n,
int m );
155template <
typename realT,
typename calcRealT>
159 std::vector<calcRealT> &c
166 if( ( n - m ) % 2 > 0 )
172 if( c.size() != 0.5 * ( n - m ) + 1 )
179 for(
size_t k = 0; k < c.size(); ++k )
181 R += c[k] * pow( rho, n - 2 * k );
187extern template float zernikeR<float, double>(
float rho,
int n,
int m, std::vector<double> &c );
189extern template double zernikeR<double, double>(
double rho,
int n,
int m, std::vector<double> &c );
191extern template long double
192zernikeR<long double, long double>(
long double rho,
int n,
int m, std::vector<long double> &c );
206template <
typename realT,
typename calcRealT>
215 if( ( n - m ) % 2 > 0 )
220 std::vector<calcRealT> c;
228extern template float zernikeR<float, double>(
float rho,
int n,
int m );
230extern template double zernikeR<double, double>(
double rho,
int n,
int m );
232extern template long double zernikeR<long double, long double>(
long double rho,
int n,
int m );
246template <
typename realT,
typename calcRealT>
251 std::vector<calcRealT> &c
257 if( n == 0 && m == 0 )
278extern template float zernike<float, double>(
float rho,
float phi,
int n,
int m, std::vector<double> &c );
280extern template double zernike<double, double>(
double rho,
double phi,
int n,
int m, std::vector<double> &c );
282extern template long double
283zernike<long double, long double>(
long double rho,
long double phi,
int n,
int m, std::vector<long double> &c );
286extern template __float128
299template <
typename realT,
typename calcRealT>
307 std::vector<calcRealT> c;
315extern template float zernike<float, double>(
float rho,
float phi,
int n,
int m );
317extern template double zernike<double, double>(
double rho,
double phi,
int n,
int m );
319extern template long double zernike<long double, long double>(
long double rho,
long double phi,
int n,
int m );
333template <
typename realT,
typename calcRealT>
348extern template float zernike<float, double>(
float rho,
float phi,
int j );
350extern template double zernike<double, double>(
double rho,
double phi,
int j );
352extern template long double zernike<long double, long double>(
long double rho,
long double phi,
int j );
364template <
typename arrayT,
typename calcRealT,
int overscan = 2>
369 typename arrayT::Scalar xcen,
371 typename arrayT::Scalar ycen,
373 typename arrayT::Scalar rad = -1
377 typedef typename arrayT::Scalar realT;
383 std::vector<calcRealT> c;
388 size_t l0 = arr.rows();
389 size_t l1 = arr.cols();
392 rad = 0.5 * std::min( l0 - 1, l1 - 1 );
394 for(
size_t i = 0; i < l0; ++i )
396 for(
size_t j = 0; j < l1; ++j )
401 r = std::sqrt( x * x + y * y );
404 if( r > rad && r <= rad + ( 1.0 / overscan ) )
411 phi = std::atan2( y, x );
412 arr( i, j ) =
zernike( rho, phi, n, m, c );
430template <
typename arrayT,
typename calcRealT>
435 typename arrayT::Scalar xcen,
436 typename arrayT::Scalar ycen,
437 typename arrayT::Scalar rad = -1
441 typedef typename arrayT::Scalar realT;
458template <
typename arrayT,
typename calcRealT>
464 typename arrayT::Scalar rad = -1
468 typename arrayT::Scalar xcen = 0.5 * ( arr.rows() - 1.0 );
469 typename arrayT::Scalar ycen = 0.5 * ( arr.cols() - 1.0 );
481template <
typename arrayT,
typename calcRealT>
486 typename arrayT::Scalar rad = -1
490 typename arrayT::Scalar xcen = 0.5 * ( arr.rows() - 1.0 );
491 typename arrayT::Scalar ycen = 0.5 * ( arr.cols() - 1.0 );
505template <
typename cubeT,
typename calcRealT>
508 typename cubeT::Scalar rad = -1,
514 typedef typename cubeT::imageT arrayT;
516 typename cubeT::imageT im;
518 im.resize( cube.rows(), cube.cols() );
521 for(
int i = 0; i < cube.planes(); ++i )
529 cube.image( i ) = im;
545template <
typename realT>
554 std::complex<realT> Q;
569 Q = sqrt( n + 1 ) * Q;
573 Q = Q * pow( -1, 0.5 * ( n - m ) ) * pow( std::complex<realT>( { 0, 1 } ), m ) * sqrt( 2 ) * cos( m * phi );
577 Q = Q * pow( -1, 0.5 * ( n + m ) ) * pow( std::complex<realT>( { 0, 1 } ), -m ) * sqrt( 2 ) * sin( -m * phi );
581 Q = Q * pow( -1, 0.5 * n );
597template <
typename realT>
625 realT Q2 = ( n + 1 ) * ( B * B );
629 Q2 = 2 * Q2 * pow( cos( m * phi ), 2 );
633 Q2 = 2 * Q2 * pow( sin( -m * phi ), 2 );
639extern template float zernikeQNorm<float>(
float k,
float phi,
int n,
int m );
641extern template double zernikeQNorm<double>(
double k,
double phi,
int n,
int m );
643extern template long double zernikeQNorm<long double>(
long double k,
long double phi,
int n,
int m );
657template <
typename realT>
680template <
typename arrayT>
689 if( arr.rows() != k.rows() || arr.cols() != k.cols() )
695 if( arr.rows() != phi.rows() || arr.cols() != phi.cols() )
705 for(
size_t i = 0; i < arr.rows(); ++i )
707 for(
size_t j = 0; j < arr.cols(); ++j )
709 arr( i, j ) =
zernikeQNorm( k( i, j ), phi( i, j ), n, m );
716template <
typename realT>
723template <
typename realT>
730template <
typename realT>
737template <
typename realT>
744template <
typename realT>
751template <
typename realT>
768template <
typename realT>
861template <
typename realT>
887template <
typename realT>
981template <
typename realT>
Declares and defines Bessel functions of the first kind.
Declares and defines the factorial function.
@ invalidarg
An argument was invalid.
error_t mxlib_error_report(const error_t &code, const std::string &expl, const std::source_location &loc=std::source_location::current())
Print a report to stderr given an mxlib error_t code and explanation and return the code.
T factorial(T x)
The factorial function.
T2 bessel_j(T1 v, T2 x)
Bessel Functions of the First Kind.
T2 jincN(const T1 &v, const T2 &x)
The JincN function.
T jinc(const T &x)
The Jinc function.
constexpr T pi()
Get the value of pi.
constexpr floatT five_thirds()
Return 5/3 in the specified precision.
constexpr T root_two()
Get the value of sqrt(2).
constexpr T two_pi()
Get the value of 2pi.
constexpr T half_root_three()
Get the value of sqrt(3)/2.
int noll_j(unsigned n, int m)
Get the Noll index j corresponding to Zernike coefficients n,m.
realT zernikeR(realT rho, int n, int m, std::vector< calcRealT > &c)
Calculate the value of a Zernike radial polynomial at a given separation.
realT zernikePPiston(const realT &kD)
Calculate the spatial power spectrum of Piston.
realT zernikeModeDOCDiffKolmogorov(unsigned noll_j)
Get the difference in degrees of correction coefficient for Zernike polynomials in Kolmogorov turbule...
realT zernikePDefocus(const realT &kD)
Calculate the spatial power spectrum of Defocus.
realT zernikePTrefoil(const realT &kD)
Calculate the spatial power spectrum of Trefoil.
realT zernikeModeDOCKolmogorov(unsigned noll_j)
Get the degrees of correction coefficient for Zernike polynomials in Kolmogorov turbulence.
realT zernike(realT rho, realT phi, int n, int m, std::vector< calcRealT > &c)
Calculate the value of a Zernike radial polynomial at a given radius and angle.
int nZernRadOrd(unsigned n)
Get the number of Zernikes up to and including a radial order.
realT zernikePTipTilt(const realT &kD)
Calculate the spatial power spectrum of Tip & Tilt.
int noll_nm(int &n, int &m, int j)
Get the Zernike coefficients n,m corrresponding the Noll index j.
realT zernikeQNorm(realT k, realT phi, int n, int m)
Calculate the square-normed Fourier transform of a Zernike polynomial at position (k,...
std::complex< realT > zernikeQ(realT k, realT phi, int n, int m)
Calculate the square-normed Fourier transform of a Zernike polynomial at position (k,...
realT zernikePAstig(const realT &kD)
Calculate the spatial power spectrum of Astigmatism.
realT zernikePComa(const realT &kD)
Calculate the spatial power spectrum of Coma.
int zernikeRCoeffs(std::vector< realT > &c, int n, int m)
Calculate the coefficients of a Zernike radial polynomial.
int zernikeBasis(cubeT &cube, typename cubeT::Scalar rad=-1, int minj=2)
Fill in an Eigencube-like array with Zernike polynomials in Noll order.
Declares and defines the Jinc and Jinc2 functions.
Declarations of some libarary wide utilities.
Declares and defines the sign function.