0
votes

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.

please see the error here as well.

1
Clarifying question: What do you expect the object Rcpp::NumericVector recencySend (0, nedge); to be like? I ask because (1), I know those three lines are (at least among) the culprits of your error, and (2) I suspect you want something more like Rcpp::NumericVector recencySend (nedge, 0); but can't know for certain without confirmation. - duckmayr
@duckmayr thank for your comments. i expect a vector of zeros with length nedge.And I see it should be Rcpp::NumericVector recencySend (nedge, 0); but still I receive that error message. I edited the code. - Mori

1 Answers

6
votes

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::NumericVectors 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).