我得到了两个稀疏矩阵 A 和 B,它们具有相同的稀疏模式(所有非零值都位于完全相同的位置):
i = randi(1000,[50,1]);
j = randi(1000,[50,1]);
a = rand(50,1);
b = rand(50,1);
A = sparse(i,j,a,1000,1000);
B = sparse(i,j,b,1000,1000);
我想仅针对非零有效计算 exp(A-B),并将其保存回 A。 我尝试使用 spfun 来完成该任务:
f = @(x,y) exp(x-y);
A = spfun(f,A,B);
但是我在 spfun 中遇到错误:“输入参数太多。” 谁能建议一种有效的计算方法? 应该计算很多次。
谢谢!
编辑:mikkola 建议
A = spfun(@f,A-B)
解决了问题,但问题仍然是如何使用无法使用相同技巧解决的两个变量的函数来实现这一点。例如:
g = @(x,y) x.*cos(y);
A = spfun(@g,A,B);
你不能使用
A = spfun(@exp, A-B);
因为对于
A
和 B
相等的条目,您将得到 0
而不是 1
。
为了解决这个问题,您可以计算非零分量处的指数向量,然后从中构建一个稀疏矩阵:
A = sparse(i,j,exp(nonzeros(A)-nonzeros(B))); %// if you have i, j stored
或
A(find(A)) = exp(nonzeros(A)-nonzeros(B));
编辑
根据文档,
spfun
只能接受两个输入:一个函数和一个稀疏矩阵。
所以你不能直接做你想做的事。最好的解决方案可能是评论中建议的,i.e.:
res = spfun(@exp, A-B);
最好的,
一个可能很好概括的解决方案(而且我发现更容易阅读)是使用二进制掩码来挑选非零元素(作为稀疏逻辑矩阵),例如
mask=(A~=0)
我已经说明了如何在这个方便的函数中使用它来完成您想要的操作。根据您的示例,您可以将其称为
A=spfun2(f,A,B);
function Y=spfun2(fun,A,B)
mask=(A~=0); % a sparse logical, so still quite efficient?
if nnz(B(mask))~=nnz(mask)
warning('Non-zeros of B are not fully aligned with non-zeros of A')
end
Y=spalloc(size(A,1),size(A,2),nnz(A));
%or simply Y=A; has the same effect of making Y the right size
Y(mask)=fun(A(mask),B(mask));
谢谢,我正在研究一个相关问题,这是我发现对其进行有用讨论的唯一地方。