How do I make a series of variables A1, A2, A3, ... A10?

169 Ansichten (letzte 30 Tage)
Doug Hull
Doug Hull am 18 Jan. 2011
Kommentiert: Collin Roesler am 7 Nov. 2023
How do I make variables like this in a loop?

Akzeptierte Antwort

Doug Hull
Doug Hull am 18 Jan. 2011
Please don't do this! You will find that MATLAB arrays (either numeric or cell) will let you do the same thing in a much faster, much more readable way. For example, if A1 through A10 contain scalars, use:
A = zeros(1,10); % Not necessary, just much faster
for i=1:10
A(i) = % some equation
end
Now refer to A(i) whenever you mean Ai. In case each Ai contains a vector or matrix, each with a different size, you want to use cell arrays, which are intended exactly for this:
for i=1:10
A{i} = 1:i;
end
Note that each A{i} contains a different size matrix. And be careful to use the curly braces for the subscript!
Another way to have your cake and eat it too is to use structures instead of cell arrays. The fields of the structure can be the variable names you want. And you can index into them with dynamic field references. For example:
names = {'fred' 'sam' 'al'};
for ind = 1:length(names)
s.(names{ind}) = magic(length(names{ind}));
end
In this case, you end up with the variable s, a structure, containing fields specified by the strings stored in the cell array names.
Now, if you still really want to create variables with dynamically generated names, you need to use EVAL. With EVAL, you use MATLAB commands to generate the string that will perform the operation you intend. For example, eval('A=10') has the same effect as A=10, and eval(['A' 'B' '=10']) has the same effect as AB=10, only the EVAL method executes much more slowly. So in a loop, you could use:
for i=1:10
eval(sprintf('A%d = [1:i]', i));
end
Notice how much more obfuscated this is. In addition, this can cause difficult-to-troubleshoot problems in your code, particularly if you try to dynamically create a variable with the same name as a function:
function y = mysin(x)
eval('sin = 5;');
y = sin(x);
Calling this function with "y = mysin(1)" will not return y = 5 (the first element of the sin variable created by EVAL) -- it will return the sine of 1, because when the function was parsed there was no variable named sin and so the usage of sin on the last line was parsed as a call to the built-in SIN function. The fact that a variable named sin existed at runtime is irrelevant; the parsetime "decision" takes precedence.
Repeat: don't create variables at runtime using EVAL unless you have a very good reason, such as someone gives you a MAT file with 2000 variables named A1428, for example. Even in that case, you can avoid EVAL:
% Assume the MAT-file example1.mat contains 2000 variables, A1 through A2000
S = load('example1.mat');
% S is now a struct array with 2000 fields, S.A1 through S.A2000.
% To access A1428, use:
x1 = S.A1428;
% If the "index" of the variable you want to access is stored in a variable:
k = 1428;
x2 = S.(sprintf('A%d', k));
x3 = S.(['A', num2str(k)]);
[From the MATLAB FAQ of Ancient Times]
  5 Kommentare
Matthew
Matthew am 19 Jul. 2013
Omg thanks so much. The structure did it nicely for me :)
Collin Roesler
Collin Roesler am 7 Nov. 2023
Thank you so much. This is perfect for my situation.

Melden Sie sich an, um zu kommentieren.

Weitere Antworten (2)

Pedro Inácio
Pedro Inácio am 14 Okt. 2017
Dear all, After read in different threads in Matlab forums, I found different solutions, which I believe they do not provide the real answer to: "Is possible to dynamically change variables names?"
The answer is Yes, and it does not need the use of eval.
I'm posting a solution to solve the question with comments step-by-step (It can be integrated in a for loop).
% NEW VARIABLE NAME
ID = 'new_NIF';
% FISCAL NUMBER SAVED IN MATLAB WORKSPACE
old_NIF = 555888222;
% CREATE A NEW PROVISORY STUCTURE
provisory_struct.(ID) = old_NIF;
% CREATE A NEW PROVISORY MAT FILE NAME
provisory_file_name = fullfile(pwd,'save_provisory_data.mat');
% SAVE THE PROVISORY STRUCTURE FIELDS AT THE
% PROVISORY MAT FILE
save(provisory_file_name,'-struct','provisory_struct');
% DELETE PROVISORY STRUCTURE VARIABLE
clear('provisory_struct');
% LOAD OUR NEW VARIABLE NAME
load(provisory_file_name,ID);
% DISPLAY NEW VARIABLE CONTENT
fprintf(1,'OLD NIF: %d\nNEW NIF: %d\n',old_NIF,new_NIF);
% DELETE PROVISORY FILE
delete(provisory_file_name);
I hope it was helpful.
  3 Kommentare
Stephen23
Stephen23 am 14 Okt. 2017
Bearbeitet: Stephen23 am 16 Okt. 2017
The function eval is not the problem, no matter how much you think it is.
The problem is creating or accessing dynamically named variables, because doing so causes code to be slow, buggy, obfuscated, hard to debug, insecure, etc, etc.
What you have proposed is a well known solution, and it shares all of the same problems as eval, evalin, assignin, because of what it does: it dynamically creates variables. It does not matter what function you use to magically create variables with, doing so will always cause the same problems. The method that you have proposed is incredibly slow (much slower than eval), because it copies all data from memory onto the drive, and then from the drive back into memory. Totally inefficient, a total waste of time.
You should read Steve Lord's comment on load-ing straight into the workspace:
A discussion on the disadvantages of loading directly into the workspace:
And how it is better to load directly into an output variable:
Summary do not magically "poof" variables into existence: Always load into a structure, and never create variable names dynamically.
Jan
Jan am 14 Okt. 2017
Bearbeitet: Jan am 15 Okt. 2017
@Perdro: Saving the data to a file and relaoding them directly into the workspace has exactly the same drawbacks as eval'ing it directly, but in addition a massive delay due to the slow disk access. Of course, it "works", as eval does also. But it causes more troubles than it solves.
This topic has been discussed frequently and exhaustively in many forums. Your idea, that these discussions "do not provide the real answer", is off track.

Melden Sie sich an, um zu kommentieren.


M.Devaki Mohanarangam
M.Devaki Mohanarangam am 14 Jun. 2023
Verschoben: Stephen23 am 14 Jun. 2023
X = Slopevalue
LP1 = sum(X(:)<-5)/numel(X)*100;
LP2 = sum(X(:)<-4)/numel(X)*100;
LP3 = sum(X(:)<-3)/numel(X)*100;
LP4 = sum(X(:)<-2)/numel(X)*100;
LP5 = sum(X(:)<-1)/numel(X)*100;
LP6 = sum(X(:)<0)/numel(X)*100;
Lc1 = LP1;
Lc2 = LP2-Lc1;
Lc3 = LP3-(Lc1+Lc2);
Lc4 = LP4-(Lc1+Lc2+Lc3);
Lc5 = LP5-(Lc1+Lc2+Lc3+Lc4);
Lc6 = LP6-(Lc1+Lc2+Lc3+Lc4+Lc5);
how to apply loop condtion in matlab code
  2 Kommentare
Stephen23
Stephen23 am 14 Jun. 2023
Bearbeitet: Stephen23 am 14 Jun. 2023
Your verbose approach with anti-pattern numbered variable names:
X = -9*rand(1,7)
X = 1×7
-2.6115 -1.4688 -2.1502 -4.2789 -7.1999 -6.1912 -4.5052
LP1 = sum(X(:)<-5)/numel(X)*100
LP1 = 28.5714
LP2 = sum(X(:)<-4)/numel(X)*100
LP2 = 57.1429
LP3 = sum(X(:)<-3)/numel(X)*100
LP3 = 57.1429
LP4 = sum(X(:)<-2)/numel(X)*100
LP4 = 85.7143
LP5 = sum(X(:)<-1)/numel(X)*100
LP5 = 100
LP6 = sum(X(:)<0)/numel(X)*100
LP6 = 100
Lc1 = LP1
Lc1 = 28.5714
Lc2 = LP2-(Lc1)
Lc2 = 28.5714
Lc3 = LP3-(Lc1+Lc2)
Lc3 = 0
Lc4 = LP4-(Lc1+Lc2+Lc3)
Lc4 = 28.5714
Lc5 = LP5-(Lc1+Lc2+Lc3+Lc4)
Lc5 = 14.2857
Lc6 = LP6-(Lc1+Lc2+Lc3+Lc4+Lc5)
Lc6 = 0
The simpler MATLAB approach using vectors:
LP = sum(X(:)<(-5:0),1)/numel(X)*100
LP = 1×6
28.5714 57.1429 57.1429 85.7143 100.0000 100.0000
LC = LP;
for k = 2:numel(LP)
LC(k) = LP(k)-sum(LC(1:k-1));
end
disp(LC)
28.5714 28.5714 0 28.5714 14.2857 0
The best approach:
LC = [LP(1),diff(LP)]
LC = 1×6
28.5714 28.5714 0 28.5714 14.2857 0
M.Devaki Mohanarangam
M.Devaki Mohanarangam am 14 Jun. 2023
thank you stephan i will check this code

Melden Sie sich an, um zu kommentieren.

Kategorien

Mehr zu Data Type Identification finden Sie in Help Center und File Exchange

Produkte

Community Treasure Hunt

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

Start Hunting!

Translated by