mxlib
c++ tools for analyzing astronomical data and other tasks by Jared R. Males. [git repo]
zernike.cpp
Go to the documentation of this file.
1 /** \file zernike.cpp
2  * \author Jared R. Males (jaredmales@gmail.com)
3  * \brief Working with the Zernike polynomials.
4  *
5  * \ingroup signal_processing_files
6  *
7  */
8 
9 //***********************************************************************//
10 // Copyright 2021 Jared R. Males (jaredmales@gmail.com)
11 //
12 // This file is part of mxlib.
13 //
14 // mxlib is free software: you can redistribute it and/or modify
15 // it under the terms of the GNU General Public License as published by
16 // the Free Software Foundation, either version 3 of the License, or
17 // (at your option) any later version.
18 //
19 // mxlib is distributed in the hope that it will be useful,
20 // but WITHOUT ANY WARRANTY; without even the implied warranty of
21 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 // GNU General Public License for more details.
23 //
24 // You should have received a copy of the GNU General Public License
25 // along with mxlib. If not, see <http://www.gnu.org/licenses/>.
26 //***********************************************************************//
27 
28 
29 
30 
31 #include "sigproc/zernike.hpp"
32 
33 namespace mx
34 {
35 namespace sigproc
36 {
37 
38 int noll_nm( int & n,
39  int & m,
40  int j
41  )
42 {
43  if( j < 1)
44  {
45  mxError("noll_nm", MXE_INVALIDARG, "The Noll index j cannot be less than 1 in the Zernike polynomials");
46  return -1;
47  }
48 
49 
50  n = ceil(-1.5 + sqrt(0.25 + 2*j) - 1e-10); // 1e-10 is to avoid wrong rounding due to numerical precision
51 
52  int jrem = j - (n * (n+1)/2+1);
53  m = (jrem + (jrem % 2) * abs( (n % 2)-1) + fabs( (jrem % 2)-1) * (n % 2)) * (-math::func::sign( (j % 2)-0.5));
54 
55  return 0;
56 }
57 
58 int noll_j( unsigned int n,
59  int m
60  )
61 {
62  if( ((n-m) % 2) ) return -1; //Check if odd
63 
64  int mn = n % 4;
65 
66  int dm = 0;
67  if( m >= 0 && (mn == 2 || mn == 3)) dm = 1;
68  else if( m <= 0 && (mn == 0 || mn == 1)) dm = 1;
69 
70  int j = (n*(n+1)) / 2 + abs(m) + dm;
71 
72  return j;
73 }
74 
75 int nZernRadOrd(unsigned int n)
76 {
77  if(n % 2) //odd
78  {
79  return noll_j(n, -n);
80  }
81  else
82  {
83  return noll_j(n, n);
84  }
85 }
86 
87 //Explicit instantiations:
88 template
89 int zernikeRCoeffs<float>( std::vector<float> & c, int n, int m);
90 
91 template
92 int zernikeRCoeffs<double>( std::vector<double> & c, int n, int m);
93 
94 template
95 int zernikeRCoeffs<long double>( std::vector<long double> & c, int n, int m);
96 
97 #ifdef HASQUAD
98 template
99 int zernikeRCoeffs<__float128>( std::vector<__float128> & c, int n, int m);
100 #endif
101 
102 template
103 float zernikeR<float, double>(float rho, int n, int m, std::vector<double> & c);
104 
105 template
106 double zernikeR<double, double>(double rho, int n, int m, std::vector<double> & c);
107 
108 template
109 long double zernikeR<long double, long double>(long double rho, int n, int m, std::vector<long double> & c);
110 
111 #ifdef HASQUAD
112 template
113 __float128 zernikeR<__float128,__float128>(__float128 rho, int n, int m, std::vector<__float128> & c);
114 #endif
115 
116 
117 template
118 float zernikeR<float, double>( float rho, int n, int m);
119 
120 template
121 double zernikeR<double,double>( double rho, int n, int m);
122 
123 template
124 long double zernikeR<long double, long double>( long double rho, int n, int m);
125 
126 #ifdef HASQUAD
127 template
128 __float128 zernikeR<__float128, __float128>( __float128 rho, int n, int m);
129 #endif
130 
131 template
132 float zernike<float,double>(float rho, float phi, int n, int m, std::vector<double> & c);
133 
134 template
135 double zernike<double,double>(double rho, double phi, int n, int m, std::vector<double> & c);
136 
137 template
138 long double zernike<long double, long double>(long double rho, long double phi, int n, int m, std::vector<long double> & c);
139 
140 #ifdef HASQUAD
141 template
142 __float128 zernike<__float128,__float128>(__float128 rho, __float128 phi, int n, int m, std::vector<__float128> & c);
143 #endif
144 
145 template
146 float zernike<float,double>( float rho, float phi, int n, int m);
147 
148 template
149 double zernike<double,double>( double rho, double phi, int n, int m);
150 
151 template
152 long double zernike<long double, long double>( long double rho, long double phi, int n, int m);
153 
154 #ifdef HASQUAD
155 template
156 __float128 zernike<__float128,__float128>( __float128 rho, __float128 phi, int n, int m);
157 #endif
158 
159 
160 template
161 float zernike<float, double>(float rho, float phi, int j);
162 
163 template
164 double zernike<double, double>(double rho, double phi, int j);
165 
166 template
167 long double zernike<long double, long double>(long double rho, long double phi, int j);
168 
169 #ifdef HASQUAD
170 template
171 __float128 zernike<__float128, __float128>(__float128 rho, __float128 phi, int j);
172 #endif
173 
174 template
175 float zernikeQNorm<float>(float k, float phi, int n, int m);
176 
177 template
178 double zernikeQNorm<double>(double k, double phi, int n, int m);
179 
180 template
181 long double zernikeQNorm<long double>(long double k, long double phi, int n, int m);
182 
183 #ifdef HASQUAD
184 template
185 __float128 zernikeQNorm<__float128>(__float128 k, __float128 phi, int n, int m);
186 #endif
187 
188 } //namespace sigproc
189 } //namespace mx
190 
191 
constexpr units::realT c()
The speed of light.
Definition: constants.hpp:60
constexpr units::realT k()
Boltzmann Constant.
Definition: constants.hpp:71
T sign(T x)
The sign function.
Definition: sign.hpp:30
int noll_j(unsigned n, int m)
Get the Noll index j corresponding to Zernike coefficients n,m.
int noll_nm(int &n, int &m, int j)
Get the Zernike coefficients n,m corrresponding the Noll index j.
Definition: zernike.cpp:38
The mxlib c++ namespace.
Definition: mxError.hpp:107
Working with the Zernike polynomials.