(Rcpp)armadillos abs() 函数在 std::abs 工作时与 c++ double 一起使用时输出错误值

Posted

技术标签:

【中文标题】(Rcpp)armadillos abs() 函数在 std::abs 工作时与 c++ double 一起使用时输出错误值【英文标题】:(Rcpp)armadillos abs() function outputs false values when used with c++ double while std::abs works 【发布时间】:2021-02-23 14:40:56 【问题描述】:

考虑这个 R 函数:

r_abs <- function(x,y,z)
    2 * abs((x >= y) - z)

还有那 2 个 RcppArmadillo 等价物:

// [[Rcpp::depends(RcppArmadillo)]]
// [[Rcpp::depends(RcppProgress)]]
#include <RcppArmadillo.h>
#include <string>
#include <progress.hpp>
using namespace arma;

// [[Rcpp::export]]
double arma_abs(const double &x, const double &y, const double &z)

    return 2 * abs((x >= y) - z);


// [[Rcpp::export]]
double std_abs(const double &x, const double &y, const double &z)

    return 2 * std::abs((x >= y) - z);

现在问题来了:

sourceCpp(".test/test.cpp")

x <- 1
y <- 2
z <- 0.5

r_abs(x,y,z)
[1] 1
arma_abs(x, y, z)
[1] 0
std_abs(x, y, z)
[1] 1

为什么 arma_abs() 在这里输出 0?该问题仅出现在-1 &lt; z &lt; 1

非常感谢您提供的任何帮助。

【问题讨论】:

【参考方案1】:

这是 C 和 C++ 的一个棘手且有些乏味的问题,部分修复最近添加的更正的std::abs()

如果您使用的是 Unix 系统,请尝试 man 3 abs。您对(不合格)abs() 的使用等同于::abs(),它从stdlib.h 获得int abs(int)

转换为int 使参数 -0.5 截断为零,乘以 2 仍然为零。简而言之,arma 与此无关。 (而且犰狳一般只有向量、矩阵、立方体等类型的函数,而不是像 double 这样的原子 C/C++ 类型。

为了完整起见,我的代码版本在下面嵌入了 R 部分。我删除了未使用的引用 RcppProgress。

// [[Rcpp::depends(RcppArmadillo)]]
#include <RcppArmadillo.h>

//using namespace arma;

// [[Rcpp::export]]
double arma_abs(const double &x, const double &y, const double &z) 
  auto val = (x >= y) - z;
  Rcpp::Rcout << "val " << val << std::endl;
  Rcpp::Rcout << "int(val) " << int(val) << std::endl;
  return 2 * ::abs((x >= y) - z);


// [[Rcpp::export]]
double std_abs(const double &x, const double &y, const double &z) 
    return 2 * std::abs((x >= y) - z);


/*** R

r_abs <- function(x,y,z)
    2 * abs((x >= y) - z)


x <- 1
y <- 2
z <- 0.5

r_abs(x,y,z)           # 1
arma_abs(x, y, z)      # 0
std_abs(x, y, z)       # 1
*/

编辑:错字已更正。上面我写的是std::fabs(),我的意思是std::abs()fabs() 是我们一直必须使用的,以避免在这里看到的 int 的演员阵容问题。

【讨论】:

以上是关于(Rcpp)armadillos abs() 函数在 std::abs 工作时与 c++ double 一起使用时输出错误值的主要内容,如果未能解决你的问题,请参考以下文章

RCPP Armadillo:在函数中打印整数值

(Rcpp, armadillo) 将 arma::vec 转换为 arma::mat

Parallel 和 Rcpp Armadillo 的问题:集群工作人员之间可能存在变量损坏

Rcpp Armadillo:RStudio 说“exp”不明确

从 Rcpp Armadillo 中的 sp_mat 访问维度名称

如何通过在 Rcpp 或 Armadillo 中将矩阵乘以向量元素来复制 R 的功能?