犰狳:将立方体子视图(管)转换为矢量

Posted

技术标签:

【中文标题】犰狳:将立方体子视图(管)转换为矢量【英文标题】:Armadillo: convert cube subview (tube) to vector 【发布时间】:2017-07-03 22:07:56 【问题描述】:

当我尝试从犰狳立方体(使用管或切片)获取向量/双精度时出现编译错误。如何从立方体到(行)vec?我找不到优雅的演员/变换犰狳函数。

#include <RcppArmadillo.h>
//#include <Rcpp.h>
using namespace Rcpp;

// [[Rcpp::export]]
void testarma() 
  arma::mat B;

  B << 0.555950 << 0.274690 << 0.540605 << 0.798938 << arma::endr
    << 0.108929 << 0.830123 << 0.891726 << 0.895283 << arma::endr
    << 0.948014 << 0.973234 << 0.216504 << 0.883152 << arma::endr
    << 0.023787 << 0.675382 << 0.231751 << 0.450332 << arma::endr;

  B.print("B:");

  // cubes ("3D matrices")
  arma::cube Q(B.n_rows, B.n_cols, 4);

  Q.slice(0) = B;
  Q.slice(1) = 2.0 * B;
  Q.slice(2) = 3.0 * B;
  Q.slice(3) = 4.0 * B;

  Q.print("Q:");

  Rcpp::Rcout << "Q.tube(0, 1): " << std::endl << Q.tube(0, 1) << std::endl;

  arma::rowvec whatIwant = arma::rowvec(4).fill(0.0);

  for (int i = 0; i < 4; i++) 
    // This gives an error. cannot convert 'arma::subview_col<double>' to 'double' in assignment
    //whatIwant[i] = Q.slice(i).row(0).col(1);
    Rcpp::Rcout << "At slice i=" << i << " value=" << Q.slice(i).row(0).col(1) << std::endl;
  

  // But I don't want to write for loop. I am sure there exists
  // an "armadillo" way (function) that does exactly this
  // How to convert output of tube to rowvec?

【问题讨论】:

请使示例代码可重现...... @coatless :很乐意,但它会有数百行代码。问题是如何在犰狳立方体的所有切片中获取一个 arma::rowvec 作为 i, j 元素(在我的情况下为 (0, 1))。 在这种情况下你能创建一个玩具示例吗? @coatless 我做到了。 【参考方案1】:

我认为有三种方法可以做到这一点:

    使用带有as_scalar() 的循环将最终子集转换为double。 多维数据集的子集,然后使用共享内存指针 直接子集到rowvec

最后一个选项很可能是您想要的,因为它可以内联完成。

在你的情况下,操作是:

arma::rowvec A = Q(arma::span(0), arma::span(1), arma::span::all);

这取自文档的 subcube 子集部分。


上述每个案例的实现如下所示。

#include <RcppArmadillo.h>

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

// [[Rcpp::export]]
void cube_subset_to_rowvec() 
    // Sample data
    arma::mat B;

    B << 0.555950 << 0.274690 << 0.540605 << 0.798938 << arma::endr
      << 0.108929 << 0.830123 << 0.891726 << 0.895283 << arma::endr
      << 0.948014 << 0.973234 << 0.216504 << 0.883152 << arma::endr
      << 0.023787 << 0.675382 << 0.231751 << 0.450332 << arma::endr;

    // cubes ("3D matrices")
    arma::cube Q(B.n_rows, B.n_cols, 4);

    Q.slice(0) = B;
    Q.slice(1) = 2.0 * B;
    Q.slice(2) = 3.0 * B;
    Q.slice(3) = 4.0 * B;

    // Objective
    Rcpp::Rcout << "Q.tube(0, 1): " << std::endl << Q.tube(0, 1) << std::endl;

    // Individually loading elements
    arma::rowvec individual_elements(4);
    for (int i = 0; i < 4; i++) 
        individual_elements[i] = arma::as_scalar(Q.slice(i).row(0).col(1));
        Rcpp::Rcout << "At slice i=" << i << " value=" << individual_elements[i] << std::endl;
    

    // Subset to cube then use a shared memory pointer
    arma::cube mem_ex = Q.tube(0,1);
    arma::rowvec cub_subset = arma::rowvec(mem_ex.memptr(), mem_ex.n_elem, 1, false);
    Rcpp::Rcout << cub_subset << std::endl;

    // Direct subset to a rowvec
    arma::rowvec direct_subset = Q(arma::span(0), arma::span(1), arma::span::all);
    Rcpp::Rcout << direct_subset << std::endl;


运行:

cube_subset_to_rowvec()

输出:

Q.tube(0, 1): 
[cube slice 0]
   0.2747

[cube slice 1]
   0.5494

[cube slice 2]
   0.8241

[cube slice 3]
   1.0988


At slice i=0 value=0.27469
At slice i=1 value=0.54938
At slice i=2 value=0.82407
At slice i=3 value=1.09876
   0.2747   0.5494   0.8241   1.0988

   0.2747   0.5494   0.8241   1.0988

【讨论】:

太糟糕了,我们不能为这里的三个答案投票三次:)

以上是关于犰狳:将立方体子视图(管)转换为矢量的主要内容,如果未能解决你的问题,请参考以下文章

犰狳中是不是有类似稀疏立方体的东西,或者使用稀疏矩阵作为立方体中的切片的某种方式?

在犰狳中对立方体切片进行操作

使用 RcppArmadillo 时无法加载犰狳立方体<uword>

犰狳错误的字段索引

有没有办法将犰狳矢量转换为 C++ 中的字符串?

视图相机矢量指向的世界位置