integrate1d#
Purpose#
Integrates a user-defined function, using adaptive quadrature, over a user defined interval
Format#
- y = integrate1d(&fct, x_min, x_max[, ...[, ctl]])#
- y = integrate1d(&fct, x_min, x_max, ctl)
- Parameters:
&fct (scalar) – pointer to the procedure containing the function to be integrated
x_min (scalar) – starting point for the integration
x_max (scalar) – ending point for the integration
... (any) – Optional input. a variable number of extra arguments to pass to the user function. These arguments will be passed to the user function untouched.
ctl (struct) –
Optional input. an instance of an
integrateControl
structure with membersctl.subDivisions
scalar, maximum number of divisions of the region (x_min, x_max)
ctl.absTol
scalar, absolute accuracy requested.
ctl.relTol
scalar, relative accuracy requested.
- Returns:
y (scalar) – the estimated integral of \(f(x)\) evaluated over the interval (x_min, x_max)
Examples#
Basic Example#
Calculate the integral \(\int_{0}^{3}\frac{1}{x+1}dx\)
// Define procedure to be integrated
proc (1) = fct(x);
retp(1 ./ (x + 1));
endp;
// Calculate integral for procedure 'fct', from 0 - 3
ans = integrate1d(&fct, 0, 3);
will result in:
ans = 1.3862943611
Passing extra arguments to the user function#
Calculate the integral \(\int_{-1000}^{1000} e^{-\frac{x^2}{2xa}dx}, a=3\)
// Define procedure to be integrated
proc (1) = myProc(x, var);
retp(exp( -(x .* x) / (2 .* var) ));
endp;
// Define limits of integration
x_min = -1000;
x_max = 1000;
// Define extra argument for procedure 'myProc'
a = 3;
ans = integrate1d(&myProc, x_min, x_max, a);
will result in:
ans = 4.3416075273
Bound at negative infinity#
Calculate the integral \(\int_{-\infty}^{0}\frac{1}{\sigma\sqrt{2\pi}}e^{-\frac{(x − \mu)^2}{2\sigma^2}}dx\)
// Define procedure to be integrated
proc (1) = myPdfn(x, mu, sigma);
retp(pdfn((x - mu) ./ sigma) ./ sigma);
endp;
// Set bounds of integration to be (-Inf, 0)
x_min = __INFN;
x_max = 0;
// Extra inputs for user function
mu = 0.33;
sigma = 7;
ans = integrate1d(&myPdfn, x_min, x_max, mu, sigma);
will result in:
ans = 0.481199685115
Using a control structure#
Calculate the integral \(\int_{-\infty}^{0}\frac{1}{\sigma\sqrt{2\pi}}e^{-\frac{(x − \mu)^2}{2\sigma^2}}dx\)
// Define procedure to be integrated
proc (1) = myPdfn(x, mu, sigma);
retp(pdfn((x - mu) ./ sigma) ./ sigma);
endp;
// Set bounds of integration to be (0, +Inf)
x_min = 0;
x_max = __INFP;
// Extra inputs for user function
mu = 0.33;
sigma = 7;
/*
** Declare instance of 'integrateControl' structure
** and fill with default values
*/
struct integrateControl ctl;
ctl = integrateControlCreate();
// Lower required tolerance for faster return
ctl.absTol = 1e-2;
ans = integrate1d(&myPdfn, x_min, x_max, mu, sigma, ctl);
will result in:
ans = 0.518798668212
Remarks#
The user-provided function must be able to accept a vector of scalar
values and return a vector of outputs. Make sure to use the element by
element operators (.* ./
) instead of the overloaded matrix operators
(* /
). For example, the following procedure:
proc (1) = myProc(x);
local ret;
ret = x / (x * x);
retp(ret);
endp;
will work as expected for a scalar input. For example:
a = 2;
b = 3;
c = myProc(a);
d = myProc(b);
will assign c to be equal to 0.5 and d to be equal to 0.334. However, if we pass in a vector like this:
a = { 2,
3 };
c = myProc(a);
we will cause an the error matrices not conformable
when we try to
multiply the incoming 2x1 vector times itself inside of myProc. To avoid
this, we simply need to change the operators *
and /
to the
element-by-element versions by prepending the operator with a dot like
this:
proc (1) = myProc(x);
local ret;
ret = x ./ (x .* x);
retp(ret);
endp;
Source#
integrate.src
See also
Functions integrateControlCreate()
, inthp2()
, inthp3()
, inthp4()