আমি ম্যাটল্যাবে এন-ডাইমেনশনাল ম্যাট্রিক্সের প্রতিটি উপাদান দিয়ে কীভাবে পুনরাবৃত্তি করব?


87

আমার একটা সমস্যা আছে. আমাকে ম্যাটল্যাবে একটি এন-ডাইমেনশনাল ম্যাট্রিক্সের প্রতিটি উপাদান দিয়ে পুনরাবৃত্তি করতে হবে। সমস্যাটি হ'ল আমি জানি না যে এটি একটি স্বেচ্ছাসেবী সংখ্যার জন্য কীভাবে করা যায়। আমি জানি আমি বলতে পারি

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

এবং এইভাবেই, তবে এটি নির্বিচারে সংখ্যক মাত্রার জন্য করার উপায় আছে কি?


13
মতলব টার্মিনোলজির নোট: মতলবটিতে খুব কম মূল তথ্য প্রকার রয়েছে। সর্বাধিক গুরুত্বপূর্ণ: স্ট্রাক্ট, ম্যাট্রিক্স এবং সেল অ্যারে। ম্যাট্রিক্সের অংশগুলি উল্লেখ করার সময়, "এলিমেন্ট" শব্দটি ব্যবহার করা সাধারণভাবে ব্যবহৃত হয় এবং একটি ঘর অ্যারের অংশগুলি উল্লেখ করার জন্য "সেল" শব্দটি সংরক্ষণ করে। উভয় এন-ডাইমেনশনাল ডেটা স্ট্রাকচার হলেও সেলের অ্যারে এবং ম্যাট্রিকের অনেকগুলি সিনট্যাকটিক এবং শব্দার্থক পার্থক্য রয়েছে।
মিঃ ফুজ

4
আপনার কি পুনরাবৃত্তি প্রয়োজন তা জিজ্ঞাসা করতে পারি? পরিবর্তে এটি করার একটি "ভেক্টরাইজড" উপায় আছে ...
হোসাম অলি

উত্তর:


92

প্রতিটি উপাদান অ্যাক্সেস করতে আপনি লিনিয়ার সূচক ব্যবহার করতে পারেন।

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

আমি, জে, কে, আপনি কী রয়েছেন তা জানা দরকার না থাকলে এটি দরকারী। তবে, আপনি কোন সূচকটিতে আছেন তা যদি আপনার জানতে না চান তবে আপনি অ্যারেফুন () ব্যবহার করে সম্ভবত ভাল


4
এছাড়াও, যদি আপনি কোনো কারণে সূচকের পুনরুদ্ধার করতে চেয়েছিলেন, আপনি কি এখনও এই দুটি সহজ কমান্ড ব্যবহার করতে পারে: I = cell(1, ndims(array)); [I{:}] = ind2sub(size(array),idx);
knedlsepp

34

মতলবগুলিতে অ্যারেগুলির জন্য রৈখিক সূচকের ধারণা একটি গুরুত্বপূর্ণ। ম্যাটল্যাবে একটি অ্যারে আসলেই কেবল উপাদানের ভেক্টর, স্মৃতিতে ছড়িয়ে পড়ে। ম্যাটল্যাব আপনাকে একটি সারি এবং কলাম সূচক বা একক রৈখিক সূচক ব্যবহার করতে দেয়। উদাহরণ স্বরূপ,

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

আপনি দেখতে পাচ্ছেন, অষ্টম উপাদানটি সংখ্যা 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

অনেক পরিস্থিতিতে আছে যেখানে লিনিয়ার সূচকটি বেশি কার্যকর। লিনিয়ার সূচক এবং দুটি (বা উচ্চতর) মাত্রিক সাবস্ক্রিপ্টগুলির মধ্যে রূপান্তরটি সাব 2 ইন্ড এবং ইন্ডি 2সুব ফাংশন সহ সম্পন্ন হয়।

লিনিয়ার সূচকটি মাতলাবের যে কোনও অ্যারেতে সাধারণভাবে প্রযোজ্য। সুতরাং আপনি এটি স্ট্রাকচার, সেল অ্যারে ইত্যাদিতে ব্যবহার করতে পারেন লিনিয়ার ইনডেক্সে কেবল তখনই সমস্যা হয় যখন তারা খুব বড় হয়। ম্যাটল্যাব এই সূচকগুলি সংরক্ষণ করতে 32 বিট পূর্ণসংখ্যার ব্যবহার করে। সুতরাং যদি আপনার অ্যারেতে আরও থাকে তবে এতে মোট 2 ^ 32 উপাদান থাকে, লিনিয়ার সূচকটি ব্যর্থ হয়। যদি আপনি প্রায়শই স্পর্স ম্যাট্রিক ব্যবহার করেন এটি সত্যিই কেবল তখনই সমস্যা হয়, যখন মাঝে মাঝে এটি সমস্যার কারণ হয়ে দাঁড়ায়। (যদিও আমি একটি bit৪ বিট ম্যাটল্যাব রিলিজ ব্যবহার করি না, তবে আমি বিশ্বাস করি যে যারা ভাগ্যবান ব্যক্তিদের ক্ষেত্রে সমস্যাটি সমাধান হয়েছে))


-৪-বিট এমএটিএলবিএক্স ইনডেক্সিং প্রকৃতপক্ষে -৪-বিট সাবস্ক্রিপ্টগুলিকে সঠিকভাবে মঞ্জুরি দেয়। যেমন: 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এবং sub2indnumelএবং এর সাথে একত্রে 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

+1 কীভাবে ম্যাটল্যাব হাঁসের টাইপিং ব্রেক করে তার একটি ভাল উদাহরণ দেখানোর জন্য 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


অস্বীকৃতি

এই পোস্টটি যে সময়সীমার তথ্য উল্লেখ করেছে তা একটি মৌলিক টাইপোর কারণে ভুল এবং ভুল, যা নীচের মন্তব্যগুলির স্ট্রিমের পাশাপাশি সম্পাদনার ইতিহাস দেখুন - বিশেষ করে এই উত্তরটির প্রথম সংস্করণটি দেখুন)। ক্রেতা সাবধান নীতি


4
1 : array(:)সমতূল্য 1 : array(1)। এটি সমস্ত উপাদানগুলির মধ্যে পুনরাবৃত্তি করে না যার কারণে আপনার রান-টাইমগুলি দ্রুত হয়। তদুপরি, ভাসমান-পয়েন্ট সংখ্যা randউত্পন্ন করে এবং এর ফলে খালি অ্যারে তৈরি হবে কারণ আপনার বিবৃতিতে বর্ধমান ভেক্টরটির প্রারম্ভিক মান 1 হিসাবে একটি সমাপ্তি মান হিসাবে শেষের মান 1 হিসাবে একটি এক্সক্লুসিভ রেঞ্জের বৃদ্ধি সহ 1 টির প্রারম্ভিক মান সহ চেষ্টা করা হচ্ছে পদক্ষেপের ১. এমন কোনও সম্ভাব্য ভেক্টর নেই, যার ফলশ্রুতি খালি ভেক্টর। আপনার লুপটি চলবে না এবং তাই আপনার দাবিটি মিথ্যা। -1 ভোট। দুঃখিত 1 : array(:)[0,1)for
রাইরিং

পছন্দ করুন অ্যারে (:) 1 এর সমান নয়: অ্যারে (1)। এটা পছন্দ reshape(...)
ম্যাথকো

@ রাইরিং মাতলাব r2013a + লিনাক্স - এটি কার্যকর! ;) আমি কেবল এই কোডটি
চালিয়েছি

1 : array(:)তৈরির পরে আপনার কমান্ড প্রম্পটে টাইপ করুন array । আপনি কি খালি ম্যাট্রিক্স পান? যদি হ্যাঁ হয় তবে আপনার কোডটি কাজ করে না। আমি আমার ভোটটি ছেড়ে দিচ্ছি কারণ আপনি মিথ্যা তথ্য দিচ্ছেন।
রায়রিং

@ রাইরিং আমি বুঝতে পারছি! হ্যাঁ, আপনি ঠিক বলেছেন, বোকা বিতর্কের জন্য দুঃখিত
ম্যাথকো

-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 বার পুনরাবৃত্তি করবে।
জ্নোভাইস

এটি ম্যাট্রিক্সের প্রতিটি মাত্রায় পুনরাবৃত্তি হওয়া উচিত। বাহ্যিক লুপটি মাত্রাটির উপরে পুনরাবৃত্তি করে, সেই মাত্রার আকারের উপরের লুপটি। কমপক্ষে, এটি ধারণা। অন্য প্রত্যেকে যেমন উল্লেখ করছেন, তিনি চান সমস্ত যদি প্রতিটি কক্ষ হয় তবে লাইনার ইনডেক্সিং সেরা। যদি তিনি প্রতিটি মাত্রার উপরে পুনরাবৃত্তি করতে চান তবে তাকে এর অনুরূপ কিছু করতে হবে।
এরিক মীরাবলাল

এছাড়াও, সম্পাদনার জন্য ধন্যবাদ। আমার লিঙ্কটি দারুণভাবে সংশ্লেষিত হয়েছিল এবং কেবলমাত্র স্বাভাবিক লিঙ্কিংয়ের উপায় ব্যবহার করে ঠিক কাজ করবে না। এছাড়াও, আমার বক্তব্যটি প্রসারিত করতে: তাকে এখনও সূচকের অন্যান্য অনেক ট্র্যাকিং করতে হবে (কাউন্টার বা এমন কিছু ব্যবহার করে)। আমি মনে করি যে তিনি যা করার চেষ্টা করছেন তার জন্য আপনার বা অ্যান্ড্রুর যোগাযোগ সহজ হবে।
এরিক মীরাবলাল

-1

আপনি লুপগুলির জন্য এন-নেস্টেড অনুকরণ করতে চান।

এন-ডাইমেনশনাল অ্যারের মাধ্যমে আইট্রেট করা এন-ডিজিট সংখ্যা বাড়িয়ে দেখা যায়।

প্রতিটি ধাপে আমাদের ড্যাম্মেন্সটির দৈর্ঘ্যের মতো অনেকগুলি সংখ্যা রয়েছে।

উদাহরণ:

ধরুন আমাদের অ্যারে (ম্যাট্রিক্স) ছিল

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]=...

এটি অনুকরণ করতে আপনাকে "এন-অঙ্কের নম্বর স্বরলিপি" ব্যবহার করতে হবে

আমাদের প্রথম সংখ্যাটির জন্য 3 টি, দ্বিতীয়টির জন্য 4 এবং তৃতীয় অঙ্কের জন্য পাঁচটি সংখ্যা সহ 3 ডিজিট নম্বর রয়েছে

আমাদের সংখ্যা বাড়াতে হবে, সুতরাং আমরা ক্রমটি পেয়ে যাব

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

সুতরাং আপনি যেমন এন অঙ্কের সংখ্যা বাড়ানোর জন্য কোড লিখতে পারেন। আপনি এটি এমনভাবে করতে পারেন যে আপনি কোনও সংখ্যার যে কোনও মান দিয়ে শুরু করতে পারেন এবং কোনও সংখ্যা দ্বারা সংখ্যাগুলি বাড়িয়ে / হ্রাস করতে পারেন। এইভাবে আপনি টেবিলে কোথাও শুরু হয়ে শেষ পর্যন্ত শেষ করবেন না এমন লুপগুলির জন্য নেস্টেড অনুকরণ করতে পারেন।

এটি যদিও সহজ কাজ নয়। মাতলাব স্বরলিপিটি দুর্ভাগ্যজনকভাবে সাহায্য করতে পারি না।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.