Skip to content

copy complex numbers/vectors/matrices from R to C++ and viceversa #427

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 14 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
complex_matrix<>
  • Loading branch information
pachadotdev committed Dec 27, 2024
commit d42f512e9e0784be8ced4428d29e41e42f28c6b6
70 changes: 70 additions & 0 deletions cpp11test/dev/partial_r_vector.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
class const_iterator {
// Iterator references:
// https://cplusplus.com/reference/iterator/
// https://stackoverflow.com/questions/8054273/how-to-implement-an-stl-style-iterator-and-avoid-common-pitfalls
// It seems like our iterator doesn't fully implement everything for
// `random_access_iterator_tag` (like an `[]` operator, for example). If we discover
// issues with it, we probably need to add more methods.
private:
const r_vector* data_;
R_xlen_t pos_;
std::array<underlying_type, 64 * 64> buf_;
R_xlen_t block_start_ = 0;
R_xlen_t length_ = 0;

public:
using difference_type = ptrdiff_t;
using value_type = T;
using pointer = T*;
using reference = T&;
using iterator_category = std::random_access_iterator_tag;

const_iterator(const r_vector* data, R_xlen_t pos);

const_iterator operator+(R_xlen_t pos);
ptrdiff_t operator-(const const_iterator& other) const;

const_iterator& operator++();
const_iterator& operator--();

const_iterator& operator+=(R_xlen_t pos);
const_iterator& operator-=(R_xlen_t pos);

bool operator!=(const const_iterator& other) const;
bool operator==(const const_iterator& other) const;

T operator*() const;

friend class writable::r_vector<T>::iterator;

private:
/// Implemented in specialization
static bool use_buf(bool is_altrep);
void fill_buf(R_xlen_t pos);
};

template <typename T>
inline bool r_vector<T>::const_iterator::operator==(
const r_vector::const_iterator& other) const {
return pos_ == other.pos_;
}

template <typename T>
bool operator==(const r_vector<T>& lhs, const r_vector<T>& rhs) {
if (lhs.size() != rhs.size()) {
return false;
}

auto lhs_it = lhs.begin();
auto rhs_it = rhs.begin();

auto end = lhs.end();
while (lhs_it != end) {
if (!(*lhs_it == *rhs_it)) {
return false;
}
++lhs_it;
++rhs_it;
}
return true;
}
36 changes: 36 additions & 0 deletions cpp11test/src/test-matrix.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ context("matrix-C++") {
expect_true(x[1].size() == 2);
expect_true(x[1].stride() == 5);
}

test_that("matrix dim attributes are correct for read only matrices") {
auto getExportedValue = cpp11::package("base")["getExportedValue"];

Expand All @@ -41,6 +42,7 @@ context("matrix-C++") {
expect_true(x[1].size() == 61);
expect_true(x[1].stride() == 87);
}

test_that("matrix<by_column> attributes are correct") {
cpp11::doubles_matrix<cpp11::by_column> x(getExportedValue("datasets", "volcano"));

Expand Down Expand Up @@ -156,4 +158,38 @@ context("matrix-C++") {
cpp11::writable::doubles_matrix<cpp11::by_row> x(5, 2);
expect_error(cpp11::writable::integers_matrix<cpp11::by_column>(x));
}

test_that("complex matrix can be created, filled, and copied") {
cpp11::writable::complexes_matrix<cpp11::by_row> x(5, 2);

for (int i = 0; i < 5; ++i) {
for (int j = 0; j < 2; ++j) {
x(i, j) = std::complex<double>(i, j);
}
}

cpp11::writable::complexes_matrix<cpp11::by_column> y(5, 2);

for (int i = 0; i < 5; ++i) {
for (int j = 0; j < 2; ++j) {
y(i, j) = std::complex<double>(i, j);
}
}

cpp11::complexes_matrix<> xc = x;
expect_true(x.nrow() == xc.nrow());
expect_true(x.ncol() == xc.ncol());

cpp11::complexes_matrix<> yc = y;
expect_true(y.nrow() == yc.nrow());
expect_true(y.ncol() == yc.ncol());

// Pacha: I need to figure out how to compare complexes with testthat
// for (int i = 0; i < 5; ++i) {
// for (int j = 0; j < 2; ++j) {
// expect_true(x(i, j) == xc(i, j));
// expect_true(y(i, j) == yc(i, j));
// }
// }
}
}
15 changes: 10 additions & 5 deletions inst/include/cpp11/matrix.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@
#include <iterator>
#include <string> // for string

#include "cpp11/R.hpp" // for SEXP, SEXPREC, R_xlen_t, INT...
#include "cpp11/r_bool.hpp" // for r_bool
#include "cpp11/r_string.hpp" // for r_string
#include "cpp11/r_vector.hpp" // for r_vector
#include "cpp11/sexp.hpp" // for sexp
#include "cpp11/R.hpp" // for SEXP, SEXPREC, R_xlen_t, INT...
#include "cpp11/r_bool.hpp" // for r_bool
#include "cpp11/r_complex.hpp" // for r_complex
#include "cpp11/r_string.hpp" // for r_string
#include "cpp11/r_vector.hpp" // for r_vector
#include "cpp11/sexp.hpp" // for sexp

namespace cpp11 {

Expand Down Expand Up @@ -214,6 +215,8 @@ template <typename S = by_column>
using logicals_matrix = matrix<r_vector<r_bool>, r_bool, S>;
template <typename S = by_column>
using strings_matrix = matrix<r_vector<r_string>, r_string, S>;
template <typename S = by_column>
using complexes_matrix = matrix<r_vector<r_complex>, r_complex, S>;

namespace writable {
template <typename S = by_column>
Expand All @@ -224,6 +227,8 @@ template <typename S = by_column>
using logicals_matrix = matrix<r_vector<r_bool>, r_vector<r_bool>::proxy, S>;
template <typename S = by_column>
using strings_matrix = matrix<r_vector<r_string>, r_vector<r_string>::proxy, S>;
template <typename S = by_column>
using complexes_matrix = matrix<r_vector<r_complex>, r_vector<r_complex>::proxy, S>;
} // namespace writable

// TODO: Add tests for Matrix class
Expand Down
Loading