|
Rcpp Version 0.9.10
|
00001 // -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; tab-width: 8 -*- 00002 // 00003 // diff.h: Rcpp R/C++ interface class library -- diff 00004 // 00005 // Copyright (C) 2010 - 2012 Dirk Eddelbuettel and Romain Francois 00006 // 00007 // This file is part of Rcpp. 00008 // 00009 // Rcpp is free software: you can redistribute it and/or modify it 00010 // under the terms of the GNU General Public License as published by 00011 // the Free Software Foundation, either version 2 of the License, or 00012 // (at your option) any later version. 00013 // 00014 // Rcpp is distributed in the hope that it will be useful, but 00015 // WITHOUT ANY WARRANTY; without even the implied warranty of 00016 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00017 // GNU General Public License for more details. 00018 // 00019 // You should have received a copy of the GNU General Public License 00020 // along with Rcpp. If not, see <http://www.gnu.org/licenses/>. 00021 00022 #ifndef Rcpp__sugar__diff_h 00023 #define Rcpp__sugar__diff_h 00024 00025 namespace Rcpp{ 00026 namespace sugar{ 00027 00028 // NOTE: caching the previous value so that we only have to fetch the 00029 // value once only works because we process the object from left to 00030 // right 00031 template <int RTYPE, bool LHS_NA, typename LHS_T> 00032 class Diff : public Rcpp::VectorBase< RTYPE, LHS_NA , Diff<RTYPE,LHS_NA,LHS_T> > { 00033 public: 00034 typedef typename Rcpp::VectorBase<RTYPE,LHS_NA,LHS_T> LHS_TYPE ; 00035 typedef typename Rcpp::traits::storage_type<RTYPE>::type STORAGE ; 00036 00037 Diff( const LHS_TYPE& lhs_ ) : lhs(lhs_), previous(lhs_[0]), was_na(false) { 00038 was_na = traits::is_na<RTYPE>(previous) ; 00039 } 00040 00041 inline STORAGE operator[]( int i ) const { 00042 STORAGE y = lhs[i+1] ; 00043 if( was_na ){ 00044 previous = y ; 00045 was_na = traits::is_na<RTYPE>(y) ; 00046 return previous ; // NA 00047 } 00048 if( traits::is_na<RTYPE>(y) ) { 00049 was_na = true ; 00050 previous = y ; 00051 return previous ; // NA 00052 } 00053 STORAGE res = y - previous ; 00054 previous = y ; 00055 was_na = false ; 00056 return res ; 00057 } 00058 inline int size() const { return lhs.size() - 1 ; } 00059 00060 private: 00061 const LHS_TYPE& lhs ; 00062 mutable STORAGE previous ; 00063 mutable bool was_na ; 00064 } ; 00065 00066 template <typename LHS_T, bool LHS_NA> 00067 class Diff<REALSXP, LHS_NA, LHS_T> : public Rcpp::VectorBase< REALSXP, LHS_NA, Diff<REALSXP,LHS_NA,LHS_T> >{ 00068 public: 00069 typedef typename Rcpp::VectorBase<REALSXP,LHS_NA,LHS_T> LHS_TYPE ; 00070 00071 Diff( const LHS_TYPE& lhs_ ) : lhs(lhs_), previous(lhs_[0]) {} 00072 00073 inline double operator[]( int i ) const { 00074 double y = lhs[i+1] ; 00075 double res = y - previous ; 00076 previous = y ; 00077 return res ; 00078 } 00079 inline int size() const { return lhs.size() - 1 ; } 00080 00081 private: 00082 const LHS_TYPE& lhs ; 00083 mutable double previous ; 00084 } ; 00085 00086 template <int RTYPE, typename LHS_T> 00087 class Diff<RTYPE,false,LHS_T> : public Rcpp::VectorBase< RTYPE, false , Diff<RTYPE,false,LHS_T> > { 00088 public: 00089 typedef typename Rcpp::VectorBase<RTYPE,false,LHS_T> LHS_TYPE ; 00090 typedef typename Rcpp::traits::storage_type<RTYPE>::type STORAGE ; 00091 00092 Diff( const LHS_TYPE& lhs_ ) : lhs(lhs_) {} 00093 00094 inline STORAGE operator[]( int i ) const { 00095 STORAGE y = lhs[i+1] ; 00096 STORAGE diff = y - previous ; 00097 previous = y ; 00098 return y - previous ; 00099 } 00100 inline int size() const { return lhs.size() - 1 ; } 00101 00102 private: 00103 const LHS_TYPE& lhs ; 00104 mutable STORAGE previous ; 00105 } ; 00106 00107 } // sugar 00108 00109 template <bool LHS_NA, typename LHS_T> 00110 inline sugar::Diff<INTSXP,LHS_NA,LHS_T> diff( 00111 const VectorBase<INTSXP,LHS_NA,LHS_T>& lhs 00112 ){ 00113 return sugar::Diff<INTSXP,LHS_NA,LHS_T>( lhs ) ; 00114 } 00115 00116 template <bool LHS_NA, typename LHS_T> 00117 inline sugar::Diff<REALSXP,LHS_NA,LHS_T> diff( 00118 const VectorBase<REALSXP,LHS_NA,LHS_T>& lhs 00119 ){ 00120 return sugar::Diff<REALSXP,LHS_NA,LHS_T>( lhs ) ; 00121 } 00122 00123 } // Rcpp 00124 #endif 00125