Rcpp Version 1.0.14
Loading...
Searching...
No Matches
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
25namespace Rcpp{
26
27template <int RTYPE, template <class> class StoragePolicy = PreserveStorage >
28class Matrix : public Vector<RTYPE, StoragePolicy>, public MatrixBase<RTYPE, true, Matrix<RTYPE,StoragePolicy> > {
29 int nrows ;
30
31public:
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
44 typedef typename VECTOR::iterator iterator ;
48 typedef typename VECTOR::Proxy 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 ) ),
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) ),
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>
80
81 Matrix( const SubMatrix<RTYPE>& ) ;
82
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 }
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
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 }
167 return Sub( const_cast<Matrix&>(*this), Range(0,nrow()-1) , col_range ) ;
168 }
170 return Sub( const_cast<Matrix&>(*this), row_range, Range(0,ncol()-1) ) ;
171 }
172
173private:
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>
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>
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>
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
212
216
217template<template <class> class StoragePolicy >
218inline 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
285template<template <class> class StoragePolicy >
286inline 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
294 int min = std::numeric_limits<int>::max();
295 int max = std::numeric_limits<int>::min();
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
351template<template <class> class StoragePolicy >
352inline 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
378template<int RTYPE, template <class> class StoragePolicy >
379inline 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
405template<int RTYPE, template <class> class StoragePolicy >
407 typedef Matrix<RTYPE, StoragePolicy> MATRIX;
408 typedef Vector<RTYPE, StoragePolicy> VECTOR;
409
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 ...
424 if (!Rf_isNull(dimNames)) {
425 // do we need dimnamesnames ?
430 }
431 return r;
432}
433
434template<template <class> class StoragePolicy>
438
439template<template <class> class StoragePolicy>
443
444template<template <class> class StoragePolicy>
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
AttributeProxy attr(const std::string &name)
R_xlen_t size() const
Definition MatrixBase.h:47
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
Matrix & operator=(const Matrix &other)
Definition Matrix.h:83
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
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:49
int * dims() const
Definition Vector.h:612
traits::r_vector_const_iterator< RTYPE, StoragePolicy >::type const_iterator
Definition Vector.h:46
iterator end()
Definition Vector.h:334
iterator begin()
Definition Vector.h:333
traits::r_vector_iterator< RTYPE, StoragePolicy >::type iterator
Definition Vector.h:45
traits::r_vector_const_proxy< RTYPE, StoragePolicy >::type const_Proxy
Definition Vector.h:42
traits::r_vector_proxy< RTYPE, StoragePolicy >::type Proxy
Definition Vector.h:41
void init()
Definition Vector.h:616
static target get(const T &input)
Definition converter.h:33
Rcpp API.
Definition algo.h:28
std::ostream & operator<<(std::ostream &os, const Date d)
Definition Date.h:172
sugar::Min< RTYPE, NA, T > min(const VectorBase< RTYPE, NA, T > &x)
Definition min.h:82
Matrix< REALSXP, StoragePolicy > transpose(const Matrix< REALSXP, StoragePolicy > &x)
Definition Matrix.h:435
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
sugar::Row< RTYPE, LHS_NA, LHS_T > row(const Rcpp::MatrixBase< RTYPE, LHS_NA, LHS_T > &lhs)
Definition row.h:55
internal::DimNameProxy colnames(SEXP x)
Definition Matrix.h:213
T as(SEXP x)
Definition as.h:151
Matrix< RTYPE, StoragePolicy > tranpose_impl(const Matrix< RTYPE, StoragePolicy > &x)
Definition Matrix.h:406