2017-08-28 85 views
2

我給定兩個向量的x,y評估arrayfun和我創建距離矩陣僅在非零項不同的結果

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是一些參數。通過預定義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中對角線上的零個條目。

+0

請將答案*寫爲答案*以便其他人可以看到此問題已解決,或將最有用的答案標記爲已接受 – Wolfie

回答

2

你應該預分配矩陣A具有相同大小B,否則MATLAB不知道A正確的大小:

A=zeros(size(B)); 

注意find回報linear indices,所以A成爲一個載體,而不是矩陣。

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。你有一個數學稀疏的標準矩陣!在稀疏矩陣上運行可能會稍有不同。

+0

謝謝您的提示。但是我必須在矩陣的每個元素上應用更多的功能。所以使用類似B =((1-B./s).^4)。*(1+4.*B./s)./20;我估計會很乏味。 – stish

+0

爲什麼比在函數f(x)中應用它更繁瑣?如果您必須應用多個功能,您可以一次全部應用它們?請舉例說明你的意思(作爲一個問題編輯,如果它很長/需要格式化) – Wolfie

2

相反的arrayfun可以使用spfun到功能應用到非零稀疏矩陣元素:

A = spfun(@f, B); 

雖然量化可能更有效。

  • spfun還與稠密矩陣和稀疏的人,但輸出的是一個稀疏矩陣

由於@Wolfie提供了一些測試,併爲他們澄清。

+1

正如我下面提到的,他們從'pdist2'獲得的輸出'B'可能不是一個MATLAB稀疏矩陣......不知道這是否會影響你的答案。 – Wolfie

+0

@Wolfie好點,然而'spfun'在Octave中使用密集矩陣和稀疏矩陣。我不知道MATLAB ... – rahnema1

+1

剛剛在MATLAB('s = [1; 2; 3 4]; spfun(@ exp,s);')中做了一個最小測試,它似乎工作得很好,輸出一個稀疏矩陣對象(即使輸入是一個稠密矩陣)。所以這應該是一個體面的解決方案,但用戶應該知道輸出變量類型 – Wolfie