Browse Source

psi test initial pass

Konstantin Ladutenko 3 years ago
parent
commit
44788ac391

+ 3 - 23
src/nmie-impl.hpp

@@ -393,18 +393,7 @@ namespace nmie {
                                std::vector<std::complex<FloatType> >& D1,
                                std::vector<std::complex<FloatType> >& D3) {
     evalDownwardD1(z, D1);
-
-
-    // Upward recurrence for PsiZeta and D3 - equations (18a) - (18d)
-    PsiZeta_[0] = static_cast<FloatType>(0.5)*(static_cast<FloatType>(1.0) - std::complex<FloatType>(nmm::cos(2.0*z.real()), nmm::sin(2.0*z.real()))
-                 *static_cast<FloatType>(nmm::exp(-2.0*z.imag())));
-    D3[0] = std::complex<FloatType>(0.0, 1.0);
-    const std::complex<FloatType> zinv = std::complex<FloatType>(1.0, 0.0)/z;
-    for (int n = 1; n <= nmax_; n++) {
-      PsiZeta_[n] = PsiZeta_[n - 1]*(static_cast<FloatType>(n)*zinv - D1[n - 1])
-                                   *(static_cast<FloatType>(n)*zinv - D3[n - 1]);
-      D3[n] = D1[n] + std::complex<FloatType>(0.0, 1.0)/PsiZeta_[n];
-    }
+    evalUpwardD3 (z, D1, D3);
   }
 
 
@@ -424,20 +413,12 @@ namespace nmie {
   void MultiLayerMie<FloatType>::calcPsiZeta(std::complex<FloatType> z,
                                   std::vector<std::complex<FloatType> >& Psi,
                                   std::vector<std::complex<FloatType> >& Zeta) {
-
-    std::complex<FloatType> c_i(0.0, 1.0);
     std::vector<std::complex<FloatType> > D1(nmax_ + 1), D3(nmax_ + 1);
-
     // First, calculate the logarithmic derivatives
     calcD1D3(z, D1, D3);
-
     // Now, use the upward recurrence to calculate Psi and Zeta - equations (20a) - (21b)
-    Psi[0] = std::sin(z);
-    Zeta[0] = std::sin(z) - c_i*std::cos(z);
-    for (int n = 1; n <= nmax_; n++) {
-      Psi[n]  =  Psi[n - 1]*(std::complex<FloatType>(n,0.0)/z - D1[n - 1]);
-      Zeta[n] = Zeta[n - 1]*(std::complex<FloatType>(n,0.0)/z - D3[n - 1]);
-    }
+    evalUpwardPsi(z,  D1, Psi);
+    evalUpwardZeta(z, D3, Zeta);
   }
 
 
@@ -584,7 +565,6 @@ namespace nmie {
 
     an_.resize(nmax_);
     bn_.resize(nmax_);
-    PsiZeta_.resize(nmax_ + 1);
 
     std::vector<std::complex<FloatType> > PsiXL(nmax_ + 1), ZetaXL(nmax_ + 1);
 

+ 0 - 6
src/nmie.hpp

@@ -260,12 +260,6 @@ inline std::complex<T> my_exp(const std::complex<T>& x) {
     std::vector<std::vector< std::complex<FloatType> > > E_, H_;  // {X[], Y[], Z[]}
     std::vector<std::vector< std::complex<FloatType> > > Es_, Hs_;  // {X[], Y[], Z[]}
     std::vector<std::complex<FloatType> > S1_, S2_;
-
-
-    //Temporary variables
-    std::vector<std::complex<FloatType> > PsiZeta_;
-
-
   };  // end of class MultiLayerMie
 
 }  // end of namespace nmie

+ 74 - 31
src/special-functions-impl.hpp

@@ -148,25 +148,6 @@ void convertRtoD1(const std::complex<FloatType> z,
 }
 
 // ********************************************************************** //
-void evalDownwardD1 (const std::complex<FloatType> z,
-               std::vector<std::complex<FloatType> >& D1) {
-  int nmax = D1.size() - 1;
-  // Downward recurrence for D1 - equations (16a) and (16b)
-  D1[nmax] = std::complex<FloatType>(0.0, 0.0);
-  std::complex<FloatType> c_one(1.0, 0.0);
-  const std::complex<FloatType> zinv = std::complex<FloatType>(1.0, 0.0)/z;
-  for (unsigned int n = nmax; n > 0; n--) {
-    D1[n - 1] = static_cast<FloatType>(n)*zinv - c_one/
-        (D1[n] + static_cast<FloatType>(n)*zinv);
-  }
- //   r0 = cot(z)
- D1[0] = complex_cot(z); // - n/mx;
-
-//  printf("D1[0] = (%16.15g, %16.15g) z=(%16.15g,%16.15g)\n", D1[0].real(),D1[0].imag(),
-//         z.real(),z.imag());
-}
-
-// ********************************************************************** //
 void evalForwardD (const std::complex<FloatType> z,
                      std::vector<std::complex<FloatType> >& D) {
   int nmax = D.size();
@@ -185,18 +166,6 @@ void evalForwardD1 (const std::complex<FloatType> z,
   evalForwardD(z,D);
 }
 
-  //**********************************************************************************//
-  // This function calculates the logarithmic derivatives of the Riccati-Bessel       //
-  // functions (D1 and D3) for a complex argument (z).                                //
-  // Equations (16a), (16b) and (18a) - (18d)                                         //
-  //                                                                                  //
-  // Input parameters:                                                                //
-  //   z: Complex argument to evaluate D1 and D3                                      //
-  //   nmax_: Maximum number of terms to calculate D1 and D3                          //
-  //                                                                                  //
-  // Output parameters:                                                               //
-  //   D1, D3: Logarithmic derivatives of the Riccati-Bessel functions                //
-  //**********************************************************************************//
 //  template <typename FloatType>
 //  void MultiLayerMie<FloatType>::calcD1D3(const std::complex<FloatType> z,
 //                               std::vector<std::complex<FloatType> >& D1,
@@ -335,5 +304,79 @@ void evalForwardD1 (const std::complex<FloatType> z,
 //  }  // end of MultiLayerMie::calcSpherHarm(...)
 //
 
+//**********************************************************************************//
+// This functions calculate the logarithmic derivatives of the Riccati-Bessel       //
+// functions (D1 and D3) for a complex argument (z).                                //
+// Equations (16a), (16b) and (18a) - (18d)                                         //
+//                                                                                  //
+// Input parameters:                                                                //
+//   z: Complex argument to evaluate D1 and D3                                      //
+//   nmax_: Maximum number of terms to calculate D1 and D3                          //
+//                                                                                  //
+// Output parameters:                                                               //
+//   D1, D3: Logarithmic derivatives of the Riccati-Bessel functions                //
+//**********************************************************************************//
+void evalDownwardD1 (const std::complex<FloatType> z,
+                     std::vector<std::complex<FloatType> >& D1) {
+  int nmax = D1.size() - 1;
+  // Downward recurrence for D1 - equations (16a) and (16b)
+  D1[nmax] = std::complex<FloatType>(0.0, 0.0);
+  std::complex<FloatType> c_one(1.0, 0.0);
+  const std::complex<FloatType> zinv = std::complex<FloatType>(1.0, 0.0)/z;
+  for (unsigned int n = nmax; n > 0; n--) {
+    D1[n - 1] = static_cast<FloatType>(n)*zinv - c_one/
+        (D1[n] + static_cast<FloatType>(n)*zinv);
+  }
+  // Use D1[0] from upward recurrence
+  D1[0] = complex_cot(z);
+
+//  printf("D1[0] = (%16.15g, %16.15g) z=(%16.15g,%16.15g)\n", D1[0].real(),D1[0].imag(),
+//         z.real(),z.imag());
+}
+
+
+void evalUpwardD3 (const std::complex<FloatType> z,
+                   const std::vector<std::complex<FloatType> >& D1,
+                   std::vector<std::complex<FloatType> >& D3) {
+  int nmax = D1.size()-1;
+  std::vector<std::complex<FloatType> > PsiZeta(nmax+1);
+
+  // Upward recurrence for PsiZeta and D3 - equations (18a) - (18d)
+  PsiZeta[0] = static_cast<FloatType>(0.5)*(static_cast<FloatType>(1.0) - std::complex<FloatType>(nmm::cos(2.0*z.real()), nmm::sin(2.0*z.real()))
+      *static_cast<FloatType>(nmm::exp(-2.0*z.imag())));
+  D3[0] = std::complex<FloatType>(0.0, 1.0);
+  const std::complex<FloatType> zinv = std::complex<FloatType>(1.0, 0.0)/z;
+  for (int n = 1; n <= nmax; n++) {
+    PsiZeta[n] = PsiZeta[n - 1]*(static_cast<FloatType>(n)*zinv - D1[n - 1])
+        *(static_cast<FloatType>(n)*zinv - D3[n - 1]);
+    D3[n] = D1[n] + std::complex<FloatType>(0.0, 1.0)/PsiZeta[n];
+  }
+}
+
+void evalUpwardPsi (const std::complex<FloatType> z,
+                    const std::vector<std::complex<FloatType> > D1,
+                   std::vector<std::complex<FloatType> >& Psi) {
+  int nmax = Psi.size() - 1;
+  std::complex<FloatType> c_i(0.0, 1.0);
+  // Now, use the upward recurrence to calculate Psi and Zeta - equations (20a) - (21b)
+  Psi[0] = std::sin(z);
+  for (int n = 1; n <= nmax; n++) {
+    Psi[n]  =  Psi[n - 1]*(std::complex<FloatType>(n,0.0)/z - D1[n - 1]);
+  }
+}
+
+// Sometimes in literature Zeta is also denoted as Ksi, it is a Riccati-Bessel function of third kind.
+void evalUpwardZeta (const std::complex<FloatType> z,
+                    const std::vector<std::complex<FloatType> > D3,
+                    std::vector<std::complex<FloatType> >& Zeta) {
+  int nmax = Zeta.size() - 1;
+  std::complex<FloatType> c_i(0.0, 1.0);
+  // Now, use the upward recurrence to calculate Zeta and Zeta - equations (20a) - (21b)
+  Zeta[0] = std::sin(z) - c_i*std::cos(z);
+  for (int n = 1; n <= nmax; n++) {
+    Zeta[n]  =  Zeta[n - 1]*(std::complex<FloatType>(n, 0.0)/z - D3[n - 1]);
+  }
+}
+
 }  // end of namespace nmie
 #endif  // SRC_SPECIAL_FUNCTIONS_IMPL_HPP_

+ 46 - 14
tests/mpmath_special_functions_test_generator.py

@@ -68,9 +68,8 @@ class UpdateSpecialFunctionsEvaluations:
         if len(new_record) < 6: raise ValueError('Not enough lines in record:', new_record)
         self.evaluated_data.append(TestData(new_record, self.filetype))
 
-
     def get_file_content(self):
-        self.evaluated_data.sort(key=lambda x: x.testname)#, reverse=True)
+        self.evaluated_data.sort(key=lambda x: x.testname)  # , reverse=True)
         out_string = ''
         for record in self.evaluated_data:
             out_string += record.get_string() + '\n'
@@ -97,6 +96,7 @@ class UpdateSpecialFunctionsEvaluations:
         z_str = ''
         try:
             z = mp.mpf(x) * mp.mpc(mr, mi)
+            if self.is_only_x: z = mp.mpf(x)
             D1nz = func(n, z)
             z_str = ('{{' +
                      mp.nstr(z.real, output_dps * 2) + ',' +
@@ -108,7 +108,7 @@ class UpdateSpecialFunctionsEvaluations:
                      mp.nstr(mp.fabs(D1nz.imag * 10 ** -output_dps), 2) +
                      '},')
             if mp.nstr(D1nz.real, output_dps) == '0.0' \
-                or mp.nstr(D1nz.imag, output_dps) == '0.0':
+                    or mp.nstr(D1nz.imag, output_dps) == '0.0':
                 isNeedMoreDPS = True
         except:
             isNeedMoreDPS = True
@@ -116,8 +116,8 @@ class UpdateSpecialFunctionsEvaluations:
 
     def get_test_data(self, Du_test, output_dps, max_num_elements_of_n_list, func, funcname):
         output_list = ['// complex(z), n, complex(f(n,z)), abs_err_real, abs_err_imag',
-        'std::vector< std::tuple< std::complex<double>, int, std::complex<double>, double, double > >',
-        str(funcname)+'_test_' + str(output_dps) + 'digits','= {']
+                       'std::vector< std::tuple< std::complex<double>, int, std::complex<double>, double, double > >',
+                       str(funcname) + '_test_' + str(output_dps) + 'digits', '= {']
         for z_record in Du_test:
             x = str(z_record[0])
             mr = str(z_record[1][0])
@@ -125,12 +125,12 @@ class UpdateSpecialFunctionsEvaluations:
             mp.mp.dps = 20
             z = mp.mpf(x) * mp.mpc(mr, mi)
             n_list = self.get_n_list(z, max_num_elements_of_n_list)
-            if z_record[4] == 'Yang': n_list = [0,1,30,50,60,70,75,80,85,90,99,116,130]
+            if z_record[4] == 'Yang': n_list = [0, 1, 30, 50, 60, 70, 75, 80, 85, 90, 99, 116, 130]
             print(z, n_list)
             failed_evaluations = 0
             for n in n_list:
                 mp.mp.dps = 20
-                old_z_string, isNeedMoreDPS = self.get_test_data_nlist(z_record, output_dps, n, func,)
+                old_z_string, isNeedMoreDPS = self.get_test_data_nlist(z_record, output_dps, n, func, )
                 mp.mp.dps = 37
                 new_z_string, isNeedMoreDPS = self.get_test_data_nlist(z_record, output_dps, n, func)
                 while old_z_string != new_z_string \
@@ -138,7 +138,7 @@ class UpdateSpecialFunctionsEvaluations:
                     new_dps = int(mp.mp.dps * 1.41)
                     if new_dps > 300: break
                     mp.mp.dps = new_dps
-                    print("New dps = ", mp.mp.dps, 'n =', n, ' (max ',n_list[-1],') for z =', z, '     ', end='')
+                    print("New dps = ", mp.mp.dps, 'n =', n, ' (max ', n_list[-1], ') for z =', z, '     ', end='')
                     old_z_string = new_z_string
                     new_z_string, isNeedMoreDPS = self.get_test_data_nlist(z_record, output_dps, n, func)
 
@@ -147,27 +147,59 @@ class UpdateSpecialFunctionsEvaluations:
                 else:
                     failed_evaluations += 1
                 #     break
-            print("\nFailed evaluations ", failed_evaluations, ' of ', len(n_list))
+            result_str = "All done!"
+            if failed_evaluations > 0: result_str = " FAILED!"
+            print("\n", result_str, "Failed evaluations ", failed_evaluations, ' of ', len(n_list))
         output_list.append('};')
         return output_list
 
-    def run_test(self, func, funcname):
-        out_list_result = self.get_test_data(mia.complex_arguments, self.output_dps,
+    def run_test(self, func, funcname, is_only_x=False):
+        self.is_only_x = is_only_x
+        self.remove_argument_duplicates()
+        out_list_result = self.get_test_data(self.complex_arguments, self.output_dps,
                                              self.max_num_elements_of_nlist,
                                              func, funcname)
-        testname = str(funcname)+'_test_' + str(self.output_dps) + 'digits'
+        testname = str(funcname) + '_test_' + str(self.output_dps) + 'digits'
         self.remove(testname)
         self.add_record(out_list_result)
 
+    def remove_argument_duplicates(self):
+        print("Arguments in input: ", len(self.complex_arguments))
+        mp.mp.dps = 20
+        self.complex_arguments.sort()
+        filtered_list = []
+        filtered_list.append(self.complex_arguments[0])
+        for i in range(1, len(self.complex_arguments)):
+            # if x and m are the same: continue
+            if (filtered_list[-1][0] == self.complex_arguments[i][0] and
+                    filtered_list[-1][1] == self.complex_arguments[i][1]):
+                continue
+            # argument list is sorted, so when only x is needed
+            # the record with the largest m
+            if (self.is_only_x
+                    and filtered_list[-1][0] == self.complex_arguments[i][0]):
+                # continue
+                del filtered_list[-1]
+            filtered_list.append(self.complex_arguments[i])
+        self.complex_arguments = filtered_list
+        # print(self.complex_arguments)
+        print("Arguments after filtering: ", len(self.complex_arguments))
+        # exit(0)
+
 
 def main():
     sf_evals = UpdateSpecialFunctionsEvaluations(filename='test_spec_functions_data.hpp',
                                                  complex_arguments=mia.complex_arguments,
                                                  output_dps=16, max_num_elements_of_nlist=51)
-                                                 # output_dps=5, max_num_elements_of_nlist=3)
+    # output_dps=5, max_num_elements_of_nlist=3)
     # sf_evals.run_test(mrb.D1, 'D1')
     # sf_evals.run_test(mrb.D2, 'D2')
-    sf_evals.run_test(mrb.D3, 'D3')
+    # sf_evals.run_test(mrb.D3, 'D3')
+    # sf_evals.run_test(mrb.psi, 'psi', is_only_x=True)
+    # # In literature Zeta or Ksi denote the Riccati-Bessel function of third kind.
+    sf_evals.run_test(mrb.ksi, 'zeta', is_only_x=True)
+
+    # sf_evals.run_test(mrb.psi, 'psi')
     # sf_evals.run_test(mrb.psi_div_ksi, 'psi_div_ksi')
     # sf_evals.run_test(mrb.psi_mul_ksi, 'psi_mul_ksi')
     # sf_evals.run_test(mrb.psi_div_xi, 'psi_div_xi')

+ 65 - 12
tests/test_Riccati_Bessel_logarithmic_derivative.cc

@@ -47,20 +47,73 @@ int LeRu_cutoff(std::complex<double> z) {
   return std::round(x + 11 * std::pow(x, (1.0 / 3.0)) + 1);
 }
 
+void parse_mpmath_data(const double min_abs_tol, const std::tuple< std::complex<double>, int, std::complex<double>, double, double > data,
+                       std::complex<double> &z, int &n, std::complex<double> &func_mp,
+                       double &re_abs_tol, double &im_abs_tol){
+  z = std::get<0>(data);
+  n = std::get<1>(data);
+  func_mp = std::get<2>(data);
+  re_abs_tol = ( std::get<3>(data) > min_abs_tol && std::real(func_mp) < min_abs_tol)
+                    ? std::get<3>(data) : min_abs_tol;
+  im_abs_tol = ( std::get<4>(data) > min_abs_tol && std::imag(func_mp) < min_abs_tol)
+                    ? std::get<4>(data) : min_abs_tol;
+  // if re(func_mp) < 0.5 then round will give 0. To avoid zero tolerance add one.
+  re_abs_tol *= std::abs(std::round(std::real(func_mp))) + 1;
+  im_abs_tol *= std::abs(std::round(std::imag(func_mp))) + 1;
+}
+
+
+//TEST(psi_test, DISABLED_mpmath_generated_input) {
+TEST(psi_test, mpmath_generated_input) {
+  double min_abs_tol = 2e-11;
+  std::complex<double> z, Psi_mp;
+  int n;
+  double re_abs_tol,  im_abs_tol;
+  for (const auto &data : psi_test_16digits) {
+    parse_mpmath_data(min_abs_tol, data, z, n, Psi_mp, re_abs_tol, im_abs_tol);
+    auto Nstop = LeRu_cutoff(z)+1;
+    if (n > Nstop) continue;
+    std::vector<std::complex<nmie::FloatType>> D1dr(Nstop+35), Psi(Nstop);
+    nmie::evalDownwardD1(z, D1dr);
+    nmie::evalUpwardPsi(z, D1dr, Psi);
+
+    EXPECT_NEAR(std::real(Psi[n]), std::real(Psi_mp), re_abs_tol)
+              << "Psi at n=" << n << " Nstop="<< Nstop<<" z="<<z;
+    EXPECT_NEAR(std::imag(Psi[n]), std::imag(Psi_mp), im_abs_tol)
+              << "Psi at n=" << n << " Nstop="<< Nstop<<" z="<<z;
+
+  }
+}
+
+
+TEST(D3test, mpmath_generated_input) {
+  double min_abs_tol = 2e-11;
+  std::complex<double> z, D3_mp;
+  int n;
+  double re_abs_tol,  im_abs_tol;
+  for (const auto &data : D3_test_16digits) {
+    parse_mpmath_data(min_abs_tol, data, z, n, D3_mp, re_abs_tol, im_abs_tol);
+    auto Nstop = LeRu_cutoff(z)+1;
+    std::vector<std::complex<nmie::FloatType>> D1dr(Nstop+35), D3(Nstop+35);
+    nmie::evalDownwardD1(z, D1dr);
+    nmie::evalUpwardD3(z, D1dr, D3);
+
+    EXPECT_NEAR(std::real(D3[n]), std::real(D3_mp), re_abs_tol)
+              << "D3 at n=" << n << " Nstop="<< Nstop<<" z="<<z;
+    EXPECT_NEAR(std::imag(D3[n]), std::imag(D3_mp), im_abs_tol)
+              << "D3 at n=" << n << " Nstop="<< Nstop<<" z="<<z;
+
+  }
+}
+
 
 TEST(D1test, mpmath_generated_input) {
   double min_abs_tol = 2e-11;
+  std::complex<double> z, D1_mp;
+  int n;
+  double re_abs_tol,  im_abs_tol;
   for (const auto &data : D1_test_16digits) {
-    auto z = std::get<0>(data);
-    auto n = std::get<1>(data);
-    auto D1_mp = std::get<2>(data);
-    auto re_abs_tol = ( std::get<3>(data) > min_abs_tol && std::real(D1_mp) < min_abs_tol)
-        ? std::get<3>(data) : min_abs_tol;
-    auto im_abs_tol = ( std::get<4>(data) > min_abs_tol && std::imag(D1_mp) < min_abs_tol)
-        ? std::get<4>(data) : min_abs_tol;
-    // if re(D1) < 0.5 then round will give 0. To avoid zero tolerance add one.
-    re_abs_tol *= std::abs(std::round(std::real(D1_mp))) + 1;
-    im_abs_tol *= std::abs(std::round(std::imag(D1_mp))) + 1;
+    parse_mpmath_data(min_abs_tol, data, z, n, D1_mp, re_abs_tol, im_abs_tol);
     auto Nstop = LeRu_cutoff(z)+1;
     std::vector<std::complex<nmie::FloatType>> Db(Nstop),Dold(Nstop+35), r;
     int valid_digits = 6;
@@ -76,9 +129,9 @@ TEST(D1test, mpmath_generated_input) {
     nmie::evalDownwardD1(z, Dold);
     if (n > Dold.size()) continue;
     EXPECT_NEAR(std::real(Dold[n]), std::real(D1_mp), re_abs_tol)
-              << "Dold at n=" << n << " Nstop="<< Nstop<<" nstar="<<nstar<< " z="<<z;
+              << "Dold at n=" << n << " Nstop="<< Nstop<< " z="<<z;
     EXPECT_NEAR(std::imag(Dold[n]), std::imag(D1_mp), im_abs_tol)
-              << "Dold at n=" << n << " Nstop="<< Nstop<<" nstar="<<nstar<< " z="<<z;
+              << "Dold at n=" << n << " Nstop="<< Nstop<< " z="<<z;
 
   }
 }

+ 449 - 14
tests/test_spec_functions_data.hpp

@@ -1649,19 +1649,454 @@ D3_test_16digits
 
 // complex(z), n, complex(f(n,z)), abs_err_real, abs_err_imag
 std::vector< std::tuple< std::complex<double>, int, std::complex<double>, double, double > >
-psi_mul_ksi_test_16digits
+psi_test_16digits
 = {
-{{84.0,80.0},0,{0.5,1.624140276402612e-70},5.0e-17,1.6e-86},
-{{84.0,80.0},1,{0.500001811514801,-3.71139617775679e-5},5.0e-17,3.7e-21},
-{{84.0,80.0},30,{0.4999484578754718,-0.01729402460398425},5.0e-17,1.7e-18},
-{{84.0,80.0},50,{0.4956325284553509,-0.04692224582862037},5.0e-17,4.7e-18},
-{{84.0,80.0},60,{0.4897893479849209,-0.0661984546136782},4.9e-17,6.6e-18},
-{{84.0,80.0},70,{0.4803262801451547,-0.08725408858529796},4.8e-17,8.7e-18},
-{{84.0,80.0},75,{0.4740593514549392,-0.09803187176761216},4.7e-17,9.8e-18},
-{{84.0,80.0},80,{0.466738701850348,-0.1087220143709562},4.7e-17,1.1e-17},
-{{84.0,80.0},85,{0.4583908913749478,-0.1191299019766889},4.6e-17,1.2e-17},
-{{84.0,80.0},90,{0.4490824803820364,-0.129071077565662},4.5e-17,1.3e-17},
-{{84.0,80.0},99,{0.4302529666196181,-0.1452856299266772},4.3e-17,1.5e-17},
-{{84.0,80.0},116,{0.3900835621894661,-0.1682281347837009},3.9e-17,1.7e-17},
-{{84.0,80.0},130,{0.355978786440762,-0.1791010472323009},3.6e-17,1.8e-17},
+{{0.055,0.0},0,{0.05497227502706773,0.0},5.5e-18,0.0},
+{{0.055,0.0},1,{0.001008028345451298,0.0},1.0e-19,0.0},
+{{0.055,0.0},2,{1.108927027577585e-5,0.0},1.1e-21,0.0},
+{{0.055,0.0},3,{8.713416468907156e-8,0.0},8.7e-24,0.0},
+{{0.055,0.0},4,{5.325028332528807e-10,0.0},5.3e-26,0.0},
+{{0.055,0.0},5,{2.662570490744701e-12,0.0},2.7e-28,0.0},
+{{0.056,0.0},0,{0.05597073525575547,0.0},5.6e-18,0.0},
+{{0.056,0.0},1,{0.00104500555351332,0.0},1.0e-19,0.0},
+{{0.056,0.0},2,{1.170511102950751e-5,0.0},1.2e-21,0.0},
+{{0.056,0.0},3,{9.364554985109859e-8,0.0},9.4e-24,0.0},
+{{0.056,0.0},4,{5.827018798125993e-10,0.0},5.8e-26,0.0},
+{{0.056,0.0},5,{2.966547354864994e-12,0.0},3.0e-28,0.0},
+{{0.099,0.0},0,{0.09883836273067998,0.0},9.9e-18,0.0},
+{{0.099,0.0},1,{0.003263799133906297,0.0},3.3e-19,0.0},
+{{0.099,0.0},2,{6.464132708660462e-5,0.0},6.5e-21,0.0},
+{{0.099,0.0},3,{9.143553161581762e-7,0.0},9.1e-23,0.0},
+{{0.099,0.0},4,{1.005890437753418e-8,0.0},1.0e-24,0.0},
+{{0.101,0.0},0,{0.100828370729568,0.0},1.0e-17,0.0},
+{{0.101,0.0},1,{0.003396865916775768,0.0},3.4e-19,0.0},
+{{0.101,0.0},2,{6.863669941520236e-5,0.0},6.9e-21,0.0},
+{{0.101,0.0},3,{9.904899174185251e-7,0.0},9.9e-23,0.0},
+{{0.101,0.0},4,{1.111664350730229e-8,0.0},1.1e-24,0.0},
+{{1.0,0.0},0,{0.8414709848078965,0.0},8.4e-17,0.0},
+{{1.0,0.0},1,{0.3011686789397568,0.0},3.0e-17,0.0},
+{{1.0,0.0},2,{0.06203505201137386,0.0},6.2e-18,0.0},
+{{1.0,0.0},3,{0.009006581117112516,0.0},9.0e-19,0.0},
+{{1.0,0.0},4,{0.001011015808413753,0.0},1.0e-19,0.0},
+{{1.0,0.0},5,{9.256115861125816e-5,0.0},9.3e-21,0.0},
+{{1.0,0.0},6,{7.156936310087086e-6,0.0},7.2e-22,0.0},
+{{1.0,0.0},7,{4.790134198739489e-7,0.0},4.8e-23,0.0},
+{{1.0,0.0},8,{2.826498802214729e-8,0.0},2.8e-24,0.0},
+{{1.0,0.0},9,{1.491376502555146e-9,0.0},1.5e-25,0.0},
+{{1.0,0.0},10,{7.116552640047313e-11,0.0},7.1e-27,0.0},
+{{1.0,0.0},11,{3.09955185479008e-12,0.0},3.1e-28,0.0},
+{{1.0,0.0},12,{1.241662596987106e-13,0.0},1.2e-29,0.0},
+{{1.0,0.0},13,{4.604637677683787e-15,0.0},4.6e-31,0.0},
+{{1.0,0.0},14,{1.589575987516976e-16,0.0},1.6e-32,0.0},
+{{1.0,0.0},15,{5.132686115443762e-18,0.0},5.1e-34,0.0},
+{{1.0,0.0},16,{1.556708270590172e-19,0.0},1.6e-35,0.0},
+{{1.0,0.0},17,{4.451177503806802e-21,0.0},4.5e-37,0.0},
+{{1.0,0.0},19,{3.088742363539549e-24,0.0},3.1e-40,0.0},
+{{1.0,0.0},20,{7.537795722236873e-26,0.0},7.5e-42,0.0},
+{{1.0,0.0},22,{3.899361309912283e-29,0.0},3.9e-45,0.0},
+{{1.0,0.0},24,{1.694580173763896e-32,0.0},1.7e-48,0.0},
+{{1.0,0.0},26,{6.273730960048117e-36,0.0},6.3e-52,0.0},
+{{1.0,0.0},28,{2.002424424322351e-39,0.0},2.0e-55,0.0},
+{{1.0,0.0},30,{5.566831266981347e-43,0.0},5.6e-59,0.0},
+{{1.0,0.0},32,{1.360066050758899e-46,0.0},1.4e-62,0.0},
+{{1.0,0.0},35,{4.146142464888971e-52,0.0},4.1e-68,0.0},
+{{1.0,0.0},38,{9.840005687079579e-58,0.0},9.8e-74,0.0},
+{{1.0,0.0},41,{1.853528272155995e-63,0.0},1.9e-79,0.0},
+{{10.0,0.0},0,{-0.5440211108893698,0.0},5.4e-17,0.0},
+{{10.0,0.0},1,{0.7846694179875155,0.0},7.8e-17,0.0},
+{{10.0,0.0},2,{0.7794219362856245,0.0},7.8e-17,0.0},
+{{10.0,0.0},3,{-0.3949584498447032,0.0},3.9e-17,0.0},
+{{10.0,0.0},4,{-1.055892851176917,0.0},1.1e-16,0.0},
+{{10.0,0.0},5,{-0.5553451162145218,0.0},5.6e-17,0.0},
+{{10.0,0.0},6,{0.4450132233409427,0.0},4.5e-17,0.0},
+{{10.0,0.0},7,{1.133862306557747,0.0},1.1e-16,0.0},
+{{10.0,0.0},8,{1.255780236495678,0.0},1.3e-16,0.0},
+{{10.0,0.0},9,{1.000964095484906,0.0},1.0e-16,0.0},
+{{10.0,0.0},10,{0.6460515449256426,0.0},6.5e-17,0.0},
+{{10.0,0.0},11,{0.3557441488589438,0.0},3.6e-17,0.0},
+{{10.0,0.0},12,{0.1721599974499281,0.0},1.7e-17,0.0},
+{{10.0,0.0},13,{0.07465584476587637,0.0},7.5e-18,0.0},
+{{10.0,0.0},14,{0.02941078341793813,0.0},2.9e-18,0.0},
+{{10.0,0.0},16,{0.00355904073510893,0.0},3.6e-19,0.0},
+{{10.0,0.0},17,{0.001109407279715256,0.0},1.1e-19,0.0},
+{{10.0,0.0},18,{0.0003238847438944672,0.0},3.2e-20,0.0},
+{{10.0,0.0},19,{8.896627269427228e-5,0.0},8.9e-21,0.0},
+{{10.0,0.0},21,{5.676977719825934e-6,0.0},5.7e-22,0.0},
+{{10.0,0.0},22,{1.327284582056831e-6,0.0},1.3e-22,0.0},
+{{10.0,0.0},24,{6.298904526324468e-8,0.0},6.3e-24,0.0},
+{{10.0,0.0},26,{2.512408773243373e-9,0.0},2.5e-25,0.0},
+{{10.0,0.0},27,{4.723441380941795e-10,0.0},4.7e-26,0.0},
+{{10.0,0.0},30,{2.512057384998943e-12,0.0},2.5e-28,0.0},
+{{80.0,0.0},0,{-0.9938886539233752,0.0},9.9e-17,0.0},
+{{80.0,0.0},1,{0.09796363566500537,0.0},9.8e-18,0.0},
+{{80.0,0.0},30,{0.9085891506822639,0.0},9.1e-17,0.0},
+{{80.0,0.0},50,{-0.8510856094465454,0.0},8.5e-17,0.0},
+{{80.0,0.0},60,{-0.6405828831301126,0.0},6.4e-17,0.0},
+{{80.0,0.0},70,{-0.9641731454914271,0.0},9.6e-17,0.0},
+{{80.0,0.0},75,{1.681221392899474,0.0},1.7e-16,0.0},
+{{80.0,0.0},80,{1.039376092082608,0.0},1.0e-16,0.0},
+{{80.0,0.0},85,{0.2018445846611147,0.0},2.0e-17,0.0},
+{{80.0,0.0},90,{0.01915014115966514,0.0},1.9e-18,0.0},
+{{80.0,0.0},99,{7.337119877778807e-5,0.0},7.3e-21,0.0},
+{{80.0,0.0},116,{6.387468798952271e-11,0.0},6.4e-27,0.0},
+{{80.0,0.0},130,{4.862998628516291e-17,0.0},4.9e-33,0.0},
+{{100.0,0.0},0,{-0.5063656411097588,0.0},5.1e-17,0.0},
+{{100.0,0.0},1,{-0.8673825286987815,0.0},8.7e-17,0.0},
+{{100.0,0.0},2,{0.4803441652487953,0.0},4.8e-17,0.0},
+{{100.0,0.0},3,{0.8913997369612213,0.0},8.9e-17,0.0},
+{{100.0,0.0},4,{-0.4179461836615099,0.0},4.2e-17,0.0},
+{{100.0,0.0},5,{-0.9290148934907572,0.0},9.3e-17,0.0},
+{{100.0,0.0},6,{0.3157545453775266,0.0},3.2e-17,0.0},
+{{100.0,0.0},7,{0.9700629843898356,0.0},9.7e-17,0.0},
+{{100.0,0.0},8,{-0.1702450977190512,0.0},1.7e-17,0.0},
+{{100.0,0.0},9,{-0.9990046510020743,0.0},1.0e-16,0.0},
+{{100.0,0.0},10,{-0.0195657859713429,0.0},2.0e-18,0.0},
+{{100.0,0.0},12,{0.2483918282394041,0.0},2.5e-17,0.0},
+{{100.0,0.0},14,{-0.5002472555392293,0.0},5.0e-17,0.0},
+{{100.0,0.0},17,{-0.5420601927737344,0.0},5.4e-17,0.0},
+{{100.0,0.0},19,{0.196419721012541,0.0},2.0e-17,0.0},
+{{100.0,0.0},23,{-0.6306580152858614,0.0},6.3e-17,0.0},
+{{100.0,0.0},26,{-0.143891546591607,0.0},1.4e-17,0.0},
+{{100.0,0.0},31,{-0.245348080601665,0.0},2.5e-17,0.0},
+{{100.0,0.0},36,{-0.08022559212383603,0.0},8.0e-18,0.0},
+{{100.0,0.0},42,{-0.7409802829736421,0.0},7.4e-17,0.0},
+{{100.0,0.0},49,{-0.8988354032424621,0.0},9.0e-17,0.0},
+{{100.0,0.0},57,{0.7715080707056898,0.0},7.7e-17,0.0},
+{{100.0,0.0},66,{0.5915705424339723,0.0},5.9e-17,0.0},
+{{100.0,0.0},76,{-0.987829555147092,0.0},9.9e-17,0.0},
+{{100.0,0.0},89,{-1.119551845294465,0.0},1.1e-16,0.0},
+{{100.0,0.0},103,{0.4862349872932045,0.0},4.9e-17,0.0},
+{{100.0,0.0},120,{0.0001044935577431419,0.0},1.0e-20,0.0},
+{{100.0,0.0},140,{2.229243941309043e-11,0.0},2.2e-27,0.0},
+{{100.0,0.0},162,{9.763089067519337e-21,0.0},9.8e-37,0.0},
+{{100.0,0.0},188,{6.861471624173392e-34,0.0},6.9e-50,0.0},
+{{100.0,0.0},219,{5.960550110959533e-52,0.0},6.0e-68,0.0},
+{{100.0,0.0},254,{6.750243200363117e-75,0.0},6.8e-91,0.0},
+{{100.0,0.0},296,{2.077300079982611e-105,0.0},2.1e-121,0.0},
+{{100.0,0.0},343,{8.525637576350521e-143,0.0},8.5e-159,0.0},
+{{100.0,0.0},399,{3.970577452228161e-191,0.0},4.0e-207,0.0},
+{{100.0,0.0},464,{1.275975218077633e-251,0.0},1.3e-267,0.0},
+{{100.0,0.0},539,{2.005718001506372e-326,0.0},2.0e-342,0.0},
+{{100.0,0.0},626,{6.078701921888599e-419,0.0},6.1e-435,0.0},
+{{100.0,0.0},727,{5.501888319350496e-533,0.0},5.5e-549,0.0},
+{{100.0,0.0},844,{9.499262854440157e-673,0.0},9.5e-689,0.0},
+{{100.0,0.0},981,{2.265887828424654e-845,0.0},2.3e-861,0.0},
+{{100.0,0.0},1139,{8.842715022418808e-1055,0.0},8.8e-1071,0.0},
+{{100.0,0.0},1324,{4.668811390736464e-1312,0.0},4.7e-1328,0.0},
+{{100.0,0.0},1537,{3.675773987185818e-1622,0.0},3.7e-1638,0.0},
+{{1000.0,0.0},0,{0.8268795405320026,0.0},8.3e-17,0.0},
+{{1000.0,0.0},1,{-0.561552196750171,0.0},5.6e-17,0.0},
+{{1000.0,0.0},2,{-0.8285641971222531,0.0},8.3e-17,0.0},
+{{1000.0,0.0},3,{0.5574093757645597,0.0},5.6e-17,0.0},
+{{1000.0,0.0},4,{0.832466062752605,0.0},8.3e-17,0.0},
+{{1000.0,0.0},5,{-0.5499171811997863,0.0},5.5e-17,0.0},
+{{1000.0,0.0},6,{-0.8385151517458026,0.0},8.4e-17,0.0},
+{{1000.0,0.0},7,{0.5390164842270908,0.0},5.4e-17,0.0},
+{{1000.0,0.0},9,{-0.5246242774439343,0.0},5.2e-17,0.0},
+{{1000.0,0.0},10,{-0.8565682602806438,0.0},8.6e-17,0.0},
+{{1000.0,0.0},11,{0.5066363439780408,0.0},5.1e-17,0.0},
+{{1000.0,0.0},13,{-0.4849308215732373,0.0},4.8e-17,0.0},
+{{1000.0,0.0},15,{0.4593727147503734,0.0},4.6e-17,0.0},
+{{1000.0,0.0},18,{-0.9105982620053164,0.0},9.1e-17,0.0},
+{{1000.0,0.0},20,{0.9260472258407888,0.0},9.3e-17,0.0},
+{{1000.0,0.0},23,{0.3157941780843729,0.0},3.2e-17,0.0},
+{{1000.0,0.0},27,{0.2175256230184992,0.0},2.2e-17,0.0},
+{{1000.0,0.0},31,{0.1010717270922797,0.0},1.0e-17,0.0},
+{{1000.0,0.0},35,{-0.03281014717791907,0.0},3.3e-18,0.0},
+{{1000.0,0.0},41,{0.2609242061122253,0.0},2.6e-17,0.0},
+{{1000.0,0.0},47,{-0.5066400369537076,0.0},5.1e-17,0.0},
+{{1000.0,0.0},54,{-0.6313512330276828,0.0},6.3e-17,0.0},
+{{1000.0,0.0},62,{-0.2129900416598473,0.0},2.1e-17,0.0},
+{{1000.0,0.0},71,{-0.926462659427137,0.0},9.3e-17,0.0},
+{{1000.0,0.0},81,{0.4047902506937166,0.0},4.0e-17,0.0},
+{{1000.0,0.0},93,{-0.5947534057635428,0.0},5.9e-17,0.0},
+{{1000.0,0.0},107,{0.8923701726937493,0.0},8.9e-17,0.0},
+{{1000.0,0.0},123,{-0.6881373362486023,0.0},6.9e-17,0.0},
+{{1000.0,0.0},141,{-0.005790484710336857,0.0},5.8e-19,0.0},
+{{1000.0,0.0},162,{-1.004341451851323,0.0},1.0e-16,0.0},
+{{1000.0,0.0},186,{0.4243208523362115,0.0},4.2e-17,0.0},
+{{1000.0,0.0},214,{0.8850377283334687,0.0},8.9e-17,0.0},
+{{1000.0,0.0},246,{-0.09666900461099306,0.0},9.7e-18,0.0},
+{{1000.0,0.0},282,{0.3093032076039036,0.0},3.1e-17,0.0},
+{{1000.0,0.0},324,{-0.6574666571444073,0.0},6.6e-17,0.0},
+{{1000.0,0.0},372,{0.909222573405285,0.0},9.1e-17,0.0},
+{{1000.0,0.0},427,{0.9597285605463302,0.0},9.6e-17,0.0},
+{{1000.0,0.0},490,{1.046104365597067,0.0},1.0e-16,0.0},
+{{1000.0,0.0},562,{-0.4772156439441007,0.0},4.8e-17,0.0},
+{{1000.0,0.0},645,{0.7143679947886889,0.0},7.1e-17,0.0},
+{{1000.0,0.0},740,{1.209734186991773,0.0},1.2e-16,0.0},
+{{1000.0,0.0},850,{-1.034435797754064,0.0},1.0e-16,0.0},
+{{10000.0,0.0},0,{-0.3056143888882521,0.0},3.1e-17,0.0},
+{{10000.0,0.0},1,{0.952124806820126,0.0},9.5e-17,0.0},
+{{10000.0,0.0},2,{0.3059000263302982,0.0},3.1e-17,0.0},
+{{10000.0,0.0},3,{-0.9519718568069609,0.0},9.5e-17,0.0},
+{{10000.0,0.0},4,{-0.3065664066300631,0.0},3.1e-17,0.0},
+{{10000.0,0.0},5,{0.9516959470409938,0.0},9.5e-17,0.0},
+{{10000.0,0.0},6,{0.3076132721718081,0.0},3.1e-17,0.0},
+{{10000.0,0.0},8,{-0.3090402162464889,0.0},3.1e-17,0.0},
+{{10000.0,0.0},11,{-0.9501179033904149,0.0},9.5e-17,0.0},
+{{10000.0,0.0},14,{0.315595157092464,0.0},3.2e-17,0.0},
+{{10000.0,0.0},18,{0.3218510506540846,0.0},3.2e-17,0.0},
+{{10000.0,0.0},23,{-0.9433601457445342,0.0},9.4e-17,0.0},
+{{10000.0,0.0},29,{0.9379666478839471,0.0},9.4e-17,0.0},
+{{10000.0,0.0},37,{0.9283397516018927,0.0},9.3e-17,0.0},
+{{10000.0,0.0},48,{-0.4152217424854132,0.0},4.2e-17,0.0},
+{{10000.0,0.0},61,{0.8777422109084248,0.0},8.8e-17,0.0},
+{{10000.0,0.0},78,{0.5799735094103576,0.0},5.8e-17,0.0},
+{{10000.0,0.0},99,{-0.6927046245889522,0.0},6.9e-17,0.0},
+{{10000.0,0.0},126,{0.8960430419640289,0.0},9.0e-17,0.0},
+{{10000.0,0.0},161,{-0.04390438580192674,0.0},4.4e-18,0.0},
+{{10000.0,0.0},205,{-0.7522577756314945,0.0},7.5e-17,0.0},
+{{10000.0,0.0},262,{-0.5766402963422176,0.0},5.8e-17,0.0},
+{{10000.0,0.0},333,{0.9169823827831649,0.0},9.2e-17,0.0},
+{{10000.0,0.0},425,{-0.9986331409734894,0.0},1.0e-16,0.0},
+{{10000.0,0.0},541,{-0.7439210236606826,0.0},7.4e-17,0.0},
+{{10000.0,0.0},690,{-0.8276630796953436,0.0},8.3e-17,0.0},
+{{10000.0,0.0},879,{-0.2559686924018959,0.0},2.6e-17,0.0},
+{{10000.0,0.0},1120,{-0.3161896326121199,0.0},3.2e-17,0.0},
+{{10000.0,0.0},1427,{0.2687936760264434,0.0},2.7e-17,0.0},
+{{10000.0,0.0},1818,{0.3801110903322125,0.0},3.8e-17,0.0},
+{{10000.0,0.0},2316,{0.3363664648717635,0.0},3.4e-17,0.0},
+{{10000.0,0.0},2950,{-0.8588302425401225,0.0},8.6e-17,0.0},
+{{10000.0,0.0},3758,{-0.8541132755119114,0.0},8.5e-17,0.0},
+{{10000.0,0.0},7771,{-1.18058612315672,0.0},1.2e-16,0.0},
+{{10000.0,0.0},9900,{-1.747822111395514,0.0},1.7e-16,0.0},
+{{10000.0,0.0},12612,{7.25197826864343e-541,0.0},7.3e-557,0.0},
+{{10000.0,0.0},16067,{1.369451063257112e-1882,0.0},1.4e-1898,0.0},
+{{10000.0,0.0},20468,{1.387136027206115e-4188,0.0},1.4e-4204,0.0},
+{{10000.0,0.0},26075,{3.402710534773112e-7804,0.0},3.4e-7820,0.0},
+{{10000.0,0.0},33218,{1.467628954663695e-13224,0.0},1.5e-13240,0.0},
+{{10000.0,0.0},42318,{5.445358924275546e-21134,0.0},5.4e-21150,0.0},
+{{10000.0,0.0},53911,{3.266521110728529e-32465,0.0},3.3e-32481,0.0},
+{{10000.0,0.0},68679,{2.775502574785064e-48480,0.0},2.8e-48496,0.0},
+{{10000.0,0.0},87493,{8.914211935647729e-70883,0.0},8.9e-70899,0.0},
+{{10000.0,0.0},111461,{2.619912559375462e-101959,0.0},2.6e-101975,0.0},
+{{10000.0,0.0},141995,{5.82392981843591e-144773,0.0},5.8e-144789,0.0},
+};
+
+// complex(z), n, complex(f(n,z)), abs_err_real, abs_err_imag
+std::vector< std::tuple< std::complex<double>, int, std::complex<double>, double, double > >
+zeta_test_16digits
+= {
+{{0.055,0.0},0,{0.05497227502706773,-0.9984878812375984},5.5e-18,1.0e-16},
+{{0.055,0.0},1,{0.001008028345451298,-18.20929738843795},1.0e-19,1.8e-15},
+{{0.055,0.0},2,{1.108927027577585e-5,-992.2359151244687},1.1e-21,9.9e-14},
+{{0.055,0.0},3,{8.713416468907156e-8,-90185.05571392689},8.7e-24,9.0e-12},
+{{0.055,0.0},4,{5.325028332528807e-10,-11477105.76403921},5.3e-26,1.1e-9},
+{{0.055,0.0},5,{2.662570490744701e-12,-1877981667.241611},2.7e-28,1.9e-7},
+{{0.056,0.0},0,{0.05597073525575547,-0.9984324097278344},5.6e-18,1.0e-16},
+{{0.056,0.0},1,{0.00104500555351332,-17.88512090896708},1.0e-19,1.8e-15},
+{{0.056,0.0},2,{1.170511102950751e-5,-957.1330448563659},1.2e-21,9.6e-14},
+{{0.056,0.0},3,{9.364554985109859e-8,-85440.42245555228},9.4e-24,8.5e-12},
+{{0.056,0.0},4,{5.827018798125993e-10,-10679095.67389918},5.8e-26,1.1e-9},
+{{0.056,0.0},5,{2.966547354864994e-12,-1716197792.88277},3.0e-28,1.7e-7},
+{{0.099,0.0},0,{0.09883836273067998,-0.9951035011759925},9.9e-18,1.0e-16},
+{{0.099,0.0},1,{0.003263799133906297,-10.1503888796599},3.3e-19,1.0e-15},
+{{0.099,0.0},2,{6.464132708660462e-5,-306.5924383066997},6.5e-21,3.1e-14},
+{{0.099,0.0},3,{9.143553161581762e-7,-15474.31619226679},9.1e-23,1.5e-12},
+{{0.099,0.0},4,{1.005890437753418e-8,-1093836.97671187},1.0e-24,1.1e-10},
+{{0.101,0.0},0,{0.100828370729568,-0.9949038343759767},1.0e-17,9.9e-17},
+{{0.101,0.0},1,{0.003396865916775768,-9.951361384353099},3.4e-19,1.0e-15},
+{{0.101,0.0},2,{6.863669941520236e-5,-294.5900877800725},6.9e-21,2.9e-14},
+{{0.101,0.0},3,{9.904899174185251e-7,-14573.71635050042},9.9e-23,1.5e-12},
+{{0.101,0.0},4,{1.111664350730229e-8,-1009764.958956804},1.1e-24,1.0e-10},
+{{1.0,0.0},0,{0.8414709848078965,-0.5403023058681397},8.4e-17,5.4e-17},
+{{1.0,0.0},1,{0.3011686789397568,-1.381773290676036},3.0e-17,1.4e-16},
+{{1.0,0.0},2,{0.06203505201137386,-3.605017566159969},6.2e-18,3.6e-16},
+{{1.0,0.0},3,{0.009006581117112516,-16.64331454012381},9.0e-19,1.7e-15},
+{{1.0,0.0},4,{0.001011015808413753,-112.8981842147067},1.0e-19,1.1e-14},
+{{1.0,0.0},5,{9.256115861125816e-5,-999.4403433922364},9.3e-21,1.0e-13},
+{{1.0,0.0},6,{7.156936310087086e-6,-10880.94559309989},7.2e-22,1.1e-12},
+{{1.0,0.0},7,{4.790134198739489e-7,-140452.8523669064},4.8e-23,1.4e-11},
+{{1.0,0.0},8,{2.826498802214729e-8,-2095911.839910496},2.8e-24,2.1e-10},
+{{1.0,0.0},9,{1.491376502555146e-9,-35490048.42611152},1.5e-25,3.5e-9},
+{{1.0,0.0},10,{7.116552640047313e-11,-672215008.2562084},7.1e-27,6.7e-8},
+{{1.0,0.0},11,{3.09955185479008e-12,-14081025124.95427},3.1e-28,1.4e-6},
+{{1.0,0.0},12,{1.241662596987106e-13,-323191362865.6919},1.2e-29,3.2e-5},
+{{1.0,0.0},13,{4.604637677683787e-15,-8065703046517.343},4.6e-31,0.00081},
+{{1.0,0.0},14,{1.589575987516976e-16,-217450790893102.6},1.6e-32,0.022},
+{{1.0,0.0},15,{5.132686115443762e-18,-6298007232853457.0},5.1e-34,0.63},
+{{1.0,0.0},16,{1.556708270590172e-19,-1.950207734275641e+17},1.6e-35,20.0},
+{{1.0,0.0},17,{4.451177503806802e-21,-6.429387515876761e+18},4.5e-37,6.4e+2},
+{{1.0,0.0},19,{3.088742363539549e-24,-8.312411676927709e+21},3.1e-40,8.3e+5},
+{{1.0,0.0},20,{7.537795722236873e-26,-3.239592218578984e+23},7.5e-42,3.2e+7},
+{{1.0,0.0},22,{3.899361309912283e-29,-5.704587152115091e+26},3.9e-45,5.7e+10},
+{{1.0,0.0},24,{1.694580173763896e-32,-1.205325845219959e+30},1.7e-48,1.2e+14},
+{{1.0,0.0},26,{6.273730960048117e-36,-3.009595435582847e+33},6.3e-52,3.0e+17},
+{{1.0,0.0},28,{2.002424424322351e-39,-8.766714157290797e+36},2.0e-55,8.8e+20},
+{{1.0,0.0},30,{5.566831266981347e-43,-2.946428547496782e+40},5.6e-59,2.9e+24},
+{{1.0,0.0},32,{1.360066050758899e-46,-1.131703135696075e+44},1.4e-62,1.1e+28},
+{{1.0,0.0},35,{4.146142464888971e-52,-3.398364364339443e+49},4.1e-68,3.4e+33},
+{{1.0,0.0},38,{9.840005687079579e-58,-1.320263364413848e+55},9.8e-74,1.3e+39},
+{{1.0,0.0},41,{1.853528272155995e-63,-6.502028762468467e+60},1.9e-79,6.5e+44},
+{{10.0,0.0},0,{-0.5440211108893698,0.8390715290764525},5.4e-17,8.4e-17},
+{{10.0,0.0},1,{0.7846694179875155,0.6279282637970151},7.8e-17,6.3e-17},
+{{10.0,0.0},2,{0.7794219362856245,-0.6506930499373479},7.8e-17,6.5e-17},
+{{10.0,0.0},3,{-0.3949584498447032,-0.953274788765689},3.9e-17,9.5e-17},
+{{10.0,0.0},4,{-1.055892851176917,-0.01659930219863438},1.1e-16,1.7e-18},
+{{10.0,0.0},5,{-0.5553451162145218,0.9383354167869181},5.6e-17,9.4e-17},
+{{10.0,0.0},6,{0.4450132233409427,1.048768260664244},4.5e-17,1.0e-16},
+{{10.0,0.0},7,{1.133862306557747,0.4250633220765995},1.1e-16,4.3e-17},
+{{10.0,0.0},8,{1.255780236495678,-0.4111732775493451},1.3e-16,4.1e-17},
+{{10.0,0.0},9,{1.000964095484906,-1.124057893910486},1.0e-16,1.1e-16},
+{{10.0,0.0},10,{0.6460515449256426,-1.724536720880578},6.5e-17,1.7e-16},
+{{10.0,0.0},11,{0.3557441488589438,-2.497469219938729},3.6e-17,2.5e-16},
+{{10.0,0.0},12,{0.1721599974499281,-4.019642484978498},1.7e-17,4.0e-16},
+{{10.0,0.0},13,{0.07465584476587637,-7.551636992507515},7.5e-18,7.6e-16},
+{{10.0,0.0},14,{0.02941078341793813,-16.36977739479179},2.9e-18,1.6e-15},
+{{10.0,0.0},16,{0.00355904073510893,-107.3844467076131},3.6e-19,1.1e-14},
+{{10.0,0.0},17,{0.001109407279715256,-314.4479566827347},1.1e-19,3.1e-14},
+{{10.0,0.0},18,{0.0003238847438944672,-993.1834016819582},3.2e-20,9.9e-14},
+{{10.0,0.0},19,{8.896627269427228e-5,-3360.330629540511},8.9e-21,3.4e-13},
+{{10.0,0.0},21,{5.676977719825934e-6,-46299.30418991622},5.7e-22,4.6e-12},
+{{10.0,0.0},22,{1.327284582056831e-6,-186974.9019631137},1.3e-22,1.9e-11},
+{{10.0,0.0},24,{6.298904526324468e-8,-3549937.544864135},6.3e-24,3.5e-10},
+{{10.0,0.0},26,{2.512408773243373e-9,-81108054.15260572},2.5e-25,8.1e-9},
+{{10.0,0.0},27,{4.723441380941795e-10,-413273080.7936202},4.7e-26,4.1e-8},
+{{10.0,0.0},30,{2.512057384998943e-12,-69083186460.94516},2.5e-28,6.9e-6},
+{{80.0,0.0},0,{-0.9938886539233752,0.1103872438390476},9.9e-17,1.1e-17},
+{{80.0,0.0},1,{0.09796363566500537,0.9952684944713633},9.8e-18,1.0e-16},
+{{80.0,0.0},30,{0.9085891506822639,-0.5060739517940013},9.1e-17,5.1e-17},
+{{80.0,0.0},50,{-0.8510856094465454,-0.7514741282998871},8.5e-17,7.5e-17},
+{{80.0,0.0},60,{-0.6405828831301126,1.056795272698575},6.4e-17,1.1e-16},
+{{80.0,0.0},70,{-0.9641731454914271,1.082903079393562},9.6e-17,1.1e-16},
+{{80.0,0.0},75,{1.681221392899474,0.2861031097638479},1.7e-16,2.9e-17},
+{{80.0,0.0},80,{1.039376092082608,-2.229727207344475},1.0e-16,2.2e-16},
+{{80.0,0.0},85,{0.2018445846611147,-6.79766591437198},2.0e-17,6.8e-16},
+{{80.0,0.0},90,{0.01915014115966514,-49.68517113491355},1.9e-18,5.0e-15},
+{{80.0,0.0},99,{7.337119877778807e-5,-9222.855138429382},7.3e-21,9.2e-13},
+{{80.0,0.0},116,{6.387468798952271e-11,-7395385511.699251},6.4e-27,7.4e-7},
+{{80.0,0.0},130,{4.862998628516291e-17,-7978214064656749.0},4.9e-33,0.8},
+{{100.0,0.0},0,{-0.5063656411097588,-0.8623188722876839},5.1e-17,8.6e-17},
+{{100.0,0.0},1,{-0.8673825286987815,0.497742452386882},8.7e-17,5.0e-17},
+{{100.0,0.0},2,{0.4803441652487953,0.8772511458592904},4.8e-17,8.8e-17},
+{{100.0,0.0},3,{0.8913997369612213,-0.4538798950939174},8.9e-17,4.5e-17},
+{{100.0,0.0},4,{-0.4179461836615099,-0.9090227385158646},4.2e-17,9.1e-17},
+{{100.0,0.0},5,{-0.9290148934907572,0.3720678486274896},9.3e-17,3.7e-17},
+{{100.0,0.0},6,{0.3157545453775266,0.9499502018648885},3.2e-17,9.5e-17},
+{{100.0,0.0},7,{0.9700629843898356,-0.2485743223850541},9.7e-17,2.5e-17},
+{{100.0,0.0},8,{-0.1702450977190512,-0.9872363502226466},1.7e-17,9.9e-17},
+{{100.0,0.0},9,{-0.9990046510020743,0.0807441428472042},1.0e-16,8.1e-18},
+{{100.0,0.0},10,{-0.0195657859713429,1.002577737363615},2.0e-18,1.0e-16},
+{{100.0,0.0},12,{0.2483918282394041,-0.9727243855038097},2.5e-17,9.7e-17},
+{{100.0,0.0},14,{-0.5002472555392293,0.8720202503425307},5.0e-17,8.7e-17},
+{{100.0,0.0},17,{-0.5420601927737344,-0.8496049309427912},5.4e-17,8.5e-17},
+{{100.0,0.0},19,{0.196419721012541,0.9904419668956676},2.0e-17,9.9e-17},
+{{100.0,0.0},23,{-0.6306580152858614,0.794394952285829},6.3e-17,7.9e-17},
+{{100.0,0.0},26,{-0.143891546591607,-1.008142711740272},1.4e-17,1.0e-16},
+{{100.0,0.0},31,{-0.245348080601665,-0.9967036472620608},2.5e-17,1.0e-16},
+{{100.0,0.0},36,{-0.08022559212383603,-1.033265431104683},8.0e-18,1.0e-16},
+{{100.0,0.0},42,{-0.7409802829736421,-0.7454135574907433},7.4e-17,7.5e-17},
+{{100.0,0.0},49,{-0.8988354032424621,0.5855924676754787},9.0e-17,5.9e-17},
+{{100.0,0.0},57,{0.7715080707056898,0.7917840064320207},7.7e-17,7.9e-17},
+{{100.0,0.0},66,{0.5915705424339723,-0.9943577408622831},5.9e-17,9.9e-17},
+{{100.0,0.0},76,{-0.987829555147092,-0.758958460609405},9.9e-17,7.6e-17},
+{{100.0,0.0},89,{-1.119551845294465,0.9874911064736249},1.1e-16,9.9e-17},
+{{100.0,0.0},103,{0.4862349872932045,-3.932782745345558},4.9e-17,3.9e-16},
+{{100.0,0.0},120,{0.0001044935577431419,-7123.747314608973},1.0e-20,7.1e-13},
+{{100.0,0.0},140,{2.229243941309043e-11,-22728970587.22979},2.2e-27,2.3e-6},
+{{100.0,0.0},162,{9.763089067519337e-21,-3.998455948928182e+19},9.8e-37,4.0e+3},
+{{100.0,0.0},188,{6.861471624173392e-34,-4.560507264377804e+32},6.9e-50,4.6e+16},
+{{100.0,0.0},219,{5.960550110959533e-52,-4.293053043714103e+50},6.0e-68,4.3e+34},
+{{100.0,0.0},254,{6.750243200363117e-75,-3.165039335082101e+73},6.8e-91,3.2e+57},
+{{100.0,0.0},296,{2.077300079982611e-105,-8.62319701238945e+103},2.1e-121,8.6e+87},
+{{100.0,0.0},343,{8.525637576350521e-143,-1.784625319681049e+141},8.5e-159,1.8e+125},
+{{100.0,0.0},399,{3.970577452228161e-191,-3.255744216903431e+189},4.0e-207,3.3e+173},
+{{100.0,0.0},464,{1.275975218077633e-251,-8.638673889350171e+249},1.3e-267,8.6e+233},
+{{100.0,0.0},539,{2.005718001506372e-326,-4.702192956140304e+324},2.0e-342,4.7e+308},
+{{100.0,0.0},626,{6.078701921888599e-419,-1.329971011220177e+417},6.1e-435,1.3e+401},
+{{100.0,0.0},727,{5.501888319350496e-533,-1.261151833780533e+531},5.5e-549,1.3e+515},
+{{100.0,0.0},844,{9.499262854440157e-673,-6.276922570590454e+670},9.5e-689,6.3e+654},
+{{100.0,0.0},981,{2.265887828424654e-845,-2.259993447656205e+843},2.3e-861,2.3e+827},
+{{100.0,0.0},1139,{8.842715022418808e-1055,-4.981370725943817e+1052},8.8e-1071,5.0e+1036},
+{{100.0,0.0},1324,{4.668811390736464e-1312,-8.108733995411389e+1309},4.7e-1328,8.1e+1293},
+{{100.0,0.0},1537,{3.675773987185818e-1622,-8.865977477340542e+1619},3.7e-1638,8.9e+1603},
+{{1000.0,0.0},0,{0.8268795405320026,-0.562379076290703},8.3e-17,5.6e-17},
+{{1000.0,0.0},1,{-0.561552196750171,-0.8274419196082933},5.6e-17,8.3e-17},
+{{1000.0,0.0},2,{-0.8285641971222531,0.5598967505318781},8.3e-17,5.6e-17},
+{{1000.0,0.0},3,{0.5574093757645597,0.8302414033609527},5.6e-17,8.3e-17},
+{{1000.0,0.0},4,{0.832466062752605,-0.5540850607083514},8.3e-17,5.5e-17},
+{{1000.0,0.0},5,{-0.5499171811997863,-0.8352281689073278},5.5e-17,8.4e-17},
+{{1000.0,0.0},6,{-0.8385151517458026,0.5448975508503708},8.4e-17,5.4e-17},
+{{1000.0,0.0},7,{0.5390164842270908,0.8423118370683826},5.4e-17,8.4e-17},
+{{1000.0,0.0},9,{-0.5246242774439343,-0.8513603059143865},5.2e-17,8.5e-17},
+{{1000.0,0.0},10,{-0.8565682602806438,0.5160870274819718},8.6e-17,5.2e-17},
+{{1000.0,0.0},11,{0.5066363439780408,0.8621981334915079},5.1e-17,8.6e-17},
+{{1000.0,0.0},13,{-0.4849308215732373,-0.8746045452517996},4.8e-17,8.7e-17},
+{{1000.0,0.0},15,{0.4593727147503734,0.8883111675348058},4.6e-17,8.9e-17},
+{{1000.0,0.0},18,{-0.9105982620053164,0.4134995149333431},9.1e-17,4.1e-17},
+{{1000.0,0.0},20,{0.9260472258407888,-0.3776858501060111},9.3e-17,3.8e-17},
+{{1000.0,0.0},23,{0.3157941780843729,0.9489732087840213},3.2e-17,9.5e-17},
+{{1000.0,0.0},27,{0.2175256230184992,0.976248337884936},2.2e-17,9.8e-17},
+{{1000.0,0.0},31,{0.1010717270922797,0.9951285718767434},1.0e-17,1.0e-16},
+{{1000.0,0.0},35,{-0.03281014717791907,0.9997770197744073},3.3e-18,1.0e-16},
+{{1000.0,0.0},41,{0.2609242061122253,-0.9658057107645263},2.6e-17,9.7e-17},
+{{1000.0,0.0},47,{-0.5066400369537076,0.8628127163075355},5.1e-17,8.6e-17},
+{{1000.0,0.0},54,{-0.6313512330276828,-0.7764560092822195},6.3e-17,7.8e-17},
+{{1000.0,0.0},62,{-0.2129900416598473,-0.9780562249615457},2.1e-17,9.8e-17},
+{{1000.0,0.0},71,{-0.926462659427137,-0.379779907874921},9.3e-17,3.8e-17},
+{{1000.0,0.0},81,{0.4047902506937166,0.9162327671042002},4.0e-17,9.2e-17},
+{{1000.0,0.0},93,{-0.5947534057635428,0.8066400984512723},5.9e-17,8.1e-17},
+{{1000.0,0.0},107,{0.8923701726937493,0.4577161030388435},8.9e-17,4.6e-17},
+{{1000.0,0.0},123,{-0.6881373362486023,0.7308771114070519},6.9e-17,7.3e-17},
+{{1000.0,0.0},141,{-0.005790484710336857,1.00505240530667},5.8e-19,1.0e-16},
+{{1000.0,0.0},162,{-1.004341451851323,-0.06905501630232919},1.0e-16,6.9e-18},
+{{1000.0,0.0},186,{0.4243208523362115,0.9153196261481822},4.2e-17,9.2e-17},
+{{1000.0,0.0},214,{0.8850377283334687,0.4904474893116481},8.9e-17,4.9e-17},
+{{1000.0,0.0},246,{-0.09666900461099306,1.011184752036795},9.7e-18,1.0e-16},
+{{1000.0,0.0},282,{0.3093032076039036,-0.973033201417064},3.1e-17,9.7e-17},
+{{1000.0,0.0},324,{-0.6574666571444073,0.7905362270426355},6.6e-17,7.9e-17},
+{{1000.0,0.0},372,{0.909222573405285,0.500862067695031},9.1e-17,5.0e-17},
+{{1000.0,0.0},427,{0.9597285605463302,-0.4302284984951585},9.6e-17,4.3e-17},
+{{1000.0,0.0},490,{1.046104365597067,-0.2306282264858935},1.0e-16,2.3e-17},
+{{1000.0,0.0},562,{-0.4772156439441007,0.9908332203529922},4.8e-17,9.9e-17},
+{{1000.0,0.0},645,{0.7143679947886889,0.8938610251077628},7.1e-17,8.9e-17},
+{{1000.0,0.0},740,{1.209734186991773,-0.1565477440422447},1.2e-16,1.6e-17},
+{{1000.0,0.0},850,{-1.034435797754064,-0.9116631948399486},1.0e-16,9.1e-17},
+{{10000.0,0.0},0,{-0.3056143888882521,0.9521553682590149},3.1e-17,9.5e-17},
+{{10000.0,0.0},1,{0.952124806820126,0.305709604425078},9.5e-17,3.1e-17},
+{{10000.0,0.0},2,{0.3059000263302982,-0.9520636553776873},3.1e-17,9.5e-17},
+{{10000.0,0.0},3,{-0.9519718568069609,-0.3061856362527669},9.5e-17,3.1e-17},
+{{10000.0,0.0},4,{-0.3065664066300631,0.9518493254323104},3.1e-17,9.5e-17},
+{{10000.0,0.0},5,{0.9516959470409938,0.307042300645656},9.5e-17,3.1e-17},
+{{10000.0,0.0},6,{0.3076132721718081,-0.9515115789016002},3.1e-17,9.5e-17},
+{{10000.0,0.0},8,{-0.3090402162464889,0.9510491600030528},3.1e-17,9.5e-17},
+{{10000.0,0.0},11,{-0.9501179033904149,-0.3118920160210031},9.5e-17,3.1e-17},
+{{10000.0,0.0},14,{0.315595157092464,-0.9488944866640447},3.2e-17,9.5e-17},
+{{10000.0,0.0},18,{0.3218510506540846,-0.946791218377749},3.2e-17,9.5e-17},
+{{10000.0,0.0},23,{-0.9433601457445342,-0.3317746154126867},9.4e-17,3.3e-17},
+{{10000.0,0.0},29,{0.9379666478839471,0.3467317659022176},9.4e-17,3.5e-17},
+{{10000.0,0.0},37,{0.9283397516018927,0.3717422973913016},9.3e-17,3.7e-17},
+{{10000.0,0.0},48,{-0.4152217424854132,0.9097266978464748},4.2e-17,9.1e-17},
+{{10000.0,0.0},61,{0.8777422109084248,0.4791529210238686},8.8e-17,4.8e-17},
+{{10000.0,0.0},78,{0.5799735094103576,-0.8146542455580336},5.8e-17,8.1e-17},
+{{10000.0,0.0},99,{-0.6927046245889522,-0.7212557152272793},6.9e-17,7.2e-17},
+{{10000.0,0.0},126,{0.8960430419640289,-0.44405730097627},9.0e-17,4.4e-17},
+{{10000.0,0.0},161,{-0.04390438580192674,0.9991010161245437},4.4e-18,1.0e-16},
+{{10000.0,0.0},205,{-0.7522577756314945,0.659029176819063},7.5e-17,6.6e-17},
+{{10000.0,0.0},262,{-0.5766402963422176,0.8172090777658204},5.8e-17,8.2e-17},
+{{10000.0,0.0},333,{0.9169823827831649,-0.3996246788860864},9.2e-17,4.0e-17},
+{{10000.0,0.0},425,{-0.9986331409734894,0.06031857764924985},1.0e-16,6.0e-18},
+{{10000.0,0.0},541,{-0.7439210236606826,0.6693660079881031},7.4e-17,6.7e-17},
+{{10000.0,0.0},690,{-0.8276630796953436,-0.5633527627627941},8.3e-17,5.6e-17},
+{{10000.0,0.0},879,{-0.2559686924018959,-0.9686951076386396},2.6e-17,9.7e-17},
+{{10000.0,0.0},1120,{-0.3161896326121199,0.9520301748728291},3.2e-17,9.5e-17},
+{{10000.0,0.0},1427,{0.2687936760264434,-0.9685541537392371},2.7e-17,9.7e-17},
+{{10000.0,0.0},1818,{0.3801110903322125,0.9340620975427486},3.8e-17,9.3e-17},
+{{10000.0,0.0},2316,{0.3363664648717635,0.9564616952166914},3.4e-17,9.6e-17},
+{{10000.0,0.0},2950,{-0.8588302425401225,-0.555880388869997},8.6e-17,5.6e-17},
+{{10000.0,0.0},3758,{-0.8541132755119114,-0.591279183531158},8.5e-17,5.9e-17},
+{{10000.0,0.0},7771,{-1.18058612315672,-0.4418649322239787},1.2e-16,4.4e-17},
+{{10000.0,0.0},9900,{-1.747822111395514,2.011491146878234},1.7e-16,2.0e-16},
+{{10000.0,0.0},12612,{7.25197826864343e-541,-8.970385150483627e+539},7.3e-557,9.0e+523},
+{{10000.0,0.0},16067,{1.369451063257112e-1882,-2.90314618431218e+1881},1.4e-1898,2.9e+1865},
+{{10000.0,0.0},20468,{1.387136027206115e-4188,-2.018288229524841e+4187},1.4e-4204,2.0e+4171},
+{{10000.0,0.0},26075,{3.402710534773112e-7804,-6.101780411131719e+7802},3.4e-7820,6.1e+7786},
+{{10000.0,0.0},33218,{1.467628954663695e-13224,-1.075478687761038e+13223},1.5e-13240,1.1e+13207},
+{{10000.0,0.0},42318,{5.445358924275546e-21134,-2.233007868840026e+21132},5.4e-21150,2.2e+21116},
+{{10000.0,0.0},53911,{3.266521110728529e-32465,-2.889388190778695e+32463},3.3e-32481,2.9e+32447},
+{{10000.0,0.0},68679,{2.775502574785064e-48480,-2.651272528165235e+48478},2.8e-48496,2.7e+48462},
+{{10000.0,0.0},87493,{8.914211935647729e-70883,-6.453073029871699e+70880},8.9e-70899,6.5e+70864},
+{{10000.0,0.0},111461,{2.619912559375462e-101959,-1.71914792791431e+101957},2.6e-101975,1.7e+101941},
+{{10000.0,0.0},141995,{5.82392981843591e-144773,-6.061204591967546e+144770},5.8e-144789,6.1e+144754},
 };