2012-06-02 5 views
5

मेरे पास 3 डिमेंशन वाई (i, j, w) के साथ एक मैट्रिक्स है। मैं एक निर्धारक वेक्टर डी (डब्ल्यू) प्राप्त करना चाहता हूं, जिसमें प्रत्येक नंबर मैट्रिक्स वाई (:,:, डब्ल्यू) का निर्धारक होगा।रिटर्निंग निर्धारक वेक्टर - मैटलैब

क्या इसके लिए एक सुरुचिपूर्ण वाक्यविन्यास है, या मुझे बस एक लूप का उपयोग करना है?

धन्यवाद

उत्तर

7

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

सामान्य रूप में निर्धारकों के खिलाफ मेरी मिनी शेख़ी कहा करने के बाद ...

विकल्प 1:

एक के रूप में सरणी के प्रत्येक विमान के साथ, वर्ग मैट्रिक्स की एक सेल सरणी में अपने 3-डी सरणी में कनवर्ट करें सेल। mat2cell आसानी से और कुशलता से चाल करेगा।

अगला, सेल सरणी पर सेलफन का उपयोग करें। सेलफन प्रत्येक सेल में एक फ़ंक्शन (@डेट) लागू कर सकता है, और फिर निर्धारक के वेक्टर को वापस कर देगा। क्या यह अविश्वसनीय रूप से कुशल है? जब तक आप एक लूप लिखते हैं, तब तक जब तक आप वेक्टर को पहले से आवंटित नहीं करते हैं, तब तक यह संभवतः एक लूप में det लागू करने पर एक बड़ा लाभ नहीं है।

विकल्प 2:

मैट्रिक्स छोटे हैं, इस प्रकार कहते हैं कि 2x2 या 3x3 मैट्रिक्स, तो निर्धारक के रूप में स्पष्ट वेक्टर पलता के लिए गुणा बाहर का विस्तार करें। मुझे लगता है कि यह स्पष्ट नहीं है के रूप में मैं यह लिख रहा हूँ एक 2x2 मामले में, जहां वाई 2x2xn है के लिए हां, तो:

d = Y(1,1,:).*Y(2,2,:) - Y(1,2,:).*Y(2,1,:); 

निश्चित रूप से आप देखते हैं कि इस मैट्रिक्स वाई के हर विमान के लिए 2x2 निर्धारकों का एक वेक्टर रूपों 3x3 केस शब्दों के छः 3-तरफा उत्पादों के रूप में भी लिखने के लिए काफी आसान है। मैंने नीचे 3x3 मामले की सावधानी से जांच नहीं की है, लेकिन यह करीब होना चाहिए।

d = Y(1,1,:).*Y(2,2,:).*Y(3,3,:) + ... 
    Y(2,1,:).*Y(3,2,:).*Y(1,3,:) + ... 
    Y(3,1,:).*Y(1,2,:).*Y(2,3,:) - ... 
    Y(3,1,:).*Y(2,2,:).*Y(1,3,:) - ... 
    Y(2,1,:).*Y(1,2,:).*Y(3,3,:) - ... 
    Y(1,1,:).*Y(3,2,:).*Y(2,3,:); 

जैसा कि आप देख सकते हैं, विकल्प 2 बहुत तेज़ होगा, और यह सदिश हो गया है।

संपादित करें: क्रिस के जवाब के रूप में, आवश्यक समय में एक महत्वपूर्ण अंतर है। 1e5 matrices के सेट के लिए आवश्यक समय पर विचार करें।

p = 2; 
n = 1e5; 
Y = rand(p,p,n); 

tic, 
d0 = squeeze(Y(1,1,:).*Y(2,2,:) - Y(2,1,:).*Y(1,2,:)); 
toc 

Elapsed time is 0.002141 seconds. 

tic, 
X = squeeze(mat2cell(Y,p,p,ones(1,n))); 
d1= cellfun(@det,X); 
toc 

Elapsed time is 12.041883 seconds. 

दो कॉल फ़्लोटिंग पॉइंट ट्रैश के भीतर समान मान लौटाते हैं।

std(d0-d1) 
ans = 
    3.8312e-17 

वास्तव में निश्चित रूप से एक लूप बेहतर नहीं होगा। तो क्या मैं कोड का एक टुकड़ा लिखना चाहता था जिसे किसी सरणी में कई ऐसे मैट्रिक्स के लिए निर्धारकों को उत्पन्न करने के कार्य का सामना करना पड़ेगा, मैं विशेष रूप से 2x2 और 3x3 matrices के लिए कोड का मामला होगा। मैं इसे 4x4 मैट्रिक्स के लिए भी लिख सकता हूं। हां, यह लिखने के लिए एक गड़बड़ है, लेकिन आवश्यक समय में एक बड़ा अंतर है।

एक कारण यह है कि MATLAB की दूरी मैट्रिक्स को कारक बनाने के लिए LU को कॉल का उपयोग करती है। यह माध्यमिक बड़े matrices के लिए गुणा से सिद्धांत में बेहतर है, लेकिन 2x2 या एक 3x3 के लिए, अतिरिक्त ओवरहेड एक हत्यारा है। (मुझे लगता है कि ब्रेक भी बिंदु गिरता है, लेकिन कोई आसानी से पर्याप्त परीक्षण कर सकता है।)

+0

मैं विकल्प 1 या यहां तक ​​कि विकल्प 2 पर लूप पसंद करता हूं। अगर मुझे लूप पर दुभाषिया से गति हानि संकेतक है तो मुझे आश्चर्य होगा और मैं अधिक लचीला कोड पसंद करूंगा। कल्पना करें कि 5x5 निर्धारक इस तरह से –

+2

@ChrisA - 12.041883/0.002141 = 5624.4 एक चौंकाने वाला अंतर है? –

+0

+1 हां! अच्छी प्रतिक्रिया। शायद ऐसा करने के लिए एक और अधिक लचीला तरीका है ... क्योंकि यह वास्तव में बुरा हो जाता है क्योंकि शब्दों की संख्या 'पी!' –

3

मैं arrayfun का प्रयोग करेंगे:

d = arrayfun(@(w) det(Y(:, :, w)), 1 : size(Y, 3)); 

संपादित करें: गति परीक्षण:

p = 10; 
n = 1e4; 
Y = rand(p,p,n); 

टेस्ट 1:

>> tic, d1 = arrayfun(@(w) det(Y(:, :, w)), 1 : size(Y, 3)); toc 
Elapsed time is 0.139030 seconds. 

टेस्ट 2 (woodchips से):

>> tic, X = squeeze(mat2cell(Y,p,p,ones(1,n))); d2= cellfun(@det,X); toc 
Elapsed time is 1.318396 seconds. 

टेस्ट 3 (अनुभवहीन दृष्टिकोण):

>> p = 10; 
>> n = 1e4; 
>> Y = rand(p,p,n); 
>> tic; d = nan(n, 1); for w = 1 : length(d), d(w) = det(Y(:, :, w)); end; toc 
Elapsed time is 0.069279 seconds. 

निष्कर्ष: अनुभवहीन दृष्टिकोण सबसे तेज है।

+0

क्या आप इस वाक्यविन्यास और सेलफन और विशेष-केस विकल्पों के बीच गति तुलना करने के लिए @woodchips उत्तर में परीक्षण-केस का उपयोग कर सकते हैं? – tmpearce

+0

@tmpearce, कोई समस्या नहीं, मैंने परीक्षा परिणाम – Serg

+0

जोड़ा परिणाम परिणाम 'पी' के आकार पर निर्भर करेगा: पी = 2 के साथ, @woodchips रास्ता शायद बहुत तेज़ है। यह दिलचस्प है कि पी = 10 के साथ, लूप सरणी से तेज है। – tmpearce