R在Rcpp中使用stats::optimize,简单的例子编译失败
R use stats::optimize in Rcpp, simple example fails to compile
我想在 Rcpp 中使用 R stats::optimize 函数,因为我找不到 Rcpp 的等效函数。下面的代码是我尝试基于优化帮助中的示例的一个简单示例,但失败了。
这是 R 函数和结果
f <- function (x) (x - .33)^2
xmin <- optimize(f, c(0, 1), tol = 0.0001)
xmin
这个returns
$minimum
[1] 0.333
$objective
[1] 0
这是获取它时失败的 Rcpp 代码。
#include <Rcpp.h>
const double tolerance = 1e-0;
// [[Rcpp::export]]
Rcpp::NumericVector f(Rcpp::NumericVector x) {
return pow(x-0.33, 2);
}
Rcpp::List fTg_opt(const double optmin, const double optmax) {
Rcpp::Environment base("package:stats");
Rcpp::Function optimize_r = base["optimize"];
Rcpp::NumericVector interval = {optmin,optmax};
return optimize_r(f, interval, tolerance);
}
Rstudio 控制台出现以下错误信息。
> Rcpp::sourceCpp("R/cpp/testopt.cpp")
In file included from testopt.cpp:1:
In file included from /Library/Frameworks/R.framework/Versions/4.1/Resources/library/Rcpp/include/Rcpp.h:27:
In file included from /Library/Frameworks/R.framework/Versions/4.1/Resources/library/Rcpp/include/RcppCommon.h:157:
In file included from /Library/Frameworks/R.framework/Versions/4.1/Resources/library/Rcpp/include/Rcpp/traits/traits.h:45:
/Library/Frameworks/R.framework/Versions/4.1/Resources/library/Rcpp/include/Rcpp/traits/is_convertible.h:35:10: error: function cannot return function type 'Rcpp::Vector<14> (Rcpp::Vector<14>)'
static T MakeT() ;
^
/Library/Frameworks/R.framework/Versions/4.1/Resources/library/Rcpp/include/Rcpp/internal/wrap.h:770:75: note: in instantiation of template class 'Rcpp::traits::is_convertible<Rcpp::Vector<14> (Rcpp::Vector<14>), SEXPREC *>' requested here
return wrap_dispatch_unknown(object, typename ::Rcpp::traits::is_convertible<T,SEXP>::type());
^
/Library/Frameworks/R.framework/Versions/4.1/Resources/library/Rcpp/include/Rcpp/internal/wrap.h:787:20: note: in instantiation of function template specialization 'Rcpp::internal::wrap_dispatch_eigen<Rcpp::Vector<14> (Rcpp::Vector<14>)>' requested here
return wrap_dispatch_eigen(object, typename traits::is_eigen_base<T>::type());
^
/Library/Frameworks/R.framework/Versions/4.1/Resources/library/Rcpp/include/Rcpp/internal/wrap.h:807:20: note: in instantiation of function template specialization 'Rcpp::internal::wrap_dispatch_unknown_importable<Rcpp::Vector<14> (Rcpp::Vector<14>)>' requested here
return wrap_dispatch_unknown_importable(object, typename ::Rcpp::traits::is_importer<T>::type());
^
/Library/Frameworks/R.framework/Versions/4.1/Resources/library/Rcpp/include/Rcpp/internal/wrap_end.h:30:25: note: in instantiation of function template specialization 'Rcpp::internal::wrap_dispatch<Rcpp::Vector<14> (Rcpp::Vector<14>)>' requested here
return internal::wrap_dispatch( object, typename ::Rcpp::traits::wrap_type_traits<T>::wrap_category() ) ;
^
/Library/Frameworks/R.framework/Versions/4.1/Resources/library/Rcpp/include/Rcpp/grow.h:44:26: note: in instantiation of function template specialization 'Rcpp::wrap<Rcpp::Vector<14> (Rcpp::Vector<14>)>' requested here
return grow( wrap(head), tail ) ;
^
/Library/Frameworks/R.framework/Versions/4.1/Resources/library/Rcpp/include/Rcpp/grow.h:65:26: note: in instantiation of function template specialization 'Rcpp::internal::grow__dispatch<Rcpp::Vector<14> (Rcpp::Vector<14>)>' requested here
return internal::grow__dispatch(typename traits::is_named<T>::type(), head, y);
^
/Library/Frameworks/R.framework/Versions/4.1/Resources/library/Rcpp/include/Rcpp/generated/grow__pairlist.h:45:9: note: in instantiation of function template specialization 'Rcpp::grow<Rcpp::Vector<14> (Rcpp::Vector<14>)>' requested here
return grow( t1, grow( t2, grow( t3, R_NilValue ) ) ) ;
^
/Library/Frameworks/R.framework/Versions/4.1/Resources/library/Rcpp/include/Rcpp/generated/Function__operator.h:45:20: note: in instantiation of function template specialization 'Rcpp::pairlist<Rcpp::Vector<14> (Rcpp::Vector<14>), Rcpp::Vector<14>, double>' requested here
return invoke(pairlist(t1, t2, t3), R_GlobalEnv);
^
testopt.cpp:13:20: note: in instantiation of function template specialization 'Rcpp::Function_Impl<PreserveStorage>::operator()<Rcpp::Vector<14> (Rcpp::Vector<14>), Rcpp::Vector<14>, double>' requested here
return optimize_r(f, interval, tolerance);
^
1 error generated.
make: *** [testopt.o] Error 1
clang++ -mmacosx-version-min=10.13 -std=gnu++14 -I"/Library/Frameworks/R.framework/Resources/include" -DNDEBUG -I"/Library/Frameworks/R.framework/Versions/4.1/Resources/library/Rcpp/include" -I"/Users/gcn/Documents/workspace/ISIMIPData/R/cpp" -I/usr/local/include -fPIC -Wall -g -O2 -c testopt.cpp -o testopt.o
Error in Rcpp::sourceCpp("R/cpp/testopt.cpp") :
Error 1 occurred building shared library.
这里的一个问题是您假设在 Rcpp::sourceCpp()
下提交给编译的函数可以在其导出名称下调用。
不是。尝试 Rcpp::sourceCpp(..., verbose=TRUE)
,即添加该参数,以查看 真正 调用的是什么。那些你可以传递的(使用 SEXP 参数和结果,但它们很笨重)。
为了证明,这是您的代码的 'working but useless' 版本。如果我们也从 R 传递 f()
,一切都是可调用的。
士气:界面仍然是 SEXP .Call("name", SEXP a, SEXP b, ...)
,即使 Rcpp 隐藏了它。没有免费的午餐 (TM)。但正如我的评论所暗示的,有一些优化包可以与 Rcpp 一起使用。
代码
#include <Rcpp.h>
// [[Rcpp::export]]
Rcpp::List fTg_opt(Rcpp::Function f, const double optmin, const double optmax) {
Rcpp::Environment base("package:stats");
Rcpp::Function optimize_r = base["optimize"];
Rcpp::NumericVector interval = {optmin,optmax};
Rcpp::List res = optimize_r(f, interval);
return res;
}
/*** R
f <- function (x) (x - .33)^2
xmin <- optimize(f, c(0, 1), tol = 0.0001)
xmin
fTg_opt(f, 0, 1)
*/
输出
> Rcpp::sourceCpp("~/git/Whosebug/68674076/question.cpp")
> f <- function (x) (x - .33)^2
> xmin <- optimize(f, c(0, 1), tol = 0.0001)
> xmin
$minimum
[1] 0.33
$objective
[1] 0
> fTg_opt(f, 0, 1)
$minimum
[1] 0.33
$objective
[1] 0
我想在 Rcpp 中使用 R stats::optimize 函数,因为我找不到 Rcpp 的等效函数。下面的代码是我尝试基于优化帮助中的示例的一个简单示例,但失败了。 这是 R 函数和结果
f <- function (x) (x - .33)^2
xmin <- optimize(f, c(0, 1), tol = 0.0001)
xmin
这个returns
$minimum
[1] 0.333
$objective
[1] 0
这是获取它时失败的 Rcpp 代码。
#include <Rcpp.h>
const double tolerance = 1e-0;
// [[Rcpp::export]]
Rcpp::NumericVector f(Rcpp::NumericVector x) {
return pow(x-0.33, 2);
}
Rcpp::List fTg_opt(const double optmin, const double optmax) {
Rcpp::Environment base("package:stats");
Rcpp::Function optimize_r = base["optimize"];
Rcpp::NumericVector interval = {optmin,optmax};
return optimize_r(f, interval, tolerance);
}
Rstudio 控制台出现以下错误信息。
> Rcpp::sourceCpp("R/cpp/testopt.cpp")
In file included from testopt.cpp:1:
In file included from /Library/Frameworks/R.framework/Versions/4.1/Resources/library/Rcpp/include/Rcpp.h:27:
In file included from /Library/Frameworks/R.framework/Versions/4.1/Resources/library/Rcpp/include/RcppCommon.h:157:
In file included from /Library/Frameworks/R.framework/Versions/4.1/Resources/library/Rcpp/include/Rcpp/traits/traits.h:45:
/Library/Frameworks/R.framework/Versions/4.1/Resources/library/Rcpp/include/Rcpp/traits/is_convertible.h:35:10: error: function cannot return function type 'Rcpp::Vector<14> (Rcpp::Vector<14>)'
static T MakeT() ;
^
/Library/Frameworks/R.framework/Versions/4.1/Resources/library/Rcpp/include/Rcpp/internal/wrap.h:770:75: note: in instantiation of template class 'Rcpp::traits::is_convertible<Rcpp::Vector<14> (Rcpp::Vector<14>), SEXPREC *>' requested here
return wrap_dispatch_unknown(object, typename ::Rcpp::traits::is_convertible<T,SEXP>::type());
^
/Library/Frameworks/R.framework/Versions/4.1/Resources/library/Rcpp/include/Rcpp/internal/wrap.h:787:20: note: in instantiation of function template specialization 'Rcpp::internal::wrap_dispatch_eigen<Rcpp::Vector<14> (Rcpp::Vector<14>)>' requested here
return wrap_dispatch_eigen(object, typename traits::is_eigen_base<T>::type());
^
/Library/Frameworks/R.framework/Versions/4.1/Resources/library/Rcpp/include/Rcpp/internal/wrap.h:807:20: note: in instantiation of function template specialization 'Rcpp::internal::wrap_dispatch_unknown_importable<Rcpp::Vector<14> (Rcpp::Vector<14>)>' requested here
return wrap_dispatch_unknown_importable(object, typename ::Rcpp::traits::is_importer<T>::type());
^
/Library/Frameworks/R.framework/Versions/4.1/Resources/library/Rcpp/include/Rcpp/internal/wrap_end.h:30:25: note: in instantiation of function template specialization 'Rcpp::internal::wrap_dispatch<Rcpp::Vector<14> (Rcpp::Vector<14>)>' requested here
return internal::wrap_dispatch( object, typename ::Rcpp::traits::wrap_type_traits<T>::wrap_category() ) ;
^
/Library/Frameworks/R.framework/Versions/4.1/Resources/library/Rcpp/include/Rcpp/grow.h:44:26: note: in instantiation of function template specialization 'Rcpp::wrap<Rcpp::Vector<14> (Rcpp::Vector<14>)>' requested here
return grow( wrap(head), tail ) ;
^
/Library/Frameworks/R.framework/Versions/4.1/Resources/library/Rcpp/include/Rcpp/grow.h:65:26: note: in instantiation of function template specialization 'Rcpp::internal::grow__dispatch<Rcpp::Vector<14> (Rcpp::Vector<14>)>' requested here
return internal::grow__dispatch(typename traits::is_named<T>::type(), head, y);
^
/Library/Frameworks/R.framework/Versions/4.1/Resources/library/Rcpp/include/Rcpp/generated/grow__pairlist.h:45:9: note: in instantiation of function template specialization 'Rcpp::grow<Rcpp::Vector<14> (Rcpp::Vector<14>)>' requested here
return grow( t1, grow( t2, grow( t3, R_NilValue ) ) ) ;
^
/Library/Frameworks/R.framework/Versions/4.1/Resources/library/Rcpp/include/Rcpp/generated/Function__operator.h:45:20: note: in instantiation of function template specialization 'Rcpp::pairlist<Rcpp::Vector<14> (Rcpp::Vector<14>), Rcpp::Vector<14>, double>' requested here
return invoke(pairlist(t1, t2, t3), R_GlobalEnv);
^
testopt.cpp:13:20: note: in instantiation of function template specialization 'Rcpp::Function_Impl<PreserveStorage>::operator()<Rcpp::Vector<14> (Rcpp::Vector<14>), Rcpp::Vector<14>, double>' requested here
return optimize_r(f, interval, tolerance);
^
1 error generated.
make: *** [testopt.o] Error 1
clang++ -mmacosx-version-min=10.13 -std=gnu++14 -I"/Library/Frameworks/R.framework/Resources/include" -DNDEBUG -I"/Library/Frameworks/R.framework/Versions/4.1/Resources/library/Rcpp/include" -I"/Users/gcn/Documents/workspace/ISIMIPData/R/cpp" -I/usr/local/include -fPIC -Wall -g -O2 -c testopt.cpp -o testopt.o
Error in Rcpp::sourceCpp("R/cpp/testopt.cpp") :
Error 1 occurred building shared library.
这里的一个问题是您假设在 Rcpp::sourceCpp()
下提交给编译的函数可以在其导出名称下调用。
不是。尝试 Rcpp::sourceCpp(..., verbose=TRUE)
,即添加该参数,以查看 真正 调用的是什么。那些你可以传递的(使用 SEXP 参数和结果,但它们很笨重)。
为了证明,这是您的代码的 'working but useless' 版本。如果我们也从 R 传递 f()
,一切都是可调用的。
士气:界面仍然是 SEXP .Call("name", SEXP a, SEXP b, ...)
,即使 Rcpp 隐藏了它。没有免费的午餐 (TM)。但正如我的评论所暗示的,有一些优化包可以与 Rcpp 一起使用。
代码
#include <Rcpp.h>
// [[Rcpp::export]]
Rcpp::List fTg_opt(Rcpp::Function f, const double optmin, const double optmax) {
Rcpp::Environment base("package:stats");
Rcpp::Function optimize_r = base["optimize"];
Rcpp::NumericVector interval = {optmin,optmax};
Rcpp::List res = optimize_r(f, interval);
return res;
}
/*** R
f <- function (x) (x - .33)^2
xmin <- optimize(f, c(0, 1), tol = 0.0001)
xmin
fTg_opt(f, 0, 1)
*/
输出
> Rcpp::sourceCpp("~/git/Whosebug/68674076/question.cpp")
> f <- function (x) (x - .33)^2
> xmin <- optimize(f, c(0, 1), tol = 0.0001)
> xmin
$minimum
[1] 0.33
$objective
[1] 0
> fTg_opt(f, 0, 1)
$minimum
[1] 0.33
$objective
[1] 0