2012-02-27 4 views
6

MATLAB में, मेरे पास for loop है जिसमें sparse मैट्रिक्स को भरने और भरने के लिए बहुत से इंटरैक्शन हैं। कार्यक्रम बहुत धीमा है और मैं इसे जल्द ही कुछ समय समाप्त करने के लिए अनुकूलित करना चाहता हूं। दो पंक्तियों में मैं find कमांड का उपयोग करता हूं, और MATLAB के संपादक ने मुझे चेतावनी दी है कि find के बजाय logical indexing का उपयोग प्रदर्शन में सुधार करेगा। मेरा कोड मैथवर्क न्यूडर, mathworks newsreader recommendation पर प्रस्तुत किया गया है, जहां मूल्यों का वेक्टर और उससे उत्पन्न अद्वितीय मूल्य का वेक्टर है। अद्वितीय मानों में इंडेक्स प्राप्त करने के लिए find का उपयोग करता है (मैट्रिक्स में मानों को अपडेट करने के लिए)। संक्षिप्त होने के लिए, दिए गए कोड है:अद्वितीय मूल्यों के वेक्टर मूल्य स्थिति को देखने के लिए, 'लॉजिकल इंडेक्सिंग' (MATLAB) के साथ `find` आदेशों को कैसे प्रतिस्थापित करें?

 positions = find(X0_outputs == unique_outputs(j,1)); 
% should read 
    positions = X0_outputs == unique_outputs(j,1); 

लेकिन अंतिम पंक्ति सूचकांक, लेकिन शून्य और का एक वेक्टर नहीं है। मेरे पास एक उदाहरण उदाहरण है, सूचकांक का एक सेट बनाओ; tt=round(rand(1,6)*10):

tt = 3  7  1  7  1  7 

एक अद्वितीय वेक्टर बनाएं;

ttUNI = 1  3  7 

उपयोग अद्वितीय मूल्यों के दस्तावेज़ में मूल्य की स्थिति सूचकांक प्राप्त करने के लिए लगता है; find(ttUNI(:) == tt(1))

ans = 2 

तार्किक अनुक्रमण का उपयोग कर के साथ तुलना करें; जब मैं एक मैट्रिक्स के लिए सूचकांक अद्यतन करने की आवश्यकता (ttUNI(:) == tt(1))

ans = 
0 
1 
0 

मूल्य 2 होने बहुत कि द्विआधारी वेक्टर की तुलना में अधिक उपयोगी है। मेरे मैट्रिक्स के लिए, मैं mat(find(ttUNI(:) == tt(1)), 4) कह सकता हूं और यह काम करता है। जबकि (ttUNI(:) == tt(1)) का उपयोग पोस्ट प्रोसेसिंग की आवश्यकता है।

क्या आवश्यकतानुसार कोई साफ और कुशल तरीका है? या find का उपयोग इन परिस्थितियों में अपरिहार्य है?

अद्यतन: के रूप में उपयोगकर्ता द्वारा सिफारिश की मैं यहाँ कोड में शामिल होंगे: @Jonas समस्या जो मैं कर रहा हूँ में बेहतर जानकारी देने के लिए और प्रोफाइलर उपकरण के परिणाम में से कुछ रिपोर्ट करने के लिए।

ALL_NODES = horzcat(network(:,1)',network(:,2)'); 
NUM_UNIQUE = unique(ALL_NODES);%unique and sorted  
UNIQUE_LENGTH = length(NUM_UNIQUE); 
TIME_MAX = max(network(:,3)); 
WEEK_NUM = floor((((TIME_MAX/60)/60)/24)/7);%divide seconds for minutes, for hours, for days and how many weeks 
%initialize tensor of temporal networks 
temp = length(NUM_UNIQUE); 
%making the tensor a sparse 2D tensor!!! So each week is another replica of 
%the matrix below 
Atensor = sparse(length(NUM_UNIQUE)*WEEK_NUM,length(NUM_UNIQUE)); 
WEEK_SECONDS = 60*60*24*7;%number of seconds in a week 

for ii=1:size(network,1)%go through all rows/observations 
    WEEK_NOW = floor(network(ii,3)/WEEK_SECONDS) + 1; 
    if(WEEK_NOW > WEEK_NUM) 
     disp('end of weeks') 
     break 
    end 
    data_node_i = network(ii,1); 
    Atensor_row_num = find(NUM_UNIQUE(:) == data_node_i)... 
     + (WEEK_NOW-1)*UNIQUE_LENGTH; 
    data_node_j = network(ii,2); 
    Atensor_col_num = find(NUM_UNIQUE(:) == data_node_j); 
    %Atensor is sparse 
    Atensor(Atensor_row_num,Atensor_col_num) = 1;   
end 
यहाँ UNIQUE_LENGTH = 223482 और size(network,1)=273209

। मैं कुछ मिनटों के लिए profiler tool रैंड करता हूं, जो प्रोग्राम खत्म होने के लिए पर्याप्त समय नहीं था, लेकिन एक स्थिर स्थिति तक पहुंचने के लिए जब समय का अनुपात बहुत अधिक नहीं बदलेगा। Atensor_row_num = find(NUM_UNI..45.6% और Atensor_col_num = find(NUM_UNI...43.4% है। Atensor(Atensor_row_num,Atenso... के साथ लाइन जो sparse मैट्रिक्स के मानों को आवंटित करती है, केवल 8.9% है। NUM_UNIQUE वेक्टर की लंबाई काफी बड़ी है, इसलिए find कोड का एक महत्वपूर्ण पहलू है; स्पैर मैट्रिक्स मैनिपुलेशन से भी ज्यादा महत्वपूर्ण है। यहां कोई भी सुधार महत्वपूर्ण होगा। मुझे नहीं पता कि find को बदलने के सीधा दृष्टिकोण लेने के बजाय इस एल्गोरिदम के लिए आगे बढ़ने के लिए और अधिक कुशल तार्किक प्रगति है या नहीं।

+0

मैं सिर्फ इतना है कि जोड़ने के लिए, जहाँ तक मैं बता सकता है चाहता था, कि चेतावनी संदेश खोजने के लिए प्रत्येक कॉल द्वारा कम या ज्यादा ट्रिगर किया जाता है। मैंने हाल ही में ऐसी परिस्थिति में भाग लिया जहां तार्किक रूप से अनुक्रमित संस्करण उस व्यक्ति की तुलना में काफी धीमा था जहां मैंने पाया()। यदि यह एक समय-महत्वपूर्ण स्थिति में है, तो मैं इसे दोनों तरीकों से आजमाउंगा। –

उत्तर

8

find कुछ परिस्थितियों में वास्तव में अपरिहार्य है। उदाहरण के लिए, यदि आप इंडेक्स पर लूप करना चाहते हैं, यानी।

idx = find(someCondition); 
for i = idx(:)' 
    doSomething 
end 

या आप बहु स्तरीय अनुक्रमण करना चाहते हैं

A = [1:4,NaN,6:10]; 
goodA = find(isfinite(A)); 
everyOtherGoodEntry = A(goodA(1:2:end)); 

या यदि आप पहले n अच्छे संस्कार चाहते

A = A(find(isfinite(A),n,'first'); 

आपके मामले में, आप से बचने के लिए सक्षम हो सकता है पर unique

[uniqueElements,indexIntoA,indexIntoUniqueElements] = unique(A); 
01 के अतिरिक्त आउटपुट का उपयोग करके find पर कॉल करें

इससे पहले कि आप जो सोचते हैं उसे ठीक करके अपना कोड अनुकूलित करने का प्रयास करें, मेरा सुझाव है कि आप वास्तव में समय लेने के लिए अपने कोड पर प्रोफाइलर चलाएं। और फिर आप संभवतः अपने वास्तविक पाश का कोड पोस्ट कर सकते हैं, और हम सहायता करने में सक्षम हो सकते हैं।

+0

मैंने कोड चलाने वाले प्रोफाइलर परिणाम और वास्तविक पाश कोड जोड़ा। खुश होती है। – Vass

5

आप एक तार्किक वेक्टर में सही मूल्य के सूचकांक प्राप्त करना चाहते हैं, तो आप निम्न कर सकते हैं:

>> r = rand(1,5) 
r = 
    0.5323 0.3401 0.4182 0.8411 0.2300 

>> logical_val = r < 0.5   % Check whether values are less than 0.5 
logical_val = 
    0  1  1  0  1 

>> temp = 1:size(r,2)    % Create a vector from 1 to the size of r 
temp = 
    1  2  3  4  5 

>> temp(logical_val)    % Get the indexes of the true values 
ans = 
    2  3  5 
संबंधित मुद्दे