You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

ABACUS_Integ.h 9.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330
  1. /**********************************************************
  2. This software is part of J.-S. Caux's ABACUS library.
  3. Copyright (c) J.-S. Caux.
  4. -----------------------------------------------------------
  5. File: ABACUS_Integ.h
  6. Purpose: Declares combinatorics-related classes and functions.
  7. ***********************************************************/
  8. #ifndef ABACUS_INTEG_H
  9. #define ABACUS_INTEG_H
  10. #include "ABACUS.h"
  11. namespace ABACUS {
  12. //********************** Class Domain ************************
  13. template<class T>
  14. class Domain {
  15. private:
  16. Vect<T> bdry;
  17. public:
  18. Domain () : bdry(Vect<T>(2))
  19. {
  20. bdry[0] = T(0);
  21. bdry[1] = T(0);
  22. }
  23. public:
  24. Domain (T xmin_ref, T xmax_ref) : bdry(Vect<T>(2))
  25. {
  26. if (xmax_ref < xmin_ref) ABACUSerror("Use xmax > xmin in Domain.");
  27. bdry[0] = xmin_ref;
  28. bdry[1] = xmax_ref;
  29. }
  30. public:
  31. inline T xmin (int i)
  32. {
  33. if (i > bdry.size()/2) ABACUSerror("i index too high in Domain::xmin.");
  34. return(bdry[2*i]);
  35. }
  36. public:
  37. inline T xmax (int i)
  38. {
  39. if (i > bdry.size()/2) ABACUSerror("i index too high in Domain::xmax.");
  40. return(bdry[2*i + 1]);
  41. }
  42. public:
  43. inline int Ndomains ()
  44. {
  45. return(bdry.size()/2);
  46. }
  47. public:
  48. void Include (T xmin_ref, T xmax_ref) {
  49. // Determine the indices of xmin_ref & xmax_ref
  50. int xmin_reg = -1;
  51. int xmax_reg = -1;
  52. for (int i = 0; i < bdry.size(); ++i) {
  53. if ((i+1) % 2 && bdry[i] <= xmin_ref) xmin_reg++;
  54. if (i % 2 && bdry[i] < xmin_ref) xmin_reg++;
  55. if ((i+1) % 2 && bdry[i] <= xmax_ref) xmax_reg++;
  56. if (i % 2 && bdry[i] < xmax_ref) xmax_reg++;
  57. }
  58. Vect<T> new_bdry(bdry.size() + 2 * ((xmin_reg % 2 && xmax_reg % 2) - (xmax_reg - xmin_reg)/2));
  59. int ishift = 0;
  60. for (int i = 0; i <= xmin_reg; ++i) new_bdry[i] = bdry[i];
  61. if (xmin_reg % 2) {
  62. new_bdry[xmin_reg + 1] = xmin_ref;
  63. ishift++;
  64. if (xmax_reg % 2) {
  65. new_bdry[xmin_reg + 2] = xmax_ref;
  66. ishift++;
  67. }
  68. }
  69. else if ((xmin_reg + 1) % 2 && xmax_reg % 2) {
  70. new_bdry[xmin_reg + 1] = xmax_ref;
  71. ishift++;
  72. }
  73. for (int i = xmin_reg + ishift + 1; i < new_bdry.size(); ++i)
  74. new_bdry[i] = bdry[xmax_reg - xmin_reg - ishift + i];
  75. bdry = new_bdry;
  76. return;
  77. }
  78. public:
  79. void Exclude (T xmin_ref, T xmax_ref) {
  80. // Determine the indices of xmin_ref & xmax_ref
  81. int xmin_reg = -1;
  82. int xmax_reg = -1;
  83. for (int i = 0; i < bdry.size(); ++i) {
  84. if ((i+1) % 2 && bdry[i] <= xmin_ref) xmin_reg++;
  85. if (i % 2 && bdry[i] < xmin_ref) xmin_reg++;
  86. if ((i+1) % 2 && bdry[i] <= xmax_ref) xmax_reg++;
  87. if (i % 2 && bdry[i] < xmax_ref) xmax_reg++;
  88. }
  89. Vect<T> new_bdry(bdry.size() + 2 * (((xmin_reg + 1) % 2 && (xmax_reg + 1) % 2) - (xmax_reg - xmin_reg)/2));
  90. int ishift = 0;
  91. for (int i = 0; i <= xmin_reg; ++i) new_bdry[i] = bdry[i];
  92. if ((xmin_reg + 1) % 2) {
  93. new_bdry[xmin_reg + 1] = xmin_ref;
  94. ishift++;
  95. if ((xmax_reg + 1) % 2) {
  96. new_bdry[xmin_reg + 2] = xmax_ref;
  97. ishift++;
  98. }
  99. }
  100. else if (xmin_reg % 2 && (xmax_reg + 1) % 2) {
  101. new_bdry[xmin_reg + 1] = xmax_ref;
  102. ishift++;
  103. }
  104. for (int i = xmin_reg + ishift + 1; i < new_bdry.size(); ++i)
  105. new_bdry[i] = bdry[xmax_reg - xmin_reg - ishift + i];
  106. bdry = new_bdry;
  107. return;
  108. }
  109. };
  110. template<class T>
  111. std::ostream& operator<< (std::ostream& s, Domain<T> dom)
  112. {
  113. for (int i = 0; i < dom.Ndomains(); ++i) {
  114. if (i > 0) s << std::endl;
  115. s << dom.xmin(i) << "\t" << dom.xmax(i);
  116. }
  117. return(s);
  118. }
  119. // ********************************* struct I_table ************************
  120. struct I_table {
  121. DP (*function) (DP, DP);
  122. int Nvals;
  123. DP rhomin;
  124. DP rhomax;
  125. DP alpha;
  126. DP logalpha;
  127. DP prec;
  128. DP* rho_tbl;
  129. DP* I_tbl;
  130. I_table (DP (*function) (DP, DP), DP rhomin_ref, DP rhomax_ref, int Nvals_ref, DP req_prec);
  131. DP Return_val (DP req_rho);
  132. void Save ();
  133. bool Load (DP rhomin_ref, DP rhomax_ref, int Nvals_ref, DP req_prec);
  134. };
  135. // ********************************* struct Integral_table ************************
  136. struct Integral_table {
  137. DP (*function) (DP, DP, int);
  138. int Nvals;
  139. DP rhomin;
  140. DP rhomax;
  141. DP alpha;
  142. DP logalpha;
  143. DP prec;
  144. int maxnrpts;
  145. DP* rho_tbl;
  146. DP* I_tbl;
  147. Integral_table (DP (*function) (DP, DP, int), const char* filenameprefix_ref, DP rhomin_ref,
  148. DP rhomax_ref, int Nvals_ref, DP req_prec, int max_nr_pts);
  149. DP Return_val (DP req_rho);
  150. void Save (const char* filenameprefix);
  151. bool Load (const char* filenameprefix, DP rhomin_ref, DP rhomax_ref, int Nvals_ref, DP req_prec, int max_nr_pts);
  152. };
  153. // ******************************** Recursive integration functions ******************************
  154. DP Integrate_Riemann (DP (*function) (Vect_DP), Vect_DP& args, int arg_to_integ, DP xmin, DP xmax, int Npts);
  155. DP Integrate_Riemann_using_table (DP (*function) (Vect_DP, I_table), Vect_DP& args, int arg_to_integ, I_table Itable,
  156. DP xmin, DP xmax, int Npts);
  157. DP Integrate_rec (DP (*function) (Vect_DP), Vect_DP& args, int arg_to_integ, DP xmin, DP xmax, DP req_prec, int max_rec_level);
  158. DP Integrate_rec_using_table (DP (*function) (Vect_DP, I_table), Vect_DP& args, int arg_to_integ, I_table Itable,
  159. DP xmin, DP xmax, DP req_prec, int max_rec_level);
  160. DP Integrate_rec_using_table (DP (*function) (Vect_DP, I_table), Vect_DP& args, int arg_to_integ, I_table Itable,
  161. DP xmin, DP xmax, DP req_prec, int max_rec_level, std::ofstream& outfile);
  162. DP Integrate_rec_using_table_and_file (DP (*function) (Vect_DP, I_table, std::ofstream&), Vect_DP& args,
  163. int arg_to_integ, I_table Itable,
  164. DP xmin, DP xmax, DP req_prec, int max_rec_level, std::ofstream& outfile);
  165. // ******************************** Recursive version: optimal ******************************
  166. struct data_pt {
  167. DP x;
  168. DP f;
  169. DP dx;
  170. };
  171. struct Integral_result {
  172. DP integ_est;
  173. DP abs_prec;
  174. DP rel_prec;
  175. int n_vals;
  176. };
  177. std::ostream& operator<< (std::ostream& s, const Integral_result& res);
  178. class Integral_data {
  179. private:
  180. data_pt* data;
  181. DP* abs_d2f_dx; // second derivative * dx
  182. DP max_abs_d2f_dx; //
  183. public:
  184. Integral_result integ_res;
  185. public:
  186. DP xmin;
  187. DP xmax;
  188. public:
  189. Integral_data (DP (*function_ref) (Vect_DP), Vect_DP& args, int arg_to_integ_ref, DP xmin_ref, DP xmax_ref);
  190. Integral_data (DP (*function_ref) (Vect_DP, I_table), Vect_DP& args, int arg_to_integ_ref,
  191. I_table Itable, DP xmin_ref, DP xmax_ref);
  192. Integral_data (DP (*function_ref) (Vect_DP, Integral_table), Vect_DP& args, int arg_to_integ_ref,
  193. Integral_table Itable, DP xmin_ref, DP xmax_ref);
  194. void Save (std::ofstream& outfile);
  195. void Improve_estimate (DP (*function) (Vect_DP), Vect_DP& args, int arg_to_integ, int Npts_max);
  196. void Improve_estimate (DP (*function) (Vect_DP, I_table), Vect_DP& args, int arg_to_integ, I_table Itable, int Npts_max);
  197. void Improve_estimate (DP (*function) (Vect_DP, Integral_table), Vect_DP& args, int arg_to_integ,
  198. Integral_table Itable, int Npts_max);
  199. ~Integral_data ();
  200. };
  201. Integral_result Integrate_optimal (DP (*function) (Vect_DP), Vect_DP& args,
  202. int arg_to_integ, DP xmin, DP xmax, DP req_rel_prec, DP req_abs_prec, int max_nr_pts);
  203. Integral_result Integrate_optimal_using_table (DP (*function) (Vect_DP, I_table Itable), Vect_DP& args, int arg_to_integ,
  204. I_table Itable, DP xmin, DP xmax, DP req_rel_prec, DP req_abs_prec, int max_nr_pts);
  205. Integral_result Integrate_optimal_using_table (DP (*function) (Vect_DP, Integral_table Itable), Vect_DP& args, int arg_to_integ,
  206. Integral_table Itable, DP xmin, DP xmax, DP req_rel_prec,
  207. DP req_abs_prec, int max_nr_pts);
  208. Integral_result Integrate_optimal_using_table (DP (*function) (Vect_DP, I_table Itable), Vect_DP& args, int arg_to_integ,
  209. I_table Itable, DP xmin, DP xmax, DP req_rel_prec,
  210. DP req_abs_prec, int max_nr_pts, std::ofstream& outfile);
  211. // ******************************** Recursive version: optimal, complex implementation ******************************
  212. // NB: function returns complex values but takes real arguments
  213. struct data_pt_CX {
  214. DP x;
  215. std::complex<DP> f;
  216. DP dx;
  217. };
  218. struct Integral_result_CX {
  219. std::complex<DP> integ_est;
  220. DP abs_prec;
  221. DP rel_prec;
  222. int n_vals;
  223. };
  224. class Integral_data_CX {
  225. private:
  226. data_pt_CX* data;
  227. DP* abs_d2f_dx; // second derivative * dx
  228. DP max_abs_d2f_dx; //
  229. public:
  230. Integral_result_CX integ_res;
  231. public:
  232. DP xmin;
  233. DP xmax;
  234. public:
  235. Integral_data_CX (std::complex<DP> (*function_ref) (Vect_DP), Vect_DP& args, int arg_to_integ_ref, DP xmin_ref, DP xmax_ref);
  236. void Save (std::ofstream& outfile);
  237. void Improve_estimate (std::complex<DP> (*function) (Vect_DP), Vect_DP& args, int arg_to_integ, int Npts_max);
  238. ~Integral_data_CX ();
  239. };
  240. Integral_result_CX Integrate_optimal (std::complex<DP> (*function) (Vect_DP), Vect_DP& args, int arg_to_integ, DP xmin, DP xmax,
  241. DP req_rel_prec, DP req_abs_prec, int max_nr_pts);
  242. //Integral_result_CX Integrate_optimal_using_table (DP (*function) (Vect_DP, I_table Itable), Vect_DP& args, int arg_to_integ,
  243. // I_table Itable, DP xmin, DP xmax, DP req_rel_prec, DP req_abs_prec, int max_nr_pts);
  244. //Integral_result_CX Integrate_optimal_using_table (DP (*function) (Vect_DP, I_table Itable), Vect_DP& args, int arg_to_integ,
  245. // I_table Itable, DP xmin, DP xmax, DP req_rel_prec, DP req_abs_prec, int max_nr_pts, std::ofstream& outfile);
  246. } // namespace ABACUS
  247. #endif