Rcpp Version 0.9.10
diff.h
Go to the documentation of this file.
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 
 All Classes Namespaces Files Functions Variables Typedefs Enumerator Friends Defines