tensor_predictors/mvbernoulli/src/types.h

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 */