Skip to content

Commit d42f512

Browse files
committed
complex_matrix<>
1 parent e642aa6 commit d42f512

File tree

3 files changed

+116
-5
lines changed

3 files changed

+116
-5
lines changed

cpp11test/dev/partial_r_vector.hpp

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
class const_iterator {
2+
// Iterator references:
3+
// https://cplusplus.com/reference/iterator/
4+
// https://stackoverflow.com/questions/8054273/how-to-implement-an-stl-style-iterator-and-avoid-common-pitfalls
5+
// It seems like our iterator doesn't fully implement everything for
6+
// `random_access_iterator_tag` (like an `[]` operator, for example). If we discover
7+
// issues with it, we probably need to add more methods.
8+
private:
9+
const r_vector* data_;
10+
R_xlen_t pos_;
11+
std::array<underlying_type, 64 * 64> buf_;
12+
R_xlen_t block_start_ = 0;
13+
R_xlen_t length_ = 0;
14+
15+
public:
16+
using difference_type = ptrdiff_t;
17+
using value_type = T;
18+
using pointer = T*;
19+
using reference = T&;
20+
using iterator_category = std::random_access_iterator_tag;
21+
22+
const_iterator(const r_vector* data, R_xlen_t pos);
23+
24+
const_iterator operator+(R_xlen_t pos);
25+
ptrdiff_t operator-(const const_iterator& other) const;
26+
27+
const_iterator& operator++();
28+
const_iterator& operator--();
29+
30+
const_iterator& operator+=(R_xlen_t pos);
31+
const_iterator& operator-=(R_xlen_t pos);
32+
33+
bool operator!=(const const_iterator& other) const;
34+
bool operator==(const const_iterator& other) const;
35+
36+
T operator*() const;
37+
38+
friend class writable::r_vector<T>::iterator;
39+
40+
private:
41+
/// Implemented in specialization
42+
static bool use_buf(bool is_altrep);
43+
void fill_buf(R_xlen_t pos);
44+
};
45+
46+
template <typename T>
47+
inline bool r_vector<T>::const_iterator::operator==(
48+
const r_vector::const_iterator& other) const {
49+
return pos_ == other.pos_;
50+
}
51+
52+
template <typename T>
53+
bool operator==(const r_vector<T>& lhs, const r_vector<T>& rhs) {
54+
if (lhs.size() != rhs.size()) {
55+
return false;
56+
}
57+
58+
auto lhs_it = lhs.begin();
59+
auto rhs_it = rhs.begin();
60+
61+
auto end = lhs.end();
62+
while (lhs_it != end) {
63+
if (!(*lhs_it == *rhs_it)) {
64+
return false;
65+
}
66+
++lhs_it;
67+
++rhs_it;
68+
}
69+
return true;
70+
}

cpp11test/src/test-matrix.cpp

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ context("matrix-C++") {
2424
expect_true(x[1].size() == 2);
2525
expect_true(x[1].stride() == 5);
2626
}
27+
2728
test_that("matrix dim attributes are correct for read only matrices") {
2829
auto getExportedValue = cpp11::package("base")["getExportedValue"];
2930

@@ -41,6 +42,7 @@ context("matrix-C++") {
4142
expect_true(x[1].size() == 61);
4243
expect_true(x[1].stride() == 87);
4344
}
45+
4446
test_that("matrix<by_column> attributes are correct") {
4547
cpp11::doubles_matrix<cpp11::by_column> x(getExportedValue("datasets", "volcano"));
4648

@@ -156,4 +158,38 @@ context("matrix-C++") {
156158
cpp11::writable::doubles_matrix<cpp11::by_row> x(5, 2);
157159
expect_error(cpp11::writable::integers_matrix<cpp11::by_column>(x));
158160
}
161+
162+
test_that("complex matrix can be created, filled, and copied") {
163+
cpp11::writable::complexes_matrix<cpp11::by_row> x(5, 2);
164+
165+
for (int i = 0; i < 5; ++i) {
166+
for (int j = 0; j < 2; ++j) {
167+
x(i, j) = std::complex<double>(i, j);
168+
}
169+
}
170+
171+
cpp11::writable::complexes_matrix<cpp11::by_column> y(5, 2);
172+
173+
for (int i = 0; i < 5; ++i) {
174+
for (int j = 0; j < 2; ++j) {
175+
y(i, j) = std::complex<double>(i, j);
176+
}
177+
}
178+
179+
cpp11::complexes_matrix<> xc = x;
180+
expect_true(x.nrow() == xc.nrow());
181+
expect_true(x.ncol() == xc.ncol());
182+
183+
cpp11::complexes_matrix<> yc = y;
184+
expect_true(y.nrow() == yc.nrow());
185+
expect_true(y.ncol() == yc.ncol());
186+
187+
// Pacha: I need to figure out how to compare complexes with testthat
188+
// for (int i = 0; i < 5; ++i) {
189+
// for (int j = 0; j < 2; ++j) {
190+
// expect_true(x(i, j) == xc(i, j));
191+
// expect_true(y(i, j) == yc(i, j));
192+
// }
193+
// }
194+
}
159195
}

inst/include/cpp11/matrix.hpp

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,12 @@
33
#include <iterator>
44
#include <string> // for string
55

6-
#include "cpp11/R.hpp" // for SEXP, SEXPREC, R_xlen_t, INT...
7-
#include "cpp11/r_bool.hpp" // for r_bool
8-
#include "cpp11/r_string.hpp" // for r_string
9-
#include "cpp11/r_vector.hpp" // for r_vector
10-
#include "cpp11/sexp.hpp" // for sexp
6+
#include "cpp11/R.hpp" // for SEXP, SEXPREC, R_xlen_t, INT...
7+
#include "cpp11/r_bool.hpp" // for r_bool
8+
#include "cpp11/r_complex.hpp" // for r_complex
9+
#include "cpp11/r_string.hpp" // for r_string
10+
#include "cpp11/r_vector.hpp" // for r_vector
11+
#include "cpp11/sexp.hpp" // for sexp
1112

1213
namespace cpp11 {
1314

@@ -214,6 +215,8 @@ template <typename S = by_column>
214215
using logicals_matrix = matrix<r_vector<r_bool>, r_bool, S>;
215216
template <typename S = by_column>
216217
using strings_matrix = matrix<r_vector<r_string>, r_string, S>;
218+
template <typename S = by_column>
219+
using complexes_matrix = matrix<r_vector<r_complex>, r_complex, S>;
217220

218221
namespace writable {
219222
template <typename S = by_column>
@@ -224,6 +227,8 @@ template <typename S = by_column>
224227
using logicals_matrix = matrix<r_vector<r_bool>, r_vector<r_bool>::proxy, S>;
225228
template <typename S = by_column>
226229
using strings_matrix = matrix<r_vector<r_string>, r_vector<r_string>::proxy, S>;
230+
template <typename S = by_column>
231+
using complexes_matrix = matrix<r_vector<r_complex>, r_vector<r_complex>::proxy, S>;
227232
} // namespace writable
228233

229234
// TODO: Add tests for Matrix class

0 commit comments

Comments
 (0)