Rcpp Version 1.0.9
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 - 2013 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__diff_h
23 #define Rcpp__sugar__diff_h
24 
25 namespace Rcpp{
26 namespace sugar{
27 
28 // NOTE: caching the previous value so that we only have to fetch the
29 // value once only works because we process the object from left to
30 // right
31 template <int RTYPE, bool LHS_NA, typename LHS_T>
32 class Diff : public Rcpp::VectorBase< RTYPE, LHS_NA , Diff<RTYPE,LHS_NA,LHS_T> > {
33 public:
36 
37  Diff( const LHS_TYPE& lhs_ ) :
38  lhs(lhs_),
39  previous(lhs_[0]),
40  previous_index(0),
41  was_na(traits::is_na<RTYPE>(previous))
42  {}
43 
44  inline STORAGE operator[]( R_xlen_t i ) const {
45  STORAGE y = lhs[i+1] ;
46  if( previous_index != i ){
47  // we don't know the previous value, we need to get it.
48  set_previous(i, lhs[i] ) ; // record the current value
49  }
50  if( was_na || traits::is_na<RTYPE>(y) ) {
51  set_previous(i+1, y ) ;
52  return traits::get_na<RTYPE>() ; // NA
53  }
54  STORAGE res = y - previous ;
55  set_previous( i+1, y) ;
56  return res ;
57  }
58 
59  inline void set_previous(R_xlen_t i, STORAGE value) const {
60  previous = value ;
61  was_na = traits::is_na<RTYPE>(previous) ;
62  previous_index = i ;
63  }
64 
65  inline R_xlen_t size() const { return lhs.size() - 1 ; }
66 
67 private:
68  const LHS_TYPE& lhs ;
69  mutable STORAGE previous ;
70  mutable R_xlen_t previous_index ;
71  mutable bool was_na ;
72 } ;
73 
74 template <typename LHS_T, bool LHS_NA>
75 class Diff<REALSXP, LHS_NA, LHS_T> : public Rcpp::VectorBase< REALSXP, LHS_NA, Diff<REALSXP,LHS_NA,LHS_T> >{
76 public:
78 
79  Diff( const LHS_TYPE& lhs_ ) : lhs(lhs_), previous(lhs_[0]), previous_index(0) {}
80 
81  inline double operator[]( R_xlen_t i ) const {
82  double y = lhs[i+1] ;
83  if( previous_index != i ) previous = lhs[i] ;
84  double res = y - previous ;
85  previous = y ;
86  previous_index = i+1 ;
87  return res ;
88  }
89  inline R_xlen_t size() const { return lhs.size() - 1 ; }
90 
91 private:
92  const LHS_TYPE& lhs ;
93  mutable double previous ;
94  mutable R_xlen_t previous_index ;
95 } ;
96 
97 template <int RTYPE, typename LHS_T>
98 class Diff<RTYPE,false,LHS_T> : public Rcpp::VectorBase< RTYPE, false , Diff<RTYPE,false,LHS_T> > {
99 public:
102 
103  Diff( const LHS_TYPE& lhs_ ) : lhs(lhs_), previous(lhs[0]), previous_index(0) {}
104 
105  inline STORAGE operator[]( R_xlen_t i ) const {
106  STORAGE y = lhs[i+1] ;
107  if( previous_index != i ) previous = lhs[i] ;
108  STORAGE diff = y - previous ;
109  previous = y ;
110  previous_index = i+1 ;
111  return y - previous ;
112  }
113  inline R_xlen_t size() const { return lhs.size() - 1 ; }
114 
115 private:
116  const LHS_TYPE& lhs ;
117  mutable STORAGE previous ;
118  mutable R_xlen_t previous_index ;
119 } ;
120 
121 } // sugar
122 
123 template <bool LHS_NA, typename LHS_T>
126  ){
127  return sugar::Diff<INTSXP,LHS_NA,LHS_T>( lhs ) ;
128 }
129 
130 template <bool LHS_NA, typename LHS_T>
133  ){
134  return sugar::Diff<REALSXP,LHS_NA,LHS_T>( lhs ) ;
135 }
136 
137 } // Rcpp
138 #endif
139 
R_xlen_t size() const
Definition: VectorBase.h:49
Rcpp::VectorBase< REALSXP, LHS_NA, LHS_T > LHS_TYPE
Definition: diff.h:77
double operator[](R_xlen_t i) const
Definition: diff.h:81
Diff(const LHS_TYPE &lhs_)
Definition: diff.h:103
STORAGE operator[](R_xlen_t i) const
Definition: diff.h:105
Rcpp::VectorBase< RTYPE, false, LHS_T > LHS_TYPE
Definition: diff.h:100
Rcpp::traits::storage_type< RTYPE >::type STORAGE
Definition: diff.h:101
STORAGE operator[](R_xlen_t i) const
Definition: diff.h:44
void set_previous(R_xlen_t i, STORAGE value) const
Definition: diff.h:59
const LHS_TYPE & lhs
Definition: diff.h:68
Rcpp::VectorBase< RTYPE, LHS_NA, LHS_T > LHS_TYPE
Definition: diff.h:34
bool was_na
Definition: diff.h:71
Diff(const LHS_TYPE &lhs_)
Definition: diff.h:37
R_xlen_t previous_index
Definition: diff.h:70
R_xlen_t size() const
Definition: diff.h:65
STORAGE previous
Definition: diff.h:69
Rcpp::traits::storage_type< RTYPE >::type STORAGE
Definition: diff.h:35
Rcpp API.
Definition: algo.h:28
sugar::IsNa< RTYPE, NA, T > is_na(const Rcpp::VectorBase< RTYPE, NA, T > &t)
Definition: is_na.h:91
sugar::Diff< INTSXP, LHS_NA, LHS_T > diff(const VectorBase< INTSXP, LHS_NA, LHS_T > &lhs)
Definition: diff.h:124