Skip to content

Commit ef5bd1e

Browse files
Sugar cumprod, cummin, cummax with unit tests
1 parent 9ec9943 commit ef5bd1e

File tree

6 files changed

+331
-0
lines changed

6 files changed

+331
-0
lines changed
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
// -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; tab-width: 8 -*-
2+
//
3+
// cumsum.h: Rcpp R/C++ interface class library -- cumsum
4+
//
5+
// Copyright (C) 2010 - 2011 Dirk Eddelbuettel and Romain Francois
6+
//
7+
// This file is part of Rcpp.
8+
//
9+
// Rcpp is free software: you can redistribute it and/or modify it
10+
// under the terms of the GNU General Public License as published by
11+
// the Free Software Foundation, either version 2 of the License, or
12+
// (at your option) any later version.
13+
//
14+
// Rcpp is distributed in the hope that it will be useful, but
15+
// WITHOUT ANY WARRANTY; without even the implied warranty of
16+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17+
// GNU General Public License for more details.
18+
//
19+
// You should have received a copy of the GNU General Public License
20+
// along with Rcpp. If not, see <http://www.gnu.org/licenses/>.
21+
22+
#ifndef Rcpp__sugar__cummax_h
23+
#define Rcpp__sugar__cummax_h
24+
25+
namespace Rcpp{
26+
namespace sugar{
27+
28+
template <int RTYPE, bool NA, typename T>
29+
class Cummax : public Lazy< Rcpp::Vector<RTYPE>, Cummax<RTYPE, NA, T> > {
30+
public:
31+
typedef typename Rcpp::VectorBase<RTYPE, NA, T> VEC_TYPE;
32+
typedef typename Rcpp::traits::storage_type<RTYPE>::type STORAGE;
33+
typedef Rcpp::Vector<RTYPE> VECTOR;
34+
35+
Cummax(const VEC_TYPE& object_) : object(object_) {}
36+
37+
VECTOR get() const {
38+
R_xlen_t n = object.size();
39+
VECTOR result(n, Rcpp::traits::get_na<RTYPE>());
40+
STORAGE current = object[0];
41+
42+
if (Rcpp::traits::is_na<RTYPE>(current)) return result;
43+
result[0] = current;
44+
for (R_xlen_t i = 1; i < n; i++) {
45+
current = object[i];
46+
if (Rcpp::traits::is_na<RTYPE>(current)) return result;
47+
result[i] = result[i-1] > current ? result[i-1] : current;
48+
}
49+
return result ;
50+
}
51+
private:
52+
const VEC_TYPE& object;
53+
};
54+
55+
} // sugar
56+
57+
58+
template <bool NA, typename T>
59+
inline sugar::Cummax<INTSXP, NA, T> cummax(const VectorBase<INTSXP, NA, T>& t) {
60+
return sugar::Cummax<INTSXP, NA, T>(t);
61+
}
62+
63+
template <bool NA, typename T>
64+
inline sugar::Cummax<REALSXP, NA, T> cummax(const VectorBase<REALSXP, NA, T>& t) {
65+
return sugar::Cummax<REALSXP, NA, T>(t);
66+
}
67+
68+
69+
} // Rcpp
70+
#endif // Rcpp__sugar__cummax_h
71+
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
// -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; tab-width: 8 -*-
2+
//
3+
// cumsum.h: Rcpp R/C++ interface class library -- cumsum
4+
//
5+
// Copyright (C) 2010 - 2011 Dirk Eddelbuettel and Romain Francois
6+
//
7+
// This file is part of Rcpp.
8+
//
9+
// Rcpp is free software: you can redistribute it and/or modify it
10+
// under the terms of the GNU General Public License as published by
11+
// the Free Software Foundation, either version 2 of the License, or
12+
// (at your option) any later version.
13+
//
14+
// Rcpp is distributed in the hope that it will be useful, but
15+
// WITHOUT ANY WARRANTY; without even the implied warranty of
16+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17+
// GNU General Public License for more details.
18+
//
19+
// You should have received a copy of the GNU General Public License
20+
// along with Rcpp. If not, see <http://www.gnu.org/licenses/>.
21+
22+
#ifndef Rcpp__sugar__cummin_h
23+
#define Rcpp__sugar__cummin_h
24+
25+
namespace Rcpp{
26+
namespace sugar{
27+
28+
template <int RTYPE, bool NA, typename T>
29+
class Cummin : public Lazy< Rcpp::Vector<RTYPE>, Cummin<RTYPE, NA, T> > {
30+
public:
31+
typedef typename Rcpp::VectorBase<RTYPE, NA, T> VEC_TYPE;
32+
typedef typename Rcpp::traits::storage_type<RTYPE>::type STORAGE;
33+
typedef Rcpp::Vector<RTYPE> VECTOR;
34+
35+
Cummin(const VEC_TYPE& object_) : object(object_) {}
36+
37+
VECTOR get() const {
38+
R_xlen_t n = object.size();
39+
VECTOR result(n, Rcpp::traits::get_na<RTYPE>());
40+
STORAGE current = object[0];
41+
42+
if (Rcpp::traits::is_na<RTYPE>(current)) return result;
43+
result[0] = current;
44+
for (R_xlen_t i = 1; i < n; i++) {
45+
current = object[i];
46+
if (Rcpp::traits::is_na<RTYPE>(current)) return result;
47+
result[i] = result[i-1] < current ? result[i-1] : current;
48+
}
49+
return result ;
50+
}
51+
private:
52+
const VEC_TYPE& object;
53+
};
54+
55+
} // sugar
56+
57+
58+
template <bool NA, typename T>
59+
inline sugar::Cummin<INTSXP, NA, T> cummin(const VectorBase<INTSXP, NA, T>& t) {
60+
return sugar::Cummin<INTSXP, NA, T>(t);
61+
}
62+
63+
template <bool NA, typename T>
64+
inline sugar::Cummin<REALSXP, NA, T> cummin(const VectorBase<REALSXP, NA, T>& t) {
65+
return sugar::Cummin<REALSXP, NA, T>(t);
66+
}
67+
68+
69+
} // Rcpp
70+
#endif // Rcpp__sugar__cummin_h
71+
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
// -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; tab-width: 8 -*-
2+
//
3+
// cumsum.h: Rcpp R/C++ interface class library -- cumsum
4+
//
5+
// Copyright (C) 2010 - 2011 Dirk Eddelbuettel and Romain Francois
6+
//
7+
// This file is part of Rcpp.
8+
//
9+
// Rcpp is free software: you can redistribute it and/or modify it
10+
// under the terms of the GNU General Public License as published by
11+
// the Free Software Foundation, either version 2 of the License, or
12+
// (at your option) any later version.
13+
//
14+
// Rcpp is distributed in the hope that it will be useful, but
15+
// WITHOUT ANY WARRANTY; without even the implied warranty of
16+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17+
// GNU General Public License for more details.
18+
//
19+
// You should have received a copy of the GNU General Public License
20+
// along with Rcpp. If not, see <http://www.gnu.org/licenses/>.
21+
22+
#ifndef Rcpp__sugar__cumprod_h
23+
#define Rcpp__sugar__cumprod_h
24+
25+
namespace Rcpp{
26+
namespace sugar{
27+
28+
template <int RTYPE, bool NA, typename T>
29+
class Cumprod : public Lazy< Rcpp::Vector<RTYPE>, Cumprod<RTYPE, NA, T> > {
30+
public:
31+
typedef typename Rcpp::VectorBase<RTYPE, NA, T> VEC_TYPE;
32+
typedef typename Rcpp::traits::storage_type<RTYPE>::type STORAGE;
33+
typedef Rcpp::Vector<RTYPE> VECTOR;
34+
35+
Cumprod(const VEC_TYPE& object_) : object(object_) {}
36+
37+
VECTOR get() const {
38+
R_xlen_t n = object.size();
39+
VECTOR result(n, Rcpp::traits::get_na<RTYPE>());
40+
STORAGE current = object[0];
41+
42+
if (Rcpp::traits::is_na<RTYPE>(current)) return result;
43+
result[0] = current;
44+
for (R_xlen_t i = 1; i < n; i++) {
45+
current = object[i];
46+
if (Rcpp::traits::is_na<RTYPE>(current)) return result;
47+
result[i] = result[i-1] * current;
48+
}
49+
return result ;
50+
}
51+
private:
52+
const VEC_TYPE& object;
53+
};
54+
55+
} // sugar
56+
57+
58+
template <bool NA, typename T>
59+
inline sugar::Cumprod<INTSXP, NA, T> cumprod(const VectorBase<INTSXP, NA, T>& t) {
60+
return sugar::Cumprod<INTSXP, NA, T>(t);
61+
}
62+
63+
template <bool NA, typename T>
64+
inline sugar::Cumprod<REALSXP, NA, T> cumprod(const VectorBase<REALSXP, NA, T>& t) {
65+
return sugar::Cumprod<REALSXP, NA, T>(t);
66+
}
67+
68+
template <bool NA, typename T>
69+
inline sugar::Cumprod<CPLXSXP, NA, T> cumprod(const VectorBase<CPLXSXP, NA, T>& t) {
70+
return sugar::Cumprod<CPLXSXP, NA, T>(t);
71+
}
72+
73+
74+
} // Rcpp
75+
#endif // Rcpp__sugar__cumprod_h
76+

inst/include/Rcpp/sugar/functions/functions.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,4 +76,9 @@
7676

7777
#include <Rcpp/sugar/functions/strings/strings.h>
7878

79+
#include <Rcpp/sugar/functions/cumprod.h>
80+
#include <Rcpp/sugar/functions/cummin.h>
81+
#include <Rcpp/sugar/functions/cummax.h>
82+
7983
#endif
84+

inst/unitTests/cpp/sugar.cpp

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -670,3 +670,49 @@ double meanLogical(Rcpp::LogicalVector x) { return(Rcpp::mean(x)); }
670670
// [[Rcpp::export]]
671671
Rcomplex meanComplex(Rcpp::ComplexVector x) { return(Rcpp::mean(x)); }
672672

673+
674+
// 30 Oct 2015: cumprod, cummin, cummax
675+
676+
// [[Rcpp::export]]
677+
NumericVector runit_cumprod_nv(NumericVector xx){
678+
NumericVector res = cumprod(xx) ;
679+
return res ;
680+
}
681+
682+
// [[Rcpp::export]]
683+
IntegerVector runit_cumprod_iv(IntegerVector xx){
684+
IntegerVector res = cumprod(xx) ;
685+
return res ;
686+
}
687+
688+
// [[Rcpp::export]]
689+
ComplexVector runit_cumprod_cv(ComplexVector xx){
690+
ComplexVector res = cumprod(xx) ;
691+
return res ;
692+
}
693+
694+
// [[Rcpp::export]]
695+
NumericVector runit_cummin_nv(NumericVector xx){
696+
NumericVector res = cummin(xx) ;
697+
return res ;
698+
}
699+
700+
// [[Rcpp::export]]
701+
IntegerVector runit_cummin_iv(IntegerVector xx){
702+
IntegerVector res = cummin(xx) ;
703+
return res ;
704+
}
705+
706+
// [[Rcpp::export]]
707+
NumericVector runit_cummax_nv(NumericVector xx){
708+
NumericVector res = cummax(xx) ;
709+
return res ;
710+
}
711+
712+
// [[Rcpp::export]]
713+
IntegerVector runit_cummax_iv(IntegerVector xx){
714+
IntegerVector res = cummax(xx) ;
715+
return res ;
716+
}
717+
718+

inst/unitTests/runit.sugar.R

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -714,5 +714,67 @@ if (.runThisTest) {
714714
checkEquals(mean(v1), meanLogical(v1), "mean of logical vector")
715715
checkEquals(mean(v2), meanLogical(v2), "mean of logical vector with NA")
716716
}
717+
718+
719+
## 30 Oct 2015: cumprod, cummin, cummax
720+
# base::cumprod defined for numeric, integer, and complex vectors
721+
test.sugar.cumprod_nv <- function() {
722+
fx <- runit_cumprod_nv
723+
x <- rnorm(10)
724+
checkEquals(fx(x), cumprod(x))
725+
x[4] <- NA
726+
checkEquals(fx(x), cumprod(x))
727+
}
728+
729+
test.sugar.cumprod_iv <- function() {
730+
fx <- runit_cumprod_iv
731+
x <- as.integer(rpois(10, 5))
732+
checkEquals(fx(x), cumprod(x))
733+
x[4] <- NA
734+
checkEquals(fx(x), cumprod(x))
735+
}
736+
737+
test.sugar.cumprod_cv <- function() {
738+
fx <- runit_cumprod_cv
739+
x <- rnorm(10) + 2i
740+
checkEquals(fx(x), cumprod(x))
741+
x[4] <- NA
742+
checkEquals(fx(x), cumprod(x))
743+
}
744+
745+
# base::cummin defined for numeric and integer vectors
746+
test.sugar.cummin_nv <- function() {
747+
fx <- runit_cummin_nv
748+
x <- rnorm(10)
749+
checkEquals(fx(x), cummin(x))
750+
x[4] <- NA
751+
checkEquals(fx(x), cummin(x))
752+
}
753+
754+
test.sugar.cummin_iv <- function() {
755+
fx <- runit_cummin_iv
756+
x <- as.integer(rpois(10, 5))
757+
checkEquals(fx(x), cummin(x))
758+
x[4] <- NA
759+
checkEquals(fx(x), cummin(x))
760+
}
761+
762+
# base::cummax defined for numeric and integer vectors
763+
test.sugar.cummax_nv <- function() {
764+
fx <- runit_cummax_nv
765+
x <- rnorm(10)
766+
checkEquals(fx(x), cummax(x))
767+
x[4] <- NA
768+
checkEquals(fx(x), cummax(x))
769+
}
770+
771+
test.sugar.cummax_iv <- function() {
772+
fx <- runit_cummax_iv
773+
x <- as.integer(rpois(10, 5))
774+
checkEquals(fx(x), cummax(x))
775+
x[4] <- NA
776+
checkEquals(fx(x), cummax(x))
777+
}
717778

718779
}
780+

0 commit comments

Comments
 (0)