Rcpp Version 0.10.3
 All Classes Namespaces Files Functions Variables Typedefs Enumerator Friends Macros
diff.h
Go to the documentation of this file.
1 // -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; tab-width: 8 -*-
2 //
3 // diff.h: Rcpp R/C++ interface class library -- diff
4 //
5 // Copyright (C) 2010 - 2012 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_ ) : lhs(lhs_), previous(lhs_[0]), was_na(false) {
38  was_na = traits::is_na<RTYPE>(previous) ;
39  }
40 
41  inline STORAGE operator[]( int i ) const {
42  STORAGE y = lhs[i+1] ;
43  if( was_na ){
44  previous = y ;
45  was_na = traits::is_na<RTYPE>(y) ;
46  return previous ; // NA
47  }
48  if( traits::is_na<RTYPE>(y) ) {
49  was_na = true ;
50  previous = y ;
51  return previous ; // NA
52  }
53  STORAGE res = y - previous ;
54  previous = y ;
55  was_na = false ;
56  return res ;
57  }
58  inline int size() const { return lhs.size() - 1 ; }
59 
60 private:
61  const LHS_TYPE& lhs ;
62  mutable STORAGE previous ;
63  mutable bool was_na ;
64 } ;
65 
66 template <typename LHS_T, bool LHS_NA>
67 class Diff<REALSXP, LHS_NA, LHS_T> : public Rcpp::VectorBase< REALSXP, LHS_NA, Diff<REALSXP,LHS_NA,LHS_T> >{
68 public:
70 
71  Diff( const LHS_TYPE& lhs_ ) : lhs(lhs_), previous(lhs_[0]) {}
72 
73  inline double operator[]( int i ) const {
74  double y = lhs[i+1] ;
75  double res = y - previous ;
76  previous = y ;
77  return res ;
78  }
79  inline int size() const { return lhs.size() - 1 ; }
80 
81 private:
82  const LHS_TYPE& lhs ;
83  mutable double previous ;
84 } ;
85 
86 template <int RTYPE, typename LHS_T>
87 class Diff<RTYPE,false,LHS_T> : public Rcpp::VectorBase< RTYPE, false , Diff<RTYPE,false,LHS_T> > {
88 public:
91 
92  Diff( const LHS_TYPE& lhs_ ) : lhs(lhs_) {}
93 
94  inline STORAGE operator[]( int i ) const {
95  STORAGE y = lhs[i+1] ;
96  STORAGE diff = y - previous ;
97  previous = y ;
98  return y - previous ;
99  }
100  inline int size() const { return lhs.size() - 1 ; }
101 
102 private:
103  const LHS_TYPE& lhs ;
104  mutable STORAGE previous ;
105 } ;
106 
107 } // sugar
108 
109 template <bool LHS_NA, typename LHS_T>
112  ){
113  return sugar::Diff<INTSXP,LHS_NA,LHS_T>( lhs ) ;
114 }
115 
116 template <bool LHS_NA, typename LHS_T>
119  ){
120  return sugar::Diff<REALSXP,LHS_NA,LHS_T>( lhs ) ;
121 }
122 
123 } // Rcpp
124 #endif
125