2012-07-01 12 views
7

में मैट्रिक्स के तत्वों योग करने के लिए मैट्रिक्स है A कहना A = magic(100); देता है। मैंने मैट्रिक्स A के सभी तत्वों की गणना करने के 2 तरीके देखे हैं।कुशल (सबसे तेज़) जिस तरह से matlab

sumOfA = sum(sum(A)); 

या

sumOfA = sum(A(:)); 

तेजी से उनमें से एक (या बेहतर अभ्यास) तो अन्य है? यदि ऐसा है तो यह कौन सा है? या वे दोनों समान रूप से तेज़ हैं?

+0

प्रत्येक विधि को मैट्रिक्स के प्रत्येक तत्व के माध्यम से चलना चाहिए। इसलिए जब जटिलता की बात आती है तो वे वही होते हैं। मैं आपको विभिन्न विधियों, विशाल मैट्रिक्स के साथ दो स्क्रिप्ट बनाने और उनके निष्पादन समय की गणना करने की सलाह दूंगा। यहां एक लंबा शॉट लेते हुए, मैं कहूंगा कि दूसरा बेहतर है, क्योंकि इसमें स्मृति आवंटन संचालन शामिल नहीं है, लेकिन जैसा कि मैंने कहा, यह एक लंबा शॉट है और मुझे यहां कुछ याद आ रहा है। –

+1

प्रयोग करने के लिए आप मैटलैब के 'टिक' और 'toc' फ़ंक्शंस का उपयोग कर सकते हैं। – Turix

+3

मैंने एक त्वरित परीक्षण किया और गति में कोई अंतर नहीं था। 'योग (ए (:)) 'का एक लाभ यह है कि आपको यह जानने की आवश्यकता नहीं है कि' ए' के कितने आयाम हैं; यह किसी भी प्रकार के dims के लिए काम करेगा। – tmpearce

उत्तर

15

ऐसा लगता है कि आप के बारे में है कि क्या प्रदर्शन या चल बिन्दु सटीकता ज्यादा महत्वपूर्ण है अपना मन बना नहीं कर सकते।

तो चल बिन्दु सटीकता सर्वोपरि सटीकता के थे, तो आप सकारात्मक और नकारात्मक तत्वों को अलग होता है, प्रत्येक खंड छँटाई। फिर पूर्ण मूल्य बढ़ाने के क्रम में राशि। हाँ, मुझे पता है, किसी के मुकाबले यह अधिक काम करेगा, और शायद यह समय बर्बाद हो जाएगा।

इसके बजाय, पर्याप्त परिशुद्धता का उपयोग करें जैसे कि कोई भी त्रुटियां अप्रासंगिक होंगी। परीक्षणों आदि के बारे में अच्छी संख्यात्मक प्रथाओं का प्रयोग करें, जैसे कि कोई समस्या उत्पन्न नहीं हुई है।

जहाँ तक समय चला जाता है, एक NxM सरणी के लिए,

राशि (ए (:)) एन * एम -1 अतिरिक्त आवश्यकता होगी।

राशि (राशि (ए)) (एन -1) * M + M-1 = एन * एम -1 अतिरिक्त आवश्यकता होगी।

या तो विधि कहते हैं, का एक ही नंबर की आवश्यकता है ताकि एक बड़े सरणी के लिए, भले ही दुभाषिया बहुत चालाक पहचान करने के लिए है कि वे दोनों एक ही सेशन रहे हैं, कौन परवाह करता है?

यह बस एक मुद्दा नहीं है। इस बारे में चिंता करने के लिए एक तिल पहाड़ी से पहाड़ न बनाएं।

संपादित करें: एक दूसरे के ऊपर विधि के लिए त्रुटियों के बारे में एमरो की टिप्पणी के जवाब में, वहाँ थोड़ा आप नियंत्रित कर सकते है। जोड़ों को एक अलग क्रम में किया जाएगा, लेकिन इस बारे में कोई आश्वासन नहीं है कि कौन सा अनुक्रम बेहतर होगा।

A = randn(1000); 
format long g 

दो समाधान काफी करीब हैं। वास्तव में, ईपीएस की तुलना में, अंतर मुश्किल से महत्वपूर्ण है।

sum(A(:)) 
ans = 
      945.760668102446 

sum(sum(A)) 
ans = 
      945.760668102449 

sum(sum(A)) - sum(A(:)) 
ans = 
     2.72848410531878e-12 

eps(sum(A(:))) 
ans = 
     1.13686837721616e-13 

आप अलग चुन सकते हैं और तरह चाल मैंने कहा मान लीजिए। देखें कि नकारात्मक और सकारात्मक भाग इतने बड़े होंगे कि परिशुद्धता का नुकसान होगा।

sum(sort(A(A<0),'descend')) 
ans = 
      -398276.24754782 

sum(sort(A(A<0),'descend')) + sum(sort(A(A>=0),'ascend')) 
ans = 
      945.7606681037 

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

[~,tags] = sort(abs(A(:))); 
sum(A(tags)) 
ans = 
      945.760668102446 

इन परीक्षणों में भी एक दिलचस्प समस्या उत्पन्न होती है। क्या कोई समस्या होगी क्योंकि परीक्षण यादृच्छिक (सामान्य) सरणी पर किए जाते हैं? अनिवार्य रूप से, हम राशि (ए (:)) को यादृच्छिक चलने के रूप में देख सकते हैं, एक शराबी चलना। लेकिन योग (योग) (ए) पर विचार करें)। योग (ए) (यानी, आंतरिक योग) का प्रत्येक तत्व स्वयं 1000 सामान्य विचलन का योग है। उनमें से कुछ को देखो:

sum(A) 
ans = 
    Columns 1 through 6 
     -32.6319600960983   36.8984589766173   38.2749084367497   27.3297721091922   30.5600109446534   -59.039228262402 
    Columns 7 through 12 
      3.82231962760523   4.11017616179294   -68.1497901792032   35.4196443983385   7.05786623564426   -27.1215387236418 
    Columns 13 through 18 

हम उन्हें जोड़ते हैं, वहाँ परिशुद्धता का नुकसान हो जाएगा। तो संभावित रूप से, ऑपरेशन योग के रूप में (ए (:)) थोड़ा और सटीक हो सकता है। ऐसा है क्या? अगर हम संचय के लिए उच्च परिशुद्धता का उपयोग करते हैं तो क्या होगा? तो सबसे पहले, मैं युगल का उपयोग कर कॉलम को जोड़ दूंगा, फिर दशमलव परिशुद्धता के 25 अंकों में परिवर्तित कर दूंगा, और पंक्तियों को जोड़ दूंगा। (मैं केवल 20 अंकों यहाँ प्रदर्शित किया है, 5 अंक गार्ड अंकों के रूप में छिपा हुआ हो जाता है।)

sum(hpf(sum(A))) 
ans = 
945.76066810244807408 

या, बजाय, परिशुद्धता के 25 अंक करने के लिए तुरंत कनवर्ट करते हैं, तो परिणाम संक्षेप।

sum(hpf(A(:)) 
945.76066810244749807 

तो दोहरी परिशुद्धता में दोनों रूप विपरीत दिशाओं में समान रूप से गलत थे। अंत में, यह सब मूक है, क्योंकि मैंने जो भी विकल्प दिखाए हैं, वे सरल विविधता योग (ए (:)) या योग (योग (ए)) की तुलना में कहीं अधिक समय ले रहे हैं। बस उनमें से एक उठाओ और चिंता मत करो।

+0

धन्यवाद, महान जवाब। यही कारण है कि मैंने इस सवाल से पूछा: मेरे पास कोड के 2 टुकड़े हैं जो दोनों एक ही सोचते हैं (हमेशा एक ही परिणाम उत्पन्न करते हैं)। लेकिन एक दूसरे के रूप में लंबे समय तक चलता है। उनके बीच बहुत कम मतभेद हैं और जिस तरह से वे योग मैट्रिक्स उनमें से एक थे। यह मेरा अनुमान था कि यह वह हिस्सा हो सकता है जो प्रदर्शन अंतर बनाता है। मुझे कहीं और देखना होगा। प्रदर्शन यहां इतना महत्वपूर्ण है क्योंकि यह बड़े डेटा पर अनुकूलन समस्या है ... और मैं परिणाम के लिए 1 दिन का इंतजार करना चाहता हूं, फिर 2 दिन। – drasto

+2

@drasto क्या आपने अपना कोड प्रोफाइल करने का प्रयास किया है? आप कहते हैं कि आपके पास "उनके बीच बहुत कम मतभेद हैं", यह केवल एक ही है। क्या आपने दूसरों को देखा है? मैं बहुत आश्चर्यचकित हूं, नहीं, अगर "बड़े डेटा पर अनुकूलन समस्या" में "बाधा" एक मैट्रिक्स के तत्वों का संक्षेप था। – abcd

+0

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

3

अभिनय की दृष्टि से, मैं दोनों बहुत समान हैं कहेंगे (हाल ही में एक MATLAB संस्करण कल्पना करते हुए)। यहाँ TIMEIT समारोह का उपयोग कर त्वरित परीक्षण है:

function sumTest() 
    M = randn(5000); 
    timeit(@() func1(M)) 
    timeit(@() func2(M)) 
end 
function v = func1(A) 
    v = sum(A(:)); 
end 
function v = func2(A) 
    v = sum(sum(A)); 
end 

परिणाम थे:

>> sumTest 
ans = 
    0.0020917 
ans = 
    0.0017159 

क्या मैं है फ्लोटिंग प्वाइंट मुद्दों के बारे में चिंता होगी। उदाहरण:

>> M = randn(1000); 
>> abs(sum(M(:)) - sum(sum(M))) 
ans = 
    3.9108e-11 

बड़ा मैट्रिक्स के लिए त्रुटि परिमाण बढ़ जाती है

+0

तो फ़्लोटिंग-पॉइंट मुद्दों के बारे में बात करना कौन सा तरीका बेहतर है? – drasto

+1

यह जानने का कोई तरीका नहीं है कि कौन सा बेहतर जवाब देगा। निचले क्रम बिट्स में दो परिणाम पूरी तरह से यादृच्छिक होंगे। यह सब इस बात पर निर्भर करता है कि संख्याओं को किस क्रम में जोड़ा गया है, जो ऐसा कुछ है जो न तो matlab या आप चिंता करेंगे। –

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

  • कोई संबंधित समस्या नहीं^_^