仅在非零条目下评估arrayfun不同的结果

时间:2017-08-28 12:57:50

标签: matlab matrix sparse-matrix

我给了两个向量x,y,我创建了距离矩阵

B=pdist2(x,y);

现在我评估某个函数f(x),

s=5;
if s-x > 0
    y=(1-x/s)^4*(1+4*x/s)/20;
else
    y=0;
end

其中s是一些参数。通过预定义和使用

A=arrayfun(@f,B);

矩阵A根据需要是正定的。

由于矩阵是稀疏的,我只想在非零返回的值上评估f(x)。我的尝试是

B=pdist2(x,y);
B(B>s)=0;
B=B/s;
indexB=find(B);
Atmp=arrayfun(@f,B(indexB));
A(indexB)=Atmp;

但是现在A不是肯定的,并且具有比以前更少的非零条目。有人能解释我在做什么/正在做什么?

谢谢大家,我发现了错误。在B的对角线上有一些零条目,我必须单独计算。

3 个答案:

答案 0 :(得分:4)

我想知道你为什么试图索引B,然后将一些函数应用于每个单独的元素。相反,让我们矢量化你的代码

% Same setup
B = pdist2(x,y); s = 5;
B(B >= s) = 0;  B = B/s;
% Don't use arrayfun, instead use vectorised code
% The previous line already dealt with the 'else' case from f(x) 
B = ((1-B/s).^4).*(1+4*B/s)/20;

请注意,每次我们在两个非标量之间操作时,我们必须使用元素方式操作.^.*。其他的划分和乘法都有标量,但我们可以安全并养成使用它们的习惯!

B = ((1-B./s).^4).*(1+4.*B./s)./20;

关于MATLAB术语的注释:小心地说这里有一个“稀疏矩阵”,即MATLAB中的special variable type。你有一个数学上稀疏的标准矩阵!在稀疏矩阵上运算可能会略有不同。

答案 1 :(得分:2)

您应该使用与A相同的大小预先分配矩阵B,否则MATLAB不知道A的正确大小:

A=zeros(size(B));

请注意,find会返回linear indices,因此A成为向量而非矩阵。

答案 2 :(得分:2)

您可以使用spfun将函数应用于非零稀疏矩阵元素,而不是arrayfun

A = spfun(@f, B);

虽然矢量化可能更有效。

  • spfun也适用于密集矩阵和稀疏矩阵,但它的输出是一个稀疏矩阵

感谢@Wolfie提供了一些测试和澄清。