gpt4 book ai didi

c++ - Armadillo :将立方体 subview (管)转换为 vector

转载 作者:行者123 更新时间:2023-11-30 01:07:17 28 4
gpt4 key购买 nike

当我尝试从 Armadillo 立方体(使用管或切片)获取 vector/ double 时出现编译错误。如何从立方体到(行)vec?我找不到优雅的 cast/transform Armadillo 函数。

#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?
}

最佳答案

我看到了三种方法:

  1. 使用带有 as_scalar() 的循环将最终子集转换为 double
  2. 子集到立方体然后使用共享内存指针
  3. 将子集指向一个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

关于c++ - Armadillo :将立方体 subview (管)转换为 vector ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44894422/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com