Rcpp Version 1.1.2
Loading...
Searching...
No Matches
diff.h
Go to the documentation of this file.
1// -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; tab-width: 4 -*-
2//
3// diff.h: Rcpp R/C++ interface class library -- diff
4//
5// Copyright (C) 2010 - 2025 Dirk Eddelbuettel and Romain Francois
6// Copyright (C) 2026 Dirk Eddelbuettel, Romain Francois and IƱaki Ucar
7//
8// This file is part of Rcpp.
9//
10// Rcpp is free software: you can redistribute it and/or modify it
11// under the terms of the GNU General Public License as published by
12// the Free Software Foundation, either version 2 of the License, or
13// (at your option) any later version.
14//
15// Rcpp is distributed in the hope that it will be useful, but
16// WITHOUT ANY WARRANTY; without even the implied warranty of
17// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18// GNU General Public License for more details.
19//
20// You should have received a copy of the GNU General Public License
21// along with Rcpp. If not, see <http://www.gnu.org/licenses/>.
22
23#ifndef Rcpp__sugar__diff_h
24#define Rcpp__sugar__diff_h
25
26namespace Rcpp{
27namespace sugar{
28
29// NOTE: caching the previous value so that we only have to fetch the
30// value once only works because we process the object from left to
31// right
32template <int RTYPE, bool LHS_NA, typename LHS_T>
33class Diff : public Rcpp::VectorBase< RTYPE, LHS_NA , Diff<RTYPE,LHS_NA,LHS_T> > {
34public:
37
38 Diff( const LHS_TYPE& lhs_ ) :
39 lhs(lhs_),
40 previous(lhs_[0]),
42 was_na(traits::is_na<RTYPE>(previous))
43 {}
44
45 inline STORAGE operator[]( R_xlen_t i ) const {
46 STORAGE y = lhs[i+1] ;
47 if( previous_index != i ){
48 // we don't know the previous value, we need to get it.
49 set_previous(i, lhs[i] ) ; // record the current value
50 }
51 if( was_na || traits::is_na<RTYPE>(y) ) {
52 set_previous(i+1, y ) ;
53 return traits::get_na<RTYPE>() ; // NA
54 }
56 set_previous( i+1, y) ;
57 return res ;
58 }
59
60 inline void set_previous(R_xlen_t i, STORAGE value) const {
61 previous = value ;
63 previous_index = i ;
64 }
65
66 inline R_xlen_t size() const { return lhs.size() - 1 ; }
67
68private:
69 const LHS_TYPE& lhs ;
70 mutable STORAGE previous ;
71 mutable R_xlen_t previous_index ;
72 mutable bool was_na ;
73} ;
74
75template <typename LHS_T, bool LHS_NA>
76class Diff<REALSXP, LHS_NA, LHS_T> : public Rcpp::VectorBase< REALSXP, LHS_NA, Diff<REALSXP,LHS_NA,LHS_T> >{
77public:
79
80 Diff( const LHS_TYPE& lhs_ ) : lhs(lhs_), previous(lhs_[0]), previous_index(0) {}
81
82 inline double operator[]( R_xlen_t i ) const {
83 double y = lhs[i+1] ;
84 if( previous_index != i ) previous = lhs[i] ;
85 double res = RCPP_SAFE_SUB(y, previous);
86 previous = y ;
87 previous_index = i+1 ;
88 return res ;
89 }
90 inline R_xlen_t size() const { return lhs.size() - 1 ; }
91
92private:
93 const LHS_TYPE& lhs ;
94 mutable double previous ;
95 mutable R_xlen_t previous_index ;
96} ;
97
98template <int RTYPE, typename LHS_T>
99class Diff<RTYPE,false,LHS_T> : public Rcpp::VectorBase< RTYPE, false , Diff<RTYPE,false,LHS_T> > {
100public:
103
104 Diff( const LHS_TYPE& lhs_ ) : lhs(lhs_), previous(lhs[0]), previous_index(0) {}
105
106 inline STORAGE operator[]( R_xlen_t i ) const {
107 STORAGE y = lhs[i+1] ;
108 if( previous_index != i ) previous = lhs[i] ;
110 previous = y ;
111 previous_index = i+1 ;
112 return res;
113 }
114 inline R_xlen_t size() const { return lhs.size() - 1 ; }
115
116private:
117 const LHS_TYPE& lhs ;
119 mutable R_xlen_t previous_index ;
120} ;
121
122} // sugar
123
124template <bool LHS_NA, typename LHS_T>
130
131template <bool LHS_NA, typename LHS_T>
137
138} // Rcpp
139#endif
140
Rcpp::VectorBase< REALSXP, LHS_NA, LHS_T > LHS_TYPE
Definition diff.h:78
double operator[](R_xlen_t i) const
Definition diff.h:82
STORAGE operator[](R_xlen_t i) const
Definition diff.h:106
Rcpp::VectorBase< RTYPE, false, LHS_T > LHS_TYPE
Definition diff.h:101
Rcpp::traits::storage_type< RTYPE >::type STORAGE
Definition diff.h:102
STORAGE operator[](R_xlen_t i) const
Definition diff.h:45
void set_previous(R_xlen_t i, STORAGE value) const
Definition diff.h:60
const LHS_TYPE & lhs
Definition diff.h:69
Rcpp::VectorBase< RTYPE, LHS_NA, LHS_T > LHS_TYPE
Definition diff.h:35
Diff(const LHS_TYPE &lhs_)
Definition diff.h:38
R_xlen_t previous_index
Definition diff.h:71
R_xlen_t size() const
Definition diff.h:66
STORAGE previous
Definition diff.h:70
Rcpp::traits::storage_type< RTYPE >::type STORAGE
Definition diff.h:36
traits used to dispatch wrap
Definition Date.h:27
storage_type< RTYPE >::type get_na()
bool is_na(typename storage_type< RTYPE >::type)
Definition is_na.h:32
Rcpp API.
Definition algo.h:28
sugar::Diff< INTSXP, LHS_NA, LHS_T > diff(const VectorBase< INTSXP, LHS_NA, LHS_T > &lhs)
Definition diff.h:125
sugar::IsNa< RTYPE, NA, T > is_na(const Rcpp::VectorBase< RTYPE, NA, T > &t)
Definition is_na.h:91
#define RCPP_SAFE_SUB(a, b)
Definition safe_math.h:34