Mercurial > jwe > octave
changeset 24062:6570fdb7d3a0
integral.m: Pass tolerances to underlying integrators, correct precision in BIST tests (bug #42037).
* integral.m: Pass correct default AbsTol to quadv if necessary. Use correct
tolerances in assert statements of BIST tests (positive for absolute, negative
for relative).
author | Rik <rik@octave.org> |
---|---|
date | Wed, 20 Sep 2017 10:23:16 -0700 |
parents | a1801e80bb11 |
children | c81ed514ca2c |
files | scripts/general/integral.m |
diffstat | 1 files changed, 35 insertions(+), 38 deletions(-) [+] |
line wrap: on
line diff
--- a/scripts/general/integral.m Wed Sep 20 16:56:10 2017 +0200 +++ b/scripts/general/integral.m Wed Sep 20 10:23:16 2017 -0700 @@ -82,7 +82,7 @@ ## Let quadgk function handle input checks on function and limits. q = quadgk (f, a, b); else - ## Parse options to determine how to call integrator + ## Parse options to determine how to call integrator. abstol = []; reltol = []; waypoints = []; @@ -109,28 +109,30 @@ endswitch endwhile - if (arrayvalued) - ## FIXME: replace warning with arrayfun(?) call to quadgk + if (! arrayvalued) + ## quadgk will accept empty values of optional parameters. + q = quadgk (f, a, b, + "AbsTol", abstol, "RelTol", reltol, "WayPoints", waypoints); + else + ## FIXME: Replace warning with array compatible call to quadgk if (! isempty (waypoints)) warning(["integral: array-valued quadrature routine currently ", ... "unable to handle WayPoints. WayPoints are ignored."]); endif - ## FIXME: remove warning once we have reltol compatible arrayval'd - ## quad or arrayfun call to quadgk. + ## FIXME: Remove warning once we have reltol compatible arrayval'd + ## quad or arrayfun call to quadgk. if (! isempty (reltol)) warning(["integral: array-valued quadrature only accepts AbsTol.", ... " RelTol ignored."]); endif - ## quadv accepts empty abstol input. - q = quadv (f, a, b, abstol); + if (isempty (abstol)) + issingle = isa (a, "single") || isa (b, "single"); + abstol = ifelse (issingle, 1e-5, 1e-10); + endif - else - ## quadgk will accept empty values of optional parameters - q = quadgk (f, a, b, "AbsTol", abstol, "RelTol", reltol, ... - "WayPoints", waypoints); - + q = quadv (f, a, b, abstol); endif endif @@ -142,12 +144,12 @@ %! f = @(x) exp (-x.^2) .* log (x).^2; %! emgamma = 0.57721566490153286; %! exact = (sqrt (pi)*(8*log (2)^2+8*emgamma*log (2)+pi^2+2*emgamma^2))/16; -%! assert (integral (f, 0, Inf), exact, 1e-6); -%! assert (integral (f, 0, Inf, "RelTol", 1e-12), exact, 1e-12); +%! assert (integral (f, 0, Inf), exact, -1e-6); +%! assert (integral (f, 0, Inf, "RelTol", 1e-12), exact, -1e-12); %!test # with parameter %! f = @(x, c) 1 ./ (x.^3 - 2*x - c); -%! assert (integral (@(x) f(x,5), 0, 2), -0.4605015338467329, 1e-12); +%! assert (integral (@(x) f(x,5), 0, 2), -0.4605015338467329, 1e-10); %!test # with tolerances %! f = @(x) log(x); @@ -155,7 +157,7 @@ %!test # waypoints %! f = @(x) 1./(2.*x-1); -%! assert (integral (f, 0, 0, "Waypoints", [1+1i, 1-1i]), -pi*1i, 1e-12); +%! assert (integral (f, 0, 0, "Waypoints", [1+1i, 1-1i]), -pi*1i, 1e-10); %!test # test array function %! f = @(x) sin ((1:5)*x); @@ -164,36 +166,31 @@ %!test %! f = @(x) x.^5 .* exp (-x) .* sin (x); -%! assert (integral (f, 0, inf, "RelTol", 1e-8, "AbsTol", 1e-12), -15, 2e-12); +%! assert (integral (f, 0, inf, "RelTol", 1e-8, "AbsTol", 1e-12), -15, -1e-8); ## tests from quadgk -%!test -%!assert (integral (@sin,-pi,pi), 0, 1e-6); -%!assert (integral (inline ("sin"),-pi,pi), 0, 1e-6); -%!assert (integral ("sin",-pi,pi), 0, 1e-6); -%!assert (integral (@sin,-pi,pi), 0, 1e-6); - -%!assert (integral (@sin,-pi,0), -2, 1e-6); -%!assert (integral (@sin,0,pi), 2, 1e-6); -%!assert (integral (@(x) 1./sqrt (x),0,1), 2, 1e-6); -%!assert (integral (@(x) abs (1 - x.^2),0,2, "Waypoints", 1), 2, 1e-6); -%!assert (integral (@(x) 1./(sqrt (x) .* (x+1)),0,Inf), pi, 1e-6); -%!assert (integral (@(z) log (z),1+i,1+i, "WayPoints", [1-i, -1,-i, -1+i]), ... -%! -pi * 1i, 1e-6); -%!assert (integral (@(x) exp (-x .^ 2),-Inf,Inf), sqrt (pi), 1e-6); -%!assert (integral (@(x) exp (-x .^ 2),-Inf,0), sqrt (pi)/2, 1e-6); +%!assert (integral (inline ("sin"),-pi,pi), 0, 1e-10); +%!assert (integral ("sin",-pi,pi), 0, 1e-10); +%!assert (integral (@sin,-pi,pi), 0, 1e-10); +%!assert (integral (@sin,-pi,0), -2, 1e-10); +%!assert (integral (@sin,0,pi), 2, 1e-10); +%!assert (integral (@(x) 1./sqrt (x), 0, 1), 2, 1e-10); +%!assert (integral (@(x) abs (1 - x.^2), 0, 2, "Waypoints", 1), 2, 1e-10); +%!assert (integral (@(x) 1./(sqrt (x) .* (x+1)),0,Inf), pi, 1e-10); +%!assert (integral (@(z) log (z),1+i,1+i, "WayPoints", [1-i, -1,-i, -1+i]), +%! -pi * 1i, 1e-10); +%!assert (integral (@(x) exp (-x .^ 2),-Inf,Inf), sqrt (pi), -1e-6); +%!assert (integral (@(x) exp (-x .^ 2),-Inf,0), sqrt (pi)/2, -1e-6); ## tests from quadv ## Test vector-valued functions -%!assert (integral (@(x) [(sin (x)), (sin (2*x))], 0, pi, "ArrayValued", 1), ... -%! [2, 0], 1e-5); +%!assert (integral (@(x) [(sin (x)), (sin (2*x))], 0, pi, "ArrayValued", 1), +%! [2, 0], 1e-10); ## Test matrix-valued functions %!test -%! warning ("off", "Octave:divide-by-zero", "local"); -%! assert (integral (@(x) [x, x, x; x, 1./sqrt(x), x; x, x, x], 0, 1, ... -%! "ArrayValued", 1), ... -%! [0.5, 0.5, 0.5; 0.5, 2, 0.5; 0.5, 0.5, 0.5], 1e-5); +%! assert (integral (@(x) [x,x,x; x,exp(x),x; x,x,x], 0, 1, "ArrayValued", 1), +%! [0.5,0.5,0.5; 0.5,(exp (1) - 1),0.5; 0.5,0.5,0.5], 1e-10); ## Test input validation %!error integral (@sin)