GNU Octave  4.4.1
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
Quad.cc
Go to the documentation of this file.
1 /*
2 
3 Copyright (C) 1993-2018 John W. Eaton
4 
5 This file is part of Octave.
6 
7 Octave is free software: you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
11 
12 Octave is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16 
17 You should have received a copy of the GNU General Public License
18 along with Octave; see the file COPYING. If not, see
19 <https://www.gnu.org/licenses/>.
20 
21 */
22 
23 #if defined (HAVE_CONFIG_H)
24 # include "config.h"
25 #endif
26 
27 #include <cassert>
28 
29 #include "Array.h"
30 #include "Quad.h"
31 #include "f77-fcn.h"
32 #include "lo-error.h"
33 #include "quit.h"
34 
37 
38 // FIXME: would be nice to not have to have this global variable.
39 // Nonzero means an error occurred in the calculation of the integrand
40 // function, and the user wants us to quit.
42 
43 typedef F77_INT (*quad_fcn_ptr) (const double&, int&, double&);
44 typedef F77_INT (*quad_float_fcn_ptr) (const float&, int&, float&);
45 
46 extern "C"
47 {
48  F77_RET_T
49  F77_FUNC (dqagp, DQAGP) (quad_fcn_ptr, const F77_DBLE&, const F77_DBLE&,
50  const F77_INT&, const F77_DBLE*,
51  const F77_DBLE&, const F77_DBLE&, F77_DBLE&,
53  const F77_INT&, const F77_INT&,
54  F77_INT&, F77_INT*, F77_DBLE*);
55 
56  F77_RET_T
57  F77_FUNC (dqagi, DQAGI) (quad_fcn_ptr, const F77_DBLE&,
58  const F77_INT&, const F77_DBLE&,
59  const F77_DBLE&, F77_DBLE&, F77_DBLE&,
60  F77_INT&, F77_INT&,
61  const F77_INT&, const F77_INT&,
62  F77_INT&, F77_INT*, F77_DBLE*);
63 
64  F77_RET_T
65  F77_FUNC (qagp, QAGP) (quad_float_fcn_ptr, const F77_REAL&, const F77_REAL&,
66  const F77_INT&, const F77_REAL*, const F77_REAL&,
67  const F77_REAL&, F77_REAL&, F77_REAL&, F77_INT&,
68  F77_INT&, const F77_INT&,
69  const F77_INT&, F77_INT&,
70  F77_INT*, F77_REAL*);
71 
72  F77_RET_T
73  F77_FUNC (qagi, QAGI) (quad_float_fcn_ptr, const F77_REAL&,
74  const F77_INT&, const F77_REAL&,
75  const F77_REAL&, F77_REAL&, F77_REAL&, F77_INT&,
76  F77_INT&, const F77_INT&,
77  const F77_INT&, F77_INT&,
78  F77_INT*, F77_REAL*);
79 }
80 
81 static F77_INT
82 user_function (const double& x, int& ierr, double& result)
83 {
84  BEGIN_INTERRUPT_WITH_EXCEPTIONS;
85 
87 
88  result = (*user_fcn) (x);
89 
91  ierr = -1;
92 
93  END_INTERRUPT_WITH_EXCEPTIONS;
94 
95  return 0;
96 }
97 
98 static F77_INT
99 float_user_function (const float& x, int& ierr, float& result)
100 {
101  BEGIN_INTERRUPT_WITH_EXCEPTIONS;
102 
104 
105  result = (*float_user_fcn) (x);
106 
108  ierr = -1;
109 
110  END_INTERRUPT_WITH_EXCEPTIONS;
111 
112  return 0;
113 }
114 
115 double
117  double& abserr)
118 {
119  F77_INT npts = octave::to_f77_int (singularities.numel () + 2);
120  double *points = singularities.fortran_vec ();
121  double result = 0.0;
122 
123  F77_INT leniw = 183*npts - 122;
124  Array<F77_INT> iwork (dim_vector (leniw, 1));
125  F77_INT *piwork = iwork.fortran_vec ();
126 
127  F77_INT lenw = 2*leniw - npts;
128  Array<double> work (dim_vector (lenw, 1));
129  double *pwork = work.fortran_vec ();
130 
131  user_fcn = f;
132  F77_INT last;
133 
134  double abs_tol = absolute_tolerance ();
135  double rel_tol = relative_tolerance ();
136 
137  // NEVAL and IER are output only parameters and F77_INT can not be a
138  // wider type than octave_idx_type so we can create local variables
139  // here that are the correct type for the Fortran subroutine and then
140  // copy them to the function parameters without needing to preserve
141  // and pass the values to the Fortran subroutine.
142 
143  F77_INT xneval, xier;
144 
146  npts, points, abs_tol, rel_tol, result,
147  abserr, xneval, xier, leniw, lenw, last,
148  piwork, pwork));
149 
150  neval = xneval;
151  ier = xier;
152 
153  return result;
154 }
155 
156 float
158 {
159  (*current_liboctave_error_handler) ("incorrect integration function called");
160 }
161 
162 double
164  double& abserr)
165 {
166  double result = 0.0;
167 
168  F77_INT leniw = 128;
169  Array<F77_INT> iwork (dim_vector (leniw, 1));
170  F77_INT *piwork = iwork.fortran_vec ();
171 
172  F77_INT lenw = 8*leniw;
173  Array<double> work (dim_vector (lenw, 1));
174  double *pwork = work.fortran_vec ();
175 
176  user_fcn = f;
177  F77_INT last;
178 
179  F77_INT inf;
180  switch (type)
181  {
182  case bound_to_inf:
183  inf = 1;
184  break;
185 
186  case neg_inf_to_bound:
187  inf = -1;
188  break;
189 
190  case doubly_infinite:
191  inf = 2;
192  break;
193 
194  default:
195  assert (0);
196  break;
197  }
198 
199  double abs_tol = absolute_tolerance ();
200  double rel_tol = relative_tolerance ();
201 
202  // NEVAL and IER are output only parameters and F77_INT can not be a
203  // wider type than octave_idx_type so we can create local variables
204  // here that are the correct type for the Fortran subroutine and then
205  // copy them to the function parameters without needing to preserve
206  // and pass the values to the Fortran subroutine.
207 
208  F77_INT xneval, xier;
209 
210  F77_XFCN (dqagi, DQAGI, (user_function, bound, inf, abs_tol, rel_tol,
211  result, abserr, xneval, xier, leniw, lenw,
212  last, piwork, pwork));
213 
214  neval = xneval;
215  ier = xier;
216 
217  return result;
218 }
219 
220 float
222 {
223  (*current_liboctave_error_handler) ("incorrect integration function called");
224 }
225 
226 double
228 {
229  (*current_liboctave_error_handler) ("incorrect integration function called");
230 }
231 
232 float
234  float& abserr)
235 {
236  F77_INT npts = octave::to_f77_int (singularities.numel () + 2);
237  float *points = singularities.fortran_vec ();
238  float result = 0.0;
239 
240  F77_INT leniw = 183*npts - 122;
241  Array<F77_INT> iwork (dim_vector (leniw, 1));
242  F77_INT *piwork = iwork.fortran_vec ();
243 
244  F77_INT lenw = 2*leniw - npts;
245  Array<float> work (dim_vector (lenw, 1));
246  float *pwork = work.fortran_vec ();
247 
248  float_user_fcn = ff;
249  F77_INT last;
250 
251  float abs_tol = single_precision_absolute_tolerance ();
252  float rel_tol = single_precision_relative_tolerance ();
253 
254  // NEVAL and IER are output only parameters and F77_INT can not be a
255  // wider type than octave_idx_type so we can create local variables
256  // here that are the correct type for the Fortran subroutine and then
257  // copy them to the function parameters without needing to preserve
258  // and pass the values to the Fortran subroutine.
259 
260  F77_INT xneval, xier;
261 
263  npts, points, abs_tol, rel_tol, result,
264  abserr, xneval, xier, leniw, lenw, last,
265  piwork, pwork));
266 
267  neval = xneval;
268  ier = xier;
269 
270  return result;
271 }
272 
273 double
275 {
276  (*current_liboctave_error_handler) ("incorrect integration function called");
277 }
278 
279 float
281  float& abserr)
282 {
283  float result = 0.0;
284 
285  F77_INT leniw = 128;
286  Array<F77_INT> iwork (dim_vector (leniw, 1));
287  F77_INT *piwork = iwork.fortran_vec ();
288 
289  F77_INT lenw = 8*leniw;
290  Array<float> work (dim_vector (lenw, 1));
291  float *pwork = work.fortran_vec ();
292 
293  float_user_fcn = ff;
294  F77_INT last;
295 
296  F77_INT inf;
297  switch (type)
298  {
299  case bound_to_inf:
300  inf = 1;
301  break;
302 
303  case neg_inf_to_bound:
304  inf = -1;
305  break;
306 
307  case doubly_infinite:
308  inf = 2;
309  break;
310 
311  default:
312  assert (0);
313  break;
314  }
315 
316  float abs_tol = single_precision_absolute_tolerance ();
317  float rel_tol = single_precision_relative_tolerance ();
318 
319  // NEVAL and IER are output only parameters and F77_INT can not be a
320  // wider type than octave_idx_type so we can create local variables
321  // here that are the correct type for the Fortran subroutine and then
322  // copy them to the function parameters without needing to preserve
323  // and pass the values to the Fortran subroutine.
324 
325  F77_INT xneval, xier;
326 
327  F77_XFCN (qagi, QAGI, (float_user_function, bound, inf, abs_tol, rel_tol,
328  result, abserr, xneval, xier, leniw, lenw,
329  last, piwork, pwork));
330 
331  neval = xneval;
332  ier = xier;
333 
334  return result;
335 }
static F77_INT float_user_function(const float &x, int &ierr, float &result)
Definition: Quad.cc:99
F77_INT(* quad_fcn_ptr)(const double &, int &, double &)
Definition: Quad.cc:43
static float_integrand_fcn float_user_fcn
Definition: Quad.cc:36
float_integrand_fcn ff
Definition: Quad.h:116
double(* integrand_fcn)(double x)
Definition: Quad.h:31
ColumnVector singularities
Definition: Quad.h:153
subroutine qagi(f, bound, inf, epsabs, epsrel, result, abserr, neval, ier, limit, lenw, last, iwork, work)
Definition: qagi.f:3
const T * fortran_vec(void) const
Definition: Array.h:584
double upper_limit
Definition: Quad.h:151
double do_integrate(octave_idx_type &ier, octave_idx_type &neval, double &abserr)
Definition: Quad.cc:163
#define F77_XFCN(f, F, args)
Definition: f77-fcn.h:41
F77_RET_T(F77_CONST_CHAR_ARG_DECL, F77_CONST_CHAR_ARG_DECL, F77_CONST_CHAR_ARG_DECL, const F77_INT &, const F77_INT &, const F77_INT &, F77_INT &, F77_INT &, F77_DBLE *, const F77_INT &, F77_DBLE *, const F77_INT &, F77_DBLE *, F77_DBLE *, F77_DBLE *, const F77_INT &, F77_DBLE *, const F77_INT &, F77_DBLE *, const F77_INT &, F77_DBLE *, F77_INT *, F77_INT &F77_CHAR_ARG_LEN_DECL F77_CHAR_ARG_LEN_DECL F77_CHAR_ARG_LEN_DECL)
OCTAVE_NORETURN double do_integrate(octave_idx_type &ier, octave_idx_type &neval, double &abserr)
Definition: Quad.cc:274
F77_INT(* quad_float_fcn_ptr)(const float &, int &, float &)
Definition: Quad.cc:44
FloatColumnVector singularities
Definition: Quad.h:218
subroutine qagp(f, a, b, npts2, points, epsabs, epsrel, result, abserr, neval, ier, leniw, lenw, last, iwork, work)
Definition: qagp.f:3
double do_integrate(octave_idx_type &ier, octave_idx_type &neval, double &abserr)
Definition: Quad.cc:116
float upper_limit
Definition: Quad.h:216
subroutine DQAGI(F, BOUND, INF, EPSABS, EPSREL, RESULT, ABSERR, NEVAL, IER, LIMIT, LENW, LAST, IWORK, WORK)
Definition: dqagi.f:3
double bound
Definition: Quad.h:180
F77_RET_T F77_FUNC(dqagp, DQAGP)(quad_fcn_ptr
subroutine DQAGP(F, A, B, NPTS2, POINTS, EPSABS, EPSREL, RESULT, ABSERR, NEVAL, IER, LENIW, LENW, LAST, IWORK, WORK)
Definition: dqagp.f:3
float lower_limit
Definition: Quad.h:215
With real return the complex result
Definition: data.cc:3260
F77_RET_T const F77_DBLE const F77_DBLE const F77_INT const F77_DBLE const F77_DBLE const F77_DBLE F77_DBLE F77_DBLE F77_INT F77_INT const F77_INT const F77_INT F77_INT F77_INT F77_DBLE *F77_RET_T const F77_DBLE const F77_INT const F77_DBLE const F77_DBLE F77_DBLE F77_DBLE F77_INT F77_INT const F77_INT const F77_INT F77_INT F77_INT F77_DBLE *F77_RET_T const F77_REAL const F77_REAL const F77_INT const F77_REAL const F77_REAL const F77_REAL F77_REAL F77_REAL F77_INT F77_INT const F77_INT const F77_INT F77_INT F77_INT F77_REAL *F77_RET_T const F77_REAL const F77_INT const F77_REAL const F77_REAL F77_REAL F77_REAL F77_INT F77_INT const F77_INT const F77_INT F77_INT F77_INT F77_REAL *static F77_INT user_function(const double &x, int &ierr, double &result)
Definition: Quad.cc:82
N Dimensional Array with copy-on-write semantics.
Definition: Array.h:125
octave_f77_int_type F77_INT
Definition: f77-fcn.h:305
float bound
Definition: Quad.h:245
double lower_limit
Definition: Quad.h:150
float(* float_integrand_fcn)(float x)
Definition: Quad.h:32
IntegralType type
Definition: Quad.h:181
IntegralType type
Definition: Quad.h:246
static integrand_fcn user_fcn
Definition: Quad.cc:35
octave_idx_type numel(void) const
Number of elements in the array.
Definition: Array.h:366
OCTAVE_NORETURN double do_integrate(octave_idx_type &ier, octave_idx_type &neval, double &abserr)
Definition: Quad.cc:227
Vector representing the dimensions (size) of an Array.
Definition: dim-vector.h:87
F77_RET_T const F77_REAL const F77_REAL F77_REAL &F77_RET_T const F77_DBLE const F77_DBLE F77_DBLE &F77_RET_T const F77_DBLE F77_DBLE &F77_RET_T const F77_REAL F77_REAL &F77_RET_T const F77_DBLE const F77_DBLE F77_DBLE const F77_INT F77_INT & ierr
integrand_fcn f
Definition: Quad.h:115
int quad_integration_error
Definition: Quad.cc:41
F77_RET_T const F77_REAL const F77_REAL F77_REAL &F77_RET_T const F77_DBLE const F77_DBLE F77_DBLE &F77_RET_T const F77_DBLE F77_DBLE &F77_RET_T const F77_REAL F77_REAL &F77_RET_T const F77_DBLE * x