|
Rcpp Version 0.9.10
|
00001 // -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; tab-width: 8 -*- 00002 // 00003 // SubMatrix.h: Rcpp R/C++ interface class library -- sub matrices 00004 // 00005 // Copyright (C) 2010 - 2011 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__vector__SubMatrix_h 00023 #define Rcpp__vector__SubMatrix_h 00024 00025 template <int RTYPE> 00026 class SubMatrix : public Rcpp::MatrixBase< RTYPE, true, SubMatrix<RTYPE> > { 00027 public: 00028 typedef Matrix<RTYPE> MATRIX ; 00029 typedef typename Vector<RTYPE>::iterator vec_iterator ; 00030 typedef typename MATRIX::Proxy Proxy ; 00031 00032 SubMatrix( MATRIX& m_, const Range& row_range_, const Range& col_range_ ) : 00033 m(m_), 00034 iter( static_cast< Vector<RTYPE>& >(m_).begin() + row_range_.get_start() + col_range_.get_start() * m_.nrow() ), 00035 m_nr( m.nrow() ), 00036 nc( col_range_.size() ), 00037 nr( row_range_.size() ) 00038 {} 00039 00040 inline int size() const { return ncol() * nrow() ; } 00041 inline int ncol() const { return nc ; } 00042 inline int nrow() const { return nr ; } 00043 00044 inline Proxy operator()(int i, int j) const { 00045 return iter[ i + j*m_nr ] ; 00046 } 00047 00048 inline vec_iterator column_iterator( int j ) const { return iter + j*m_nr ; } 00049 00050 private: 00051 MATRIX& m ; 00052 vec_iterator iter ; 00053 int m_nr, nc, nr ; 00054 } ; 00055 00056 template <int RTYPE> 00057 Matrix<RTYPE>::Matrix( const SubMatrix<RTYPE>& sub ) : nrows(sub.nrow()) { 00058 int nc = sub.ncol() ; 00059 VECTOR::setSEXP( Rf_allocMatrix( RTYPE, nrows, nc ) ) ; 00060 iterator start = VECTOR::begin() ; 00061 iterator rhs_it ; 00062 for( int j=0; j<nc; j++){ 00063 rhs_it = sub.column_iterator(j) ; 00064 for( int i=0; i<nrows; i++, ++start){ 00065 *start = rhs_it[i] ; 00066 } 00067 } 00068 } 00069 00070 template <int RTYPE> 00071 Matrix<RTYPE>& Matrix<RTYPE>::operator=( const SubMatrix<RTYPE>& sub ){ 00072 int nc = sub.ncol(), nr = sub.nrow() ; 00073 if( nc != nrow() || nr != ncol() ){ 00074 nrows = nr ; 00075 VECTOR::setSEXP( Rf_allocMatrix( RTYPE, nr, nc ) ) ; 00076 } 00077 iterator start = VECTOR::begin() ; 00078 iterator rhs_it ; 00079 for( int j=0; j<nc; j++){ 00080 rhs_it = sub.column_iterator(j) ; 00081 for( int i=0; i<nrows; i++, ++start){ 00082 *start = rhs_it[i] ; 00083 } 00084 } 00085 return *this ; 00086 } 00087 00088 #undef RCPP_WRAP_SUBMATRIX 00089 #define RCPP_WRAP_SUBMATRIX(RTYPE) \ 00090 template<> inline SEXP wrap< SubMatrix<RTYPE> >( \ 00091 const SubMatrix<RTYPE>& object \ 00092 ) { \ 00093 return Matrix<RTYPE>( object ) ; \ 00094 } 00095 RCPP_WRAP_SUBMATRIX(REALSXP) 00096 RCPP_WRAP_SUBMATRIX(INTSXP) 00097 RCPP_WRAP_SUBMATRIX(LGLSXP) 00098 RCPP_WRAP_SUBMATRIX(RAWSXP) 00099 // RCPP_WRAP_SUBMATRIX(STRSXP) 00100 // RCPP_WRAP_SUBMATRIX(VECSXP) 00101 // RCPP_WRAP_SUBMATRIX(EXPRSXP) 00102 #undef RCPP_WRAP_SUBMATRIX 00103 00104 00105 #endif