87 lines
2.4 KiB
C
87 lines
2.4 KiB
C
|
// Included by Rcpp through naming convention into the generated RcppExports.cpp
|
||
|
// file. This anables to use custom Rcpp types throughout the package.
|
||
|
|
||
|
#ifndef MVBERNOULLI_INCLUDE_GUARD_H
|
||
|
#define MVBERNOULLI_INCLUDE_GUARD_H
|
||
|
|
||
|
#include <vector>
|
||
|
#include <algorithm>
|
||
|
#include <RcppCommon.h>
|
||
|
|
||
|
#include "../../src/types.h"
|
||
|
|
||
|
// Custom type consersion declarations
|
||
|
namespace Rcpp {
|
||
|
|
||
|
// from R to C++
|
||
|
template <> MVBinary as(SEXP);
|
||
|
// from C++ to R
|
||
|
template <> SEXP wrap(const MVBinary&);
|
||
|
|
||
|
} /* namespace Rcpp */
|
||
|
|
||
|
#include <Rcpp.h>
|
||
|
|
||
|
// Custom type implementations
|
||
|
namespace Rcpp {
|
||
|
|
||
|
// from R to C++
|
||
|
template <>
|
||
|
MVBinary as(SEXP x) {
|
||
|
|
||
|
if ((TYPEOF(x) == LGLSXP || TYPEOF(x) == INTSXP) && Rf_isMatrix(x)) {
|
||
|
int nrow = Rf_nrows(x);
|
||
|
int ncol = Rf_ncols(x);
|
||
|
|
||
|
if (31 < ncol) {
|
||
|
Rcpp::stop("Event dimension too big, max is 31");
|
||
|
}
|
||
|
|
||
|
MVBinary binary(nrow, ncol);
|
||
|
|
||
|
// convert logical/integer vector to numeric representation
|
||
|
int* data = (TYPEOF(x) == LGLSXP) ? LOGICAL(x) : INTEGER(x);
|
||
|
for (int i = 0; i < nrow; ++i) {
|
||
|
uint32_t num = 0;
|
||
|
for (int j = 0; j < ncol; ++j) {
|
||
|
num |= static_cast<bool>(data[i + nrow * j]) * (1 << j);
|
||
|
}
|
||
|
binary.push_back(num);
|
||
|
}
|
||
|
|
||
|
return binary;
|
||
|
} else if ((TYPEOF(x) == INTSXP) && Rf_isVector(x)) {
|
||
|
int n = Rf_length(x);
|
||
|
SEXP pAttr = Rf_getAttrib(x, Rf_install("p"));
|
||
|
int p = -1;
|
||
|
if (TYPEOF(pAttr) == INTSXP) {
|
||
|
p = Rf_asInteger(pAttr);
|
||
|
} else if (TYPEOF(pAttr) == REALSXP) {
|
||
|
p = Rf_asInteger(pAttr);
|
||
|
} else {
|
||
|
Rcpp::stop("Unable to determin ncol (illegal `p` attribute)");
|
||
|
}
|
||
|
if (p < 2 || 31 < p) {
|
||
|
Rcpp::stop("Unable to determin ncol (illegal `p` attribute)");
|
||
|
}
|
||
|
|
||
|
return MVBinary(INTEGER(x), INTEGER(x) + n, p);
|
||
|
} else {
|
||
|
Rcpp::stop("Unexpected dim/type");
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
// from C++ to R
|
||
|
template <>
|
||
|
SEXP wrap(const MVBinary& binary) {
|
||
|
auto sexp = Rcpp::IntegerVector(binary.begin(), binary.end());
|
||
|
sexp.attr("class") = Rcpp::CharacterVector::create("mvbinary");
|
||
|
sexp.attr("p") = binary.dim();
|
||
|
return sexp;
|
||
|
}
|
||
|
|
||
|
} /* namespace Rcpp */
|
||
|
|
||
|
#endif /* MVBERNOULLI_INCLUDE_GUARD_H */
|