Rcpp Version 0.9.10
Matrix.h
Go to the documentation of this file.
00001 // -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; indent-tabs-mode: nil; -*-
00002 //
00003 // Matrix.h: Rcpp R/C++ interface class library -- 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__Matrix_h
00023 #define Rcpp__vector__Matrix_h
00024 
00025 template <int RTYPE> 
00026 class Matrix : public Vector<RTYPE>, public MatrixBase<RTYPE,true, Matrix<RTYPE> > {
00027 public:
00028     struct r_type : traits::integral_constant<int,RTYPE>{} ;
00029     struct can_have_na : traits::true_type{} ;
00030         
00031     typedef Vector<RTYPE> VECTOR ;
00032     typedef typename VECTOR::iterator iterator ;
00033     typedef typename VECTOR::converter_type converter_type ;
00034     typedef typename VECTOR::stored_type stored_type ;
00035     typedef typename VECTOR::Proxy Proxy ;
00036     
00037     Matrix() : VECTOR() {}
00038         
00039     Matrix(SEXP x) : VECTOR(), nrows(0) {
00040         if( ! ::Rf_isMatrix(x) ) throw not_compatible("not a matrix") ;
00041         SEXP y = r_cast<RTYPE>( x ) ;
00042         VECTOR::setSEXP( y );
00043         nrows = VECTOR::dims()[0] ;
00044     }
00045         
00046     Matrix( const Dimension& dims) : VECTOR(), nrows(dims[0]) {
00047         if( dims.size() != 2 ) throw not_compatible("not a matrix") ;
00048         VECTOR::setSEXP( Rf_allocMatrix( RTYPE, dims[0], dims[1] ) ) ;
00049         VECTOR::init() ;
00050     }
00051         
00052     Matrix( const int& nrows_, const int& ncols) : 
00053         VECTOR( Dimension( nrows_, ncols ) ), 
00054         nrows(nrows_)
00055     {}
00056         
00057     template <typename Iterator>
00058     Matrix( const int& nrows_, const int& ncols, Iterator start ) : 
00059         VECTOR( start, start + (nrows_*ncols) ),
00060         nrows(nrows_)
00061     {
00062         VECTOR::attr( "dim" ) = Dimension( nrows, ncols ) ; 
00063     }
00064         
00065     Matrix( const int& n) : VECTOR( Dimension( n, n ) ), nrows(n) {}
00066         
00067     Matrix( const Matrix& other) : VECTOR(), nrows(other.nrows) {
00068         SEXP x = other.asSexp() ;
00069         if( ! ::Rf_isMatrix(x) ) throw not_compatible("not a matrix") ;
00070         VECTOR::setSEXP( x ) ;
00071     }
00072         
00073     Matrix& operator=(const Matrix& other) {
00074         SEXP x = other.asSexp() ;
00075         if( ! ::Rf_isMatrix(x) ) not_compatible("not a matrix") ;
00076         VECTOR::setSEXP( x ) ;
00077         nrows = other.nrows ;
00078         return *this ;
00079     }
00080         
00081     template <bool NA, typename MAT>
00082     Matrix( const MatrixBase<RTYPE,NA,MAT>& other ) : VECTOR(), nrows(other.nrow()) {
00083         int nc = other.ncol() ;
00084         RObject::setSEXP( Rf_allocMatrix( RTYPE, nrows, nc ) ) ;
00085         import_matrix_expression<NA,MAT>( other, nrows, nc ) ;
00086     }
00087         
00088     // defined later
00089     Matrix( const SubMatrix<RTYPE>& ) ;
00090     Matrix& operator=( const SubMatrix<RTYPE>& ) ;
00091    
00092 private:
00093         
00094     template <bool NA, typename MAT>
00095     void import_matrix_expression( const MatrixBase<RTYPE,NA,MAT>& other, int nr, int nc ){
00096         iterator start = VECTOR::begin() ;
00097         for( int j=0; j<nc; j++){
00098             for( int i=0; i<nr; i++, ++start){
00099                 *start = other(i,j) ;
00100             }
00101         }
00102     }
00103 
00104 public:
00105         
00106     template <typename U>
00107     void fill_diag( const U& u){
00108         fill_diag__dispatch( typename traits::is_trivial<RTYPE>::type(), u ) ;  
00109     }
00110         
00111     template <typename U>
00112     static Matrix diag( int size, const U& diag_value ){
00113         Matrix res(size,size) ;
00114         res.fill_diag( diag_value ) ;
00115         return res ;
00116     }
00117     
00118     inline Proxy operator[]( int i ){
00119         return static_cast< Vector<RTYPE>* >( this )->operator[]( i ) ;
00120     }
00121     
00122     inline Proxy operator[]( int i ) const {
00123         return static_cast< const Vector<RTYPE>* >( this )->operator[]( i ) ;
00124     }
00125     
00126     inline Proxy operator()( const size_t& i, const size_t& j) {
00127         return static_cast< Vector<RTYPE>* >( this )->operator[]( 
00128                                                                  offset( i, j )
00129                                                                   ) ;
00130     }
00131         
00132     inline Proxy operator()( const size_t& i, const size_t& j) const {
00133         return static_cast< const Vector<RTYPE>* >( this )->operator[]( 
00134                                                                        offset( i, j )
00135                                                                         ) ;
00136     }
00137         
00138     typedef MatrixRow<RTYPE> Row ;
00139     typedef MatrixColumn<RTYPE> Column ;
00140     typedef SubMatrix<RTYPE> Sub ;
00141 
00142     inline Row operator()( int i, internal::NamedPlaceHolder ){
00143         return Row( *this, i ) ;
00144     }
00145         
00146     inline Column operator()( internal::NamedPlaceHolder, int i ){
00147         return Column( *this, i ) ;
00148     }
00149         
00150     inline Sub operator()( const Range& row_range, const Range& col_range){
00151         return Sub( const_cast<Matrix&>(*this), row_range, col_range ) ;
00152     }
00153         
00154     inline Sub operator()( internal::NamedPlaceHolder, const Range& col_range){
00155         return Sub( const_cast<Matrix&>(*this), Range(0,nrow()-1) , col_range ) ;
00156     }
00157         
00158     inline Sub operator()( const Range& row_range, internal::NamedPlaceHolder ){
00159         return Sub( const_cast<Matrix&>(*this), row_range, Range(0,ncol()-1) ) ;
00160     }
00161         
00162         
00163 private:
00164     
00165     inline int offset( int i, int j) const {
00166         return i + nrows * j ;
00167     }
00168     
00169     virtual void update(){
00170         RCPP_DEBUG_1( "%s::update", DEMANGLE(Matrix) ) ;
00171         VECTOR::update_vector() ;
00172     }
00173         
00174     template <typename U>
00175     void fill_diag__dispatch( traits::false_type, const U& u){
00176         SEXP elem = PROTECT( converter_type::get( u ) ) ;
00177         int n = Matrix::ncol() ;
00178         int offset = n +1 ;
00179         iterator it( VECTOR::begin()) ;
00180         for( int i=0; i<n; i++){
00181             *it = ::Rf_duplicate( elem );
00182             it += offset; 
00183         }
00184         UNPROTECT(1); // elem
00185     }
00186         
00187     template <typename U>
00188     void fill_diag__dispatch( traits::true_type, const U& u){
00189         stored_type elem = converter_type::get( u ) ;
00190         int n = Matrix::ncol() ;
00191         int offset = n + 1 ;
00192         iterator it( VECTOR::begin()) ;
00193         for( int i=0; i<n; i++){
00194             *it = elem ;
00195             it += offset; 
00196         }
00197     }
00198 
00199 public:
00200     inline int ncol() const {
00201         return VECTOR::dims()[1]; 
00202     }
00203     inline int nrow() const {
00204         return nrows ; 
00205     }
00206     inline int cols() const { 
00207         return VECTOR::dims()[1]; 
00208     }
00209     inline int rows() const { 
00210         return nrows ; 
00211     }
00212         
00213     inline Row row( int i ){ return Row( *this, i ) ; }
00214     inline Column column( int i ){ return Column(*this, i ) ; }
00215         
00216     inline iterator begin() const{ return VECTOR::begin() ; }
00217     inline iterator end() const{ return VECTOR::end() ; }
00218     
00219 private:
00220     int nrows ; 
00221         
00222 } ;
00223 
00224 
00225 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerator Friends Defines