Asked by Italo
on 13 Nov 2013

Hello community,

my knowledge of Matlab is limited, I admit it. So, I am sorry if I am going to make mistakes.

I have to create a series of variable using a "for" loop.

I make this:

for i=1:3 eval(['A' num2str(i) '= i']) end

and it works well, it makes 3 variables A1, A2, A3.

But I need to use this variables to make other variables B1, B2, B3 where Bi=Ai*i. So I should have B1=A1*1=1, B2=A2*2=2*2=4, B3=A3*3=3*3=9

I tried something like this:

for i=1:3 eval(['A' num2str(i) '= i']) eval(['B' num2str(i) '= 'A' num2str(i) '*i]) end

but it gives me error and it doesn't work. Of course I simplified things, the real code is a bt more complicated but I need to know the basics of how this could work.

Thank you

Answer by Stephen Cobeldick
on 12 Jan 2016

Accepted Answer

Ugh... this is a really bad idea!

Avoid creating dynamically named variables in MATLAB. This is poor practice as has been explained many times on this forum, and is not recommended by MATLAB themselves:

http://www.mathworks.com/help/matlab/matlab_prog/string-evaluation.html

When you are a beginner it seems like a cunning and fast way to store information, but actually it is **really bad** practice to name your variables dynamically. MATLAB is also not intended for this kind of variable naming: if you continue to include data in the variable names then you will find yourself fighting many more of these battles against MATLAB.

However when you use more appropriate storage for your data (and meta-data) then you will suddenly find lots of MATLAB functions that do many useful operations for you, quickly and easily.

In your case a much more robust solution would be to use:

- the dimensions of numeric arrays: fully vectorized code is often the fastest MATLAB data processing!
- cell arrays
- structures, where you can include fields for each kind of data (e.g. Process type, Flow data, Temperature data, Notes, Units, etc). Structures can even be non-scalar, which is extremely useful! And yes, you can even define structure fieldnames dynamically.

There are many functions that support working on structures and cell arrays and can access their data easily, and many functions operate on complete numeric arrays all at once without any loops (i.e. vectorized code, which is something you need to learn about).

Placing your data in a structure or cell array also makes it much easier to pass to functions: can you imagine the fight you would have trying to pass hundreds of dynamically named variables to a function?

If you have a newer version of matlab you can also use a table , which stores the data together in one array but also allows key-name access to the columns. This might be a good alternative for your data.

In case you are interested, here are some pages explaining why dynamically assigning variable names is a really bad idea in MATLAB:

http://www.mathworks.com/matlabcentral/newsreader/view_thread/240867

http://blogs.mathworks.com/loren/2005/12/28/evading-eval/

http://matlab.wikia.com/wiki/FAQ#How_can_I_create_variables_A1.2C_A2.2C....2CA10_in_a_loop.3F

http://ww.mathworks.com/matlabcentral/answers/143-how-do-i-make-a-series-of-variables-a1-a2-a3-a10

http://www.mathworks.com/matlabcentral/answers/51946-systematic-do-not-use-global-don-t-use-eval

http://www.mathworks.com/matlabcentral/answers/74778-loop-file-and-variablenames-when-importin

http://stackoverflow.com/questions/10272522/use-and-implications-of-evalexpression-in-matlab-code

Here is a discussion of why it is a bad idea to include meta-data (such as an index) in a variable name:

http://www.mathworks.com/matlabcentral/answers/225435-save-variable-as-string-from-user-input

And here is a discussion of why it is a really bad idea to make variables magically appear any workspace (even though beginners love doing this):

And in case you thought this is a MATLAB restriction, here is the same discussion for some other languages, advising "DO NOT create dynamic variable names":

http://nedbatchelder.com/blog/201112/keep_data_out_of_your_variable_names.html

http://www.techrepublic.com/blog/it-security/never-use-dynamic-variable-names/

http://stackoverflow.com/questions/11118486/python-list-as-variable-name

Jan
on 30 Apr 2018

+1. Another time: Thanks Stephen.

Giovanni Barbarossa
on 27 Jun 2018

Sign in to comment.

Answer by Amit
on 22 Jan 2014

Edited by Amit
on 22 Jan 2014

Italo, I am glad you're trying out things on matlab.

Matlab is very good with matrixes. What you're doing in these can be done much easily. For example:

A = 1:3; B = A.*A; %

You can find many tutorials online on how to use MAtlab. For example: http://www.mathworks.com/academia/student_center/tutorials/launchpad.html

Amit
on 22 Jan 2014

In you code:

for i=1:3 eval(['A' num2str(i) '= i']) eval(['B' num2str(i) '= A' num2str(i) '*i']) % Issue was Here. Notice the positions of ' end

Bruno Pop-Stefanov
on 22 Jan 2014

I would like to add that `eval` is #1 in this list: Top 10 MATLAB code practices that make me cry

Sign in to comment.

Answer by Jerry
on 28 Apr 2018

Edited by Jerry
on 28 Apr 2018

I did find dynamically named variables useful for a specific need. I have several files in a directory. Each file has a few columns that are read into a structure. It's convenient to read and simultaneously name the variables per a filename. For instance I read to a temp var then use the ill-advised exec capability to assign this to a variable specific to the file I read in. Looping, I read all files in the dir efficiently. 'files' is a cell array of file names discovered in that directory....

tmp = table(dataArray{1:end-1}, 'VariableNames', {'max_mag','max_noise','max_cnt'}); eval([files{i} '=tmp'])

I do see where this is not good for general variable naming, but I believe there's a niche usage in this case. Opinions? Best, Jerry

Stephen Cobeldick
on 28 Apr 2018

*" It's convenient to read and simultaneously name the variables per a filename."*

A structure would be simpler, as well as be more efficient and easier to debug:

S.(files{i}) = table(...);

Or simply store the tables themselves in a cell array, and keep the corresponding `files` data in another cell array: this would be trivial to achieve using indexing, and also has the significant advantage that then the `files` data are not restricted to valid field/variable names.

Or just use one table, and add a `files` column to distinguish between the different cases.

*"I do see where this is not good for general variable naming"*

How do you then access those dynamically defined variables? Your *"niche case"* does not see to be any different to any of the other cases that have been described on this forum: can you explain why writing slow, complex code is better than using a simple structure, like I showed? Or better than using very simple (and very efficient) indexing?

*"but I believe there's a niche usage in this case"*

So far you have not actually described anywhere in your answer *why* it is necessary to dynamically create/access variable names: other methods would also store your data more efficiently than what you have shown, and you have not given any reason why none of those methods would work.

Jan
on 30 Apr 2018

I cannot emphasize it enough how important Stephen's suggestions are. Creating the variables dynamically impedes the JIT acceleration massively, such that the complete function can runs ways slower, not just the line containing these variables. The JIT must be able to handle the case, that one of the "files{i}" is called "plot". Afterwards `plot` is not a command anymore, but a `table` object. To catch such problems, all function calls must be checked *manually* if they have been overwritten dynamically.

Using dynamic field names instead by `S.(files{i})=table(...)` is safe and efficient. In addition reading the code allows to identify these variables directly: If I find "S.function" in the source code, I know where it is coming from, while for a simple "function" I cannot be sure, if this is a typo or a dynamically created variable. The editor cannot distinguish this also and will assume an illegal definition of a function. Such strange effect can never happen with dynamic field names.

Summary: No, there is no niche for dynamically created variables. `eval` is a shot in your knee. Sometimes it does not hurt immediately, but the later it starts to bite you, the harder it will be to clean up the code.

This has been discussed exhaustively in the links, Stephen has posted in his answer above. Believe him and the bunch of corresponding threads.

Jerry
on 12 Aug 2018 at 12:55

Hi Stephen, I'll give the idea of provide parallel constructs where the file-specific variable references are in one cell while data is collected in structure. I've shifted in the last month or so to use python for preprocessing - so this problem has largely gone away and been replaces with xlsread, csvread etc.

>>files data are not restricted to valid field/variable names

My file names are conventionally, ascii with underscores and timestamps yyyymmdd_hhmmss type, so I do see where this is problem.
They are pretty specific so I **thought** I was giving a concrete counter example in contrast to @Italo and @Muna, who started this thread naming generic matrices.

>>you have not given any reason why none of those methods would work.

You're absolutely correct. I latched onto that solution as it was elegant for what I needed.

Thanks for the interaction, best, Jerry

Sign in to comment.

Answer by César Silva Proaño
on 12 Aug 2018 at 3:04

Hi, look I was doing something similar in order to create a function with the Krammer Method, for solving any size of matrix-equation problem. Look I created a function in order to do this, therefore, I needed to do it automatically, creating variables dinamically. Look at this fucntion.

function [ X ] = funcionMetodoKrammer( A ) %UNTITLED Summary of this function goes here % Detailed explanation goes here

% ex: A = [-3 2 1 10;5 -8 3 15;-8 -9 10 20]; sizeA = size(A); sizeFilasA = sizeA(1,1); sizeColumnasA = sizeA(1,2); matrizASinResultado = A(1:sizeFilasA,1:sizeFilasA); matrizResultados = A(:,sizeColumnasA);

if (sizeFilasA == sizeColumnasA - 1) for (i = 1:sizeColumnasA) genvarname('matrizColumna', num2str(i)); eval(['matrizColumna' num2str(i) '=A(:,i)']); end

for (i = 1:sizeFilasA) genvarname('matrizTemporalColumna', num2str(i)); eval(['matrizTemporalColumna' num2str(i) '=matrizASinResultado(:,i)']); end

matrizIncognita1 = [matrizResultados,matrizASinResultado(:,2:sizeFilasA)];

for (i = 2:sizeFilasA) genvarname('matrizIncognita', num2str(i)); eval(['matrizIncognita' num2str(i) '=[matrizASinResultado(:,1:i- 1),matrizResultados,matrizASinResultado(:,i+1:sizeFilasA)]']); end

else msgbox('La matriz ingresada para el método Krammer es incorrecta'); end

for (i = 1:sizeFilasA) genvarname('X', num2str(i)); genvarname('matrizIncognita', num2str(i)); eval(['X' num2str(i) '= det(matrizIncognita' num2str(i) ')/det(matrizASinResultado)']); end

X = zeros(1,sizeFilasA); for (i = 1:sizeFilasA) genvarname('X', num2str(i)); eval(['X' '(1,' num2str(i) ')=X' num2str(i)]); end

end

%{ Asuminedo que existen variables B1, B2 y B3 se pueden acceder a las variables de la siguiente manera

B1 = 10; B2 = 11; B3 = 12;

for (i = 1:3) genvarname('Prueba', num2str(i)); genvarname('B', num2str(i)); eval(['Prueba' num2str(i) '=' 'B' num2str(i) '+10']); end %}

I strongly disagree with the idea that you shouldn't use this because, if it exists I mean why not? It is not prohibited, and additionally it is very helpful in some cases.

Regards,

Sebastián

César Silva Proaño
on 12 Aug 2018 at 6:57

Thanks for the feedback. But I can see that in every post, in which this question about the generation of dinamic variables with eval and genvarname is lauched, you just attack this method and you do not present an formal solution. Thanks for the critics, yes in fact, that code is not the final one. This is the one:

function [X] = funcionMetodoKrammer(A) %{ Esta función resuelve un sistema se ecuaciones lineales con el método de Krammer, se debe ingresar una matriz de tamaño n x n+1, es decir la parte n x n contiene los valores de x1, x2, etc, y la columna n+1 tiene los valores resultado de cada ecuación. %}

% ex: A = [-3 2 1 10;5 -8 3 15;-8 -9 10 20];

sizeA = size(A); sizeFilasA = sizeA(1,1); sizeColumnasA = sizeA(1,2); matrizASinResultado = A(1:sizeFilasA,1:sizeFilasA); matrizResultados = A(:,sizeColumnasA);

if (sizeFilasA == sizeColumnasA - 1) % Aquí se forman las matrices para cada respuesta: matrizIncognita1 = [matrizResultados,matrizASinResultado(:,2:sizeFilasA)];

for (i = 2:sizeFilasA) genvarname('matrizIncognita', num2str(i)); eval(['matrizIncognita' num2str(i) '=[matrizASinResultado(:,1:i-1),matrizResultados,matrizASinResultado(:,i+1:sizeFilasA)]']); end

% Se determinan las respuestas for (i = 1:sizeFilasA) genvarname('X', num2str(i)); genvarname('matrizIncognita', num2str(i)); eval(['X' num2str(i) '= det(matrizIncognita' num2str(i) ')/det(matrizASinResultado)']); end

% Ahora se determina el vector con las respuestas: X = zeros(1,sizeFilasA); for (i = 1:sizeFilasA) genvarname('X', num2str(i)); eval(['X' '(1,' num2str(i) ')=X' num2str(i)]); end

% En caso de que la matriz ingresada sea incorrecta: else msgbox('La matriz ingresada para el método Krammer es incorrecta'); end

end

It seems that you have a personal issue with this form of approaching the dinamic generation of variables. Perhaps you are an excellent Matlab user, so why don't you give us an enlightening solution for this problem, instead of criticizing?

The question should be, how do you generate dinamic variables?

But please make us all a favor and present a code, not just words or links, because as my previous code, that is useless for people who want to learn matlab in a good manner. And yes, I am a beginner in this program, that is why perhaps I can commit mistakes, but I beg my pardon, everyone can make mistakes, specially me and others who are not so smart as you ;) Regards,

Stephen Cobeldick
on 12 Aug 2018 at 7:09

*"...you just attack this method..."*

Because that method is pointlessly slow, pointlessly inefficient, and pointlessly complex.

*"...and you do not present an formal solution."*

We seem to have cross-posted.

Please see my previous comment, where I presented you with my version of your function: much simpler, much more efficient, more than one hundred times faster, no `eval`. Exactly the same output.

You will also find that two years ago I presented several *"formal solutions"* as alternatives to dynamic variable names, here, in this tutorial:

Exactly as I wrote two years ago in that tutorial, using efficient MATLAB indexing is the *"formal solution"* that I used to create a much more efficient version of your function. That tutorial was linked to at the top of this thread, for everyone to read. In my tutorial you will find links to many blogs and threads: plenty of other people have written on this topic as well... because the fact that *dynamically accessing variables names is inefficient* was not invented by me!

*"so why don't you give us an enlightening solution for this problem, instead of criticizing?"*

See my previous comment.

*"But please make us all a favor and present a code, not just words or links, because as my previous code, that is useless for people who want to learn matlab in a good manner.*"

See my previous comment.

*"It seems that you have a personal issue with this form of approaching the dinamic generation of variables."*

Not really, I just like writing good code. And I read the MATLAB documentation: *"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"*

source: https://www.mathworks.com/help/matlab/matlab_prog/string-evaluation.html

If you *"...want to learn matlab in a good manner"* then you can also read the MATLAB documentation.

*"that is why perhaps I can commit mistakes, but I beg my pardon, everyone can make mistakes, specially me and others who are not so smart as you"*

I make mistakes, you make mistakes, we all make mistakes. That is why computer programmers have developed lots of useful code checking tools that check the code syntax while you type, check function calling syntaxes, etc.. None of these tools work with the strings inside `eval`. So if you want to avoid mistakes, then these tools can help... as long as you don't use `eval`!

*"The question should be, how do you generate dinamic variables?"*

I don't.

Walter Roberson
on 13 Aug 2018 at 7:10

César Silva Proaño:

Imagine that you were building a bird house by using a beer bottle to hammer in nails. You get *something* made and present it to us as a model for how to make bird houses.

Imagine that we notice that you used the wrong *size* of nails for the materials, that you used the wrong *kind* of nails for the materials, that using a beer bottle as a hammer is dangerous, and that our considered experience is that it is a lot better to build bird houses with screws instead of with nails.

In those circumstances, should we advise you to use screws and a screwdriver instead of nails, or should we refrain from saying anything, seeing as you created a birdhouse that looks good enough to you? Should we just shrug our shoulders about the dangers of bottles shattering in hands when used as hammers, figuring that people will eventually figure it out for themselves?

Sign in to comment.

Opportunities for recent engineering grads.

Apply Today
## 2 Comments

## Muna (view profile)

Direct link to this comment:https://www.mathworks.com/matlabcentral/answers/105936-how-to-make-dynamic-variable-names-a1-a2-an-with-for-loop-using-eval-num2str#comment_191573

## Stephen Cobeldick (view profile)

Direct link to this comment:https://www.mathworks.com/matlabcentral/answers/105936-how-to-make-dynamic-variable-names-a1-a2-an-with-for-loop-using-eval-num2str#comment_510894

@Muna: you should read this:

https://www.mathworks.com/matlabcentral/answers/304528-tutorial-why-variables-should-not-be-named-dynamically-eval

Sign in to comment.