我是 C++ 初学者,希望能在这里找到一些帮助。
为了激发我的问题,我希望编写一个函数,通过无限精度或有理算术在 C++ 中执行卷积。由于我希望从 R 调用此函数(通过Rcpp),因此我从以下方法开始(基于Dirk 的示例)。
#include <Rcpp.h>
// [[Rcpp::export]]
Rcpp::NumericVector convolve5cpp(Rcpp::NumericVector & xa,
Rcpp::NumericVector & xb) {
int n_xa = xa.size();
int n_xb = xb.size();
Rcpp::NumericVector xab(n_xa + n_xb - 1);
Rcpp::Range r(0, n_xb-1);
for (int i=0; i<n_xa; i++, r++) {
xab[r] += xa[i] * xb;
}
return xab;
}
意识到我必须为我的 C++ 变量转换一个无限精度的有理类型,接下来我尝试执行类型重新转换,依赖于boost库。从一个涉及标量的简单示例开始(如下所示)...
// [[Rcpp::depends(BH)]]
namespace mp = boost::multiprecision;
mp::mpq_rational divideQ(int a, int b) {
mp::mpq_rational c = a / b;
return c;
}
我遇到了一个错误"cannot convert type to SEXP"
。
我在这一点上迷路了。我知道在 R 中提供类对象的gmp R 包bigq
,但不知道是否可以利用它来将mpq_rational
s 转换为 SEXP。
我的问题是:
- 如何将 boost 库有理类型转换为有效的 R 对象?(最好是
bigq
上课) - 我的推理是否有意义,或者有其他方法吗?(例如,对于
convolve5cpp
执行无限精度内部操作的向量,是否已经存在上述实现?)
非常感谢!
(2021 年 12 月 30 日更新)
感谢所有在下面留下有用评论的人。经过反复试验,我继续尝试在本地编辑gmp库中的一些源文件(可在此处获得)。
我编写了以下函数,它紧跟上面 Dirk 的示例。我镜像了 的结构operator+
,另一个定义为添加两个bigrational
s 的函数。
/**
* \brief Return conv( a, b )
*/
bigrational operatorCONV(const bigrational& lhs, const bigrational& rhs)
{
/* get sizes of each vector */
int n_xa = lhs.size();
int n_xb = rhs.size();
/* initialize big rational of size */
bigrational xab(n_xa + n_xb - 1);
/* fill in the entries */
Rcpp::Range r(0, n_xb-1);
for (int i=0; i<n_xa; i++, r++) {
xab[r] = bigrationalR::create_bigrational(xab[r], bigrationalR::create_bigrational(lhs[i], rhs, mpq_mul), mpq_add);
}
/* return */
return xab;
}
这没有用。在构建包时,我遇到了以下错误,看起来它们属于两大类。
- 'bigrational' 中没有名为 'size' 的成员:
int n_xa = lhs.size()
。 - 类型 'const bigrational' 不提供下标运算符:
bigrationalR::create_bigrational(lhs[i], rhs, mpq_mul)
- 使用未声明的标识符“Rcpp”:
Rcpp::Range r(0, n_xb-1)
- 使用未声明的标识符“r”:
bigrationalR::create_bigrational(xab[r],...
即,1 和 2 出现是因为我将lhs
和rhs
视为 s 的向量bigrational
;出现 3 和 4 是因为我使用了一个仅由Rcpp识别但未包含在文件中的对象。
如何解决这两个广泛的问题?对于 1 和 2,我不明白add.bigq
(它调用bigrational_add
,一个接受两个bigrational
s 的函数)如何接受两个向量,但不知何故,像上面这样的卷积函数不像那样“灵活”。对于 3 和 4,有没有可以相对简单地调用的stdlib
替代方法Rcpp::Range
,还是我必须创建自己的对象类型?
再次感谢!