|  | @@ -56,11 +56,9 @@
 | 
											
												
													
														|  |  #include "nmie-precision.hpp"
 |  |  #include "nmie-precision.hpp"
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  namespace nmie {
 |  |  namespace nmie {
 | 
											
												
													
														|  | -////helper functions
 |  | 
 | 
											
												
													
														|  | -//template<class T> inline T pow2(const T value) {return value*value;}
 |  | 
 | 
											
												
													
														|  | -
 |  | 
 | 
											
												
													
														|  |  // Note, that Kapteyn seems to be too optimistic (at least by 3 digits
 |  |  // Note, that Kapteyn seems to be too optimistic (at least by 3 digits
 | 
											
												
													
														|  |  // in some cases) for forward recurrence, see D1test with WYang_data
 |  |  // in some cases) for forward recurrence, see D1test with WYang_data
 | 
											
												
													
														|  | 
 |  | +template <typename FloatType>
 | 
											
												
													
														|  |  int evalKapteynNumberOfLostSignificantDigits(const int ni,
 |  |  int evalKapteynNumberOfLostSignificantDigits(const int ni,
 | 
											
												
													
														|  |                                               const std::complex<FloatType> zz) {
 |  |                                               const std::complex<FloatType> zz) {
 | 
											
												
													
														|  |    using std::abs;  using std::imag; using std::real; using std::log; using std::sqrt; using std::round;
 |  |    using std::abs;  using std::imag; using std::real; using std::log; using std::sqrt; using std::round;
 | 
											
										
											
												
													
														|  | @@ -74,6 +72,7 @@ int evalKapteynNumberOfLostSignificantDigits(const int ni,
 | 
											
												
													
														|  |        )))/ log(10.));
 |  |        )))/ log(10.));
 | 
											
												
													
														|  |  }
 |  |  }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | 
 |  | +template <typename FloatType>
 | 
											
												
													
														|  |  int getNStar(int nmax, std::complex<FloatType> z, const int valid_digits) {
 |  |  int getNStar(int nmax, std::complex<FloatType> z, const int valid_digits) {
 | 
											
												
													
														|  |    if (nmax == 0) nmax = 1;
 |  |    if (nmax == 0) nmax = 1;
 | 
											
												
													
														|  |    int nstar = nmax;
 |  |    int nstar = nmax;
 | 
											
										
											
												
													
														|  | @@ -92,8 +91,8 @@ int getNStar(int nmax, std::complex<FloatType> z, const int valid_digits) {
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  // Custom implementation of complex cot function to avoid overflow
 |  |  // Custom implementation of complex cot function to avoid overflow
 | 
											
												
													
														|  |  // if Im(z) < 0, then it evaluates cot(z) as conj(cot(conj(z)))
 |  |  // if Im(z) < 0, then it evaluates cot(z) as conj(cot(conj(z)))
 | 
											
												
													
														|  | -const std::complex<FloatType>
 |  | 
 | 
											
												
													
														|  | -complex_cot(const std::complex<FloatType> z) {
 |  | 
 | 
											
												
													
														|  | 
 |  | +template <typename FloatType>
 | 
											
												
													
														|  | 
 |  | +std::complex<FloatType> complex_cot(const std::complex<FloatType> z) {
 | 
											
												
													
														|  |    auto Remx = z.real();
 |  |    auto Remx = z.real();
 | 
											
												
													
														|  |    auto Immx = z.imag();
 |  |    auto Immx = z.imag();
 | 
											
												
													
														|  |    int sign = (Immx>0) ? 1: -1; // use complex conj if needed for exp and return
 |  |    int sign = (Immx>0) ? 1: -1; // use complex conj if needed for exp and return
 | 
											
										
											
												
													
														|  | @@ -109,6 +108,7 @@ complex_cot(const std::complex<FloatType> z) {
 | 
											
												
													
														|  |  }
 |  |  }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  // Forward iteration for evaluation of ratio of the Riccati–Bessel functions
 |  |  // Forward iteration for evaluation of ratio of the Riccati–Bessel functions
 | 
											
												
													
														|  | 
 |  | +template <typename FloatType>
 | 
											
												
													
														|  |  void evalForwardR (const std::complex<FloatType> z,
 |  |  void evalForwardR (const std::complex<FloatType> z,
 | 
											
												
													
														|  |                     std::vector<std::complex<FloatType> >& r) {
 |  |                     std::vector<std::complex<FloatType> >& r) {
 | 
											
												
													
														|  |    if (r.size() < 1) throw std::invalid_argument(
 |  |    if (r.size() < 1) throw std::invalid_argument(
 | 
											
										
											
												
													
														|  | @@ -123,6 +123,7 @@ void evalForwardR (const std::complex<FloatType> z,
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  // Backward iteration for evaluation of ratio of the Riccati–Bessel functions
 |  |  // Backward iteration for evaluation of ratio of the Riccati–Bessel functions
 | 
											
												
													
														|  | 
 |  | +template <typename FloatType>
 | 
											
												
													
														|  |  void evalBackwardR (const std::complex<FloatType> z,
 |  |  void evalBackwardR (const std::complex<FloatType> z,
 | 
											
												
													
														|  |                     std::vector<std::complex<FloatType> >& r) {
 |  |                     std::vector<std::complex<FloatType> >& r) {
 | 
											
												
													
														|  |    if (r.size() < 1) throw std::invalid_argument(
 |  |    if (r.size() < 1) throw std::invalid_argument(
 | 
											
										
											
												
													
														|  | @@ -137,6 +138,7 @@ void evalBackwardR (const std::complex<FloatType> z,
 | 
											
												
													
														|  |  //  nmm::cout << "R0 = " << r[0] <<" at arg = "<<z<<'\n';
 |  |  //  nmm::cout << "R0 = " << r[0] <<" at arg = "<<z<<'\n';
 | 
											
												
													
														|  |  }
 |  |  }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | 
 |  | +template <typename FloatType>
 | 
											
												
													
														|  |  void convertRtoD1(const std::complex<FloatType> z,
 |  |  void convertRtoD1(const std::complex<FloatType> z,
 | 
											
												
													
														|  |                    std::vector<std::complex<FloatType> >& r,
 |  |                    std::vector<std::complex<FloatType> >& r,
 | 
											
												
													
														|  |                    std::vector<std::complex<FloatType> >& D1) {
 |  |                    std::vector<std::complex<FloatType> >& D1) {
 | 
											
										
											
												
													
														|  | @@ -151,6 +153,7 @@ void convertRtoD1(const std::complex<FloatType> z,
 | 
											
												
													
														|  |  }
 |  |  }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  // ********************************************************************** //
 |  |  // ********************************************************************** //
 | 
											
												
													
														|  | 
 |  | +template <typename FloatType>
 | 
											
												
													
														|  |  void evalForwardD (const std::complex<FloatType> z,
 |  |  void evalForwardD (const std::complex<FloatType> z,
 | 
											
												
													
														|  |                       std::vector<std::complex<FloatType> >& D) {
 |  |                       std::vector<std::complex<FloatType> >& D) {
 | 
											
												
													
														|  |    int nmax = D.size();
 |  |    int nmax = D.size();
 | 
											
										
											
												
													
														|  | @@ -162,6 +165,7 @@ void evalForwardD (const std::complex<FloatType> z,
 | 
											
												
													
														|  |  }
 |  |  }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  // ********************************************************************** //
 |  |  // ********************************************************************** //
 | 
											
												
													
														|  | 
 |  | +template <typename FloatType>
 | 
											
												
													
														|  |  void evalForwardD1 (const std::complex<FloatType> z,
 |  |  void evalForwardD1 (const std::complex<FloatType> z,
 | 
											
												
													
														|  |                     std::vector<std::complex<FloatType> >& D) {
 |  |                     std::vector<std::complex<FloatType> >& D) {
 | 
											
												
													
														|  |    if (D.size()<1) throw std::invalid_argument("Should have a leas one element!\n");
 |  |    if (D.size()<1) throw std::invalid_argument("Should have a leas one element!\n");
 | 
											
										
											
												
													
														|  | @@ -319,6 +323,7 @@ void evalForwardD1 (const std::complex<FloatType> z,
 | 
											
												
													
														|  |  // Output parameters:                                                               //
 |  |  // Output parameters:                                                               //
 | 
											
												
													
														|  |  //   D1, D3: Logarithmic derivatives of the Riccati-Bessel functions                //
 |  |  //   D1, D3: Logarithmic derivatives of the Riccati-Bessel functions                //
 | 
											
												
													
														|  |  //**********************************************************************************//
 |  |  //**********************************************************************************//
 | 
											
												
													
														|  | 
 |  | +template <typename FloatType>
 | 
											
												
													
														|  |  void evalDownwardD1 (const std::complex<FloatType> z,
 |  |  void evalDownwardD1 (const std::complex<FloatType> z,
 | 
											
												
													
														|  |                       std::vector<std::complex<FloatType> >& D1) {
 |  |                       std::vector<std::complex<FloatType> >& D1) {
 | 
											
												
													
														|  |    int nmax = D1.size() - 1;
 |  |    int nmax = D1.size() - 1;
 | 
											
										
											
												
													
														|  | @@ -344,6 +349,7 @@ void evalDownwardD1 (const std::complex<FloatType> z,
 | 
											
												
													
														|  |  }
 |  |  }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | 
 |  | +template <typename FloatType>
 | 
											
												
													
														|  |  void evalUpwardD3 (const std::complex<FloatType> z,
 |  |  void evalUpwardD3 (const std::complex<FloatType> z,
 | 
											
												
													
														|  |                     const std::vector<std::complex<FloatType> >& D1,
 |  |                     const std::vector<std::complex<FloatType> >& D1,
 | 
											
												
													
														|  |                     std::vector<std::complex<FloatType> >& D3,
 |  |                     std::vector<std::complex<FloatType> >& D3,
 | 
											
										
											
												
													
														|  | @@ -362,6 +368,7 @@ void evalUpwardD3 (const std::complex<FloatType> z,
 | 
											
												
													
														|  |  }
 |  |  }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | 
 |  | +template <typename FloatType>
 | 
											
												
													
														|  |  void evalUpwardPsi (const std::complex<FloatType> z,
 |  |  void evalUpwardPsi (const std::complex<FloatType> z,
 | 
											
												
													
														|  |                      const std::vector<std::complex<FloatType> > D1,
 |  |                      const std::vector<std::complex<FloatType> > D1,
 | 
											
												
													
														|  |                     std::vector<std::complex<FloatType> >& Psi) {
 |  |                     std::vector<std::complex<FloatType> >& Psi) {
 | 
											
										
											
												
													
														|  | @@ -374,6 +381,7 @@ void evalUpwardPsi (const std::complex<FloatType> z,
 | 
											
												
													
														|  |  }
 |  |  }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  // Sometimes in literature Zeta is also denoted as Ksi, it is a Riccati-Bessel function of third kind.
 |  |  // Sometimes in literature Zeta is also denoted as Ksi, it is a Riccati-Bessel function of third kind.
 | 
											
												
													
														|  | 
 |  | +template <typename FloatType>
 | 
											
												
													
														|  |  void evalUpwardZeta (const std::complex<FloatType> z,
 |  |  void evalUpwardZeta (const std::complex<FloatType> z,
 | 
											
												
													
														|  |                      const std::vector<std::complex<FloatType> > D3,
 |  |                      const std::vector<std::complex<FloatType> > D3,
 | 
											
												
													
														|  |                      std::vector<std::complex<FloatType> >& Zeta) {
 |  |                      std::vector<std::complex<FloatType> >& Zeta) {
 |