user9429904
user9429904

Reputation:

Rcpp multiple functions in a file and no matching function

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;
}

Upvotes: 3

Views: 654

Answers (2)

Hong Ooi
Hong Ooi

Reputation: 57686

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.

Upvotes: 4

Ralf Stubner
Ralf Stubner

Reputation: 26823

The function signatures in the definition:

arma::vec mN(double kappa, double ni, arma::vec m, arma::vec C)

does not match its usage:

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

You have to decide whether the function needs 4 or 5 arguments.

Upvotes: 3

Related Questions