I wrote the following code in Rcpp(sorry if it is abit sloppy. It is my first experience in Rcpp) :
#include <RcppArmadillo.h>
// [[Rcpp::depends(RcppArmadillo)]]
using namespace Rcpp;
using namespace arma;
// [[Rcpp::export]]
Rcpp::NumericMatrix rr (Rcpp::NumericMatrix edge,Rcpp::NumericMatrix riskset,
Rcpp::NumericVector nodes, double memory,int type) {
int n = nodes.size();
int nedge = n*(n-1);
Rcpp::NumericMatrix ref = riskset;
//rownames(x) = CharacterVector::create("a", "b", "c");
colnames(ref) = CharacterVector::create("sender", "receiver");
Rcpp::NumericMatrix RE(edge.nrow(),ref.nrow());
for (int ee1 = 1; ee1 < edge.nrow(); ee1++) {
Rcpp::NumericVector recencySend (nedge, 0);
Rcpp::NumericVector recencyReceiv (nedge, 0);
Rcpp::NumericVector recencyContinue (nedge, 0);
for (int ee2 = 0; ee2 < ee1-1; ee2++) {
double verschil = edge(ee1,1) - edge(ee2,1);
if(verschil>memory){
verschil =1e6;
} else {
verschil=verschil;}
// In case, both x1 and x2 are scalar
//Rcpp::IntegerVector res1 = ifelse( v1>v2, 1, 0);
Rcpp::NumericMatrix::Column col_ref_se = ref( _ , 1); // Reference to the column sender
Rcpp::NumericMatrix::Column col_edge_se = edge( _ , 2); // Reference to the column sender
Rcpp::NumericMatrix::Column col_ref_rec = ref( _ , 2); // Reference to the column receiver
Rcpp::NumericMatrix::Column col_edge_rec = edge( _ , 3); // Reference to the column receiver
if(type==1){
// sender sender
Rcpp::IntegerVector v = Rcpp::seq(0, col_ref_se.size()-1);
Rcpp::IntegerVector gg = v[col_ref_se==col_edge_se[ee2]];
Rcpp::IntegerVector recencyS (gg.size(), 1/(verschil+1));
recencySend[gg] = recencyS;
//recencySend[vv] = 1/(verschil0+1);
RE( ee1 , _ ) = recencySend;
}else if (type==2){
Rcpp::IntegerVector v = Rcpp::seq(0, col_ref_rec.size()-1);
Rcpp::IntegerVector gg = v[col_ref_rec==col_edge_rec[ee2]];
Rcpp::IntegerVector recencyRec (gg.size(), 1/(verschil+1));
recencyReceiv[gg] = recencyRec;
RE( ee1 , _ ) = recencyReceiv;
} else{
// sender receiver , sender receiver
Rcpp::IntegerVector v = Rcpp::seq(0, col_ref_se.size()-1);
Rcpp::IntegerVector gg = v[(col_ref_se==col_edge_se[ee2])&(col_ref_rec==col_edge_rec[ee2])];
Rcpp::IntegerVector recency_SendRec (gg.size(), 1/(verschil+1));
recencyContinue[gg] = recency_SendRec;
RE( ee1 , _ ) = recencyContinue;
}
}
}
return RE;
}
I encountered the following error: no matching function for call to 'distance (int&,int&)' rcpp
Actually the inputs are a a matrix edge, a matrix riskset, a vector nodes, a number type which must be 1,2,or 3, and a memory which should be 60. when I execute
sourceCpp("rr.cpp")
I see that error message.
Changing
Rcpp::NumericVector recencySend (nedge, 0);
Rcpp::NumericVector recencyReceiv (nedge, 0);
Rcpp::NumericVector recencyContinue (nedge, 0);
to
Rcpp::NumericVector recencySend (nedge, 0.0);
Rcpp::NumericVector recencyReceiv (nedge, 0.0);
Rcpp::NumericVector recencyContinue (nedge, 0.0);
will resolve your error message (it compiled fine for me that way).
You're wanting Rcpp::NumericVector
s filled with double
values of 0.0
, but you're sending it int
values. While something like that might fly in a case like
void foo(double x) {
return;
}
void bar() {
foo(0);
}
when you're creating a Rcpp::NumericVector
, you're invoking deep template deduction magic that can be more finicky. So, just use 0.0
rather than 0
and you'll be A-OK.
Or, even better, you can just rely on the fact that a constructor like
Rcpp::NumericVector x(n);
creates a Rcpp::NumericVector
of length n that by default is filled with 0.0
. (See, e.g., the Rcpp Quick Reference Guide).