BubbleProfiler  0.3.0
by Peter Athron, Csaba Balazs, Michael Bardsley, Andrew Fowlie, Dylan Harries & Graham White
integration_utils.hpp
Go to the documentation of this file.
1 /*
2  * This file is part of BubbleProfiler.
3  *
4  * BubbleProfiler is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 3 of the License, or
7  * (at your option) any later version.
8  *
9  * BubbleProfiler is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with BubbleProfiler. If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #ifndef BUBBLEPROFILER_INTEGRATION_UTILS_HPP_INCLUDED
19 #define BUBBLEPROFILER_INTEGRATION_UTILS_HPP_INCLUDED
20 
21 #include "error.hpp"
22 #include "raii_guard.hpp"
23 
24 #include <gsl/gsl_errno.h>
25 #include <gsl/gsl_integration.h>
26 
27 #include <tuple>
28 #include <iostream>
29 namespace BubbleProfiler {
30 
31 enum class Integration_rule {
32  GK15, GK21, GK31, GK41, GK51, GK61
33 };
34 
36 
37 template <typename F>
38 std::tuple<int,double,double> integrate_gsl_qag(F f, double a, double b,
39  double abs_tol, double rel_tol,
40  std::size_t max_intervals,
41  Integration_rule rule)
42 {
43  gsl_integration_workspace* workspace
44  = gsl_integration_workspace_alloc(max_intervals);
45 
46  if (!workspace) {
47  throw Out_of_memory_error("cannot allocate integration workspace");
48  }
49 
50  const auto handler = gsl_set_error_handler_off();
51 
52  const auto workspace_guard = make_raii_guard(
53  [workspace, handler]() {
54  gsl_integration_workspace_free(workspace);
55  gsl_set_error_handler(handler);
56  });
57 
58  gsl_function func;
59  func.function = [](double x, void* params) {
60  return (*static_cast<F*>(params))(x);
61  };
62  func.params = &f;
63 
64  double result = 0.;
65  double error = 0.;
66  const int status = gsl_integration_qag(&func, a, b, abs_tol, rel_tol,
67  max_intervals,
69  workspace, &result, &error);
70 
71  return std::make_tuple(status, result, error);
72 }
73 
74 template <typename F>
75 std::tuple<int,double,double> integrate_gsl_qags(F f, double a, double b,
76  double abs_tol, double rel_tol,
77  std::size_t max_intervals)
78 {
79  gsl_integration_workspace* workspace
80  = gsl_integration_workspace_alloc(max_intervals);
81 
82  if (!workspace) {
83  throw Out_of_memory_error("cannot allocate integration workspace");
84  }
85 
86  const auto handler = gsl_set_error_handler_off();
87 
88  const auto workspace_guard = make_raii_guard(
89  [workspace, handler]() {
90  gsl_integration_workspace_free(workspace);
91  gsl_set_error_handler(handler);
92  });
93 
94  gsl_function func;
95  func.function = [](double x, void* params) {
96  return (*static_cast<F*>(params))(x);
97  };
98  func.params = &f;
99 
100  double result = 0.;
101  double error = 0.;
102  const int status = gsl_integration_qags(&func, a, b, abs_tol, rel_tol,
103  max_intervals,
104  workspace, &result, &error);
105 
106  return std::make_tuple(status, result, error);
107 }
108 
109 template <typename F>
110 std::tuple<int,double,double,int> integrate_gsl_cquad(F f, double a, double b,
111  double abs_tol,
112  double rel_tol,
113  std::size_t n_intervals)
114 {
115  if (n_intervals < 3) {
116  throw Setup_error("at least 3 intervals required in CQUAD routine");
117  }
118 
119  gsl_integration_cquad_workspace* workspace
120  = gsl_integration_cquad_workspace_alloc(n_intervals);
121 
122  if (!workspace) {
123  throw Out_of_memory_error("cannot allocate integration workspace");
124  }
125 
126  const auto handler = gsl_set_error_handler_off();
127 
128  const auto workspace_guard = make_raii_guard(
129  [workspace, handler]() {
130  gsl_integration_cquad_workspace_free(workspace);
131  gsl_set_error_handler(handler);
132  });
133 
134  gsl_function func;
135  func.function = [](double x, void* params) {
136  return (*static_cast<F*>(params))(x);
137  };
138  func.params = &f;
139 
140  double result = 0.;
141  double error = 0.;
142  std::size_t n_evals = 0;
143  const int status = gsl_integration_cquad(&func, a, b, abs_tol, rel_tol,
144  workspace, &result, &error,
145  &n_evals);
146 
147  return std::make_tuple(status, result, error, n_evals);
148 }
149 
150 } // namespace BubbleProfiler
151 
152 #endif
std::tuple< int, double, double > integrate_gsl_qag(F f, double a, double b, double abs_tol, double rel_tol, std::size_t max_intervals, Integration_rule rule)
std::tuple< int, double, double, int > integrate_gsl_cquad(F f, double a, double b, double abs_tol, double rel_tol, std::size_t n_intervals)
Exception indicating that memory allocation failed.
Definition: error.hpp:98
constexpr RAII_guard< F > make_raii_guard(F f)
Definition: raii_guard.hpp:43
std::tuple< int, double, double > integrate_gsl_qags(F f, double a, double b, double abs_tol, double rel_tol, std::size_t max_intervals)
Exception indicating general setup error.
Definition: error.hpp:32
int get_integration_rule_key(Integration_rule)