Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rcpp multiple functions in a file and no matching function

Tags:

r

rcpp

armadillo

I am trying to run the function weights below in R. Functions mN and PsiN below work individually, and I do not need to export them into R (i.e. their only purpose is to keep the function weights looking neater).

For some reason, only mN gives me the error "no matching function call" within the function weights. Any idea as to why?

#include <RcppArmadillo.h>
// [[Rcpp::depends(RcppArmadillo)]]
using namespace Rcpp;
using namespace arma;

arma::vec mN(double kappa, double ni, arma::vec m, arma::vec C) {
  arma::vec mN; 
  double kappaN;
  kappaN = kappa + ni;
  mN = (kappa/kappaN) * m + (ni/kappaN) * C;
  return mN; 
}
arma::mat PsiN(double ni, double kappa, double kappaN,
               arma::mat y, arma::vec indic, arma::vec C, arma::vec m,
               arma::mat Psi) { 
  double r = indic.n_elem;
  double p = y.n_cols; 
  double n = y.n_rows;
  arma::mat S(p, p); 
  arma::mat PN(p, p); 
  if (r == 1) {
    PN = Psi + kappa*ni/kappaN * ( (C - m ) * (C - m).t() ); 
  } else {
    for (int i = 0; i < n; i++) {
      S += y.row(i).t() * y.row(i);
    }
    PN = Psi + S + kappa*ni/kappaN * ( (C - m ) * (C - m).t() ) ;  
  }
  return PN;
}

// [[Rcpp::export]]

arma::vec weights(int alpha, int v, int kappa, int m,
                  arma::vec nj, arma::mat x, arma::mat Psi, 
               List C, List indic) {
  int p = x.n_cols;
  int n = x.n_rows;
  int kappaN;
  int vN; 
  int crp; 
  arma::vec Q; 
  arma::vec mu;
  arma::mat Sigma;

  for (int i = 0; i < n; i++) {
    kappaN = kappa + nj[i];
    vN     = v + nj[i] - p + 1;
    Sigma  = PsiN(nj[i], kappa, kappaN, x, indic[i], C[i], m, Psi);
    Sigma  = Sigma*(kappaN + 1)/(kappaN*(vN - p + 1));
    mu     = mN(kappa, kappaN, nj[i], m, C[i]); 
    crp    = log(nj[i]) - log(n + alpha - 1);
    Q[i]   = (crp - lgamma((vN + p)/2) - lgamma(vN/2) - p/2*(log(vN) + log(
      datum::pi)) - 1/2*log_det(Sigma) - (vN + p)/2 * (log(1 + 1/v*(x - mu).t()*Sigma.i()*(x-mu)))) ;
  }

 return Q;
}

1 Answers

Your function signature for mN is

arma::vec mN(double, double, arma::vec, arma::vec) 

But you call it as

mu     = mN(kappa, kappaN, nj[i], m, C[i]);

where kappa is int, kappaN is int, nj[i] is double, m is int and C is a List of SEXPs.

Note that unlike R, you can't in general mix doubles and ints in C++ with abandon. In particular, I'll also point out that declarations like

double r = indic.n_elem;
double p = y.n_cols; 
double n = y.n_rows;

should all be ints or unsigned ints.

like image 132
Hong Ooi Avatar answered Dec 03 '25 16:12

Hong Ooi



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!