Skip to content

Commit 682bd7a

Browse files
committed
Extension of fastFindInterval
1 parent 35d8ffe commit 682bd7a

File tree

9 files changed

+123
-28
lines changed

9 files changed

+123
-28
lines changed

DESCRIPTION

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
Package: spatstat.utils
2-
Version: 3.1-3
3-
Date: 2025-03-15
2+
Version: 3.1-3.001
3+
Date: 2025-04-04
44
Title: Utility Functions for 'spatstat'
55
Authors@R: c(person("Adrian", "Baddeley",
66
role = c("aut", "cre"),

NEWS

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,16 @@
11

2+
CHANGES IN spatstat.utils VERSION 3.1-3.001
3+
4+
OVERVIEW
5+
6+
o Extension to 'fastFindInterval'.
7+
8+
SIGNIFICANT USER-VISIBLE CHANGES
9+
10+
o fastFindInterval
11+
New argument 'left.open' controls whether intervals
12+
are left-open, right-closed or left-closed, right-open.
13+
214
CHANGES IN spatstat.utils VERSION 3.1-3
315

416
OVERVIEW

R/utilseq.R

Lines changed: 38 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
#'
44
#' Utilities for sequences, vectors, ranges of values
55
#'
6-
#' $Revision: 1.23 $ $Date: 2024/06/16 09:07:13 $
6+
#' $Revision: 1.25 $ $Date: 2025/04/04 07:00:04 $
77
#'
88
#' ==>> ORIGINAL FILE is in spatstat/develop/Spatstat/R <<==
99

@@ -271,24 +271,37 @@ adjustthinrange <- function(ur,vstep,vr) {
271271
return(ur)
272272
}
273273

274-
fastFindInterval <- function(x, b, labels=FALSE, reltol=0.001, dig.lab=3L) {
274+
fastFindInterval <- function(x, b, labels=FALSE, reltol=0.001, dig.lab=3L,
275+
left.open=TRUE) {
275276
nintervals <- length(b) - 1
276277
nx <- length(x)
277278
if(nx == 0) {
278279
y <- integer(0)
279280
} else if(evenly.spaced(b, reltol)) {
280281
## breaks are equally spaced
281-
zz <- .C(C_fastinterv,
282-
x = as.double(x),
283-
n = as.integer(nx),
284-
brange = as.double(range(b)),
285-
nintervals = as.integer(nintervals),
286-
y = as.integer(integer(nx))
287-
)
282+
if(left.open) {
283+
## intervals are left-open, right-closed ( ] except the first interval
284+
zz <- .C(C_fastCinterv,
285+
x = as.double(x),
286+
n = as.integer(nx),
287+
brange = as.double(range(b)),
288+
nintervals = as.integer(nintervals),
289+
y = as.integer(integer(nx))
290+
)
291+
} else {
292+
## intervals are left-closed, right-open [ ) except the last interval
293+
zz <- .C(C_fastFinterv,
294+
x = as.double(x),
295+
n = as.integer(nx),
296+
brange = as.double(range(b)),
297+
nintervals = as.integer(nintervals),
298+
y = as.integer(integer(nx))
299+
)
300+
}
288301
y <- zz$y
289302
} else {
290303
## use R's interval search algorithm
291-
y <- findInterval(x, b, rightmost.closed=TRUE)
304+
y <- findInterval(x, b, rightmost.closed=TRUE, left.open=left.open)
292305
}
293306
if(labels) {
294307
#' digits in labels code copied from base::cut.default (with adaptations)
@@ -297,11 +310,21 @@ fastFindInterval <- function(x, b, labels=FALSE, reltol=0.001, dig.lab=3L) {
297310
if(all(ch.br[-1L] != ch.br[1L:nintervals]))
298311
break
299312
}
300-
blab <- paste0("[",
301-
ch.br[1:nintervals],
302-
",",
303-
ch.br[-1L],
304-
c(rep(")", nintervals-1), "]"))
313+
if(left.open) {
314+
## left-open except the first one
315+
blab <- paste0(c("[", rep("(", nintervals-1)),
316+
ch.br[1:nintervals],
317+
",",
318+
ch.br[-1L],
319+
"]")
320+
} else {
321+
## right-open except the last one
322+
blab <- paste0("[",
323+
ch.br[1:nintervals],
324+
",",
325+
ch.br[-1L],
326+
c(rep(")", nintervals-1), "]"))
327+
}
305328
y <- as.integer(y)
306329
levels(y) <- as.character(blab)
307330
class(y) <- "factor"

inst/doc/packagesizes.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,3 +28,4 @@ date version nhelpfiles nobjects ndatasets Rlines srclines
2828
"2024-08-17" "3.1-0" 41 189 0 3613 2429
2929
"2024-11-02" "3.1-1" 41 189 0 3614 2429
3030
"2025-03-15" "3.1-3" 42 192 0 3650 2429
31+
"2025-04-04" "3.1-3.001" 42 192 0 3673 2462

inst/info/packagesizes.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,3 +28,4 @@ date version nhelpfiles nobjects ndatasets Rlines srclines
2828
"2024-08-17" "3.1-0" 41 189 0 3613 2429
2929
"2024-11-02" "3.1-1" 41 189 0 3614 2429
3030
"2025-03-15" "3.1-3" 42 192 0 3650 2429
31+
"2025-04-04" "3.1-3.001" 42 192 0 3673 2462

man/fastFindInterval.Rd

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@
88
for intervals which are equally-spaced.
99
}
1010
\usage{
11-
fastFindInterval(x, b, labels = FALSE, reltol = 0.001, dig.lab = 3L)
11+
fastFindInterval(x, b, labels = FALSE, reltol = 0.001, dig.lab = 3L,
12+
left.open=TRUE)
1213
}
1314
\arguments{
1415
\item{x}{
@@ -29,6 +30,11 @@ fastFindInterval(x, b, labels = FALSE, reltol = 0.001, dig.lab = 3L)
2930
Integer. Maximum number of digits to use in the labels
3031
for the intervals, when \code{labels=TRUE}.
3132
}
33+
\item{left.open}{
34+
Logical value specifying whether intervals are left-open and
35+
right-closed (\code{left.open=TRUE}, the default)
36+
or left-closed and right-open (\code{left.open=FALSE}).
37+
}
3238
}
3339
\details{
3440
This is an alternative to
@@ -38,11 +44,30 @@ fastFindInterval(x, b, labels = FALSE, reltol = 0.001, dig.lab = 3L)
3844

3945
If \code{labels=FALSE} (the default), the result is an integer vector
4046
giving, for each value \code{x[i]}, the index \code{j} of the interval that
41-
contains \code{x[i]}, such that \code{b[j] <= x[i] < b[j + 1]}.
47+
contains \code{x[i]}:
48+
\itemize{
49+
\item
50+
If \code{left.open=TRUE} (the default), the intervals are left-open
51+
and right-closed, except for the first interval. This means that
52+
\code{x[i]} belongs to the \code{j}th interval if
53+
\code{b[j] < x[i] <= b[j+1]} for \code{j > 1}
54+
and \code{b[1] <= x[i] <= b[2]} for \code{j=1}.
55+
\item
56+
If \code{left.open=FALSE}, the intervals are left-closed
57+
and right-open, except for the last interval. This means that
58+
\code{x[i]} belongs to the \code{j}th interval if
59+
\code{b[j] <= x[i] < b[j+1]} for \code{j < m}
60+
and \code{b[m] <= x[i] <= b[m+1]} for \code{j=m}
61+
where \code{m = length(b)-1} is the number of intervals.
62+
}
4263

4364
If \code{labels=TRUE}, the result is a factor, and the levels are
4465
synthetic labels for the intervals, similar to those produced by
4566
\code{\link[base]{findInterval}}.
67+
68+
Note that the default value of \code{left.open}
69+
is \code{TRUE} for \code{fastFindInterval}
70+
but \code{FALSE} for \code{\link[base]{findInterval}}.
4671
}
4772
\value{
4873
Integer vector, or factor.

src/fastinterv.c

Lines changed: 38 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,19 +8,25 @@
88
Fast version of findInterval when breaks are known to be evenly spaced
99
and are known to embrace the data.
1010
11-
$Revision: 1.5 $ $Date: 2022/10/19 03:29:04 $
11+
fastCinterv Intervals are left-open, right-closed ( ] except first one
12+
"ceiling intervals"
13+
14+
fastFinterv Intervals are left-closed, right-open [ ) except last one
15+
"floor intervals"
16+
17+
$Revision: 1.6 $ $Date: 2025/04/04 06:58:25 $
1218
1319
Copyright (C) Adrian Baddeley, Ege Rubak and Rolf Turner 2001-2018
1420
Licence: GNU Public Licence >= 2
1521
1622
*/
1723

18-
void fastinterv(
19-
double *x, /* values to be classified */
20-
int *n, /* number of x values */
21-
double *brange, /* range of breakpoints */
22-
int *nintervals, /* number of intervals */
23-
int *y /* resulting indices (start from 1) */
24+
void fastCinterv(
25+
double *x, /* values to be classified */
26+
int *n, /* number of x values */
27+
double *brange, /* range of breakpoints */
28+
int *nintervals, /* number of intervals */
29+
int *y /* resulting indices (start from 1) */
2430
) {
2531
double bmin, bmax, db;
2632
int i, j, m, N;
@@ -40,3 +46,28 @@ void fastinterv(
4046
}
4147

4248

49+
void fastFinterv(
50+
double *x, /* values to be classified */
51+
int *n, /* number of x values */
52+
double *brange, /* range of breakpoints */
53+
int *nintervals, /* number of intervals */
54+
int *y /* resulting indices (start from 1) */
55+
) {
56+
double bmin, bmax, db;
57+
int i, j, m, N;
58+
59+
m = *nintervals;
60+
N = *n;
61+
62+
bmin = brange[0];
63+
bmax = brange[1];
64+
db = (bmax - bmin)/m;
65+
66+
for(i = 0; i < N; i++) {
67+
j = 1 + (int) floor((x[i] - bmin)/db);
68+
if(j <= 0) { j = 1; } else if(j > m) { j = m; }
69+
y[i] = j;
70+
}
71+
}
72+
73+

src/init.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@ static const R_CMethodDef CEntries[] = {
2323
{"CUmatch2int", (DL_FUNC) &CUmatch2int, 7},
2424
{"CUmatch3int", (DL_FUNC) &CUmatch3int, 9},
2525
{"drevcumsum", (DL_FUNC) &drevcumsum, 2},
26-
{"fastinterv", (DL_FUNC) &fastinterv, 5},
26+
{"fastCinterv", (DL_FUNC) &fastCinterv, 5},
27+
{"fastFinterv", (DL_FUNC) &fastFinterv, 5},
2728
{"inxyp", (DL_FUNC) &inxyp, 8},
2829
{"irevcumsum", (DL_FUNC) &irevcumsum, 2},
2930
{"nnd2segs", (DL_FUNC) &nnd2segs, 10},

src/proto.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@ void CUmatch2int(int *, int *, int *, int *, int *, int *, int *);
2323
void CSmatch3int(int *, int *, int *, int *, int *, int *, int *, int *, int *);
2424
void CUmatch3int(int *, int *, int *, int *, int *, int *, int *, int *, int *);
2525
void irevcumsum(int *, int *); void drevcumsum(double *, int *);
26-
void fastinterv(double *, int *, double *, int *, int *);
26+
void fastCinterv(double *, int *, double *, int *, int *);
27+
void fastFinterv(double *, int *, double *, int *, int *);
2728
void Cmatchxy(int *, double *, double *, int *, double *, double *, int *);
2829
void inxyp(double *, double *, double *, double *, int *, int *, int *, int *);
2930
void prdist2segs(double *, double *, int *, double *, double *, double *, double *, int *, double *, double *);

0 commit comments

Comments
 (0)