Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/66.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Rcpp犰狳中将S4对象转换为矩阵类型_R_Rcpp_Armadillo - Fatal编程技术网

Rcpp犰狳中将S4对象转换为矩阵类型

Rcpp犰狳中将S4对象转换为矩阵类型,r,rcpp,armadillo,R,Rcpp,Armadillo,在我的RcppArmadillo项目中,我有一些矩阵(例如mat A,B,C;)和一个S4对象,例如D(来自R中的外部函数)。因为我需要在这些矩阵和D之间进行一些计算,所以我想在RcppArmadillo中将“D”转换为合适的数据类型,例如arma::mat D。 可能吗?做这件事最好的方法是什么? 这是一个类似的代码: #include <RcppArmadillo.h> // [[Rcpp::depends(RcppArmadillo)]] // [[Rcpp::export]

在我的
RcppArmadillo
项目中,我有一些矩阵(例如mat A,B,C;)和一个S4对象,例如D(来自R中的外部函数)。因为我需要在这些矩阵和D之间进行一些计算,所以我想在
RcppArmadillo
中将“D”转换为合适的数据类型,例如
arma::mat D
。 可能吗?做这件事最好的方法是什么? 这是一个类似的代码:

#include <RcppArmadillo.h>
// [[Rcpp::depends(RcppArmadillo)]]

// [[Rcpp::export]]
Rcpp::List func1(arma::mat A, arma::mat B){

  // Incoming
  Rcpp::List outcome;
  arma::mat rvecs;
  arma::vec rvals;
   Rcpp::Environment Matrix("package:Matrix"); 
   Rcpp::Function nearPD = Matrix["nearPD"];

 // Computation   
 Rcpp::List PD=nearPD(B);
 Rcpp::S4 D = PD["mat"];
 eig_sym(rvals, rvecs, D);
 arma::mat RI12_hat = rvecs * arma::diagmat(1.0/sqrt(rvals)) * rvecs.t();
  arma::mat diff = A - D;

  // Release results
  outcome = Rcpp::List::create(Rcpp::Named("rvals")    = rvals, 
                               Rcpp::Named("RI12_hat") = RI12_hat, 
                               Rcpp::Named("rvecs")    = rvecs);
  return outcome;   
}
#包括
//[[Rcpp::depends(RcppArmadillo)]]
//[[Rcpp::导出]]
Rcpp::List func1(arma::mat A,arma::mat B){
//传入
Rcpp:列出结果;
arma::mat-rvecs;
arma::vec-rvals;
Rcpp::环境矩阵(“包:矩阵”);
Rcpp::函数nearPD=矩阵[“nearPD”];
//计算
Rcpp::列表PD=近PD(B);
Rcpp::s4d=PD[“mat”];
eig_sym(rvals、rvecs、D);
arma::mat RI12_hat=rvecs*arma::diagmat(1.0/sqrt(rvals))*rvecs.t();
arma::mat diff=A-D;
//发布结果
结果=Rcpp::List::create(Rcpp::Named(“rvals”)=rvals,
Rcpp::命名(“RI12_-hat”)=RI12_-hat,
Rcpp::命名(“rvecs”)=rvecs);
返回结果;
}

其中D是类
dpoMatrix
的矩阵,计算出的正定矩阵和错误消息是“
运算符不匹配”

不幸的是,对象还没有
as()
wrap()
。然而,使用
S4
类,我们可以提取出必要的组件,并使用它重用内存。首先,我们必须通过观察对象或构造示例来理解对象

考虑以下几点:

B <- matrix(1, 3,3); B[1,3] <- B[3,1] <- 0
n.B <- nearPD(B, corr=TRUE, do2eigen=FALSE)
str(n.B)
因此,我们可以使用
.slot(“此处的name_”)
成员函数从
x
插槽检索矩阵值,并从
Dim
插槽检索维度

实施 话虽如此,我们将快速实施如下:

#include <RcppArmadillo.h>
// [[Rcpp::depends(RcppArmadillo)]]

// [[Rcpp::export]]
Rcpp::List magic_func(arma::mat A, arma::mat B){

  // Incoming
  Rcpp::List outcome;
  arma::mat rvecs;
  arma::vec rvals;
  Rcpp::Environment Matrix("package:Matrix"); // Load the Matrix package in R!
  Rcpp::Function nearPD = Matrix["nearPD"];   // Extract nearPD() R function

  // Compute with R function an S4 object
  Rcpp::List PD = nearPD(B);
  Rcpp::S4 D_s4 = PD["mat"];

  // Convert the S4 object to an Armadillo matrix
  Rcpp::NumericVector temp = Rcpp::NumericVector(D_s4.slot("x"));
  Rcpp::NumericVector dims = D_s4.slot("Dim");

  // Advanced armadillo matrix ctor that reuses memory
  arma::mat D(temp.begin(), // pointer to NumericVector
              dims[0],      // Number of Rows
              dims[1],      // Number of Columns
              false,        // Avoid copying by disabling `copy_aux_mem`
              true);        // Bind memory by enabling `strict`

  // Computation
  eig_sym(rvals, rvecs, D);
  arma::mat RI12_hat = rvecs * arma::diagmat(1.0/sqrt(rvals)) * rvecs.t();
  arma::mat diff = A - D;

  // Return result
  outcome = Rcpp::List::create(Rcpp::Named("rvals")    = rvals, 
                               Rcpp::Named("RI12_hat") = RI12_hat, 
                               Rcpp::Named("rvecs")    = rvecs);
  return outcome;   
}

对请发布您目前拥有的代码。@coatless我添加了代码的一个简单部分。您需要指定S4对象是什么。。。它是来自
矩阵
包的矩阵吗?请提供
D
对象的
dput()。这里的S4对象是矩阵包中的一个矩阵。也许今天对您来说没有价值,但这可能会得到普遍解决,非常感谢您的完整答案。这是非常有用的。
#include <RcppArmadillo.h>
// [[Rcpp::depends(RcppArmadillo)]]

// [[Rcpp::export]]
Rcpp::List magic_func(arma::mat A, arma::mat B){

  // Incoming
  Rcpp::List outcome;
  arma::mat rvecs;
  arma::vec rvals;
  Rcpp::Environment Matrix("package:Matrix"); // Load the Matrix package in R!
  Rcpp::Function nearPD = Matrix["nearPD"];   // Extract nearPD() R function

  // Compute with R function an S4 object
  Rcpp::List PD = nearPD(B);
  Rcpp::S4 D_s4 = PD["mat"];

  // Convert the S4 object to an Armadillo matrix
  Rcpp::NumericVector temp = Rcpp::NumericVector(D_s4.slot("x"));
  Rcpp::NumericVector dims = D_s4.slot("Dim");

  // Advanced armadillo matrix ctor that reuses memory
  arma::mat D(temp.begin(), // pointer to NumericVector
              dims[0],      // Number of Rows
              dims[1],      // Number of Columns
              false,        // Avoid copying by disabling `copy_aux_mem`
              true);        // Bind memory by enabling `strict`

  // Computation
  eig_sym(rvals, rvecs, D);
  arma::mat RI12_hat = rvecs * arma::diagmat(1.0/sqrt(rvals)) * rvecs.t();
  arma::mat diff = A - D;

  // Return result
  outcome = Rcpp::List::create(Rcpp::Named("rvals")    = rvals, 
                               Rcpp::Named("RI12_hat") = RI12_hat, 
                               Rcpp::Named("rvecs")    = rvecs);
  return outcome;   
}
set.seed(27)
A = matrix(round(rnorm(9),2), 3, 3)
A = A + t(A)

B = matrix(1, 3, 3); B[1,3] <- B[3,1] <- 0

magic_func(A, B)
$rvals
             [,1]
[1,] 2.414214e-08
[2,] 1.000000e+00
[3,] 2.414214e+00

$RI12_hat
          [,1]      [,2]      [,3]
[1,]  1609.647 -2275.222  1608.647
[2,] -2275.222  3218.293 -2275.222
[3,]  1608.647 -2275.222  1609.647

$rvecs
           [,1]          [,2]      [,3]
[1,] -0.5000000 -7.071068e-01 0.5000000
[2,]  0.7071068 -7.077672e-16 0.7071068
[3,] -0.5000000  7.071068e-01 0.5000000