犰狳的 print() 方法和 cout 从 Rcpp 调用时的顺序不一致

Posted

技术标签:

【中文标题】犰狳的 print() 方法和 cout 从 Rcpp 调用时的顺序不一致【英文标题】:Armadillo's print() method and cout are inconsistent in order when called from Rcpp 【发布时间】:2020-02-05 15:29:43 【问题描述】:

最近,我一直在使用RcppArmadillo,但我注意到某些对象的打印顺序有些不一致。特别是在使用coutprint() 时。有时会先打印print(),然后再打印cout;其他时候则相反。

我不明白为什么会这样。我想coutprint() 是异步调用的,因此顺序不同,但为什么会这样呢?以及如何预防?

示例

如果我有以下test_order.cpp 文件

#include <RcppArmadillo.h>

// [[Rcpp::depends(RcppArmadillo)]]

using namespace Rcpp;
using namespace arma;


// [[Rcpp::export]]
int test(int n)

  cout << "Print 1\n";
  arma::mat X(n, n);
  cout << "Print 2\n";
  X.print();
  cout << "Print 3\n";

  return 1;



然后像这样从 R 中调用它

library(Rcpp)

sourceCpp("test_order.cpp")

test(3)

打印时我得到不同的结果。以下是三种不同的结果:

> test(3)
  2.1220e-314            0  6.9531e-310Print 1
Print 2

  2.3044e-314  6.9275e-310  6.9532e-310
  2.1916e-314  2.1916e-314  2.2718e-314
Print 3
[1] 1
> test(3)
  Print 1
Print 2
6.9531e-310  2.3044e-314  4.9407e-324
  6.9532e-310  2.1916e-314  4.9407e-324
            0  6.9275e-310  4.9407e-324
Print 3
[1] 1

> test(3)
  6.9531e-310  2.3044e-314  4.9407e-324
  6.9532e-310  2.1916e-314  4.9407e-324
            0  6.9275e-310  4.9407e-324Print 1
Print 2

[1]Print 3
 1

【问题讨论】:

建议使用Rcout。这样做,我在 RStudio 中看不到问题,而问题甚至比您使用 cout 显示的问题还要严重。 罗兰 100% 正确。该问题在 Writing R Extensions 中进行了讨论,并且是一个与 Rcpp 正交的 R 问题:您应该仅使用 R 的输出工具你在这里观察的原因。 相关的,当然,是我们实际上将犰狳的输出重定向到 R 的事实,所以两者是同步的。实际上只有手册std::cout(或printf())不好,为此分别使用Rcpp::RcoutRprintf()。不幸的是,我们无法进一步自动化。 【参考方案1】:

基于Roland和Dirk的cmets,以及Dirk's book和this Rcpp article,解决方案是使用Rcout而不是coutprint()

根据Dirk's book:

因为 R 为我们的统计计算提供了“外壳”, 程序需要将它们的(打印的)输出与使用的 R 同步 它自己的缓冲。

此外,CRAN 维护人员标记包含 std::cout 的代码。

所以test_order.cpp 文件应该是这样的:

#include <RcppArmadillo.h>

// [[Rcpp::depends(RcppArmadillo)]]

using namespace Rcpp;
using namespace arma;


// [[Rcpp::export]]
int test(int n)
    Rcout << "Print 1\n";
    arma::mat X(n, n);
    Rcout << "Print 2\n";
    Rcout << X << "\n";
    Rcout << "Print 3\n";

    return 1;

【讨论】:

以上是关于犰狳的 print() 方法和 cout 从 Rcpp 调用时的顺序不一致的主要内容,如果未能解决你的问题,请参考以下文章

如何将犰狳库修复为 C++

犰狳初始化列表不起作用

使用犰狳做 `Q.slice(a).col(b)` 的更有效方法

交叉编译犰狳线性代数库

如何从 C++(带有犰狳)代码链接到 PETSc?

将犰狳中的矩阵从稀疏转换为密集(spmat 到 mat)