这里显示了我的 Rcpp 代码,我使用 sourceCpp 编译了 cpp 文件。没有报告错误,只有一些警告。当我尝试使用softImpute(m1, NULL, mr1, mr2, 0, -1)实现函数softImpute时,报告的错误是Not compatible with requested type: [type=NULL; 目标=双]。
注:m1为数值矩阵,mr1和mr2为两个逻辑矩阵。例如,我们可以生成 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);
}