MATLAB में एक n- आयामी मैट्रिक्स में प्रत्येक तत्व के माध्यम से कैसे पुनरावृति करता हूं?


87

मुझे एक समस्या है। मुझे MATLAB में एक n- आयामी मैट्रिक्स में हर तत्व के माध्यम से पुनरावृति करने की आवश्यकता है। समस्या यह है, मुझे नहीं पता कि यह कैसे करना है एक मनमाना संख्या में आयामों के लिए। मुझे पता है मैं कह सकता हूं

for i = 1:size(m,1)
    for j = 1:size(m,2)
        for k = 1:size(m,3)

और इसी तरह, लेकिन क्या यह एक मनमाना संख्या के आयामों के लिए करने का एक तरीका है?


13
मतलाब शब्दावली नोट: मतलाब में कोर डेटा प्रकार की एक छोटी संख्या है। सबसे महत्वपूर्ण हैं: संरचना, मैट्रिक्स और सेल सरणी। मैट्रिक्स के कुछ हिस्सों का उल्लेख करते समय, "तत्व" शब्द का उपयोग करना आम है, और सेल सरणी के कुछ हिस्सों को संदर्भित करने के लिए "सेल" शब्द को आरक्षित करना है। सेल सरणियों और मैट्रिसेस में कई सिंटैक्टिक और सिमेंटिक अंतर होते हैं, भले ही दोनों एन-डायमेंशनल डेटा स्ट्रक्चर हों।
19

3
क्या मुझे पूछना चाहिए कि आपको इसके लिए क्या चाहिए? हो सकता है कि इसके बजाय ऐसा करने का एक "सदिश" तरीका हो ...
होसम ऐली

जवाबों:


92

आप प्रत्येक तत्व तक पहुंचने के लिए रैखिक अनुक्रमण का उपयोग कर सकते हैं।

for idx = 1:numel(array)
    element = array(idx)
    ....
end

यह उपयोगी है यदि आपको यह जानने की आवश्यकता नहीं है कि मैं, j, k, आप क्या हैं। हालाँकि, अगर आपको यह जानने की ज़रूरत नहीं है कि आप किस सूचकांक में हैं, तो आप शायद अरफुन () का उपयोग करके बेहतर हैं


1
इसके अलावा, यदि आप किसी कारण से सूचकांकों को पुनर्प्राप्त करना चाहते हैं, तो आप अभी भी इन दो सरल आदेशों का उपयोग कर सकते हैं I = cell(1, ndims(array)); [I{:}] = ind2sub(size(array),idx);:।
knedlsepp

34

मतलाब में सरणियों के लिए एक रैखिक सूचकांक का विचार एक महत्वपूर्ण है। MATLAB में एक सरणी वास्तव में तत्वों का एक सदिश है, जो स्मृति में फैला है। MATLAB आपको एक पंक्ति और कॉलम इंडेक्स, या एक एकल रैखिक सूचकांक का उपयोग करने की अनुमति देता है। उदाहरण के लिए,

A = magic(3)
A =
     8     1     6
     3     5     7
     4     9     2

A(2,3)
ans =
     7

A(8)
ans =
     7

हम उस क्रम को देख सकते हैं जिसमें तत्वों को वेक्टर में सरणी को अनियंत्रित करके मेमोरी में संग्रहीत किया जाता है।

A(:)
ans =
     8
     3
     4
     1
     5
     9
     6
     7
     2

जैसा कि आप देख सकते हैं, 8 वां तत्व नंबर 7 है। वास्तव में, फ़ंक्शन एक रैखिक सूचकांक के रूप में अपने परिणाम देता है।

find(A>6)
ans =
     1
     6
     8

इसका परिणाम यह है, हम प्रत्येक तत्व को एक लूप का उपयोग करके सामान्य एनडी सरणी के बदले में एक्सेस कर सकते हैं। उदाहरण के लिए, यदि हम ए के तत्वों को वर्ग करना चाहते थे (हाँ, मुझे पता है कि ऐसा करने के बेहतर तरीके हैं), कोई भी ऐसा कर सकता है:

B = zeros(size(A));
for i = 1:numel(A)
  B(i) = A(i).^2;
end

B
B =
    64     1    36
     9    25    49
    16    81     4

कई परिस्थितियां हैं जहां रैखिक सूचकांक अधिक उपयोगी है। रैखिक सूचकांक और दो (या उच्चतर) आयामी सब्सक्राइबरों के बीच रूपांतरण उप 2ind और ind2sub फ़ंक्शन के साथ पूरा किया जाता है।

मैटलैब में किसी भी सरणी में सामान्य रूप से रैखिक सूचकांक लागू होता है। तो आप इसे संरचनाओं, सेल सरणियों आदि पर उपयोग कर सकते हैं। रैखिक सूचकांक के साथ एकमात्र समस्या यह है कि जब वे बहुत बड़े हो जाते हैं। MATLAB इन इंडेक्स को स्टोर करने के लिए 32 बिट पूर्णांक का उपयोग करता है। तो अगर आपके सरणी में अधिक है तो इसमें कुल 2 ^ 32 तत्व हैं, रैखिक सूचकांक विफल हो जाएगा। यह वास्तव में केवल एक मुद्दा है यदि आप अक्सर विरल मैट्रिस का उपयोग करते हैं, जब कभी-कभी यह समस्या का कारण होगा। (हालांकि मैं 64 बिट MATLAB रिलीज़ का उपयोग नहीं करता हूं, मेरा मानना ​​है कि समस्या उन भाग्यशाली व्यक्तियों के लिए हल हो गई है जो करते हैं।)


64-बिट MATLAB में अनुक्रमण वास्तव में 64-बिट सदस्यता की अनुमति देता है। उदाहरण के लिए: x = ones(1,2^33,'uint8'); x(2^33)उम्मीद के मुताबिक काम करता है।
एडिक

@ विदेश - निश्चित रूप से, यह एक ऐसा व्यवहार है जो निश्चित रूप से वर्षों में बदल गया होगा (और कई रिलीज) जब से मैंने यह बयान दिया है। हालांकि जाँच के लिए धन्यवाद।

:) मुझे पता नहीं था कि जब तक मैंने टिप्पणी की तब तक जवाब कितना पुराना था - सवाल सिर्फ मेरे आरएसएस फ़ीड में दिखा, और मैंने यह भी नहीं देखा कि मैंने इसका जवाब दिया था!
एड्रिका

15

के रूप में कुछ अन्य उत्तर में बताया, तो आप के ऊपर एक मैट्रिक्स में सभी तत्वों पुनरावृति कर सकते हैं A(किसी भी आयाम की) एक का उपयोग कर रैखिक सूचकांक से 1करने के लिए numel(A)एक एकल में पाश के लिए। आपके द्वारा उपयोग किए जा सकने वाले कुछ फ़ंक्शन भी हैं: arrayfunऔर cellfun

आइए पहले मान लें कि आपके पास एक फ़ंक्शन है जिसे आप A(बुलाया my_func) के प्रत्येक तत्व पर लागू करना चाहते हैं । आप पहली बार इस फंक्शन को फंक्शन हैंडल बनाते हैं :

fcn = @my_func;

यदि Aमनमाना आयाम का एक मैट्रिक्स (प्रकार डबल, एकल, आदि) है, तो आप प्रत्येक तत्व arrayfunपर लागू my_funcकरने के लिए उपयोग कर सकते हैं :

outArgs = arrayfun(fcn, A);

तो Aएक है सेल सरणी मनमाना आयाम की है, तो आप उपयोग कर सकते हैं cellfunलागू करने के लिए my_funcप्रत्येक कक्ष के लिए:

outArgs = cellfun(fcn, A);

फ़ंक्शन my_funcको Aइनपुट के रूप में स्वीकार करना होगा । यदि वहाँ से कोई आउटपुट हैं my_func, तो इन्हें अंदर रखा outArgsजाएगा, जो आकार / आयाम के समान होगा A

आउटपुट पर एक कैविएट ... यदि my_funcयह अलग-अलग आकार और प्रकार के आउटपुट देता है, जब यह अलग-अलग तत्वों पर काम करता है A, तो outArgsसेल सरणी में बनाना होगा। यह arrayfunया तो cellfunएक अतिरिक्त पैरामीटर / मान युग्म के साथ कॉल करके किया जाता है :

outArgs = arrayfun(fcn, A, 'UniformOutput', false);
outArgs = cellfun(fcn, A, 'UniformOutput', false);

13

एक अन्य चाल का उपयोग करने के लिए ind2subऔर है sub2ind। के साथ संयोजन के रूप में numelऔर size, यह आपको निम्नलिखित की तरह सामान कर सकता है, जो एक एन-आयामी सरणी बनाता है, और फिर "विकर्ण" पर सभी तत्वों को 1 सेट करता है।

d = zeros( 3, 4, 5, 6 ); % Let's pretend this is a user input
nel = numel( d );
sz = size( d );
szargs = cell( 1, ndims( d ) ); % We'll use this with ind2sub in the loop
for ii=1:nel
    [ szargs{:} ] = ind2sub( sz, ii ); % Convert linear index back to subscripts
    if all( [szargs{2:end}] == szargs{1} ) % On the diagonal?
        d( ii ) = 1;
    end
end

MATLAB कैसे टूटता है टाइपिंग का एक अच्छा उदाहरण दिखाने के लिए +1।
फिलिप क्लाउड

1

आप एक पुनरावर्ती कार्य कर सकते हैं

  • चलो L = size(M)
  • चलो idx = zeros(L,1)
  • length(L)अधिकतम गहराई के रूप में लें
  • लूप for idx(depth) = 1:L(depth)
  • यदि आपकी गहराई है length(L), तो तत्व संचालन करें, अन्यथा फ़ंक्शन को फिर से कॉल करेंdepth+1

यदि आप सभी बिंदुओं की जांच करना चाहते हैं, तो वेक्टरकृत विधियों के रूप में तेज़ नहीं है, लेकिन यदि आपको उनमें से अधिकांश का मूल्यांकन करने की आवश्यकता नहीं है, तो यह काफी समय सेवर हो सकता है।


1

ये समाधान उपयोग करने की तुलना में अधिक तेज़ (लगभग 11%) हैं numel;)

for idx = reshape(array,1,[]),
     element = element + idx;
end

या

for idx = array(:)',
    element = element + idx;
end

युपीडी। अंतिम उत्तर में त्रुटि का पता लगाने के लिए tnx @rayryeng


अस्वीकरण

इस पोस्ट में जिस समय की जानकारी का संदर्भ दिया गया है वह एक मौलिक टाइपो के कारण गलत और गलत है (नीचे टिप्पणी स्ट्रीम के साथ-साथ संपादन इतिहास - विशेष रूप से इस उत्तर के पहले संस्करण को देखें)। कैविट एमप्टर


1
1 : array(:)के बराबर है 1 : array(1)। यह सभी तत्वों के माध्यम से पुनरावृत्ति नहीं करता है, यही कारण है कि आपका रन-टाइम त्वरित है। इसके अलावा, फ्लोटिंग-पॉइंट नंबर randउत्पन्न करता है , और ऐसा करने से एक खाली सरणी उत्पन्न होती है क्योंकि आपका स्टेटमेंट 1 के रूप में अपने शुरुआती मूल्य के साथ एक बढ़ते हुए वेक्टर को खोजने की कोशिश कर रहा है, जो कि फ़्लोटिंग पॉइंट नंबर के रूप में 1 के अनन्य रेंज के साथ बढ़ते हुए है। 1. चरणों में ऐसा कोई संभावित वेक्टर नहीं है, जिसके परिणामस्वरूप एक खाली वेक्टर होता है। आपका लूप नहीं चलता है, और इसलिए आपका दावा गलत है। -1 वोट। माफ़ करना। 1 : array(:)[0,1)for
रेयिनेंग

@rayryeng आप सही नहीं हैं। सरणी (:) 1: सरणी (1) के बराबर नहीं है। यह पसंद है reshape(...)

@rayryeng matlab r2013a + linux - यह काम करता है! ;) मैं अभी उस कोड को भी चला गया
mathcow

1 : array(:)बनाने के बाद अपने कमांड प्रॉम्प्ट पर टाइप करें array । क्या आपको एक खाली मैट्रिक्स मिलता है? यदि हाँ तो आपका कोड काम नहीं करता है। मैं अपना वोट छोड़ रहा हूं क्योंकि आप गलत जानकारी दे रहे हैं।
रेयरेंगeng

@rayryeng मैं समझ रहा हूँ! हां, आप सही हैं, मूर्ख विवाद के लिए क्षमा करें
mathcow 12

-1

यदि आप के अन्य उपयोगों में गहराई से sizeदेखते हैं, तो आप देख सकते हैं कि आप वास्तव में प्रत्येक आयाम के आकार का एक वेक्टर प्राप्त कर सकते हैं। यह लिंक आपको दस्तावेज़ दिखाता है:

www.mathworks.com/access/helpdesk/help/techdoc/ref/size.html

आकार वेक्टर प्राप्त करने के बाद, उस वेक्टर पर पुनरावृति करें। कुछ इस तरह से (मेरे सिंटैक्स को क्षमा करें क्योंकि मैंने कॉलेज के बाद से मतलाब का उपयोग नहीं किया है):

d = size(m);
dims = ndims(m);
for dimNumber = 1:dims
   for i = 1:d[dimNumber]
      ...

इसे वास्तविक मतलाब-कानूनी वाक्यविन्यास में बनाओ, और मुझे लगता है कि यह वही करेगा जो आप चाहते हैं।

इसके अलावा, आपको यहाँ वर्णित के रूप में रैखिक अनुक्रमण करने में सक्षम होना चाहिए ।


मैं यह नहीं देख सकता कि लूप का ऑर्डर मैट्रिक्स के सभी तत्वों पर कैसे लागू होगा। उदाहरण के लिए, यदि आपके पास 3-बाय -4 मैट्रिक्स (12 तत्वों के साथ) है, तो आपका आंतरिक लूप केवल 7 बार पुनरावृत्त होगा।
gnovice

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

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

-1

आप छोरों के लिए एन-नेस्टेड अनुकरण करना चाहते हैं।

N-dimmunning अरै के माध्यम से इरेटिंग को n-digit संख्या को बढ़ाते हुए देखा जा सकता है।

प्रत्येक मंदता के समय हमारे पास जितने अंक होते हैं, उतने ही मंदक की सीमा होती है।

उदाहरण:

मान लीजिए कि हमारे पास सरणी (मैट्रिक्स) थी

int[][][] T=new int[3][4][5];

"नोटेशन के लिए" हमारे पास है:

for(int x=0;x<3;x++)
   for(int y=0;y<4;y++)
       for(int z=0;z<5;z++)
          T[x][y][z]=...

इसका अनुकरण करने के लिए आपको "n-digit number अंकन" का उपयोग करना होगा

हमारे पास 3 अंकों की संख्या है, जिसमें पहले के लिए 3 अंक, दूसरे के लिए 4 और तीसरे अंक के लिए पांच अंक हैं

हमें संख्या बढ़ानी होगी, इसलिए हमें अनुक्रम मिलेगा

0 0 0
0 0 1
0 0 2    
0 0 3
0 0 4
0 1 0
0 1 1
0 1 2
0 1 3
0 1 4
0 2 0
0 2 1
0 2 2
0 2 3
0 2 4
0 3 0
0 3 1
0 3 2
0 3 3
0 3 4
and so on

तो आप ऐसे n-digit नंबर को बढ़ाने के लिए कोड लिख सकते हैं। आप इसे इस तरह से कर सकते हैं कि आप संख्या के किसी भी मूल्य से शुरू कर सकते हैं और किसी भी संख्या से अंकों को बढ़ा / घटा सकते हैं। इस तरह आप उन छोरों के लिए नेस्टेड अनुकरण कर सकते हैं जो तालिका में कहीं शुरू होते हैं और अंत में समाप्त नहीं होते हैं।

हालांकि यह एक आसान काम नहीं है। मैं matlab अंकन दुर्भाग्य के साथ मदद नहीं कर सकता।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.