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.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391
  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()
  90. + 2 * (((xmin_reg + 1) % 2 && (xmax_reg + 1) % 2) - (xmax_reg - xmin_reg)/2));
  91. int ishift = 0;
  92. for (int i = 0; i <= xmin_reg; ++i) new_bdry[i] = bdry[i];
  93. if ((xmin_reg + 1) % 2) {
  94. new_bdry[xmin_reg + 1] = xmin_ref;
  95. ishift++;
  96. if ((xmax_reg + 1) % 2) {
  97. new_bdry[xmin_reg + 2] = xmax_ref;
  98. ishift++;
  99. }
  100. }
  101. else if (xmin_reg % 2 && (xmax_reg + 1) % 2) {
  102. new_bdry[xmin_reg + 1] = xmax_ref;
  103. ishift++;
  104. }
  105. for (int i = xmin_reg + ishift + 1; i < new_bdry.size(); ++i)
  106. new_bdry[i] = bdry[xmax_reg - xmin_reg - ishift + i];
  107. bdry = new_bdry;
  108. return;
  109. }
  110. };
  111. template<class T>
  112. std::ostream& operator<< (std::ostream& s, Domain<T> dom)
  113. {
  114. for (int i = 0; i < dom.Ndomains(); ++i) {
  115. if (i > 0) s << std::endl;
  116. s << dom.xmin(i) << "\t" << dom.xmax(i);
  117. }
  118. return(s);
  119. }
  120. // ********************************* struct I_table ************************
  121. struct I_table {
  122. DP (*function) (DP, DP);
  123. int Nvals;
  124. DP rhomin;
  125. DP rhomax;
  126. DP alpha;
  127. DP logalpha;
  128. DP prec;
  129. DP* rho_tbl;
  130. DP* I_tbl;
  131. I_table (DP (*function) (DP, DP), DP rhomin_ref, DP rhomax_ref, int Nvals_ref, DP req_prec);
  132. DP Return_val (DP req_rho);
  133. void Save ();
  134. bool Load (DP rhomin_ref, DP rhomax_ref, int Nvals_ref, DP req_prec);
  135. };
  136. // ********************************* struct Integral_table ************************
  137. struct Integral_table {
  138. DP (*function) (DP, DP, int);
  139. int Nvals;
  140. DP rhomin;
  141. DP rhomax;
  142. DP alpha;
  143. DP logalpha;
  144. DP prec;
  145. int maxnrpts;
  146. DP* rho_tbl;
  147. DP* I_tbl;
  148. Integral_table (DP (*function) (DP, DP, int), const char* filenameprefix_ref, DP rhomin_ref,
  149. DP rhomax_ref, int Nvals_ref, DP req_prec, int max_nr_pts);
  150. DP Return_val (DP req_rho);
  151. void Save (const char* filenameprefix);
  152. bool Load (const char* filenameprefix, DP rhomin_ref, DP rhomax_ref, int Nvals_ref, DP req_prec, int max_nr_pts);
  153. };
  154. // ******************************** Recursive integration functions ******************************
  155. DP Integrate_Riemann (DP (*function) (Vect_DP),
  156. Vect_DP& args, int arg_to_integ,
  157. DP xmin, DP xmax,
  158. int Npts);
  159. DP Integrate_Riemann_using_table (DP (*function) (Vect_DP, I_table),
  160. Vect_DP& args, int arg_to_integ,
  161. I_table Itable,
  162. DP xmin, DP xmax, int Npts);
  163. DP Integrate_rec (DP (*function) (Vect_DP),
  164. Vect_DP& args, int arg_to_integ,
  165. DP xmin, DP xmax,
  166. DP req_prec, int max_rec_level);
  167. DP Integrate_rec_using_table (DP (*function) (Vect_DP, I_table),
  168. Vect_DP& args, int arg_to_integ,
  169. I_table Itable,
  170. DP xmin, DP xmax,
  171. DP req_prec, int max_rec_level);
  172. DP Integrate_rec_using_table (DP (*function) (Vect_DP, I_table),
  173. Vect_DP& args, int arg_to_integ,
  174. I_table Itable,
  175. DP xmin, DP xmax,
  176. DP req_prec, int max_rec_level,
  177. std::ofstream& outfile);
  178. DP Integrate_rec_using_table_and_file (DP (*function) (Vect_DP, I_table, std::ofstream&),
  179. Vect_DP& args, int arg_to_integ,
  180. I_table Itable,
  181. DP xmin, DP xmax,
  182. DP req_prec, int max_rec_level,
  183. std::ofstream& outfile);
  184. // ******************************** Recursive version: optimal ******************************
  185. struct data_pt {
  186. DP x;
  187. DP f;
  188. DP dx;
  189. };
  190. struct Integral_result {
  191. DP integ_est;
  192. DP abs_prec;
  193. DP rel_prec;
  194. int n_vals;
  195. };
  196. std::ostream& operator<< (std::ostream& s, const Integral_result& res);
  197. class Integral_data {
  198. private:
  199. data_pt* data;
  200. DP* abs_d2f_dx; // second derivative * dx
  201. DP max_abs_d2f_dx; //
  202. public:
  203. Integral_result integ_res;
  204. public:
  205. DP xmin;
  206. DP xmax;
  207. public:
  208. Integral_data (DP (*function_ref) (Vect_DP),
  209. Vect_DP& args, int arg_to_integ_ref,
  210. DP xmin_ref, DP xmax_ref);
  211. Integral_data (DP (*function_ref) (Vect_DP, I_table),
  212. Vect_DP& args, int arg_to_integ_ref,
  213. I_table Itable,
  214. DP xmin_ref, DP xmax_ref);
  215. Integral_data (DP (*function_ref) (Vect_DP, Integral_table),
  216. Vect_DP& args, int arg_to_integ_ref,
  217. Integral_table Itable,
  218. DP xmin_ref, DP xmax_ref);
  219. void Save (std::ofstream& outfile);
  220. void Improve_estimate (DP (*function) (Vect_DP),
  221. Vect_DP& args, int arg_to_integ,
  222. int Npts_max);
  223. void Improve_estimate (DP (*function) (Vect_DP, I_table),
  224. Vect_DP& args, int arg_to_integ,
  225. I_table Itable,
  226. int Npts_max);
  227. void Improve_estimate (DP (*function) (Vect_DP, Integral_table),
  228. Vect_DP& args, int arg_to_integ,
  229. Integral_table Itable,
  230. int Npts_max);
  231. ~Integral_data ();
  232. };
  233. Integral_result Integrate_optimal (DP (*function) (Vect_DP),
  234. Vect_DP& args, int arg_to_integ,
  235. DP xmin, DP xmax,
  236. DP req_rel_prec, DP req_abs_prec,
  237. int max_nr_pts);
  238. Integral_result Integrate_optimal_using_table (DP (*function) (Vect_DP, I_table Itable),
  239. Vect_DP& args, int arg_to_integ,
  240. I_table Itable,
  241. DP xmin, DP xmax,
  242. DP req_rel_prec, DP req_abs_prec,
  243. int max_nr_pts);
  244. Integral_result Integrate_optimal_using_table (DP (*function) (Vect_DP, Integral_table Itable),
  245. Vect_DP& args, int arg_to_integ,
  246. Integral_table Itable,
  247. DP xmin, DP xmax,
  248. DP req_rel_prec, DP req_abs_prec,
  249. int max_nr_pts);
  250. Integral_result Integrate_optimal_using_table (DP (*function) (Vect_DP, I_table Itable),
  251. Vect_DP& args, int arg_to_integ,
  252. I_table Itable,
  253. DP xmin, DP xmax,
  254. DP req_rel_prec, DP req_abs_prec,
  255. int max_nr_pts,
  256. std::ofstream& outfile);
  257. // ********************** Recursive version: optimal, complex implementation ********************
  258. // NB: function returns complex values but takes real arguments
  259. struct data_pt_CX {
  260. DP x;
  261. std::complex<DP> f;
  262. DP dx;
  263. };
  264. struct Integral_result_CX {
  265. std::complex<DP> integ_est;
  266. DP abs_prec;
  267. DP rel_prec;
  268. int n_vals;
  269. };
  270. class Integral_data_CX {
  271. private:
  272. data_pt_CX* data;
  273. DP* abs_d2f_dx; // second derivative * dx
  274. DP max_abs_d2f_dx; //
  275. public:
  276. Integral_result_CX integ_res;
  277. public:
  278. DP xmin;
  279. DP xmax;
  280. public:
  281. Integral_data_CX (std::complex<DP> (*function_ref) (Vect_DP),
  282. Vect_DP& args, int arg_to_integ_ref,
  283. DP xmin_ref, DP xmax_ref);
  284. void Save (std::ofstream& outfile);
  285. void Improve_estimate (std::complex<DP> (*function) (Vect_DP),
  286. Vect_DP& args, int arg_to_integ,
  287. int Npts_max);
  288. ~Integral_data_CX ();
  289. };
  290. Integral_result_CX Integrate_optimal (std::complex<DP> (*function) (Vect_DP),
  291. Vect_DP& args, int arg_to_integ,
  292. DP xmin, DP xmax,
  293. DP req_rel_prec, DP req_abs_prec,
  294. int max_nr_pts);
  295. } // namespace ABACUS
  296. #endif