如何在犰狳中按元素划分2个稀疏矩阵?

Posted

技术标签:

【中文标题】如何在犰狳中按元素划分2个稀疏矩阵?【英文标题】:How to element-wise divide 2 sparse matrices in Armadillo? 【发布时间】:2021-02-05 14:50:55 【问题描述】:

我是 C++ 新手,但我正在使用 R 和 RcppArmadillo,我的目标是按元素划分 2 个稀疏矩阵。我在犰狳的文档中读到操作员是/,但是当我使用sourceCpp 获取我的代码时,我收到了这个错误:

'operator/' 不匹配(操作数类型为 'arma::sp_mat' aka 'arma::SpMat' 和 'arma::sp_mat' aka 'arma::SpMat')

我写了一个小例子的代码。请注意,当我从脚本中删除除法函数时,乘法函数工作正常。

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

using namespace Rcpp;

//' Sparse Matrix element-wise multiplication
//'
//' @param X sp_mat 
// [[Rcpp::export]]
arma::sp_mat sp_mat_mul(arma::sp_mat X)
  
  arma::sp_mat Y = X % X;
  return Y;
  



//' Sparse Matrix element-wise division
//'
//' @param X sp_mat 
// [[Rcpp::export]]
arma::sp_mat sp_mat_div(arma::sp_mat X)
  
  arma::sp_mat Y = X / X;
  return Y;
  

感谢您的宝贵时间,我真的很感激!

【问题讨论】:

“以下操作和函数的子集可用于稀疏矩阵”段落下的Armadillo documentation 并不建议我实现了该运算符。因此,您可能会遇到错误? 第一点“基本算术运算(如加法和乘法)”它为您带来“运算符”,其中包括/ 这可能会产生误导。该“操作”部分是密集矩阵的 AFAICT,该部分中的所有示例也是如此。请注意您所指的关于稀疏矩阵的句子如何限定为“例如加法和乘法”,以及下面几行的示例稀疏矩阵如何仅显示乘法。使用这四个示例行进行编译。但是,一旦您将* 替换为/,它就会失败。因为,正如我所建议的,运算符根本没有实现用于稀疏矩阵。 FWIW 它与+ 一起工作,所以我认为文档很好(模可能是链接)。 明白,谢谢! 不建议按元素划分两个稀疏矩阵。稀疏矩阵中的大多数元素都为零,因此所有元素的元素除法将导致由于被零除而以 NaN 为主的矩阵。生成的矩阵不是稀疏的,这是不可取的。 【参考方案1】:

使用 transform/foreach 计算逆然后相乘。

//' Sparse Matrix element-wise division
//'
//' @param X sp_mat 
// [[Rcpp::export]]
arma::sp_mat sp_mat_div(arma::sp_mat X)
  arma::sp_mat x_inverse(X);
  x_inverse.transform([](double val) return (1.0/val););
  arma::sp_mat Y = X % x_inverse;
  return Y;

R:

i <- c(1,3:8)
j <- c(2,9,6:10)
x <- 7 * (1:7)
A <- sparseMatrix(i, j, x = x)

sp_mat_div(A)
[1,] . 1 . . . . . . . .
[2,] . . . . . . . . . .
[3,] . . . . . . . . 1 .
[4,] . . . . . 1 . . . .
[5,] . . . . . . 1 . . .
[6,] . . . . . . . 1 . .
[7,] . . . . . . . . 1 .
[8,] . . . . . . . . . 1

顺便说一句,你确定这个操作有意义吗?

你忽略了矩阵中的所有零(因为它是稀疏的),如果这是一个非稀疏矩阵,你会被零除很多。

【讨论】:

这正是我想要的,忽略所有的零。感谢您的回答,这是一个很酷的主意!

以上是关于如何在犰狳中按元素划分2个稀疏矩阵?的主要内容,如果未能解决你的问题,请参考以下文章

C++犰狳稀疏矩阵类型转换

犰狳中是不是有类似稀疏立方体的东西,或者使用稀疏矩阵作为立方体中的切片的某种方式?

将犰狳中的矩阵从稀疏转换为密集(spmat 到 mat)

使用 Rcpp 通过引用传递犰狳稀疏矩阵

使用 Rcpp 代码访问和修改 arma::sp_mat 类稀疏矩阵的非零元素

稀疏矩阵定义以及存储格式(COO,CSR,CSC)