-
Notifications
You must be signed in to change notification settings - Fork 12
Expand file tree
/
Copy pathMatrix.h
More file actions
200 lines (155 loc) · 6.96 KB
/
Matrix.h
File metadata and controls
200 lines (155 loc) · 6.96 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
#ifndef Rcpp__vector__Matrix_h
#define Rcpp__vector__Matrix_h
namespace Rcpp{
template <int RTYPE, typename Mat>
class MatrixColumn : public VectorBase<RTYPE,true,MatrixColumn<RTYPE,Mat>> {
public:
using iterator = typename Mat::iterator ;
using Proxy = typename Mat::Proxy ;
using const_iterator = typename Mat::const_iterator ;
using const_Proxy = typename Mat::const_Proxy ;
MatrixColumn( Mat& mat_, int i) : mat(mat_), index(i), n(mat.nrow()){}
MatrixColumn& operator=( const MatrixColumn& other ){
if( &other != this ){
std::copy( other.begin(), other.end(), begin() );
}
return *this ;
}
template <bool NA, typename Vec>
MatrixColumn& operator=( const VectorBase<RTYPE,NA,Vec>& expr ){
iterator start = begin() ;
for( int i=0; i<n; i++) {
start[i] = expr[i] ;
}
return *this ;
}
inline int size() const { return n ;}
inline Proxy operator[]( int i){ return mat[ index*n + i] ; }
inline const_Proxy operator[]( int i) const { return mat[ index*n + i] ; }
inline iterator begin() { return mat.begin() + index * n ; }
inline iterator end(){ return mat.begin() + (index+1)* n ; }
inline const_iterator begin() const { return mat.begin() + index * n ; }
inline const_iterator end() const { return mat.begin() + (index+1)* n ; }
private:
Mat& mat ;
int index ;
int n ;
};
template <int RTYPE, typename Mat>
class MatrixRow : public VectorBase<RTYPE,true,MatrixRow<RTYPE,Mat>> {
public:
using Proxy = typename Mat::Proxy ;
using const_Proxy = typename Mat::const_Proxy ;
using iterator = StrideIterator<typename Mat::iterator> ;
using const_iterator = StrideIterator<typename Mat::const_iterator> ;
MatrixRow( Mat& mat_, int i) :
mat(mat_), index(i), n(mat.ncol()), nr(mat.nrow()){}
MatrixRow& operator=( const MatrixRow& other ){
if( &other != this ){
import(other) ;
}
return *this ;
}
template <bool NA, typename Vec>
MatrixRow& operator=( const VectorBase<RTYPE,NA,Vec>& expr ){
import(expr) ;
return *this ;
}
inline int size() const { return n ;}
inline Proxy at(int i){ return mat[ index + i*nr ] ; }
inline Proxy operator[]( int i){ return at(i) ; }
inline const_Proxy at(int i) const { return mat[ index + i*nr ] ; }
inline const_Proxy operator[]( int i) const { return at(i) ; }
inline iterator begin() { return iterator( mat.begin() + index, nr ) ; }
inline iterator end() { return iterator( mat.begin() + index + n*nr , nr ) ; }
inline const_iterator begin() const { return const_iterator( mat.begin() + index, nr ) ; }
inline const_iterator end() const { return const_iterator( mat.begin() + index + n*nr , nr ) ; }
private:
Mat& mat ;
int index ;
int n ;
int nr ;
template <typename T>
inline void import( const T& x){
for( int i=0, k=0; i<n; i++) {
at(i) = x[i] ;
}
}
};
template <int RTYPE, template <class> class StoragePolicy>
class Matrix : public MatrixBase<RTYPE, true, Matrix<RTYPE,StoragePolicy> >{
private:
Vector<RTYPE,StoragePolicy> vec ;
int* dims ;
public:
using Proxy = typename Vector<RTYPE,StoragePolicy>::Proxy ;
using const_Proxy = typename Vector<RTYPE,StoragePolicy>::const_Proxy ;
using iterator = typename Vector<RTYPE,StoragePolicy>::iterator ;
using const_iterator = typename Vector<RTYPE,StoragePolicy>::const_iterator ;
using Column = MatrixColumn<RTYPE, Matrix> ;
using Row = MatrixRow<RTYPE, Matrix> ;
Matrix(int nr, int nc) : vec(nr*nc){
set_dimensions(nr,nc) ;
}
template <typename U>
Matrix(int nr, int nc, const U& u) : vec(nr*nc, u){
set_dimensions(nr,nc) ;
}
Matrix() : Matrix(0,0){}
Matrix( SEXP x ){
SEXP d = Rf_getAttrib(x,R_DimSymbol) ;
if( d == R_NilValue || Rf_length(d) != 2)
throw not_a_matrix() ;
vec = x ;
dims = INTEGER(d) ;
}
template <bool NA, typename Mat>
Matrix( const MatrixBase<RTYPE,NA,Mat>& mat ) : Matrix( mat.nrow(), mat.ncol() ) {
int nr = dims[0] ;
int nc = dims[1] ;
for( int j=0, k=0; j<nc; j++){
for( int i=0; i<nr; i++){
vec[k++] = mat(i,j) ;
}
}
}
inline operator SEXP() const { return vec ; }
inline int nrow() const { return dims[0] ; }
inline int ncol() const { return dims[1] ; }
inline int size() const { return vec.size() ; }
inline iterator begin(){ return vec.begin() ; }
inline iterator end(){ return vec.end(); }
inline const_iterator begin() const { return vec.begin() ; }
inline const_iterator end() const { return vec.end(); }
inline Proxy operator[](int i){ return vec[i] ; }
inline const_Proxy operator[](int i) const{ return vec[i] ; }
inline Proxy operator()(int i, int j) { return vec[offset(i,j)] ; }
inline const_Proxy operator()(int i, int j) const { return vec[offset(i,j)] ; }
inline Column column(int i){ return Column(*this, i) ; }
inline Column operator()(internal::NamedPlaceHolder, int i){ return column(i); }
inline Row row(int i){ return Row(*this, i) ; }
inline Row operator()(int i, internal::NamedPlaceHolder){ return row(i); }
private:
inline int offset(int i, int j) const {
return i + nrow()*j ;
}
inline void set_dimensions(int nr, int nc){
Shield<SEXP> dim = Rf_allocVector(INTSXP, 2 ) ;
dims = INTEGER(dim) ;
dims[0] = nr ;
dims[1] = nc ;
Rf_setAttrib(vec, R_DimSymbol, dim ) ;
}
} ;
typedef Matrix<CPLXSXP> ComplexMatrix ;
typedef Matrix<INTSXP> IntegerMatrix ;
typedef Matrix<LGLSXP> LogicalMatrix ;
typedef Matrix<REALSXP> NumericMatrix ;
typedef Matrix<REALSXP> DoubleMatrix ;
typedef Matrix<RAWSXP> RawMatrix ;
typedef Matrix<STRSXP> CharacterMatrix ;
typedef Matrix<STRSXP> StringMatrix ;
typedef Matrix<VECSXP> GenericMatrix ;
typedef Matrix<EXPRSXP> ExpressionMatrix ;
}
#endif