Creating new registors using Loop

1 次查看(过去 30 天)
Ghulam
Ghulam 2018-3-21
评论: Jan 2018-3-24
Hi, I am writing a code in which a block of code is repeated many times. But for every time the values are saved in new variables which are repeated too. I want that the names of the variables updates automatically like using a loop or something like that.
if true
% My Code
[R1,R2,R3,R4,F,M1,M2,M3,M4,OG, G1,G2,G3,G4]=fir();
[tr,rc,lc,br]=rotatearray(G1);
[tr2,rc2,lc2,br2]=rotatearray(R1);
channel1= M1(:,:,1);
channel2= M1(:,:,2);
channel3= M1(:,:,3);
Zero1 = uint8(zeros(1728));
Zero2 = uint8(zeros(1728));
Zero3 = uint8(zeros(1728));
Zero1([tr2:br2],[lc2:rc2]) = channel1([1:end],[(rc-rc2+1):end]);
Zero2([tr2:br2],[lc2:rc2]) = channel2([1:end],[(rc-rc2+1):end]);
Zero3([tr2:br2],[lc2:rc2]) = channel3([1:end],[(rc-rc2+1):end]);
final1 = cat(3,Zero1,Zero2,Zero3);
%FOR a3
[tr,rc,lc,br]=rotatearray(G2);
[tr2,rc2,lc2,br2]=rotatearray(R2);
channel1= M2(:,:,1);
channel2= M2(:,:,2);
channel3= M2(:,:,3);
Zero1 = uint8(zeros(1728));
Zero2 = uint8(zeros(1728));
Zero3 = uint8(zeros(1728));
Zero1([tr2:br2],[lc2:rc2]) = channel1([(br-br2+1):end],[(rc-rc2+1):end]);
Zero2([tr2:br2],[lc2:rc2]) = channel2([(br-br2+1):end],[(rc-rc2+1):end]);
Zero3([tr2:br2],[lc2:rc2]) = channel3([(br-br2+1):end],[(rc-rc2+1):end]);
final2 = cat(3,Zero1,Zero2,Zero3);
%FOR a4
[tr,rc,lc,br]=rotatearray(G3);
[tr2,rc2,lc2,br2]=rotatearray(R3);
channel1= M3(:,:,1);
channel2= M3(:,:,2);
channel3= M3(:,:,3);
Zero1 = uint8(zeros(1728));
Zero2 = uint8(zeros(1728));
Zero3 = uint8(zeros(1728));
Zero1([tr2:br2],[lc2:rc2]) = channel1([(br-br2+1):end],[1:(end-lc2+1)]);
Zero2([tr2:br2],[lc2:rc2]) = channel2([(br-br2+1):end],[1:(end-lc2+1)]);
Zero3([tr2:br2],[lc2:rc2]) = channel3([(br-br2+1):end],[1:(end-lc2+1)]);
final3 = cat(3,Zero1,Zero2,Zero3);
end
From here you can have the idea that most of the block of code is same just the input register (M 1,2,3) is changing, So can how can we select the input register automatically. I have tried using a loop but it didn't work.
Kindly guide me about it.
Regards
  3 个评论
Stephen23
Stephen23 2018-3-21
编辑:Stephen23 2018-3-21
"I want that the names of the variables updates automatically like using a loop or something like that"
Dynamically accessing variable names is how beginners force themselves into writing slow, complex, buggy code that is hard to debug. The MATLAB documentation specifically recommends against dynamically accessing variable names: "A frequent use of the eval function is to create sets of variables such as A1, A2, ..., An, but this approach does not use the array processing power of MATLAB and is not recommended. The preferred method is to store related data in a single array."
All MATLAB experts will also advise you to use one array and indexing. Indexing is simple, neat, easy to debug, and very efficient. When you put a number on the end of variable names then you are using de-facto indexing, so why not simply turn it into real indexing? Then your code will immediately be faster, simpler, less buggy, and easier to debug.
Read this to know more:
Jan
Jan 2018-3-24
@Ghulam: Please do not use flags to post a comment. Flagging is used to call the admins for cleaning up a message due to spam or rudeness. Use comments instead.

请先登录,再进行评论。

回答(2 个)

Jan
Jan 2018-3-21
编辑:Jan 2018-3-21
Do not create variables dynamically. See Tutorial: Avoid EVAL . So the answer to
I want that the names of the variables updates automatically
is: Don't do this. Use a multi-dimensional array instead, if all arrays have the same size and type. Otherwise use a cell array.
[R{1},R{2},R{3},R{4},F,M{1},M{2},M{3},M{4},OG, ...
G{1},G{2},G{3},G{4}] = fir();
final = cell(1, 4);
for k = 1:4
[tr,rc,lc,br]=rotatearray(G{k});
[tr2,rc2,lc2,br2]=rotatearray(R{k});
channel1 = M{k}(:,:,1);
channel2 = M{k}(:,:,2);
channel3 = M{k}(:,:,3);
Z = zeros(1728, 1728, 3, 'uint8');
Z(tr2:br2, lc2:rc2, 1) = channel1(:, (rc-rc2+1):end);
Z(tr2:br2, lc2:rc2, 2) = channel2(:, (rc-rc2+1):end);
Z(tr2:br2, lc2:rc2, 3) = channel3(:, (rc-rc2+1):end);
final{k} = Z;
end
Or even shorter:
[R{1},R{2},R{3},R{4},F,M{1},M{2},M{3},M{4},OG, ...
G{1},G{2},G{3},G{4}] = fir();
final = cell(1, 4);
for k = 1:4
[tr,rc,lc,br] = rotatearray(G{k});
[tr2,rc2,lc2,br2] = rotatearray(R{k});
Z = zeros(1728, 1728, 3, 'uint8');
Z(tr2:br2, lc2:rc2, :) = M{k}(:, (rc-rc2+1):end, :);
final{k} = Z;
end
Some notes:
Using square brackets for the indexing wastes time. See Why not use square brackets. Replace:
Zero1([tr2:br2],[lc2:rc2]) = channel1([(br-br2+1):end],[(rc-rc2+1):end]);
by
Zero1(tr2:br2, lc2:rc2) = channel1((br-br2+1):end, (rc-rc2+1):end);
which is nicer and faster. Especially [1:end] should be replaced by the more efficient : .
This
Zero1 = uint8(zeros(1728))
Creates a 1728x1728 array of type double at first, which needs 23.9 MB, only to convert it to UINT8 afterwards. More efficient:
Zero1 = zeros(1728, 1728, 'uint8');
Now the output is created directly with 2.99 MB filled by zeros.
  1 个评论
Guillaume
Guillaume 2018-3-21
If it were possible, I would give more than one vote to all of Jan's advice in this answer.
Do not create dynamic variable names. It always lead to more complicated and less efficient code.

请先登录,再进行评论。


Ghulam
Ghulam 2018-3-23
All answers are perfect and perfect solutions to my problem. thanks to all of you.

标签

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by