Skip to content

Commit f7383a0

Browse files
committed
fix #273
1 parent aeb1895 commit f7383a0

File tree

5 files changed

+115
-4
lines changed

5 files changed

+115
-4
lines changed

cpp11test/R/cpp11.R

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,14 @@ col_sums <- function(x) {
112112
.Call(`_cpp11test_col_sums`, x)
113113
}
114114

115+
log_mat_mat <- function(x) {
116+
.Call(`_cpp11test_log_mat_mat`, x)
117+
}
118+
119+
log_mat_sexp <- function(x) {
120+
.Call(`_cpp11test_log_mat_sexp`, x)
121+
}
122+
115123
protect_one_ <- function(x, n) {
116124
invisible(.Call(`_cpp11test_protect_one_`, x, n))
117125
}

cpp11test/src/cpp11.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,20 @@ extern "C" SEXP _cpp11test_col_sums(SEXP x) {
215215
return cpp11::as_sexp(col_sums(cpp11::as_cpp<cpp11::decay_t<cpp11::doubles_matrix<cpp11::by_column>>>(x)));
216216
END_CPP11
217217
}
218+
// matrix.cpp
219+
cpp11::doubles_matrix<> log_mat_mat(cpp11::doubles_matrix<> x);
220+
extern "C" SEXP _cpp11test_log_mat_mat(SEXP x) {
221+
BEGIN_CPP11
222+
return cpp11::as_sexp(log_mat_mat(cpp11::as_cpp<cpp11::decay_t<cpp11::doubles_matrix<>>>(x)));
223+
END_CPP11
224+
}
225+
// matrix.cpp
226+
SEXP log_mat_sexp(cpp11::doubles_matrix<> x);
227+
extern "C" SEXP _cpp11test_log_mat_sexp(SEXP x) {
228+
BEGIN_CPP11
229+
return cpp11::as_sexp(log_mat_sexp(cpp11::as_cpp<cpp11::decay_t<cpp11::doubles_matrix<>>>(x)));
230+
END_CPP11
231+
}
218232
// protect.cpp
219233
void protect_one_(SEXP x, int n);
220234
extern "C" SEXP _cpp11test_protect_one_(SEXP x, SEXP n) {
@@ -488,6 +502,8 @@ static const R_CallMethodDef CallEntries[] = {
488502
{"_cpp11test_gibbs_rcpp", (DL_FUNC) &_cpp11test_gibbs_rcpp, 2},
489503
{"_cpp11test_gibbs_rcpp2", (DL_FUNC) &_cpp11test_gibbs_rcpp2, 2},
490504
{"_cpp11test_grow_", (DL_FUNC) &_cpp11test_grow_, 1},
505+
{"_cpp11test_log_mat_mat", (DL_FUNC) &_cpp11test_log_mat_mat, 1},
506+
{"_cpp11test_log_mat_sexp", (DL_FUNC) &_cpp11test_log_mat_sexp, 1},
491507
{"_cpp11test_my_message", (DL_FUNC) &_cpp11test_my_message, 2},
492508
{"_cpp11test_my_message_n1", (DL_FUNC) &_cpp11test_my_message_n1, 1},
493509
{"_cpp11test_my_message_n1fmt", (DL_FUNC) &_cpp11test_my_message_n1fmt, 1},

cpp11test/src/matrix.cpp

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,3 +104,42 @@ using namespace Rcpp;
104104

105105
return sums;
106106
}
107+
108+
[[cpp11::register]] cpp11::doubles_matrix<> log_mat_mat(cpp11::doubles_matrix<> x) {
109+
cpp11::writable::doubles_matrix<> out(x.nrow(), x.ncol());
110+
111+
for (int i = 0; i < x.nrow(); i++) {
112+
for (int j = 0; j < x.ncol(); j++) {
113+
out(i, j) = log(x(i, j));
114+
}
115+
}
116+
117+
// SEXP dimnames = x.attr("dimnames");
118+
// if (dimnames != R_NilValue) {
119+
// Rf_setAttrib(out.data(), R_DimNamesSymbol, dimnames);
120+
// std::cout << "dimnames set successfully" << std::endl;
121+
// }
122+
123+
out.attr("dimnames") = x.attr("dimnames");
124+
125+
return out;
126+
}
127+
128+
[[cpp11::register]] SEXP log_mat_sexp(cpp11::doubles_matrix<> x) {
129+
cpp11::writable::doubles_matrix<> out(x.nrow(), x.ncol());
130+
131+
for (int i = 0; i < x.nrow(); i++) {
132+
for (int j = 0; j < x.ncol(); j++) {
133+
out(i, j) = log(x(i, j));
134+
}
135+
}
136+
137+
// SEXP dimnames = x.attr("dimnames");
138+
// if (dimnames != R_NilValue) {
139+
// Rf_setAttrib(out.data(), R_DimNamesSymbol, dimnames);
140+
// }
141+
142+
out.attr("dimnames") = x.attr("dimnames");
143+
144+
return out;
145+
}

cpp11test/tests/testthat/test-matrix.R

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,16 @@ test_that("col_sums gives same result as colSums", {
2323
y[3, ] <- NA;
2424
expect_equal(col_sums(y), colSums(y))
2525
})
26+
27+
test_that("log_mat_mat returns a matrix with colnames and rownames", {
28+
x <- matrix(c(1, 2, 3, 4), nrow = 2, ncol = 2)
29+
colnames(x) <- letters[1:2]
30+
rownames(x) <- letters[3:4]
31+
32+
y <- log_mat_mat(x)
33+
z <- log_mat_sexp(x)
34+
r <- log(x)
35+
36+
expect_equal(y, r)
37+
expect_equal(z, r)
38+
})

inst/include/cpp11/matrix.hpp

Lines changed: 39 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#pragma once
22

3+
#include <initializer_list> // for initializer_list
34
#include <iterator>
45
#include <string> // for string
56

@@ -188,13 +189,47 @@ class matrix : public matrix_slices<S> {
188189

189190
operator SEXP() const { return SEXP(vector_); }
190191

191-
// operator sexp() { return sexp(vector_); }
192+
auto attr(const char* name) { return vector_.attr(name); }
192193

193-
sexp attr(const char* name) const { return SEXP(vector_.attr(name)); }
194+
auto attr(const std::string& name) { return vector_.attr(name); }
194195

195-
sexp attr(const std::string& name) const { return SEXP(vector_.attr(name)); }
196+
auto attr(SEXP name) { return vector_.attr(name); }
196197

197-
sexp attr(SEXP name) const { return SEXP(vector_.attr(name)); }
198+
void attr(const char* name, SEXP value) { vector_.attr(name) = value; }
199+
200+
void attr(const std::string& name, SEXP value) { vector_.attr(name) = value; }
201+
202+
void attr(SEXP name, SEXP value) { vector_.attr(name) = value; }
203+
204+
void attr(const char* name, std::initializer_list<SEXP> value) {
205+
SEXP attr = PROTECT(Rf_allocVector(VECSXP, value.size()));
206+
int i = 0;
207+
for (SEXP v : value) {
208+
SET_VECTOR_ELT(attr, i++, v);
209+
}
210+
vector_.attr(name) = attr;
211+
UNPROTECT(1);
212+
}
213+
214+
void attr(const std::string& name, std::initializer_list<SEXP> value) {
215+
SEXP attr = PROTECT(Rf_allocVector(VECSXP, value.size()));
216+
int i = 0;
217+
for (SEXP v : value) {
218+
SET_VECTOR_ELT(attr, i++, v);
219+
}
220+
vector_.attr(name) = attr;
221+
UNPROTECT(1);
222+
}
223+
224+
void attr(SEXP name, std::initializer_list<SEXP> value) {
225+
SEXP attr = PROTECT(Rf_allocVector(VECSXP, value.size()));
226+
int i = 0;
227+
for (SEXP v : value) {
228+
SET_VECTOR_ELT(attr, i++, v);
229+
}
230+
vector_.attr(name) = attr;
231+
UNPROTECT(1);
232+
}
198233

199234
r_vector<r_string> names() const { return r_vector<r_string>(vector_.names()); }
200235

0 commit comments

Comments
 (0)