Skip to content

Commit e0db007

Browse files
committed
initial headers for dense Matrix (not matrix)
1 parent aeb1895 commit e0db007

File tree

6 files changed

+214
-1
lines changed

6 files changed

+214
-1
lines changed

cpp11test/R/cpp11.R

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,18 @@ row_sums <- function(x) {
108108
.Call(`_cpp11test_row_sums`, x)
109109
}
110110

111+
row_sums_2 <- function(x) {
112+
.Call(`_cpp11test_row_sums_2`, x)
113+
}
114+
115+
row_sums_3 <- function(x) {
116+
.Call(`_cpp11test_row_sums_3`, x)
117+
}
118+
119+
row_sums_4 <- function(x) {
120+
.Call(`_cpp11test_row_sums_4`, x)
121+
}
122+
111123
col_sums <- function(x) {
112124
.Call(`_cpp11test_col_sums`, x)
113125
}

cpp11test/src/cpp11.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,27 @@ extern "C" SEXP _cpp11test_row_sums(SEXP x) {
209209
END_CPP11
210210
}
211211
// matrix.cpp
212+
cpp11::doubles row_sums_2(cpp11::dge_matrix<> x);
213+
extern "C" SEXP _cpp11test_row_sums_2(SEXP x) {
214+
BEGIN_CPP11
215+
return cpp11::as_sexp(row_sums_2(cpp11::as_cpp<cpp11::decay_t<cpp11::dge_matrix<>>>(x)));
216+
END_CPP11
217+
}
218+
// matrix.cpp
219+
cpp11::doubles row_sums_3(cpp11::dsy_matrix<> x);
220+
extern "C" SEXP _cpp11test_row_sums_3(SEXP x) {
221+
BEGIN_CPP11
222+
return cpp11::as_sexp(row_sums_3(cpp11::as_cpp<cpp11::decay_t<cpp11::dsy_matrix<>>>(x)));
223+
END_CPP11
224+
}
225+
// matrix.cpp
226+
cpp11::writable::doubles row_sums_4(cpp11::dsp_matrix<> x);
227+
extern "C" SEXP _cpp11test_row_sums_4(SEXP x) {
228+
BEGIN_CPP11
229+
return cpp11::as_sexp(row_sums_4(cpp11::as_cpp<cpp11::decay_t<cpp11::dsp_matrix<>>>(x)));
230+
END_CPP11
231+
}
232+
// matrix.cpp
212233
cpp11::doubles col_sums(cpp11::doubles_matrix<cpp11::by_column> x);
213234
extern "C" SEXP _cpp11test_col_sums(SEXP x) {
214235
BEGIN_CPP11
@@ -518,6 +539,9 @@ static const R_CallMethodDef CallEntries[] = {
518539
{"_cpp11test_rcpp_sum_int_for_", (DL_FUNC) &_cpp11test_rcpp_sum_int_for_, 1},
519540
{"_cpp11test_remove_altrep", (DL_FUNC) &_cpp11test_remove_altrep, 1},
520541
{"_cpp11test_row_sums", (DL_FUNC) &_cpp11test_row_sums, 1},
542+
{"_cpp11test_row_sums_2", (DL_FUNC) &_cpp11test_row_sums_2, 1},
543+
{"_cpp11test_row_sums_3", (DL_FUNC) &_cpp11test_row_sums_3, 1},
544+
{"_cpp11test_row_sums_4", (DL_FUNC) &_cpp11test_row_sums_4, 1},
521545
{"_cpp11test_string_proxy_assignment_", (DL_FUNC) &_cpp11test_string_proxy_assignment_, 0},
522546
{"_cpp11test_string_push_back_", (DL_FUNC) &_cpp11test_string_push_back_, 0},
523547
{"_cpp11test_sum_dbl_accumulate2_", (DL_FUNC) &_cpp11test_sum_dbl_accumulate2_, 1},

cpp11test/src/matrix.cpp

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#include "cpp11/matrix.hpp"
2+
#include "cpp11/dmatrix.hpp"
23
#include "Rmath.h"
34
#include "cpp11/doubles.hpp"
45
using namespace cpp11;
@@ -82,10 +83,42 @@ using namespace Rcpp;
8283
}
8384
++i;
8485
}
85-
86+
// 4
8687
return sums;
8788
}
8889

90+
[[cpp11::register]] cpp11::doubles row_sums_2(cpp11::dge_matrix<> x) {
91+
int nrow = x.nrow();
92+
int ncol = x.ncol();
93+
cpp11::writable::doubles result(nrow);
94+
95+
for (int i = 0; i < nrow; ++i) {
96+
double sum = 0;
97+
for (int j = 0; j < ncol; ++j) {
98+
sum += x(i, j);
99+
}
100+
result[i] = sum;
101+
}
102+
103+
return result;
104+
}
105+
106+
[[cpp11::register]] cpp11::doubles row_sums_3(cpp11::dsy_matrix<> x) {
107+
int nrow = x.nrow();
108+
int ncol = x.ncol();
109+
cpp11::writable::doubles result(nrow);
110+
111+
for (int i = 0; i < nrow; ++i) {
112+
double sum = 0;
113+
for (int j = 0; j < ncol; ++j) {
114+
sum += x(i, j);
115+
}
116+
result[i] = sum;
117+
}
118+
119+
return result;
120+
}
121+
89122
[[cpp11::register]] cpp11::doubles col_sums(cpp11::doubles_matrix<cpp11::by_column> x) {
90123
cpp11::writable::doubles sums(x.ncol());
91124

cpp11test/tests/testthat/test-matrix.R

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,16 @@ test_that("row_sums gives same result as rowSums", {
99
y <- cbind(x1 = 3, x2 = c(4:1, 2:5))
1010
y[3, ] <- NA;
1111
expect_equal(row_sums(y), rowSums(y))
12+
13+
# Pacha: test dgeMatrix and other d**Matrix (Matrix package)
14+
15+
z <- cbind(x1 = 3, x2 = c(4, 4))
16+
z2 <- Matrix::Matrix(z) # dgeMatrix
17+
expect_equal(rowSums(z), row_sums_2(z2))
18+
19+
z3 <- matrix(c(1, 2, 2, 1), nrow = 2)
20+
z4 <- new("dsyMatrix", Dim = c(2L, 2L), x = c(1, 2, 2, 1))
21+
expect_equal(rowSums(z3), row_sums_3(z4))
1222
})
1323

1424
test_that("col_sums gives same result as colSums", {

inst/include/cpp11.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include "cpp11/list_of.hpp"
1515
#include "cpp11/logicals.hpp"
1616
#include "cpp11/matrix.hpp"
17+
#include "cpp11/dmatrix.hpp"
1718
#include "cpp11/named_arg.hpp"
1819
#include "cpp11/protect.hpp"
1920
#include "cpp11/r_bool.hpp"

inst/include/cpp11/dmatrix.hpp

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
#pragma once
2+
3+
#include "cpp11/R.hpp"
4+
#include "cpp11/r_vector.hpp"
5+
#include "cpp11/sexp.hpp"
6+
7+
// dgeMatrix: Class "dgeMatrix" of Dense Numeric (S4 Class) Matrices
8+
9+
namespace cpp11 {
10+
11+
template <typename S = by_column>
12+
class dge_matrix {
13+
private:
14+
writable::r_vector<double> vector_;
15+
int nrow_;
16+
int ncol_;
17+
18+
public:
19+
dge_matrix(SEXP data) {
20+
SEXP x_slot = R_do_slot(data, Rf_install("x"));
21+
22+
// get dimensions
23+
24+
// nrow_ = Rf_nrows(data);
25+
// ncol_ = Rf_ncols(data);
26+
27+
// use attr instead (Matrix != matrix class)
28+
SEXP dim = R_do_slot(data, Rf_install("Dim"));
29+
nrow_ = INTEGER(dim)[0];
30+
ncol_ = INTEGER(dim)[1];
31+
32+
if (nrow_ <= 0 || ncol_ <= 0) {
33+
throw std::runtime_error("Invalid matrix dimensions");
34+
}
35+
36+
vector_ = writable::r_vector<double>(Rf_allocVector(REALSXP, Rf_length(x_slot)));
37+
for (int i = 0; i < Rf_length(x_slot); ++i) {
38+
vector_[i] = REAL(x_slot)[i];
39+
}
40+
41+
SEXP dims = PROTECT(Rf_allocVector(INTSXP, 2));
42+
INTEGER(dims)[0] = nrow_;
43+
INTEGER(dims)[1] = ncol_;
44+
vector_.attr(R_DimSymbol) = dims;
45+
UNPROTECT(1);
46+
}
47+
48+
int nrow() const { return nrow_; }
49+
int ncol() const { return ncol_; }
50+
51+
double operator()(int row, int col) const { return vector_[row + (col * nrow_)]; }
52+
};
53+
54+
namespace writable {
55+
template <typename S = by_column>
56+
using dge_matrix = cpp11::dge_matrix<S>;
57+
} // namespace writable
58+
59+
} // namespace cpp11
60+
61+
// dsyMatrix: Symmetric Dense (Packed or Unpacked) Numeric Matrices
62+
63+
namespace cpp11 {
64+
65+
template <typename S = by_column>
66+
class dsy_matrix {
67+
private:
68+
writable::r_vector<double> vector_;
69+
int nrow_;
70+
int ncol_;
71+
bool is_packed_;
72+
bool is_upper_;
73+
74+
public:
75+
dsy_matrix(SEXP data) {
76+
SEXP x_slot = R_do_slot(data, Rf_install("x"));
77+
78+
// use attr instead (Matrix != matrix class)
79+
SEXP dim = R_do_slot(data, Rf_install("Dim"));
80+
nrow_ = INTEGER(dim)[0];
81+
ncol_ = INTEGER(dim)[1];
82+
83+
if (nrow_ <= 0 || ncol_ <= 0) {
84+
throw std::runtime_error("Invalid matrix dimensions");
85+
}
86+
87+
// Check if the matrix is packed and if it's upper or lower triangular
88+
SEXP uplo = R_do_slot(data, Rf_install("uplo"));
89+
is_upper_ = (Rf_asChar(uplo) == Rf_mkChar("U"));
90+
is_packed_ = (Rf_length(x_slot) == (nrow_ * (nrow_ + 1)) / 2);
91+
92+
vector_ = writable::r_vector<double>(Rf_allocVector(REALSXP, Rf_length(x_slot)));
93+
for (int i = 0; i < Rf_length(x_slot); ++i) {
94+
vector_[i] = REAL(x_slot)[i];
95+
}
96+
97+
SEXP dims = PROTECT(Rf_allocVector(INTSXP, 2));
98+
INTEGER(dims)[0] = nrow_;
99+
INTEGER(dims)[1] = ncol_;
100+
vector_.attr(R_DimSymbol) = dims;
101+
UNPROTECT(1);
102+
}
103+
104+
int nrow() const { return nrow_; }
105+
int ncol() const { return ncol_; }
106+
107+
double operator()(int row, int col) const {
108+
if (is_packed_) {
109+
if (is_upper_) {
110+
if (row <= col) {
111+
return vector_[col * (col + 1) / 2 + row];
112+
} else {
113+
return vector_[row * (row + 1) / 2 + col];
114+
}
115+
} else {
116+
if (row >= col) {
117+
return vector_[row * (row + 1) / 2 + col];
118+
} else {
119+
return vector_[col * (col + 1) / 2 + row];
120+
}
121+
}
122+
} else {
123+
return vector_[row + (col * nrow_)];
124+
}
125+
}
126+
};
127+
128+
namespace writable {
129+
template <typename S = by_column>
130+
using dsy_matrix = cpp11::dsy_matrix<S>;
131+
} // namespace writable
132+
133+
} // namespace cpp11

0 commit comments

Comments
 (0)