Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

min and max in Rcpp programs

Tags:

r

rcpp

I was converting an R function into Rcpp function. It is all fine but I have difficulties in using the standard max and min function. The code below:

#include <math.h>
#include <RcppArmadillo.h>
#include <algorithm>
#include <iostream>

// [[Rcpp::depends(RcppArmadillo)]]

using namespace Rcpp;
using namespace arma;
using namespace std;

double f4RandomC(double x, double a, double b) {
  double out, temp;

  temp=(log( (a*(1-x)) / (a+x) )) /log(b) ;
  out= std::min(1,temp );
  return out;
}

returns me error "no matchinf function for call min(int, &double). If possible, I would lioke to use the std:: library min function

like image 387
Giorgio Spedicato Avatar asked Jan 06 '15 23:01

Giorgio Spedicato


People also ask

What is RCPP function?

Description The 'Rcpp' package provides R functions as well as C++ classes which offer a seamless integration of R and C++. Many R data types and objects can be mapped back and forth to C++ equivalents which facilitates both writing of new code as well as easier integration of third-party libraries.

Why use Rcpp?

Rcpp provides a clean, approachable API that lets you write high-performance code, insulated from R's arcane C API. Typical bottlenecks that C++ can address include: Loops that can't be easily vectorised because subsequent iterations depend on previous ones.


1 Answers

Just change std::min(1,temp) to std::min(1.0,temp):

#include <cmath>
#include <Rcpp.h>
// [[Rcpp::export]]
double f4RandomC(double x, double a, double b) {
  double out, temp;

  temp =(log( (a*(1-x)) / (a+x) )) /log(b) ;
  out = std::min(1.0,temp );
  return out;
}

I'm assuming this has to do with the template definition of std::min

template <class T> const T& min (const T& a, const T& b);

which is defined in terms of only one type (T), whereas you were passing it two data types (int and double).

Or since you are only comparing two values, you could do this a little more concisely by replacing std::min with the ternary operator (?:):

double f4RandomC(double x, double a, double b) {
  double temp;

  temp =(log( (a*(1-x)) / (a+x) )) /log(b) ;
  return temp < 1 ? temp : 1;
}

I'm guessing the type deduction is a little more flexible for operator< than std::min.

Two other options with std::min:

// [[Rcpp::export]]
double f4RandomC2(double x, double a, double b) {
  double out, temp;
  int z = 1;
  temp =(log( (a*(1-x)) / (a+x) )) /log(b) ;
  out = std::min( static_cast<double>(z),temp );
  return out;
}

// [[Rcpp::export]]
double f4RandomC3(double x, double a, double b) {
  double out, temp;
  int z = 1;
  temp =(log( (a*(1-x)) / (a+x) )) /log(b) ;
  out = std::min<double>( z,temp );
  return out;
}

Although in this case it's certainly much easier to just change 1 to 1.0 than to (unnecessarily) define int z just to cast it to a double anyways later on.

You can learn a lot by reading through function / class definitions (as with most programming languages) - cplusplus.com and cppreference.com are pretty standard sources - and it will often make compiler errors seem much less cryptic.

like image 53
nrussell Avatar answered Oct 17 '22 18:10

nrussell