Rcpp Version 1.0.9
Matrix.h
Go to the documentation of this file.
1 // -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; indent-tabs-mode: nil; -*-
2 //
3 // Matrix.h: Rcpp R/C++ interface class library -- matrices
4 //
5 // Copyright (C) 2010 - 2016 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__vector__Matrix_h
23 #define Rcpp__vector__Matrix_h
24 
25 namespace Rcpp{
26 
27 template <int RTYPE, template <class> class StoragePolicy = PreserveStorage >
28 class Matrix : public Vector<RTYPE, StoragePolicy>, public MatrixBase<RTYPE, true, Matrix<RTYPE,StoragePolicy> > {
29  int nrows ;
30 
31 public:
32  using Vector<RTYPE, StoragePolicy>::size; // disambiguate diamond pattern for g++-6 and later
33 
34  struct r_type : traits::integral_constant<int,RTYPE>{} ;
41 
42  typedef StoragePolicy<Matrix> Storage ;
44  typedef typename VECTOR::iterator iterator ;
47  typedef typename VECTOR::stored_type stored_type ;
48  typedef typename VECTOR::Proxy Proxy ;
49  typedef typename VECTOR::const_Proxy const_Proxy ;
50 
51  Matrix() : VECTOR(Dimension(0, 0)), nrows(0) {}
52 
53  Matrix(SEXP x) : VECTOR(x), nrows( VECTOR::dims()[0] ) {}
54 
55  Matrix( const Dimension& dims) : VECTOR( Rf_allocMatrix( RTYPE, dims[0], dims[1] ) ), nrows(dims[0]) {
56  if( dims.size() != 2 ) throw not_a_matrix();
57  VECTOR::init() ;
58  }
59  Matrix( const int& nrows_, const int& ncols) : VECTOR( Dimension( nrows_, ncols ) ),
60  nrows(nrows_)
61  {}
62 
63  template <typename Iterator>
64  Matrix( const int& nrows_, const int& ncols, Iterator start ) :
65  VECTOR( start, start + (static_cast<R_xlen_t>(nrows_)*ncols) ),
66  nrows(nrows_)
67  {
68  VECTOR::attr( "dim" ) = Dimension( nrows, ncols ) ;
69  }
70 
71  Matrix( const int& n) : VECTOR( Dimension( n, n ) ), nrows(n) {}
72 
73 
74  Matrix( const Matrix& other) : VECTOR( other.get__() ), nrows(other.nrows) {}
75 
76  template <bool NA, typename MAT>
77  Matrix( const MatrixBase<RTYPE,NA,MAT>& other ) : VECTOR( Rf_allocMatrix( RTYPE, other.nrow(), other.ncol() ) ), nrows(other.nrow()) {
78  import_matrix_expression<NA,MAT>( other, nrows, ncol() ) ;
79  }
80 
81  Matrix( const SubMatrix<RTYPE>& ) ;
82 
83  Matrix& operator=(const Matrix& other) {
84  SEXP x = other.get__() ;
85  if( ! ::Rf_isMatrix(x) ) throw not_a_matrix();
86  VECTOR::set__( x ) ;
87  nrows = other.nrows ;
88  return *this ;
89  }
90  Matrix& operator=( const SubMatrix<RTYPE>& ) ;
91 
92  explicit Matrix( const no_init_matrix& obj) : VECTOR(Rf_allocMatrix(RTYPE, obj.nrow(), obj.ncol())), nrows(obj.nrow()) {}
93 
94  inline int ncol() const {
95  return VECTOR::dims()[1];
96  }
97  inline int nrow() const {
98  return nrows ;
99  }
100  inline int cols() const {
101  return VECTOR::dims()[1];
102  }
103  inline int rows() const {
104  return nrows ;
105  }
106 
107  inline Row row( int i ){ return Row( *this, i ) ; }
108  inline ConstRow row( int i ) const{ return ConstRow( *this, i ) ; }
109  inline Column column( int i ){ return Column(*this, i ) ; }
110  inline ConstColumn column( int i ) const{ return ConstColumn( *this, i ) ; }
111 
112  inline const_iterator begin() const{ return VECTOR::begin() ; }
113  inline const_iterator end() const{ return VECTOR::end() ; }
114  inline const_iterator cbegin() const{ return VECTOR::begin() ; }
115  inline const_iterator cend() const{ return VECTOR::end() ; }
116  inline iterator begin() { return VECTOR::begin() ; }
117  inline iterator end() { return VECTOR::end() ; }
118 
119  template <typename U>
120  void fill_diag( const U& u) {
122  }
123 
124  template <typename U> static Matrix diag( int size, const U& diag_value ) {
125  Matrix res(size,size) ;
126  res.fill_diag( diag_value ) ;
127  return res ;
128  }
129 
130  inline Proxy operator[]( R_xlen_t i ) {
131  return static_cast< Vector<RTYPE>* >( this )->operator[]( i ) ;
132  }
133  inline const_Proxy operator[]( R_xlen_t i ) const {
134  return static_cast< const Vector<RTYPE>* >( this )->operator[]( i ) ;
135  }
136 
137  inline Proxy operator()( const size_t& i, const size_t& j) {
138  return static_cast< Vector<RTYPE>* >( this )->operator[]( offset( i, j ) ) ;
139  }
140  inline const_Proxy operator()( const size_t& i, const size_t& j) const {
141  return static_cast< const Vector<RTYPE>* >( this )->operator[]( offset( i, j ) ) ;
142  }
143 
144  inline Proxy at( const size_t& i, const size_t& j) {
145  return static_cast< Vector<RTYPE>* >( this )->operator()( i, j ) ;
146  }
147  inline const_Proxy at( const size_t& i, const size_t& j) const {
148  return static_cast< const Vector<RTYPE>* >( this )->operator()( i, j ) ;
149  }
150 
152  return Row( *this, i ) ;
153  }
155  return ConstRow( *this, i ) ;
156  }
158  return Column( *this, i ) ;
159  }
161  return ConstColumn( *this, i ) ;
162  }
163  inline Sub operator()( const Range& row_range, const Range& col_range) {
164  return Sub( const_cast<Matrix&>(*this), row_range, col_range ) ;
165  }
166  inline Sub operator()( internal::NamedPlaceHolder, const Range& col_range) {
167  return Sub( const_cast<Matrix&>(*this), Range(0,nrow()-1) , col_range ) ;
168  }
169  inline Sub operator()( const Range& row_range, internal::NamedPlaceHolder ) {
170  return Sub( const_cast<Matrix&>(*this), row_range, Range(0,ncol()-1) ) ;
171  }
172 
173 private:
174  inline R_xlen_t offset(const int i, const int j) const { return i + static_cast<R_xlen_t>(nrows) * j ; }
175 
176  template <typename U>
178  Shield<SEXP> elem( converter_type::get( u ) );
179 
180  R_xlen_t bounds = std::min(Matrix::nrow(), Matrix::ncol());
181  for (R_xlen_t i = 0; i < bounds; ++i) {
182  (*this)(i, i) = elem;
183  }
184  }
185 
186  template <typename U>
188  stored_type elem = converter_type::get( u );
189 
190  R_xlen_t bounds = std::min(Matrix::nrow(), Matrix::ncol());
191 
192  for (R_xlen_t i = 0; i < bounds; ++i) {
193  (*this)(i, i) = elem;
194  }
195  }
196 
197  template <bool NA, typename MAT>
198  void import_matrix_expression( const MatrixBase<RTYPE,NA,MAT>& other, int nr, int nc ) {
199  iterator start = VECTOR::begin() ;
200  for( int j=0; j<nc; j++){
201  for( int i=0; i<nr; i++, ++start){
202  *start = other(i,j) ;
203  }
204  }
205  }
206 
207 };
208 
210  return internal::DimNameProxy(x, 0);
211 }
212 
214  return internal::DimNameProxy(x, 1);
215 }
216 
217 template<template <class> class StoragePolicy >
218 inline std::ostream &operator<<(std::ostream & s, const Matrix<REALSXP, StoragePolicy> & rhs) {
219  typedef Matrix<REALSXP, StoragePolicy> MATRIX;
220 
221  std::ios::fmtflags flags = s.flags();
222  s.unsetf(std::ios::floatfield);
223  std::streamsize precision = s.precision();
224 
225  const int rows = rhs.rows();
226 
227  for (int i = 0; i < rows; ++i) {
228  typename MATRIX::Row row = const_cast<MATRIX &>(rhs).row(i);
229 
230  typename MATRIX::Row::iterator j = row.begin();
231  typename MATRIX::Row::iterator jend = row.end();
232 
233  if (j != jend) {
234  s << std::showpoint << std::setw(precision + 1) << (*j);
235  j++;
236 
237  for ( ; j != jend; j++) {
238  s << " " << std::showpoint << std::setw(precision + 1) << (*j);
239  }
240  }
241 
242  s << std::endl;
243  }
244 
245  s.flags(flags);
246  return s;
247 }
248 
249 #ifndef RCPP_NO_SUGAR
250 #define RCPP_GENERATE_MATRIX_SCALAR_OPERATOR(__OPERATOR__) \
251  template <int RTYPE, template <class> class StoragePolicy, typename T > \
252  inline typename traits::enable_if< traits::is_convertible< typename traits::remove_const_and_reference< T >::type, \
253  typename Matrix<RTYPE, StoragePolicy>::stored_type >::value, Matrix<RTYPE, StoragePolicy> >::type \
254  operator __OPERATOR__ (const Matrix<RTYPE, StoragePolicy> &lhs, const T &rhs) { \
255  Vector<RTYPE, StoragePolicy> v = static_cast<const Vector<RTYPE, StoragePolicy> &>(lhs) __OPERATOR__ rhs; \
256  v.attr("dim") = Vector<INTSXP>::create(lhs.nrow(), lhs.ncol()); \
257  return as< Matrix<RTYPE, StoragePolicy> >(v); \
258  }
259 
264 
265 #undef RCPP_GENERATE_MATRIX_SCALAR_OPERATOR
266 
267 #define RCPP_GENERATE_SCALAR_MATRIX_OPERATOR(__OPERATOR__) \
268  template <int RTYPE, template <class> class StoragePolicy, typename T > \
269  inline typename traits::enable_if< traits::is_convertible< typename traits::remove_const_and_reference< T >::type, \
270  typename Matrix<RTYPE, StoragePolicy>::stored_type >::value, Matrix<RTYPE, StoragePolicy> >::type \
271  operator __OPERATOR__ (const T &lhs, const Matrix<RTYPE, StoragePolicy> &rhs) { \
272  Vector<RTYPE, StoragePolicy> v = lhs __OPERATOR__ static_cast<const Vector<RTYPE, StoragePolicy> &>(rhs); \
273  v.attr("dim") = Vector<INTSXP>::create(rhs.nrow(), rhs.ncol()); \
274  return as< Matrix<RTYPE, StoragePolicy> >(v); \
275  }
276 
281 
282 #undef RCPP_GENERATE_SCALAR_MATRIX_OPERATOR
283 #endif
284 
285 template<template <class> class StoragePolicy >
286 inline std::ostream &operator<<(std::ostream & s, const Matrix<INTSXP, StoragePolicy> & rhs) {
287  typedef Matrix<INTSXP, StoragePolicy> MATRIX;
288  typedef Vector<INTSXP, StoragePolicy> VECTOR;
289 
290  std::ios::fmtflags flags = s.flags();
291 
292  s << std::dec;
293 
296 
297  typename VECTOR::iterator j = static_cast<VECTOR &>(const_cast<MATRIX &>(rhs)).begin();
298  typename VECTOR::iterator jend = static_cast<VECTOR &>(const_cast<MATRIX &>(rhs)).end();
299 
300  for ( ; j != jend; ++j) {
301  if (*j < min) {
302  min = *j;
303  }
304 
305  if (*j > max) {
306  max = *j;
307  }
308  }
309 
310  int digitsMax = (max >= 0) ? 0 : 1;
311  int digitsMin = (min >= 0) ? 0 : 1;
312 
313  while (min != 0)
314  {
315  ++digitsMin;
316  min /= 10;
317  }
318 
319  while (max != 0)
320  {
321  ++digitsMax;
322  max /= 10;
323  }
324 
325  int digits = std::max(digitsMin, digitsMax);
326 
327  const int rows = rhs.rows();
328 
329  for (int i = 0; i < rows; ++i) {
330  typename MATRIX::Row row = const_cast<MATRIX &>(rhs).row(i);
331 
332  typename MATRIX::Row::iterator j = row.begin();
333  typename MATRIX::Row::iterator jend = row.end();
334 
335  if (j != jend) {
336  s << std::setw(digits) << (*j);
337  ++j;
338 
339  for ( ; j != jend; ++j) {
340  s << " " << std::setw(digits) << (*j);
341  }
342  }
343 
344  s << std::endl;
345  }
346 
347  s.flags(flags);
348  return s;
349 }
350 
351 template<template <class> class StoragePolicy >
352 inline std::ostream &operator<<(std::ostream & s, const Matrix<STRSXP, StoragePolicy> & rhs) {
353  typedef Matrix<STRSXP, StoragePolicy> MATRIX;
354 
355  const int rows = rhs.rows();
356 
357  for (int i = 0; i < rows; ++i) {
358  typename MATRIX::Row row = const_cast<MATRIX &>(rhs).row(i);
359 
360  typename MATRIX::Row::iterator j = row.begin();
361  typename MATRIX::Row::iterator jend = row.end();
362 
363  if (j != jend) {
364  s << "\"" << (*j) << "\"";
365  j++;
366 
367  for ( ; j != jend; j++) {
368  s << " \"" << (*j) << "\"";
369  }
370  }
371 
372  s << std::endl;
373  }
374 
375  return s;
376 }
377 
378 template<int RTYPE, template <class> class StoragePolicy >
379 inline std::ostream &operator<<(std::ostream & s, const Matrix<RTYPE, StoragePolicy> & rhs) {
380  typedef Matrix<RTYPE, StoragePolicy> MATRIX;
381 
382  const int rows = rhs.rows();
383 
384  for (int i = 0; i < rows; ++i) {
385  typename MATRIX::Row row = const_cast<MATRIX &>(rhs).row(i);
386 
387  typename MATRIX::Row::iterator j = row.begin();
388  typename MATRIX::Row::iterator jend = row.end();
389 
390  if (j != jend) {
391  s << (*j);
392  j++;
393 
394  for ( ; j != jend; j++) {
395  s << (*j);
396  }
397  }
398 
399  s << std::endl;
400  }
401 
402  return s;
403 }
404 
405 template<int RTYPE, template <class> class StoragePolicy >
407  typedef Matrix<RTYPE, StoragePolicy> MATRIX;
408  typedef Vector<RTYPE, StoragePolicy> VECTOR;
409 
410  Vector<INTSXP, StoragePolicy> dims = ::Rf_getAttrib(x, R_DimSymbol);
411  int nrow = dims[0], ncol = dims[1];
412  MATRIX r(Dimension(ncol, nrow)); // new Matrix with reversed dimension
413  R_xlen_t len = XLENGTH(x), len2 = XLENGTH(x)-1;
414 
415  // similar approach as in R: fill by in column, "accessing row-wise"
416  VECTOR s = VECTOR(r.get__());
417  for (R_xlen_t i = 0, j = 0; i < len; i++, j += nrow) {
418  if (j > len2) j -= len2;
419  s[i] = x[j];
420  }
421 
422  // there must be a simpler, more C++-ish way for this ...
423  SEXP dimNames = Rf_getAttrib(x, R_DimNamesSymbol);
424  if (!Rf_isNull(dimNames)) {
425  // do we need dimnamesnames ?
426  Shield<SEXP> newDimNames(Rf_allocVector(VECSXP, 2));
427  SET_VECTOR_ELT(newDimNames, 0, VECTOR_ELT(dimNames, 1));
428  SET_VECTOR_ELT(newDimNames, 1, VECTOR_ELT(dimNames, 0));
429  Rf_setAttrib(r, R_DimNamesSymbol, newDimNames);
430  }
431  return r;
432 }
433 
434 template<template <class> class StoragePolicy>
436  return tranpose_impl<REALSXP, StoragePolicy>(x);
437 }
438 
439 template<template <class> class StoragePolicy>
441  return tranpose_impl<INTSXP, StoragePolicy>(x);
442 }
443 
444 template<template <class> class StoragePolicy>
446  return tranpose_impl<STRSXP, StoragePolicy>(x);
447 }
448 
449 }
450 
451 #endif
#define RCPP_GENERATE_MATRIX_SCALAR_OPERATOR(__OPERATOR__)
Definition: Matrix.h:250
#define RCPP_GENERATE_SCALAR_MATRIX_OPERATOR(__OPERATOR__)
Definition: Matrix.h:267
Sub operator()(const Range &row_range, internal::NamedPlaceHolder)
Definition: Matrix.h:169
MatrixRow< RTYPE > Row
Definition: Matrix.h:36
Proxy operator()(const size_t &i, const size_t &j)
Definition: Matrix.h:137
int ncol() const
Definition: Matrix.h:94
ConstRow operator()(int i, internal::NamedPlaceHolder) const
Definition: Matrix.h:154
ConstMatrixRow< RTYPE > ConstRow
Definition: Matrix.h:37
ConstColumn operator()(internal::NamedPlaceHolder, int i) const
Definition: Matrix.h:160
static Matrix diag(int size, const U &diag_value)
Definition: Matrix.h:124
VECTOR::const_iterator const_iterator
Definition: Matrix.h:45
Row row(int i)
Definition: Matrix.h:107
ConstColumn column(int i) const
Definition: Matrix.h:110
Matrix(const int &n)
Definition: Matrix.h:71
VECTOR::Proxy Proxy
Definition: Matrix.h:48
void import_matrix_expression(const MatrixBase< RTYPE, NA, MAT > &other, int nr, int nc)
Definition: Matrix.h:198
int cols() const
Definition: Matrix.h:100
iterator end()
Definition: Matrix.h:117
Column operator()(internal::NamedPlaceHolder, int i)
Definition: Matrix.h:157
ConstMatrixColumn< RTYPE > ConstColumn
Definition: Matrix.h:39
Vector< RTYPE, StoragePolicy > VECTOR
Definition: Matrix.h:43
Column column(int i)
Definition: Matrix.h:109
const_Proxy at(const size_t &i, const size_t &j) const
Definition: Matrix.h:147
int nrow() const
Definition: Matrix.h:97
MatrixColumn< RTYPE > Column
Definition: Matrix.h:38
const_iterator begin() const
Definition: Matrix.h:112
Row operator()(int i, internal::NamedPlaceHolder)
Definition: Matrix.h:151
const_iterator cend() const
Definition: Matrix.h:115
Proxy at(const size_t &i, const size_t &j)
Definition: Matrix.h:144
iterator begin()
Definition: Matrix.h:116
void fill_diag__dispatch(traits::false_type, const U &u)
Definition: Matrix.h:177
const_Proxy operator()(const size_t &i, const size_t &j) const
Definition: Matrix.h:140
Matrix(const Dimension &dims)
Definition: Matrix.h:55
const_Proxy operator[](R_xlen_t i) const
Definition: Matrix.h:133
Matrix(const int &nrows_, const int &ncols, Iterator start)
Definition: Matrix.h:64
void fill_diag__dispatch(traits::true_type, const U &u)
Definition: Matrix.h:187
Sub operator()(internal::NamedPlaceHolder, const Range &col_range)
Definition: Matrix.h:166
Sub operator()(const Range &row_range, const Range &col_range)
Definition: Matrix.h:163
Matrix(const no_init_matrix &obj)
Definition: Matrix.h:92
StoragePolicy< Matrix > Storage
Definition: Matrix.h:42
const_iterator cbegin() const
Definition: Matrix.h:114
int rows() const
Definition: Matrix.h:103
Matrix & operator=(const Matrix &other)
Definition: Matrix.h:83
VECTOR::converter_type converter_type
Definition: Matrix.h:46
Matrix(const Matrix &other)
Definition: Matrix.h:74
VECTOR::stored_type stored_type
Definition: Matrix.h:47
Matrix(const MatrixBase< RTYPE, NA, MAT > &other)
Definition: Matrix.h:77
ConstRow row(int i) const
Definition: Matrix.h:108
VECTOR::const_Proxy const_Proxy
Definition: Matrix.h:49
Matrix(SEXP x)
Definition: Matrix.h:53
Matrix(const int &nrows_, const int &ncols)
Definition: Matrix.h:59
void fill_diag(const U &u)
Definition: Matrix.h:120
SubMatrix< RTYPE > Sub
Definition: Matrix.h:40
int nrows
Definition: Matrix.h:29
const_iterator end() const
Definition: Matrix.h:113
R_xlen_t offset(const int i, const int j) const
Definition: Matrix.h:174
VECTOR::iterator iterator
Definition: Matrix.h:44
Proxy operator[](R_xlen_t i)
Definition: Matrix.h:130
traits::storage_type< RTYPE >::type stored_type
Definition: Vector.h:50
traits::r_vector_proxy< RTYPE, StoragePolicy >::type Proxy
Definition: Vector.h:42
traits::r_vector_const_proxy< RTYPE, StoragePolicy >::type const_Proxy
Definition: Vector.h:43
iterator end()
Definition: Vector.h:335
traits::r_vector_iterator< RTYPE, StoragePolicy >::type iterator
Definition: Vector.h:46
traits::r_vector_const_iterator< RTYPE, StoragePolicy >::type const_iterator
Definition: Vector.h:47
iterator begin()
Definition: Vector.h:334
void init()
Definition: Vector.h:617
static target get(const T &input)
Definition: converter.h:33
traits::enable_if< helpers::decays_to_ctype< typename std::iterator_traits< InputIterator >::value_type >::value, typename helpers::ctype< typename std::iterator_traits< InputIterator >::value_type >::type >::type min(InputIterator begin, InputIterator end)
Definition: algorithm.h:370
traits::enable_if< helpers::decays_to_ctype< typename std::iterator_traits< InputIterator >::value_type >::value, typename helpers::ctype< typename std::iterator_traits< InputIterator >::value_type >::type >::type max(InputIterator begin, InputIterator end)
Definition: algorithm.h:324
Rcpp API.
Definition: algo.h:28
Matrix< RTYPE, StoragePolicy > tranpose_impl(const Matrix< RTYPE, StoragePolicy > &x)
Definition: Matrix.h:406
sugar::Row< RTYPE, LHS_NA, LHS_T > row(const Rcpp::MatrixBase< RTYPE, LHS_NA, LHS_T > &lhs)
Definition: row.h:55
internal::DimNameProxy rownames(SEXP x)
Definition: Matrix.h:209
sugar::Max< RTYPE, NA, T > max(const VectorBase< RTYPE, NA, T > &x)
Definition: max.h:82
internal::DimNameProxy colnames(SEXP x)
Definition: Matrix.h:213
std::ostream & operator<<(std::ostream &os, const Date d)
Definition: Date.h:172
Matrix< REALSXP, StoragePolicy > transpose(const Matrix< REALSXP, StoragePolicy > &x)
Definition: Matrix.h:435
sugar::Min< RTYPE, NA, T > min(const VectorBase< RTYPE, NA, T > &x)
Definition: min.h:82