在 C++ 函数中使用 R 函数
Using R functions within a C++ function
我正在尝试将实现黄金分割法的 R 代码转换为 C++ 代码。这是 R 代码:
goldensectionR <- function(f, dXl, dXr, dXm, dTol = 1e-9, ...) {
dFr = f(dXr, ...)
dFl = f(dXl, ...)
dFm = f(dXm, ...)
dRho = (1.0 + sqrt(5))/2.0
if (dFl > dFm | dFr > dFm) {
stop("Inital conditions are not satisfied")
}
while (abs(dXr - dXl) > dTol) {
if (dXr - dXm > dXm - dXl) {
dY = dXm + (dXr - dXm)/(1.0 + dRho)
dFy = f(dY, ...)
if (dFy >= dFm) {
dXl = dXm
dXm = dY
} else {
dXr = dY
}
} else {
dY = dXm - (dXm - dXl)/(1.0 + dRho)
dFy = f(dY, ...)
if (dFy >= dFm) {
dXr = dXm
dXm =dY
} else {
dXl = dY
}
}
dFm = f(dXm, ...)
}
return(dXm)
}
到目前为止,这是我在 C++ 中重新创建此代码的尝试:
//[[Rcpp::depends(RcppArmadillo)]]
#include <RcppArmadillo.h>
#include <Rcpp.h>
using namespace arma;
using namespace Rcpp;
// [[Rcpp::export]]
double goldensection(Function f, double dXl, double dXr, double dXm, double dTol = 1e-9) {
double dFr = f(dXr);
double dFl = f(dXl);
double dFm = f(dXm);
double dRho = (1.0 + sqrt(5))/2.0;
if (dFl > dFm || dFr > dFm) {
stop("Inital conditions are not satisfied");
}
while (fabs(dXr - dXl) > dTol) {
if (dXr - dXm > dXm - dXl) {
double dY = dXm + (dXr - dXm)/(1.0 + dRho);
double dFy = f(dY);
if (dFy >= dFm) {
dXl = dXm;
dXm = dY;
} else {
dXr = dY;
}
} else {
double dY = dXm - (dXm - dXl)/(1.0 + dRho);
double dFy = f(dY);
if (dFy >= dFm) {
dXr = dXm;
dXm =dY;
} else {
dXl = dY;
}
}
dFm = f(dXm);
}
return(dXm);
}
f off 当然是指在 R 中定义的函数。当尝试使用 sourceCpp
将此代码导入 R 时,我在函数中使用 f 的地方出现了错误消息:
cannot convert 'SEXP' {aka 'SEXPREC*'} to 'double' in initialization
所以我显然没有在 C++ 函数中正确使用 R 函数。你如何正确地做到这一点?
问题是 Rcpp 不知道该函数会 return 一个双精度数,所以它 return 而不是一个 SEXP - 它基本上是一个包装器,可以站在对于列表、数字、字符串或其他东西。如果您确定您的 SExpr 将始终为实数,您可以使用 asReal
函数将 SEXP
转换为两倍,例如
double dFy = asReal(f(dY));
我正在尝试将实现黄金分割法的 R 代码转换为 C++ 代码。这是 R 代码:
goldensectionR <- function(f, dXl, dXr, dXm, dTol = 1e-9, ...) {
dFr = f(dXr, ...)
dFl = f(dXl, ...)
dFm = f(dXm, ...)
dRho = (1.0 + sqrt(5))/2.0
if (dFl > dFm | dFr > dFm) {
stop("Inital conditions are not satisfied")
}
while (abs(dXr - dXl) > dTol) {
if (dXr - dXm > dXm - dXl) {
dY = dXm + (dXr - dXm)/(1.0 + dRho)
dFy = f(dY, ...)
if (dFy >= dFm) {
dXl = dXm
dXm = dY
} else {
dXr = dY
}
} else {
dY = dXm - (dXm - dXl)/(1.0 + dRho)
dFy = f(dY, ...)
if (dFy >= dFm) {
dXr = dXm
dXm =dY
} else {
dXl = dY
}
}
dFm = f(dXm, ...)
}
return(dXm)
}
到目前为止,这是我在 C++ 中重新创建此代码的尝试:
//[[Rcpp::depends(RcppArmadillo)]]
#include <RcppArmadillo.h>
#include <Rcpp.h>
using namespace arma;
using namespace Rcpp;
// [[Rcpp::export]]
double goldensection(Function f, double dXl, double dXr, double dXm, double dTol = 1e-9) {
double dFr = f(dXr);
double dFl = f(dXl);
double dFm = f(dXm);
double dRho = (1.0 + sqrt(5))/2.0;
if (dFl > dFm || dFr > dFm) {
stop("Inital conditions are not satisfied");
}
while (fabs(dXr - dXl) > dTol) {
if (dXr - dXm > dXm - dXl) {
double dY = dXm + (dXr - dXm)/(1.0 + dRho);
double dFy = f(dY);
if (dFy >= dFm) {
dXl = dXm;
dXm = dY;
} else {
dXr = dY;
}
} else {
double dY = dXm - (dXm - dXl)/(1.0 + dRho);
double dFy = f(dY);
if (dFy >= dFm) {
dXr = dXm;
dXm =dY;
} else {
dXl = dY;
}
}
dFm = f(dXm);
}
return(dXm);
}
f off 当然是指在 R 中定义的函数。当尝试使用 sourceCpp
将此代码导入 R 时,我在函数中使用 f 的地方出现了错误消息:
cannot convert 'SEXP' {aka 'SEXPREC*'} to 'double' in initialization
所以我显然没有在 C++ 函数中正确使用 R 函数。你如何正确地做到这一点?
问题是 Rcpp 不知道该函数会 return 一个双精度数,所以它 return 而不是一个 SEXP - 它基本上是一个包装器,可以站在对于列表、数字、字符串或其他东西。如果您确定您的 SExpr 将始终为实数,您可以使用 asReal
函数将 SEXP
转换为两倍,例如
double dFy = asReal(f(dY));