112 lines
3.6 KiB
C++
112 lines
3.6 KiB
C++
#ifndef TYPES_INCLUDE_GUARD_H
|
|
#define TYPES_INCLUDE_GUARD_H
|
|
|
|
#include <Rinternals.h>
|
|
#include <cstdint>
|
|
#include <vector>
|
|
#include <stdexcept>
|
|
|
|
#include "int_utils.h"
|
|
|
|
/**
|
|
* Multivariate Binary Dataset
|
|
*
|
|
* Note: The maximum binary vector size for one observation is 32.
|
|
*/
|
|
class MVBinary : public std::vector<uint32_t> {
|
|
public:
|
|
MVBinary(std::size_t n, std::size_t p) : p{p} {
|
|
this->reserve(n);
|
|
}
|
|
template<typename _InputIterator>
|
|
MVBinary(_InputIterator first, _InputIterator last, std::size_t p)
|
|
: p{p}
|
|
, std::vector<uint32_t>(first, last) { };
|
|
|
|
std::size_t dim() const { return p; }
|
|
std::size_t nrow() const { return size(); }
|
|
std::size_t ncol() const { return p; }
|
|
|
|
private:
|
|
std::size_t p = 0;
|
|
};
|
|
|
|
/**
|
|
* View to a SEXP numeric vector representing a half vectorized matrix.
|
|
*
|
|
* This means that there esists a `p` such that the length is `p (p + 1) / 2`.
|
|
*/
|
|
class VechView {
|
|
public:
|
|
|
|
VechView(const std::size_t p)
|
|
: _sexp{nullptr}
|
|
, _size{p * (p + 1) / 2}
|
|
, _dim{p}
|
|
, _data{new double[_size]} { }
|
|
|
|
// Only ctor, its a SEXP view
|
|
VechView(SEXP x) : _sexp{x} {
|
|
// check type
|
|
if (TYPEOF(x) != REALSXP) {
|
|
throw std::invalid_argument("expected numeric vector");
|
|
}
|
|
// get size, compute underlying dimension and validate size consistency
|
|
// which is that `_size = length(x) = _dim (_dim + 1) / 2`.
|
|
_size = Rf_length(x);
|
|
if (!(_dim = invTriag(_size))) {
|
|
throw std::invalid_argument("Expected `length(theta) == p * (p + 1) / 2`");
|
|
}
|
|
// set data memory hook
|
|
_data = REAL(x);
|
|
}
|
|
// // for now, do not allow to use `Rcpp::wrap`
|
|
// operator SEXP() { return _sexp; };
|
|
// operator SEXP() const { return _sexp; };
|
|
|
|
// dtor in case of owning the data instead of beeing a view to a SEXP the
|
|
// aquired memory needs to be free
|
|
~VechView() {
|
|
if (!_sexp) {
|
|
delete[] _data;
|
|
}
|
|
}
|
|
|
|
std::size_t size() const { return _size; }
|
|
std::size_t dim() const { return _dim; }
|
|
|
|
std::size_t index(std::size_t i, std::size_t j) const {
|
|
return (i * (2 * _dim - 1 - i)) / 2 + j;
|
|
}
|
|
std::size_t index(std::size_t i) const { return index(i, i); }
|
|
|
|
double operator[](std::size_t i) const { return _data[i]; }
|
|
double& operator[](std::size_t i) { return _data[i]; }
|
|
double operator()(std::size_t i, std::size_t j) const {
|
|
return _data[(i * (2 * _dim - 1 - i)) / 2 + j];
|
|
}
|
|
double& operator()(std::size_t i, std::size_t j) {
|
|
return _data[(i * (2 * _dim - 1 - i)) / 2 + j];
|
|
}
|
|
double operator()(std::size_t i) const { return (*this)(i, i); }
|
|
double& operator()(std::size_t i) { return (*this)(i, i); }
|
|
|
|
double* begin() { return _data; }
|
|
double* end() { return _data + _size; }
|
|
const double* begin() const { return _data; }
|
|
const double* end() const { return _data + _size; }
|
|
const double* cbegin() { return _data; }
|
|
const double* cend() { return _data + _size; }
|
|
|
|
private:
|
|
SEXP _sexp; // original R object of which this is a view to the data
|
|
std::size_t _size; // length of _data
|
|
std::size_t _dim; // dimension of references _data, relation to _size
|
|
// is given by `2 _size = _dim (_dim + 1)`
|
|
double* _data; // pointer to underlying data
|
|
// bool _owner = false;// set to true if the SEXP object is created and needs
|
|
// // to be unprotected (from the GC) at destruction
|
|
};
|
|
|
|
#endif /* TYPES_INCLUDE_GUARD_H */
|