2013-12-10 6 views
5

से मिलता है क्या bsxfun जैसे तत्व-वार ऑपरेशंस करने का कोई तरीका है, लेकिन केवल स्पैर मैट्रिक्स के गैर-शून्य तत्वों पर काम करता है?जहां spfun bsxfun

विशेष रूप से, स्थिति (i,j) पर मैट्रिक्स A में प्रत्येक गैर शून्य तत्व के लिए मैं, i वें पंक्ति में गैर शून्य के सभी तत्वों के उत्पाद को खोजने की तत्व (i,j) के अलावा चाहते हैं।

उदाहरण के लिए i-th पंक्ति इस तरह दिखता है:

0 5 3 0 0 4 0 0 

परिणाम इस तरह दिखना चाहिए:

0 12 20 0 0 15 0 0 

सबसे स्पष्ट समाधान गैर का उत्पाद लेने के लिए होने लगते हैं प्रत्येक पंक्ति के साथ शून्य तत्व, और फिर प्रत्येक तत्व को पंक्ति उत्पाद से बाहर विभाजित करें। इसलिए, उपर्युक्त उदाहरण में, पंक्ति उत्पाद 5 x 3 x 4 = 60 है, और फिर मैं अपने संबंधित स्थानों पर 53 और 4 को विभाजित करता हूं।

एक विरल मैट्रिक्स A को देखते हुए, यह मेरा सबसे अच्छा समाधान अब तक है:

[M N] = size(A); 
[row col vals] = find(A); 
row_prod = accumarray(row,vals,[],@prod); 
B = bsxfun(@ldivide, A, row_prod); 
B = sparse(row,col,B(sub2ind([M N],row,col)),M,N); 

पहली तीन पंक्तियों को प्राप्त जो मैं चाहता: एक स्तंभ वेक्टर प्रत्येक पंक्ति के गैर शून्य तत्वों के उत्पाद का प्रतिनिधित्व। हालांकि, पिछले दो लाइनों के साथ कुछ समस्याएं हैं।

  • bsxfun एक गैर विरल मैट्रिक्स के A
  • यह शून्य अनावश्यक रूप से विभाजित चक्र का एक बहुत बर्बाद करने के लिए जा रहा है आकार वापस जाने के लिए जा रहा है।
  • परिणाम एक मैट्रिक्स है जिसमें ज्यादातर Inf या -Inf शामिल हैं जहां मैं वास्तव में शून्य चाहता हूं।
  • मैं Inf एस को मास्क नहीं कर सकता क्योंकि मैटलैब शून्य समय अनंतता को NaN होने के लिए परिभाषित करता है।
  • क्या मुझे सिर्फ बुलेट काटने और इसके लिए एक लूप लिखने की आवश्यकता है? या यह दृष्टिकोण करने का एक और तरीका है?

    उत्तर

    3

    मुझे लगता है कि मुझे एक समाधान मिला है जो ऊपर मेरी अधिकांश चिंताओं को हल करता है। कभी-कभी जब मेरे हाथ में bsxfun हथौड़ा है, तो पूरी दुनिया एक नाखून की तरह दिखने लगती है। मैं भूल जाता हूं कि bsxfun के साथ मैं जो कुछ सरल गुणा करता हूं, मैट्रिक्स गुणा का उपयोग करके हल किया जा सकता है (और तर्कसंगत रूप से अधिक पठनीय)। जबकि मुझे नहीं लगता कि इस समस्या का मेरा समाधान अब और अधिक पठनीय है, यह मेरे अंतिम समाधान की तुलना में परिमाण के आदेश अधिक कुशल है।

    % 'This happens once, outside the loop, since the size' 
    % 'and sparsity structure of A dont change in the loop' 
    [M N] = size(A); 
    [row col] = find(A); 
    
    %% 'Inside iterative loop' 
    
        % 'Get the product of non-zero row elements' 
        row_prod = accumarray(row,nonzeros(A),[],@prod); 
    
        % 'Use row products to compute 'leave-one-out' row products' 
        B = spdiags(row_prod,0,M,M)*spfun(@(x) 1./x, A); 
    

    यदि यह सुधार किया जा सकता है तो भी मुझे अन्य सुझाव सुनने में रुचि होगी।

    संबंधित मुद्दे