Call elements with different ending in a loop

6 visualizaciones (últimos 30 días)
Sebastian Neckermann
Sebastian Neckermann el 5 de Jul. de 2017
Editada: Stephen23 el 7 de Jul. de 2017
Hey,
i have different 6x6 arrays in my workspace with names like Ms1, Ms2, Ms3, Msi I want to extract the element in the first row and the first line and create a Vector ix1.
Here is the idea how to do it, but instead of caling Ms1, Ms2 ... i want to call like Msi...
clear A
for i = 1:50
A(i,1) = Ms'i' (1,1);
end
This expression (Ms'i') is wrong, but i dont know how to write it properly.
Would be thankful if anybody could give me the answer to my problem.
Thanks in advance ;)
  1 comentario
Stephen23
Stephen23 el 7 de Jul. de 2017
Editada: Stephen23 el 7 de Jul. de 2017
Do NOT waste your time writing bad code that creates separate variables with numbered 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."
Just use indexing: simple, fast, efficient, neat, simple, easy to understand, much less buggy, easier to debug, etc, etc, etc. If you are importing those variables then it is trivial to load or import them into one variable in a loop.
etc, etc, etc.

Iniciar sesión para comentar.

Respuesta aceptada

Honglei Chen
Honglei Chen el 5 de Jul. de 2017
  3 comentarios
James Tursa
James Tursa el 6 de Jul. de 2017
Editada: James Tursa el 6 de Jul. de 2017
The point is to not create a series of variables with names like Ms1, Ms2, Ms3, etc in the first place. MATLAB is not a language that can deal with these easily downstream in your code. You should instead create 3D arrays or cell arrays. E.g., had you used a cell array called Ms and had your matrices be Ms{1}, Ms{2}, Ms{3}, etc then they would be easy to use downstream in your code.
But to answer your question and to show how ugly the solution is (and hopefully motivate you to not do this in MATLAB), here is a way:
for i = 1:50
A(i,1) = eval(['Ms' num2str(i) '(1,1)']);
end
Had you used a cell array, the loop would look much cleaner:
for i = 1:50
A(i,1) = Ms{i}(1,1);
end
Moreover, there are vectorized ways to do this with cell arrays (and 3D arrays) in one line without even needing an explicit loop. E.g.,
A = cellfun(@(x)x(1,1),Ms).';
Jan
Jan el 6 de Jul. de 2017
Editada: Jan el 6 de Jul. de 2017
I agree with James. It is worth to point out, that the eval approach is not only ugly, but slows down the processing, see e.g. Answers: faq-create-variables-a1-a2-a10-in-a-loop: comment

Iniciar sesión para comentar.

Más respuestas (1)

John BG
John BG el 5 de Jul. de 2017
Editada: John BG el 6 de Jul. de 2017
Hi Sebastian
If you stack all Msi there's no need to use the for loop to generate vector A:
1.
example with Ms1 Ms2 Ms3
Ms1=randi([-10 10],6)
=
7 2 9 -9 1 -4
-5 -1 -4 -9 -1 1
9 -3 5 1 -10 -7
-3 7 5 6 -3 2
-6 2 -3 9 -7 -5
-5 1 1 -8 6 3
Ms2=randi([-10 10],6)
=
4 -7 -8 -9 -7 1
5 7 10 -2 -5 -7
-1 1 -10 -5 -7 7
-9 10 6 6 -8 3
-6 -9 7 -1 8 -3
9 -1 8 9 2 0
Ms3=randi([-10 10],6)
=
-2 -2 -3 -5 2 -10
-9 -9 8 -2 -9 -7
-5 8 -3 -8 -6 3
-8 9 -8 -8 -3 5
-7 0 6 9 7 3
-5 0 -2 10 -10 -1
[s1 s2]=size(Ms1)
M2=zeros(s1,s2,3);
M2(:,:,1)=Ms1;
M2(:,:,2)=Ms2;
M2(:,:,3)=Ms3;
2.
building the A vector
A=squeeze(M2(1,1,:))'
=
7 4 -2
3.
Calling Msi from workspace
To avoid having to manually call and stack 50 matrices, one can use command who
d2=who('Ms*')
=
3×1 cell array
'Ms1'
'Ms2'
'Ms3'
[sd1 sd2]=size(d2)
sd1 =
3
sd2 =
1
M2=zeros(6,6,sd1)
for k=1:1:sd1
L=['M2(:,:,' num2str(k) ')=' d2{k,:}]
evalin('base',L)
end
Set sd1 to 50 or whatever total amount of Msi matrices in order to automate the stacking of all Msi onto M2
.
if you find this answer useful would you please be so kind to consider marking my answer as Accepted Answer?
To any other reader, if you find this answer useful please consider clicking on the thumbs-up vote link
thanks in advance
John BG
  3 comentarios
Jan
Jan el 6 de Jul. de 2017
Editada: Jan el 6 de Jul. de 2017
The posted method runs in the command window only due to the evalin('base', ...) command, but an eval instead would solve this. The whos('Ms*') leads to a crash if e.g. the variable "MsInfo" has been created anywhere. Matlab's JIT acceleration does not work efficiently after a dynamic creation of variables, such that the runtime of loops can increase massively.
I find eval -like commands ugly. The community finds them ugly, MathWorks suggests to prefer better methods, the FAQ finds them ugly, there is an exhaustive explanation in the forum of the ugly problems caused by these commands. eval causes more problems than it solves.
See the direct, clean, lean and efficient solution suggest by James in the comment above:
A = zeros(50, 1);
for k = 1:50
A(k) = Ms{k}(1,1);
end
Nice.
John BG
John BG el 7 de Jul. de 2017
thanks for pointing out the possibility of evalin not working correctly for variables name starting with Ms but with other spelling than Ms# .. where # is the numeral.
I assumed that in the context of this question, the question originator, Mr Sebastian Neckermann, would make sure that such variable conflicts do not occur.
regards
John BG

Iniciar sesión para comentar.

Categorías

Más información sobre Matrix Indexing en Help Center y File Exchange.

Community Treasure Hunt

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

Start Hunting!

Translated by