0

我是 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_rationals 转换为 SEXP。

我的问题是:

  • 如何将 boost 库有理类型转换为有效的 R 对象?(最好是bigq上课)
  • 我的推理是否有意义,或者有其他方法吗?(例如,对于convolve5cpp执行无限精度内部操作的向量,是否已经存在上述实现?)

非常感谢!


(2021 年 12 月 30 日更新)

感谢所有在下面留下有用评论的人。经过反复试验,我继续尝试在本地编辑gmp库中的一些源文件(可在此处获得)。

我编写了以下函数,它紧跟上面 Dirk 的示例。我镜像了 的结构operator+,另一个定义为添加两个bigrationals 的函数。

/**
 * \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;
}

这没有用。在构建包时,我遇到了以下错误,看起来它们属于两大类。

  1. 'bigrational' 中没有名为 'size' 的成员:int n_xa = lhs.size()
  2. 类型 'const bigrational' 不提供下标运算符:bigrationalR::create_bigrational(lhs[i], rhs, mpq_mul)
  3. 使用未声明的标识符“Rcpp”:Rcpp::Range r(0, n_xb-1)
  4. 使用未声明的标识符“r”:bigrationalR::create_bigrational(xab[r],...

即,1 和 2 出现是因为我将lhsrhs视为 s 的向量bigrational;出现 3 和 4 是因为我使用了一个仅由Rcpp识别但未包含在文件中的对象。

如何解决这两个广泛的问题?对于 1 和 2,我不明白add.bigq(它调用bigrational_add,一个接受两个bigrationals 的函数)如何接受两个向量,但不知何故,像上面这样的卷积函数不像那样“灵活”。对于 3 和 4,有没有可以相对简单地调用的stdlib替代方法Rcpp::Range,还是我必须创建自己的对象类型?

再次感谢!

4

0 回答 0