GNU Octave  4.2.1
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
Quad.cc
Go to the documentation of this file.
1 /*
2 
3 Copyright (C) 1993-2017 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 the
9 Free Software Foundation; either version 3 of the License, or (at your
10 option) any later version.
11 
12 Octave is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 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 <http://www.gnu.org/licenses/>.
20 
21 */
22 
23 #if defined (HAVE_CONFIG_H)
24 # include "config.h"
25 #endif
26 
27 #include "Quad.h"
28 #include "f77-fcn.h"
29 #include "lo-error.h"
30 #include "quit.h"
31 #include "sun-utils.h"
32 
35 
36 // FIXME: would be nice to not have to have this global variable.
37 // Nonzero means an error occurred in the calculation of the integrand
38 // function, and the user wants us to quit.
40 
41 typedef octave_idx_type (*quad_fcn_ptr) (double*, int&, double*);
42 typedef octave_idx_type (*quad_float_fcn_ptr) (float*, int&, float*);
43 
44 extern "C"
45 {
46  F77_RET_T
47  F77_FUNC (dqagp, DQAGP) (quad_fcn_ptr, const F77_DBLE&, const F77_DBLE&,
48  const F77_INT&, const F77_DBLE*,
49  const F77_DBLE&, const F77_DBLE&, F77_DBLE&,
50  F77_DBLE&, F77_INT&, F77_INT&,
51  const F77_INT&, const F77_INT&,
52  F77_INT&, F77_INT*, F77_DBLE*);
53 
54  F77_RET_T
55  F77_FUNC (dqagi, DQAGI) (quad_fcn_ptr, const F77_DBLE&,
56  const F77_INT&, const F77_DBLE&,
57  const F77_DBLE&, F77_DBLE&, F77_DBLE&,
58  F77_INT&, F77_INT&,
59  const F77_INT&, const F77_INT&,
60  F77_INT&, F77_INT*, F77_DBLE*);
61 
62  F77_RET_T
63  F77_FUNC (qagp, QAGP) (quad_float_fcn_ptr, const F77_REAL&, const F77_REAL&,
64  const F77_INT&, const F77_REAL*, const F77_REAL&,
65  const F77_REAL&, F77_REAL&, F77_REAL&, F77_INT&,
66  F77_INT&, const F77_INT&,
67  const F77_INT&, F77_INT&,
68  F77_INT*, F77_REAL*);
69 
70  F77_RET_T
71  F77_FUNC (qagi, QAGI) (quad_float_fcn_ptr, const F77_REAL&,
72  const F77_INT&, const F77_REAL&,
73  const F77_REAL&, F77_REAL&, F77_REAL&, F77_INT&,
74  F77_INT&, const F77_INT&,
75  const F77_INT&, F77_INT&,
76  F77_INT*, F77_REAL*);
77 }
78 
79 static octave_idx_type
80 user_function (double *x, int& ierr, double *result)
81 {
82  BEGIN_INTERRUPT_WITH_EXCEPTIONS;
83 
84 #if defined (__sparc) && defined (__GNUC__)
85  double xx = access_double (x);
86 #else
87  double xx = *x;
88 #endif
89 
90  quad_integration_error = 0;
91 
92  double xresult = (*user_fcn) (xx);
93 
94 #if defined (__sparc) && defined (__GNUC__)
95  assign_double (result, xresult);
96 #else
97  *result = xresult;
98 #endif
99 
100  if (quad_integration_error)
101  ierr = -1;
102 
103  END_INTERRUPT_WITH_EXCEPTIONS;
104 
105  return 0;
106 }
107 
108 static octave_idx_type
109 float_user_function (float *x, int& ierr, float *result)
110 {
111  BEGIN_INTERRUPT_WITH_EXCEPTIONS;
112 
113  quad_integration_error = 0;
114 
115  *result = (*float_user_fcn) (*x);
116 
117  if (quad_integration_error)
118  ierr = -1;
119 
120  END_INTERRUPT_WITH_EXCEPTIONS;
121 
122  return 0;
123 }
124 
125 double
127  double& abserr)
128 {
129  octave_idx_type npts = singularities.numel () + 2;
130  double *points = singularities.fortran_vec ();
131  double result = 0.0;
132 
133  octave_idx_type leniw = 183*npts - 122;
134  Array<octave_idx_type> iwork (dim_vector (leniw, 1));
135  octave_idx_type *piwork = iwork.fortran_vec ();
136 
137  octave_idx_type lenw = 2*leniw - npts;
138  Array<double> work (dim_vector (lenw, 1));
139  double *pwork = work.fortran_vec ();
140 
141  user_fcn = f;
142  octave_idx_type last;
143 
144  double abs_tol = absolute_tolerance ();
145  double rel_tol = relative_tolerance ();
146 
148  npts, points, abs_tol, rel_tol, result,
149  abserr, neval, ier, leniw, lenw, last,
150  piwork, pwork));
151 
152  return result;
153 }
154 
155 float
157 {
158  (*current_liboctave_error_handler) ("incorrect integration function called");
159 }
160 
161 double
163  double& abserr)
164 {
165  double result = 0.0;
166 
167  octave_idx_type leniw = 128;
168  Array<octave_idx_type> iwork (dim_vector (leniw, 1));
169  octave_idx_type *piwork = iwork.fortran_vec ();
170 
171  octave_idx_type lenw = 8*leniw;
172  Array<double> work (dim_vector (lenw, 1));
173  double *pwork = work.fortran_vec ();
174 
175  user_fcn = f;
176  octave_idx_type last;
177 
178  octave_idx_type inf;
179  switch (type)
180  {
181  case bound_to_inf:
182  inf = 1;
183  break;
184 
185  case neg_inf_to_bound:
186  inf = -1;
187  break;
188 
189  case doubly_infinite:
190  inf = 2;
191  break;
192 
193  default:
194  assert (0);
195  break;
196  }
197 
198  double abs_tol = absolute_tolerance ();
199  double rel_tol = relative_tolerance ();
200 
201  F77_XFCN (dqagi, DQAGI, (user_function, bound, inf, abs_tol, rel_tol,
202  result, abserr, neval, ier, leniw, lenw,
203  last, piwork, pwork));
204 
205  return result;
206 }
207 
208 float
210 {
211  (*current_liboctave_error_handler) ("incorrect integration function called");
212 }
213 
214 double
216 {
217  (*current_liboctave_error_handler) ("incorrect integration function called");
218 }
219 
220 float
222  float& abserr)
223 {
224  octave_idx_type npts = singularities.numel () + 2;
225  float *points = singularities.fortran_vec ();
226  float result = 0.0;
227 
228  octave_idx_type leniw = 183*npts - 122;
229  Array<octave_idx_type> iwork (dim_vector (leniw, 1));
230  octave_idx_type *piwork = iwork.fortran_vec ();
231 
232  octave_idx_type lenw = 2*leniw - npts;
233  Array<float> work (dim_vector (lenw, 1));
234  float *pwork = work.fortran_vec ();
235 
236  float_user_fcn = ff;
237  octave_idx_type last;
238 
239  float abs_tol = single_precision_absolute_tolerance ();
240  float rel_tol = single_precision_relative_tolerance ();
241 
243  npts, points, abs_tol, rel_tol, result,
244  abserr, neval, ier, leniw, lenw, last,
245  piwork, pwork));
246 
247  return result;
248 }
249 
250 double
252 {
253  (*current_liboctave_error_handler) ("incorrect integration function called");
254 }
255 
256 float
258  float& abserr)
259 {
260  float result = 0.0;
261 
262  octave_idx_type leniw = 128;
263  Array<octave_idx_type> iwork (dim_vector (leniw, 1));
264  octave_idx_type *piwork = iwork.fortran_vec ();
265 
266  octave_idx_type lenw = 8*leniw;
267  Array<float> work (dim_vector (lenw, 1));
268  float *pwork = work.fortran_vec ();
269 
270  float_user_fcn = ff;
271  octave_idx_type last;
272 
273  octave_idx_type inf;
274  switch (type)
275  {
276  case bound_to_inf:
277  inf = 1;
278  break;
279 
280  case neg_inf_to_bound:
281  inf = -1;
282  break;
283 
284  case doubly_infinite:
285  inf = 2;
286  break;
287 
288  default:
289  assert (0);
290  break;
291  }
292 
293  float abs_tol = single_precision_absolute_tolerance ();
294  float rel_tol = single_precision_relative_tolerance ();
295 
296  F77_XFCN (qagi, QAGI, (float_user_function, bound, inf, abs_tol, rel_tol,
297  result, abserr, neval, ier, leniw, lenw,
298  last, piwork, pwork));
299 
300  return result;
301 }
float(* float_integrand_fcn)(float x)
Definition: Quad.h:34
F77_RET_T F77_REAL &F77_RET_T F77_DBLE &F77_RET_T F77_REAL &F77_RET_T F77_DBLE &F77_RET_T F77_REAL &F77_RET_T F77_DBLE &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 F77_REAL &F77_RET_T F77_DBLE &F77_RET_T F77_DBLE &F77_RET_T F77_REAL &F77_RET_T F77_REAL &F77_RET_T F77_DBLE &F77_RET_T const F77_DBLE F77_DBLE &F77_RET_T const F77_REAL F77_REAL &F77_RET_T F77_REAL F77_REAL &F77_RET_T F77_DBLE F77_DBLE &F77_RET_T const F77_DBLE const F77_DBLE F77_DBLE const F77_INT F77_INT * ierr
static float_integrand_fcn float_user_fcn
Definition: Quad.cc:34
float_integrand_fcn ff
Definition: Quad.h:118
double(* integrand_fcn)(double x)
Definition: Quad.h:33
ColumnVector singularities
Definition: Quad.h:155
octave_idx_type numel(void) const
Number of elements in the array.
Definition: Array.h:363
float single_precision_absolute_tolerance(void) const
Definition: Quad-opts.h:88
subroutine dqagp(F, A, B, NPTS2, POINTS, EPSABS, EPSREL, RESULT, ABSERR, NEVAL, IER, LENIW, LENW, LAST, IWORK, WORK)
Definition: dqagp.f:1
subroutine qagi(f, bound, inf, epsabs, epsrel, result, abserr, neval, ier, limit, lenw, last, iwork, work)
Definition: qagi.f:1
double upper_limit
Definition: Quad.h:153
double do_integrate(octave_idx_type &ier, octave_idx_type &neval, double &abserr)
Definition: Quad.cc:162
#define F77_XFCN(f, F, args)
Definition: f77-fcn.h:52
OCTAVE_NORETURN double do_integrate(octave_idx_type &ier, octave_idx_type &neval, double &abserr)
Definition: Quad.cc:251
FloatColumnVector singularities
Definition: Quad.h:220
#define F77_REAL
Definition: f77-fcn.h:332
subroutine qagp(f, a, b, npts2, points, epsabs, epsrel, result, abserr, neval, ier, leniw, lenw, last, iwork, work)
Definition: qagp.f:1
double do_integrate(octave_idx_type &ier, octave_idx_type &neval, double &abserr)
Definition: Quad.cc:126
float upper_limit
Definition: Quad.h:218
double bound
Definition: Quad.h:182
octave_idx_type(* quad_float_fcn_ptr)(float *, int &, float *)
Definition: Quad.cc:42
F77_RET_T F77_FUNC(dqagp, DQAGP)(quad_fcn_ptr
static octave_idx_type float_user_function(float *x, int &ierr, float *result)
Definition: Quad.cc:109
float single_precision_relative_tolerance(void) const
Definition: Quad-opts.h:91
float lower_limit
Definition: Quad.h:217
#define F77_INT
Definition: f77-fcn.h:335
With real return the complex result
Definition: data.cc:3375
double relative_tolerance(void) const
Definition: Quad-opts.h:85
float bound
Definition: Quad.h:247
octave_idx_type(* quad_fcn_ptr)(double *, int &, double *)
Definition: Quad.cc:41
double lower_limit
Definition: Quad.h:152
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 octave_idx_type user_function(double *x, int &ierr, double *result)
Definition: Quad.cc:80
IntegralType type
Definition: Quad.h:183
IntegralType type
Definition: Quad.h:248
static integrand_fcn user_fcn
Definition: Quad.cc:33
double absolute_tolerance(void) const
Definition: Quad-opts.h:82
const T * fortran_vec(void) const
Definition: Array.h:584
OCTAVE_NORETURN double do_integrate(octave_idx_type &ier, octave_idx_type &neval, double &abserr)
Definition: Quad.cc:215
Vector representing the dimensions (size) of an Array.
Definition: dim-vector.h:87
integrand_fcn f
Definition: Quad.h:117
int quad_integration_error
Definition: Quad.cc:39
#define F77_DBLE
Definition: f77-fcn.h:331
F77_RET_T F77_REAL &F77_RET_T F77_DBLE &F77_RET_T F77_REAL &F77_RET_T F77_DBLE &F77_RET_T F77_REAL &F77_RET_T F77_DBLE &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 F77_REAL &F77_RET_T F77_DBLE &F77_RET_T F77_DBLE &F77_RET_T F77_REAL &F77_RET_T F77_REAL &F77_RET_T F77_DBLE &F77_RET_T const F77_DBLE F77_DBLE &F77_RET_T const F77_REAL F77_REAL &F77_RET_T F77_REAL F77_REAL &F77_RET_T F77_DBLE F77_DBLE &F77_RET_T const F77_DBLE * x
subroutine dqagi(F, BOUND, INF, EPSABS, EPSREL, RESULT, ABSERR, NEVAL, IER, LIMIT, LENW, LAST, IWORK, WORK)
Definition: dqagi.f:1