1 view (last 30 days)
Show older comments
Sebastian Neckermann on 5 Jul 2017
-
-
Link
Direct link to this question
https://matlabcentral.mathworks.com/matlabcentral/answers/347527-call-elements-with-different-ending-in-a-loop
Edited: Stephen23 on 7 Jul 2017
Accepted Answer: Honglei Chen
Open in MATLAB Online
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 Comment Show -1 older commentsHide -1 older comments
Show -1 older commentsHide -1 older comments
Stephen23 on 7 Jul 2017
Direct link to this comment
https://matlabcentral.mathworks.com/matlabcentral/answers/347527-call-elements-with-different-ending-in-a-loop#comment_467159
Edited: Stephen23 on 7 Jul 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."
source: http://www.mathworks.com/help/matlab/matlab_prog/string-evaluation.html
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.
https://www.mathworks.com/matlabcentral/answers/304528-tutorial-why-variables-should-not-be-named-dynamically-eval
https://www.mathworks.com/matlabcentral/answers/143-how-do-i-make-a-series-of-variables-a1-a2-a3-a10
https://www.mathworks.com/matlabcentral/answers/57445-faq-how-can-i-create-variables-a1-a2-a10-in-a-loop
etc, etc, etc.
Sign in to comment.
Sign in to answer this question.
Accepted Answer
Honglei Chen on 5 Jul 2017
Here is a post you may find useful
https://www.mathworks.com/matlabcentral/answers/143-how-do-i-make-a-series-of-variables-a1-a2-a3-a10
HTH
3 Comments Show 1 older commentHide 1 older comment
Show 1 older commentHide 1 older comment
Sebastian Neckermann on 5 Jul 2017
Direct link to this comment
https://matlabcentral.mathworks.com/matlabcentral/answers/347527-call-elements-with-different-ending-in-a-loop#comment_466781
Maybe i dont get it really, but i dont find my answer in there :(
In Python you can do it like this:
A = 'Ms%d' %i
James Tursa on 6 Jul 2017
Direct link to this comment
https://matlabcentral.mathworks.com/matlabcentral/answers/347527-call-elements-with-different-ending-in-a-loop#comment_466807
Edited: James Tursa on 6 Jul 2017
Open in MATLAB Online
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 on 6 Jul 2017
Direct link to this comment
https://matlabcentral.mathworks.com/matlabcentral/answers/347527-call-elements-with-different-ending-in-a-loop#comment_467022
Edited: Jan on 6 Jul 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
Sign in to comment.
More Answers (1)
John BG on 5 Jul 2017
Edited: John BG on 6 Jul 2017
Open in MATLAB Online
Hi Sebastian
this is John BG ( <mailto:jgb2012@sky.com jgb2012@sky.com> )
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
<mailto:jgb2012@sky.com jgb2012@sky.com>
3 Comments Show 1 older commentHide 1 older comment
Show 1 older commentHide 1 older comment
John BG on 6 Jul 2017
Direct link to this comment
https://matlabcentral.mathworks.com/matlabcentral/answers/347527-call-elements-with-different-ending-in-a-loop#comment_466814
ain't ugly if it works and solves the question
Jan on 6 Jul 2017
Direct link to this comment
https://matlabcentral.mathworks.com/matlabcentral/answers/347527-call-elements-with-different-ending-in-a-loop#comment_467018
Edited: Jan on 6 Jul 2017
Open in MATLAB Online
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 on 7 Jul 2017
Direct link to this comment
https://matlabcentral.mathworks.com/matlabcentral/answers/347527-call-elements-with-different-ending-in-a-loop#comment_467104
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
<mailto:jgb2012@sky.com jgb2012@sky.com>
Sign in to comment.
Sign in to answer this question.
See Also
Categories
MATLABEnvironment and Settings
Find more on Environment and Settings in Help Center and File Exchange
Tags
- call element
- arrays with continuous numbers
- eval
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!
An Error Occurred
Unable to complete the action because of changes made to the page. Reload the page to see its updated state.
Select a Web Site
Choose a web site to get translated content where available and see local events and offers. Based on your location, we recommend that you select: .
You can also select a web site from the following list
Americas
- América Latina (Español)
- Canada (English)
- United States (English)
- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)
- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- Deutsch
- English
- Français
- United Kingdom(English)
Asia Pacific
- Australia (English)
- India (English)
- New Zealand (English)
- 中国
- 日本Japanese (日本語)
- 한국Korean (한국어)
Contact your local office