Skip to content

Commit

Permalink
integrate() now signals an error when one of its bounds is longer tha…
Browse files Browse the repository at this point in the history
…n one

git-svn-id: https://svn.r-project.org/R/trunk@70401 00db46b3-68df-0310-9c12-caf00c1e9a41
  • Loading branch information
maechler committed Mar 30, 2016
1 parent cd3598f commit 53c4fa4
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 10 deletions.
2 changes: 1 addition & 1 deletion doc/NEWS.Rd
Expand Up @@ -8,7 +8,7 @@
\section{\Rlogo CHANGES IN R-devel}{
\subsection{NEW FEATURES}{
\itemize{
\item Placeholder.
\item User errors such as \code{integrate(f, 0:1, 2)} are now caught.
}
}
\subsection{DEPRECATED AND DEFUNCT}{
Expand Down
12 changes: 6 additions & 6 deletions src/library/stats/R/integrate.R
@@ -1,7 +1,7 @@
# File src/library/stats/R/integrate.R
# Part of the R package, https://www.R-project.org
#
# Copyright (C) 1995-2012 The R Core Team
# Copyright (C) 1995-2016 The R Core Team
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -34,20 +34,20 @@ integrate <- function(f, lower, upper, ..., subdivisions = 100L,
as.double(abs.tol), as.double(rel.tol),
limit = limit)
} else { # indefinite integral
if(is.na(lower) || is.na(upper)) stop("a limit is missing")
if(anyNA(lower) || anyNA(upper)) stop("a limit is NA or NaN")
if (is.finite(lower)) {
inf <- 1
inf <- 1L
bound <- lower
} else if (is.finite(upper)) {
inf <- -1
inf <- -1L
bound <- upper
} else {
inf <- 2
inf <- 2L
bound <- 0.0
}
wk <- .External(C_call_dqagi,
ff, rho = environment(),
as.double(bound), as.integer(inf),
as.double(bound), inf,
as.double(abs.tol), as.double(rel.tol),
limit = limit)
}
Expand Down
10 changes: 9 additions & 1 deletion src/library/stats/man/integrate.Rd
@@ -1,6 +1,6 @@
% File src/library/stats/man/integrate.Rd
% Part of the R package, https://www.R-project.org
% Copyright 1995-2014 R Core Team
% Copyright 1995-2016 R Core Team
% Distributed under GPL 2 or later

\name{integrate}
Expand Down Expand Up @@ -43,6 +43,10 @@ integrate(f, lower, upper, \dots, subdivisions = 100L,
\code{rel.tol} cannot be less than \code{max(50*.Machine$double.eps,
0.5e-28)} if \code{abs.tol <= 0}.
In \R versions \eqn{\le}{<=} 3.2.x, the first entry of
\code{lower} and \code{upper} were used where as an error is signalled
now if they are not of length one.
}
\note{
Like all numerical integration routines, these evaluate the function
Expand Down Expand Up @@ -110,6 +114,10 @@ integrate(dnorm, 0, 200)
integrate(dnorm, 0, 2000)
integrate(dnorm, 0, 20000) ## fails on many systems
integrate(dnorm, 0, Inf) ## works
\dontshow{tools::assertError(}
integrate(dnorm, 0:1, 20) #-> error!
## "silently" gave integrate(dnorm, 0, 20) in earlier versions of R
\dontshow{ , verbose=TRUE)}
}
\keyword{math}
\keyword{utilities}
12 changes: 11 additions & 1 deletion src/library/stats/src/integrate.c
Expand Up @@ -25,7 +25,14 @@
#include <Rinternals.h>
#include <R_ext/Applic.h>

/* alled via .External(.) :*/
#ifdef ENABLE_NLS
#include <libintl.h>
#define _(String) dgettext ("stats", String)
#else
#define _(String) (String)
#endif

/* called via .External(.) :*/
SEXP call_dqags(SEXP args);
SEXP call_dqagi(SEXP args);

Expand Down Expand Up @@ -74,7 +81,9 @@ SEXP call_dqags(SEXP args)
args = CDR(args);
is.f = CAR(args); args = CDR(args);
is.env = CAR(args); args = CDR(args);
if(length(CAR(args)) > 1) error(_("'%s' must be of length one"), "lower");
lower = asReal(CAR(args)); args = CDR(args);
if(length(CAR(args)) > 1) error(_("'%s' must be of length one"), "upper");
upper = asReal(CAR(args)); args = CDR(args);
epsabs = asReal(CAR(args)); args = CDR(args);
epsrel = asReal(CAR(args)); args = CDR(args);
Expand Down Expand Up @@ -116,6 +125,7 @@ SEXP call_dqagi(SEXP args)
args = CDR(args);
is.f = CAR(args); args = CDR(args);
is.env = CAR(args); args = CDR(args);
if(length(CAR(args)) > 1) error(_("'%s' must be of length one"), "bound");
bound = asReal(CAR(args)); args = CDR(args);
inf = asInteger(CAR(args)); args = CDR(args);
epsabs = asReal(CAR(args)); args = CDR(args);
Expand Down
11 changes: 10 additions & 1 deletion tests/Examples/stats-Ex.Rout.save
@@ -1,5 +1,5 @@

R Under development (unstable) (2016-03-28 r70390) -- "Unsuffered Consequences"
R Under development (unstable) (2016-03-29 r70391) -- "Unsuffered Consequences"
Copyright (C) 2016 The R Foundation for Statistical Computing
Platform: x86_64-pc-linux-gnu (64-bit)

Expand Down Expand Up @@ -8074,6 +8074,15 @@ Error in integrate(f, 0, 1) :
0 with absolute error < 0
> integrate(dnorm, 0, Inf) ## works
0.5 with absolute error < 4.7e-05
> ## Don't show:
> tools::assertError(
+ ## End(Don't show)
+ integrate(dnorm, 0:1, 20) #-> error!
+ ## "silently" gave integrate(dnorm, 0, 20) in earlier versions of R
+ ## Don't show:
+ , verbose=TRUE)
Asserted error: 'lower' must be of length one
> ## End(Don't show)
>
>
>
Expand Down

0 comments on commit 53c4fa4

Please sign in to comment.