GNU Octave  9.1.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Quad.cc
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 //
3 // Copyright (C) 1993-2024 The Octave Project Developers
4 //
5 // See the file COPYRIGHT.md in the top-level directory of this
6 // distribution or <https://octave.org/copyright/>.
7 //
8 // This file is part of Octave.
9 //
10 // Octave is free software: you can redistribute it and/or modify it
11 // under the terms of the GNU General Public License as published by
12 // the Free Software Foundation, either version 3 of the License, or
13 // (at your option) any later version.
14 //
15 // Octave is distributed in the hope that it will be useful, but
16 // WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU General Public License for more details.
19 //
20 // You should have received a copy of the GNU General Public License
21 // along with Octave; see the file COPYING. If not, see
22 // <https://www.gnu.org/licenses/>.
23 //
24 ////////////////////////////////////////////////////////////////////////
25 
26 #if defined (HAVE_CONFIG_H)
27 # include "config.h"
28 #endif
29 
30 #include <cassert>
31 
32 #include "Array.h"
33 #include "Quad.h"
34 #include "f77-fcn.h"
35 #include "lo-error.h"
36 #include "quit.h"
37 
38 static integrand_fcn user_fcn;
39 static float_integrand_fcn float_user_fcn;
40 
41 typedef F77_INT (*quad_fcn_ptr) (const double&, int&, double&);
42 typedef F77_INT (*quad_float_fcn_ptr) (const 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&,
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
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 F77_INT
80 user_function (const double& x, int&, double& result)
81 {
82  result = (*user_fcn) (x);
83 
84  return 0;
85 }
86 
87 static F77_INT
88 float_user_function (const float& x, int&, float& result)
89 {
90  result = (*float_user_fcn) (x);
91 
92  return 0;
93 }
94 
95 double
97  double& abserr)
98 {
99  F77_INT npts = octave::to_f77_int (m_singularities.numel () + 2);
100  double *points = m_singularities.fortran_vec ();
101  double result = 0.0;
102 
103  F77_INT leniw = 183*npts - 122;
104  Array<F77_INT> iwork (dim_vector (leniw, 1));
105  F77_INT *piwork = iwork.fortran_vec ();
106 
107  F77_INT lenw = 2*leniw - npts;
108  Array<double> work (dim_vector (lenw, 1));
109  double *pwork = work.fortran_vec ();
110 
111  user_fcn = m_f;
112  F77_INT last;
113 
114  double abs_tol = absolute_tolerance ();
115  double rel_tol = relative_tolerance ();
116 
117  // NEVAL and IER are output only parameters and F77_INT can not be a
118  // wider type than octave_idx_type so we can create local variables
119  // here that are the correct type for the Fortran subroutine and then
120  // copy them to the function parameters without needing to preserve
121  // and pass the values to the Fortran subroutine.
122 
123  F77_INT xneval, xier;
124 
125  F77_XFCN (dqagp, DQAGP, (user_function, m_lower_limit, m_upper_limit,
126  npts, points, abs_tol, rel_tol, result,
127  abserr, xneval, xier, leniw, lenw, last,
128  piwork, pwork));
129 
130  neval = xneval;
131  ier = xier;
132 
133  return result;
134 }
135 
136 float
138 {
139  (*current_liboctave_error_handler) ("incorrect integration function called");
140 }
141 
142 double
144  double& abserr)
145 {
146  double result = 0.0;
147 
148  F77_INT leniw = 128;
149  Array<F77_INT> iwork (dim_vector (leniw, 1));
150  F77_INT *piwork = iwork.fortran_vec ();
151 
152  F77_INT lenw = 8*leniw;
153  Array<double> work (dim_vector (lenw, 1));
154  double *pwork = work.fortran_vec ();
155 
156  user_fcn = m_f;
157  F77_INT last;
158 
159  F77_INT inf;
160  switch (m_type)
161  {
162  case bound_to_inf:
163  inf = 1;
164  break;
165 
166  case neg_inf_to_bound:
167  inf = -1;
168  break;
169 
170  case doubly_infinite:
171  inf = 2;
172  break;
173 
174  default:
175  assert (0);
176  break;
177  }
178 
179  double abs_tol = absolute_tolerance ();
180  double rel_tol = relative_tolerance ();
181 
182  // NEVAL and IER are output only parameters and F77_INT can not be a
183  // wider type than octave_idx_type so we can create local variables
184  // here that are the correct type for the Fortran subroutine and then
185  // copy them to the function parameters without needing to preserve
186  // and pass the values to the Fortran subroutine.
187 
188  F77_INT xneval, xier;
189 
190  F77_XFCN (dqagi, DQAGI, (user_function, m_bound, inf, abs_tol, rel_tol,
191  result, abserr, xneval, xier, leniw, lenw,
192  last, piwork, pwork));
193 
194  neval = xneval;
195  ier = xier;
196 
197  return result;
198 }
199 
200 float
202 {
203  (*current_liboctave_error_handler) ("incorrect integration function called");
204 }
205 
206 double
208 {
209  (*current_liboctave_error_handler) ("incorrect integration function called");
210 }
211 
212 float
214  float& abserr)
215 {
216  F77_INT npts = octave::to_f77_int (m_singularities.numel () + 2);
217  float *points = m_singularities.fortran_vec ();
218  float result = 0.0;
219 
220  F77_INT leniw = 183*npts - 122;
221  Array<F77_INT> iwork (dim_vector (leniw, 1));
222  F77_INT *piwork = iwork.fortran_vec ();
223 
224  F77_INT lenw = 2*leniw - npts;
225  Array<float> work (dim_vector (lenw, 1));
226  float *pwork = work.fortran_vec ();
227 
228  float_user_fcn = m_ff;
229  F77_INT last;
230 
231  float abs_tol = single_precision_absolute_tolerance ();
232  float rel_tol = single_precision_relative_tolerance ();
233 
234  // NEVAL and IER are output only parameters and F77_INT can not be a
235  // wider type than octave_idx_type so we can create local variables
236  // here that are the correct type for the Fortran subroutine and then
237  // copy them to the function parameters without needing to preserve
238  // and pass the values to the Fortran subroutine.
239 
240  F77_INT xneval, xier;
241 
242  F77_XFCN (qagp, QAGP, (float_user_function, m_lower_limit, m_upper_limit,
243  npts, points, abs_tol, rel_tol, result,
244  abserr, xneval, xier, leniw, lenw, last,
245  piwork, pwork));
246 
247  neval = xneval;
248  ier = xier;
249 
250  return result;
251 }
252 
253 double
255 {
256  (*current_liboctave_error_handler) ("incorrect integration function called");
257 }
258 
259 float
261  float& abserr)
262 {
263  float result = 0.0;
264 
265  F77_INT leniw = 128;
266  Array<F77_INT> iwork (dim_vector (leniw, 1));
267  F77_INT *piwork = iwork.fortran_vec ();
268 
269  F77_INT lenw = 8*leniw;
270  Array<float> work (dim_vector (lenw, 1));
271  float *pwork = work.fortran_vec ();
272 
273  float_user_fcn = m_ff;
274  F77_INT last;
275 
276  F77_INT inf;
277  switch (m_type)
278  {
279  case bound_to_inf:
280  inf = 1;
281  break;
282 
283  case neg_inf_to_bound:
284  inf = -1;
285  break;
286 
287  case doubly_infinite:
288  inf = 2;
289  break;
290 
291  default:
292  assert (0);
293  break;
294  }
295 
296  float abs_tol = single_precision_absolute_tolerance ();
297  float rel_tol = single_precision_relative_tolerance ();
298 
299  // NEVAL and IER are output only parameters and F77_INT can not be a
300  // wider type than octave_idx_type so we can create local variables
301  // here that are the correct type for the Fortran subroutine and then
302  // copy them to the function parameters without needing to preserve
303  // and pass the values to the Fortran subroutine.
304 
305  F77_INT xneval, xier;
306 
307  F77_XFCN (qagi, QAGI, (float_user_function, m_bound, inf, abs_tol, rel_tol,
308  result, abserr, xneval, xier, leniw, lenw,
309  last, piwork, pwork));
310 
311  neval = xneval;
312  ier = xier;
313 
314  return result;
315 }
F77_INT(* quad_float_fcn_ptr)(const float &, int &, float &)
Definition: Quad.cc:42
F77_RET_T F77_FUNC(dqagp, DQAGP)(quad_fcn_ptr
F77_INT(* quad_fcn_ptr)(const double &, int &, double &)
Definition: Quad.cc:41
double(* integrand_fcn)(double x)
Definition: Quad.h:34
float(* float_integrand_fcn)(float x)
Definition: Quad.h:35
N Dimensional Array with copy-on-write semantics.
Definition: Array.h:130
T * fortran_vec()
Size of the specified dimension.
Definition: Array-base.cc:1764
octave_idx_type numel() const
Number of elements in the array.
Definition: Array.h:414
double do_integrate(octave_idx_type &ier, octave_idx_type &neval, double &abserr)
Definition: Quad.cc:96
OCTAVE_NORETURN double do_integrate(octave_idx_type &ier, octave_idx_type &neval, double &abserr)
Definition: Quad.cc:207
@ doubly_infinite
Definition: Quad.h:239
@ bound_to_inf
Definition: Quad.h:239
@ neg_inf_to_bound
Definition: Quad.h:239
OCTAVE_NORETURN double do_integrate(octave_idx_type &ier, octave_idx_type &neval, double &abserr)
Definition: Quad.cc:254
double do_integrate(octave_idx_type &ier, octave_idx_type &neval, double &abserr)
Definition: Quad.cc:143
@ bound_to_inf
Definition: Quad.h:168
@ doubly_infinite
Definition: Quad.h:168
@ neg_inf_to_bound
Definition: Quad.h:168
float single_precision_relative_tolerance() const
Definition: Quad-opts.h:92
double absolute_tolerance() const
Definition: Quad-opts.h:83
float single_precision_absolute_tolerance() const
Definition: Quad-opts.h:89
double relative_tolerance() const
Definition: Quad-opts.h:86
float_integrand_fcn m_ff
Definition: Quad.h:118
integrand_fcn m_f
Definition: Quad.h:117
Vector representing the dimensions (size) of an Array.
Definition: dim-vector.h:94
subroutine dqagi(F, BOUND, INF, EPSABS, EPSREL, RESULT, ABSERR, NEVAL, IER, LIMIT, LENW, LAST, IWORK, WORK)
Definition: dqagi.f:3
subroutine dqagp(F, A, B, NPTS2, POINTS, EPSABS, EPSREL, RESULT, ABSERR, NEVAL, IER, LENIW, LENW, LAST, IWORK, WORK)
Definition: dqagp.f:3
float F77_REAL
Definition: f77-fcn.h:303
#define F77_XFCN(f, F, args)
Definition: f77-fcn.h:45
double F77_DBLE
Definition: f77-fcn.h:302
octave_f77_int_type F77_INT
Definition: f77-fcn.h:306
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)
F77_RET_T const F77_DBLE * x
subroutine qagi(f, bound, inf, epsabs, epsrel, result, abserr, neval, ier, limit, lenw, last, iwork, work)
Definition: qagi.f:3
subroutine qagp(f, a, b, npts2, points, epsabs, epsrel, result, abserr, neval, ier, leniw, lenw, last, iwork, work)
Definition: qagp.f:3