将Eigen :: MatrixXd转换为arma :: mat并在新对象上进行复制 [英] Converting Eigen::MatrixXd to arma::mat and make a copy on a new object

查看:231
本文介绍了将Eigen :: MatrixXd转换为arma :: mat并在新对象上进行复制的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个函数想要将Eigen::MatrixXd对象转换为arma::mat.

I have a function within which I want to convert an Eigen::MatrixXd object to arma::mat.

我知道这问题,但我似乎无法纠正我得到的行为.从R调用matrixxd_to_armamat不会造成任何问题,问题是当我在C中的另一个函数中进行此转换时.这有点令人困惑,我想了解发生了什么.

I am aware of this question but I can't seem to be able to correct the behavior that I'm getting. Calling matrixxd_to_armamat from R would cause no issues, the problem is when I have this conversion in another function in C. This is a little confusing and I would like to understand what's going on.

#include <RcppArmadillo.h>
#include <RcppEigen.h>

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

using namespace std;

arma::mat matrixxd_to_armamat(Eigen::MatrixXd eigen_A) {
  arma::mat arma_B = arma::mat(eigen_A.data(), eigen_A.rows(), eigen_A.cols(),
                               false, false);
  return arma_B;
}

arma::mat matrixxd_to_armamat2(Eigen::MatrixXd& eigen_A) {
  arma::mat arma_B = arma::mat(eigen_A.data(), eigen_A.rows(), eigen_A.cols(),
                               false, false);
  return arma_B;
}



//[[Rcpp::export]]
arma::mat tester(){
  Eigen::MatrixXd A_eigen(2,2);
  A_eigen(0,0) = 1.0;
  A_eigen(1,0) = 2.0;
  A_eigen(0,1) = -1.0;
  A_eigen(1,1) = -2.0;

  Rcpp::Rcout << A_eigen << endl;

  arma::mat A_arma  = matrixxd_to_armamat(A_eigen);
  arma::mat A_arma2 = matrixxd_to_armamat2(A_eigen);

  Rcpp::Rcout << A_arma << endl;
  Rcpp::Rcout << A_arma2 << endl;

  return A_arma2;
}
/* In R
> tester()
 1 -1
 2 -2
  4.6503e-310  -1.0000e+00
  4.9407e-324   7.2661e-43

   1.0000  -1.0000
   2.0000  -2.0000

              [,1] [,2]
[1,] 4.650273e-310   -1
[2,]  2.000000e+00   -2
*/

推荐答案

因此,运行此命令后,我只能在创建A_arma对象时出现问题.此处的对象获得一个奇数值,表明内存映射错误.我对此的想法是因为将其复制到函数中而不是引用更新中.原始答案显示了在有范围的功能下的操作,该功能允许引用和内存的重用.

So, after running this, I can only produce a problem with A_arma object creation. The object here is getting an odd value indicating that the memory mapping was bad. My thought on this is because it is being copied into the function instead of a reference update. The original answer showed the manipulation under a scoped function that allowed the reference and memory re-use.

尤其是,来自 armadillo有关高级ctor的文档:

In particular, from the armadillo docs on advanced ctors:

使用可写辅助(外部)存储器中的数据创建矩阵,其中ptr_aux_mem是指向该存储器的指针.默认情况下,矩阵会分配自己的内存,并从辅助内存中复制数据(出于安全考虑). 但是,如果将copy_aux_mem设置为false,则矩阵将直接使用辅助存储器(即,不进行复制);这会更快,但除非您知道自己在做什么,否则可能很危险!

后一部分是我的重点.

因此,在这种情况下,如果采用通用的复制功能,则在传递复制范式下,需要完全复制对象,而不是参考更新.

So, here under a pass-by-copy paradigm, the object needs to be fully copied vs. a reference update if writing a common cast function.

arma::mat matrixxd_to_armamat(Eigen::MatrixXd eigen_A) {
    arma::mat arma_B = arma::mat(eigen_A.data(), eigen_A.rows(), eigen_A.cols(),
                                 true,   // changed from false to true.
                                 false); 
    return arma_B;
}

现在,如果您可以通过引用链接回原始的Eigen对象,那么这应该可行:

Now, if you are okay with linking back to the original Eigen object through a reference, then this should work:

arma::mat matrixxd_to_armamat2(Eigen::MatrixXd& eigen_A) {
    arma::mat arma_B = arma::mat(eigen_A.data(), eigen_A.rows(), eigen_A.cols(),
                                 false, false);
    return arma_B;
}

同时运行两个结果:

tester()
# 1 -1
# 2 -2
#   1.0000  -1.0000
#   2.0000  -2.0000
#
#   1.0000  -1.0000
#   2.0000  -2.0000
#
#     [,1] [,2]
#[1,]    1   -1
#[2,]    2   -2

这篇关于将Eigen :: MatrixXd转换为arma :: mat并在新对象上进行复制的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆