0

这里显示了我的 Rcpp 代码,我使用 sourceCpp 编译了 cpp 文件。没有报告错误,只有一些警告。当我尝试使用softImpute(m1, NULL, mr1, mr2, 0, -1)实现函数softImpute时,报告的错误是Not compatible with requested type: [type=NULL; 目标=双]

注:m1为数值矩阵,mr1mr2为两个逻辑矩阵。例如,我们可以生成 m1、mr1、mr2,如下所示:

m1 <- matrix(rnorm(30),5,6)
mr1 <- matrix(runif(30) > 0.5,5,6)
mr2 <- !mr1

你有什么想法来解决这个错误吗?先感谢您!

rcpp 代码:

#include <RcppArmadillo.h>

// [[Rcpp::depends(RcppArmadillo)]]
// [[Rcpp::export]]
Rcpp::List dcSVD(arma::mat X) {
  arma::mat u, v;
  arma::vec d;
  arma::svd(u, d, v, X, "dc");
  return Rcpp::List::create(Rcpp::Named("u") = u,
                            Rcpp::Named("d") = d,
                            Rcpp::Named("v") = v);
}

// [[Rcpp::depends(RcppArmadillo)]]
// [[Rcpp::export]] 
Rcpp::List svd_st(arma::mat X, double lambda){
  
  Rcpp::List mysvd = dcSVD(X);
  arma::mat U = mysvd["u"];
  arma::mat V = mysvd["v"];
  arma::mat VT = V.t();
  arma::vec d = mysvd["d"];
  arma::mat D = arma::diagmat(d);
  arma::uvec index_list = arma::find(d >= lambda);
  arma::vec w;
  arma::mat W;
  arma::mat L;
  if(index_list.n_elem > 1){
    w = d.elem(index_list) - lambda;
    W = arma::diagmat(w);
    arma::mat U1 = U.cols(index_list);
    arma::mat VT1 = VT.rows(index_list);
    L = U1 * W * VT1; 
  }else if(index_list.n_elem == 1){
    w = d.elem(index_list) - lambda;
    W = arma::diagmat(w);
    L = U.cols(index_list) * W * VT.rows(index_list);
  }else if(index_list.n_elem == 0){
    W = arma::zeros(1,1);
    L = arma::zeros(X.n_rows, X.n_cols);
  }
  return Rcpp::List::create(Rcpp::Named("L") = L, Rcpp::Named("W") = W); 
}

// [[Rcpp::depends(RcppArmadillo)]]
// [[Rcpp::export]]
Rcpp::List soft(arma::mat X, Rcpp::Nullable<Rcpp::NumericMatrix> Z_ = R_NilValue, Rcpp::Nullable<Rcpp::LogicalMatrix> Ome_ = R_NilValue, 
                      Rcpp::Nullable<Rcpp::LogicalMatrix> Ome1_ = R_NilValue, Rcpp::Nullable<Rcpp::LogicalMatrix> Ome2_ = R_NilValue, 
                      Rcpp::Nullable<Rcpp::NumericVector> alpha0_ = R_NilValue, Rcpp::Nullable<Rcpp::NumericVector> maxRank_ = R_NilValue){
  
  Rcpp::NumericMatrix ZH = R_NilValue;
  double alpha = 0; 
  int maxRank = -1; 
  arma::mat Z;
  if (Ome_.isNotNull() && Ome1_.isNotNull() && Ome2_.isNotNull()){
    Rcpp::LogicalMatrix Ome(Ome_);
    arma::umat Omega = Rcpp::as<arma::umat>(Ome);
    Rcpp::LogicalMatrix Ome1(Ome1_);
    arma::umat Omega1 = Rcpp::as<arma::umat>(Ome1);
    Rcpp::LogicalMatrix Ome2(Ome2_);
    arma::umat Omega2 = Rcpp::as<arma::umat>(Ome2);
    arma::mat X_0 = X % Omega;
    if (!Z_.isNotNull()){
      Rcpp::NumericMatrix ZH = Rcpp::wrap(X_0);     
    }else{  
      Rcpp::NumericMatrix ZH = Rcpp::as<Rcpp::NumericMatrix>(Z_);
    }
    if (!alpha0_.isNotNull()){
      Rcpp::List my_svd = dcSVD(X_0);
      arma::vec d = my_svd["d"];
      double alpha = arma::as_scalar(d(1));  
    }else{
      Rcpp::NumericVector aa(alpha0_);
      double alpha = arma::as_scalar(aa(0)); 
    }
    if (!maxRank_.isNotNull()){
      int maxRank = -1;  
    }else{
      Rcpp::NumericVector bb(maxRank_);
      int maxRank = arma::as_scalar(bb(0));  
    }    
    Z = Rcpp::as<arma::mat>(ZH);
  }
  return Rcpp::List::create(Rcpp::Named("Z") = Z, 
                            Rcpp::Named("alpha") = alpha, 
                            Rcpp::Named("maxRank") = maxRank);
}  
4

0 回答 0