forked from RcppCore/RcppEigen
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathwrap.cpp
More file actions
244 lines (207 loc) · 9.15 KB
/
wrap.cpp
File metadata and controls
244 lines (207 loc) · 9.15 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
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
#include <RcppEigen.h>
using namespace Rcpp;
// [[Rcpp::depends(RcppEigen)]]
typedef Eigen::ArrayXd Ar1;
typedef Eigen::Map<Ar1> MAr1;
typedef Eigen::ArrayXXd Ar2;
typedef Eigen::Map<Ar2> MAr2;
typedef Eigen::MatrixXd Mat;
typedef Eigen::Map<Mat> MMat;
typedef Eigen::VectorXd Vec;
typedef Eigen::Map<Vec> MVec;
// integer
typedef Eigen::ArrayXi iAr1;
typedef Eigen::Map<iAr1> MiAr1;
typedef Eigen::ArrayXXi iAr2;
typedef Eigen::Map<iAr2> MiAr2;
typedef Eigen::MatrixXi iMat;
typedef Eigen::Map<iMat> MiMat;
typedef Eigen::VectorXi iVec;
typedef Eigen::Map<iVec> MiVec;
// unsigned integer
typedef Eigen::Array<unsigned int, Eigen::Dynamic, 1> uiAr1;
typedef Eigen::Map<uiAr1> MuiAr1;
typedef Eigen::Array<unsigned int, Eigen::Dynamic, Eigen::Dynamic> uiAr2;
typedef Eigen::Map<uiAr2> MuiAr2;
typedef Eigen::Matrix<unsigned int, Eigen::Dynamic, Eigen::Dynamic> uiMat;
typedef Eigen::Map<uiMat> MuiMat;
typedef Eigen::Matrix<unsigned int, Eigen::Dynamic, 1> uiVec;
typedef Eigen::Map<uiVec> MuiVec;
// float
typedef Eigen::ArrayXf fAr1;
typedef Eigen::Map<fAr1> MfAr1;
typedef Eigen::ArrayXXf fAr2;
typedef Eigen::Map<fAr2> MfAr2;
typedef Eigen::MatrixXf fMat;
typedef Eigen::Map<fMat> MfMat;
typedef Eigen::VectorXf fVec;
typedef Eigen::Map<fVec> MfVec;
// complex double
typedef Eigen::ArrayXcd cdAr1;
typedef Eigen::Map<cdAr1> McdAr1;
typedef Eigen::ArrayXXcd cdAr2;
typedef Eigen::Map<cdAr2> McdAr2;
typedef Eigen::MatrixXcd cdMat;
typedef Eigen::Map<cdMat> McdMat;
typedef Eigen::VectorXcd cdVec;
typedef Eigen::Map<cdVec> McdVec;
// [[Rcpp::export]]
Rcpp::List wrap_vectors() {
List vecs = List::create(
_["Vec<complex>"] = cdVec::Zero(5),
_["Vec<double>"] = Vec::Zero(5),
_["Vec<float>"] = fVec::Zero(5),
_["Vec<int>"] = iVec::Zero(5),
_["Vec<unsigned int>"] = uiVec::Zero(5)
);
// A VectorX<T> behaves as a matrix with one column but is converted to
// a vector object in R, not a matrix of one column. The distinction is
// that VectorX<T> objects are defined at compile time to have one column,
// whereas a MatrixX<T> has a dynamic number of columns that is set to 1
// during execution of the code. A MatrixX<T> object can be resized to have
// a different number of columns. A VectorX<T> object cannot.
List cols = List::create(
_["Col<complex>"] = cdMat::Zero(5, 1),
_["Col<double>"] = Mat::Zero(5, 1),
_["Col<float>"] = fMat::Zero(5, 1),
_["Col<int>"] = iMat::Zero(5, 1),
_["Col<unsigned int>"] = uiMat::Zero(5, 1)
);
List rows = List::create(
_["Row<complex>"] = Eigen::RowVectorXcd::Zero(5),
_["Row<double>"] = Eigen::RowVectorXd::Zero(5),
_["Row<float>"] = Eigen::RowVectorXf::Zero(5),
_["Row<int>"] = Eigen::RowVectorXi::Zero(5),
_["Row<unsigned int>"] = Eigen::Matrix<unsigned int, 1, Eigen::Dynamic>::Zero(5)
);
List matrices = List::create(
_["Mat<complex>"] = cdMat::Identity(3, 3),
_["Mat<double>"] = Mat::Identity(3, 3),
_["Mat<float>"] = fMat::Identity(3, 3),
_["Mat<int>"] = iMat::Identity(3, 3),
_["Mat<unsigned int>"] = uiMat::Identity(3, 3)
);
// ArrayXX<t> objects have the same structure as matrices but allow
// componentwise arithmetic. A * B is matrix multiplication for
// matrices and componentwise multiplication for arrays.
List arrays2 = List::create(
_["Arr2<complex>"] = cdAr2::Zero(3, 3),
_["Arr2<double>"] = Ar2::Zero(3, 3),
_["Arr2<float>"] = fAr2::Zero(3, 3),
_["Arr2<int>"] = iAr2::Zero(3, 3),
_["Arr2<unsigned int>"] = uiAr2::Zero(3, 3)
);
// ArrayX<t> objects have the same structure as VectorX<T> objects
// but allow componentwise arithmetic, including functions like exp, log,
// sqrt, ...
List arrays1 = List::create(
_["Arr1<complex>"] = cdAr1::Zero(5),
_["Arr1<double>"] = Ar1::Zero(5),
_["Arr1<float>"] = fAr1::Zero(5),
_["Arr1<int>"] = iAr1::Zero(5),
_["Arr1<unsigned int>"] = uiAr1::Zero(5)
);
List operations = List::create(
_["Op_seq"] = Eigen::ArrayXd::LinSpaced(6, 1, 10), // arguments are length.out, start, end
_["Op_log"] = Eigen::ArrayXd::LinSpaced(6, 1, 10).log(),
_["Op_exp"] = Eigen::ArrayXd::LinSpaced(6, 1, 10).exp(),
_["Op_sqrt"] = Eigen::ArrayXd::LinSpaced(6, 1, 10).sqrt(),
_["Op_cos"] = Eigen::ArrayXd::LinSpaced(6, 1, 10).cos()
);
List output = List::create(
_["vectors : VectorX<T>"] = vecs,
_["matrices : MatrixX<T>"] = matrices,
_["rows : RowVectorX<T>"] = rows,
_["columns : MatrixX<T>"] = cols,
_["arrays2d : ArrayXX<T>"] = arrays2,
_["arrays1d : ArrayX<T>"] = arrays1,
_["operations : ArrayXd"] = operations
);
return output;
}
// [[Rcpp::export]]
Rcpp::List as_Vec(Rcpp::List input) {
// Column vector
iVec m1 = input[0] ; /* implicit as */
Vec m2 = input[1] ; /* implicit as */
uiVec m3 = input[0] ; /* implicit as */
fVec m4 = input[1] ; /* implicit as */
// Row vector
Eigen::Matrix<int, 1, Eigen::Dynamic> m5 = input[0] ; /* implicit as */
Eigen::Matrix<double, 1, Eigen::Dynamic> m6 = input[1] ; /* implicit as */
Eigen::Matrix<unsigned int, 1, Eigen::Dynamic> m7 = input[0] ; /* implicit as */
Eigen::Matrix<float, 1, Eigen::Dynamic> m8 = input[1] ; /* implicit as */
// Mapped vector
MiVec m9 = input[0] ; /* implicit as */
MVec m10 = input[1] ; /* implicit as */
List res = List::create(m1.sum(), m2.sum(), m3.sum(), m4.sum(),
m5.sum(), m6.sum(), m7.sum(), m8.sum(),
m9.sum(), m10.sum());
return res ;
}
// [[Rcpp::export]]
Rcpp::List as_Array(Rcpp::List input) {
// Column array
iAr1 m1 = input[0] ; /* implicit as */
Ar1 m2 = input[1] ; /* implicit as */
uiAr1 m3 = input[0] ; /* implicit as */
fAr1 m4 = input[1] ; /* implicit as */
// Row array
Eigen::Array<int, 1, Eigen::Dynamic> m5 = input[0] ; /* implicit as */
Eigen::Array<double, 1, Eigen::Dynamic> m6 = input[1] ; /* implicit as */
Eigen::Array<unsigned int, 1, Eigen::Dynamic> m7 = input[0] ; /* implicit as */
Eigen::Array<float, 1, Eigen::Dynamic> m8 = input[1] ; /* implicit as */
// Mapped array
MiAr1 m9 = input[0] ; /* implicit as */
MAr1 m10 = input[1] ; /* implicit as */
List res = List::create(m1.sum(), m2.sum(), m3.sum(), m4.sum(),
m5.sum(), m6.sum(), m7.sum(), m8.sum(),
m9.sum(), m10.sum());
return res ;
}
// [[Rcpp::export]]
Rcpp::List as_Mat(Rcpp::List input) {
// Copy to matrix
iMat m1 = input[0] ; /* implicit as */
Mat m2 = input[1] ; /* implicit as */
uiMat m3 = input[0] ; /* implicit as */
fMat m4 = input[1] ; /* implicit as */
// Mapped matrix
MiMat m5 = input[0] ; /* implicit as */
MMat m6 = input[1] ; /* implicit as */
List res = List::create(m1.sum(), m2.sum(), m3.sum(), m4.sum(),
m5.sum(), m6.sum());
return res ;
}
// [[Rcpp::export]]
Rcpp::List as_Array2D(Rcpp::List input) {
// Copy to 2D array
iAr2 m1 = input[0] ; /* implicit as */
Ar2 m2 = input[1] ; /* implicit as */
uiAr2 m3 = input[0] ; /* implicit as */
fAr2 m4 = input[1] ; /* implicit as */
// Mapped 2D array
MiAr2 m5 = input[0] ; /* implicit as */
MAr2 m6 = input[1] ; /* implicit as */
List res = List::create(m1.sum(), m2.sum(), m3.sum(), m4.sum(),
m5.sum(), m6.sum());
return res ;
}
// wrap large vector, passes for n > 2^31-1 as no dim attribute
// [[Rcpp::export]]
Rcpp::IntegerVector vector_large_wrap(R_xlen_t n) {
Eigen::VectorXi x(n, 1);
for (R_xlen_t i = 0; i < n; ++i) {
x(i) = static_cast<int32_t>(i % 10);
}
return Rcpp::wrap(x);
}
// wrap large matrix, fails for n > 2^31-1 if dim attribute > 2^31-1
// [[Rcpp::export]]
Rcpp::IntegerMatrix matrix_large_wrap(R_xlen_t n) {
Eigen::MatrixXi x(n, 1);
for (R_xlen_t i = 0; i < n; ++i) {
x(i, 0) = static_cast<int32_t>(i % 10);
}
return Rcpp::wrap(x);
}