将 Eigen::MatrixXd 转换为 arma::mat 并在新对象上制作副本
Converting Eigen::MatrixXd to arma::mat and make a copy on a new object
我有一个函数,我想在其中将一个 Eigen::MatrixXd
对象转换为 arma::mat
。
我知道 但我似乎无法纠正我遇到的问题。从 R 调用 matrixxd_to_armamat
不会导致任何问题,问题是当我在 C 的另一个函数中进行此转换时。这有点令人困惑,我想了解发生了什么。
#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
对象创建方面产生问题。这里的对象得到一个奇数值,表明内存映射是错误的。我对此的想法是因为它被复制到函数中而不是引用更新。原始答案显示了在允许引用和内存重用的作用域函数下的操作。
特别是来自 armadillo
docs on advanced ctors:
Create a matrix using data from writable auxiliary (external) memory, where ptr_aux_mem is a pointer to the memory. By default the matrix allocates its own memory and copies data from the auxiliary memory (for safety). However, if copy_aux_mem is set to false, the matrix will instead directly use the auxiliary memory (ie. no copying); this is faster, but can be dangerous unless you know what you are doing!
后半部分是我的重点
因此,在传递复制范例下,如果编写一个普通的转换函数,则需要完全复制对象而不是引用更新。
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
对象,那么这应该可行:
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
。
我知道 matrixxd_to_armamat
不会导致任何问题,问题是当我在 C 的另一个函数中进行此转换时。这有点令人困惑,我想了解发生了什么。
#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
对象创建方面产生问题。这里的对象得到一个奇数值,表明内存映射是错误的。我对此的想法是因为它被复制到函数中而不是引用更新。原始答案显示了在允许引用和内存重用的作用域函数下的操作。
特别是来自 armadillo
docs on advanced ctors:
Create a matrix using data from writable auxiliary (external) memory, where ptr_aux_mem is a pointer to the memory. By default the matrix allocates its own memory and copies data from the auxiliary memory (for safety). However, if copy_aux_mem is set to false, the matrix will instead directly use the auxiliary memory (ie. no copying); this is faster, but can be dangerous unless you know what you are doing!
后半部分是我的重点
因此,在传递复制范例下,如果编写一个普通的转换函数,则需要完全复制对象而不是引用更新。
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
对象,那么这应该可行:
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