Putting the result from eval into a cell array

13 views (last 30 days)
Got the piece of code below. Basically, when I run it I get x_1 all the way to x_600 so i get 600 outputs I would like to put all of these into a cell array does anyone know how to do this cause I've failed at every attempt?
count=1;
for i=1:600
G = [ F(i)+1 , F(i+1) ];
a = unwrap(B);
eval(['x_' num2str(count) ' = a;']);
count=count+1;
end

Answers (2)

Stephen23
Stephen23 on 21 Jul 2019
Edited: Stephen23 on 21 Jul 2019
N = 600;
C = cell(1,N); % preallocate.
for k = 1:N
G = [F(k)+1,F(k+1)]; % you never use G anywhere in your code...
C{K} = unwrap(B); % where is B defined?
end
"...I've failed at every attempt"
Because you picked a complex, slow, inefficient approach (using eval to create lots of variables), as opposed to simply using a cell array in the first place.
  9 Comments
TADA
TADA on 21 Jul 2019
Edited: TADA on 21 Jul 2019
This example shows how using eval is unnecessary
% create mock data
B = linspace(0, 10*pi(), 20)';
C = (1:numel(B))';
C(randi(18, 1, 3)) = 0; % randomly pop zeros in there to start new batches
% find all batches start and end points
[ D, E ] = find( C == 0 ); % D when zero occuers so batch starts
if D(1) ~= 1
D = [1; D]; % start from first index no matter what...
end
F = [D - 1; numel(B)]; % F when batch finishes
% if you need it for something...
count = numel(D);
% prepare cell array with cells for all detected batches
x=cell(1, count);
% iterate through all batches and extract the data into cell array "x"
for i=1:count
G = [ F(i)+1 , F(i+1) ]; % finding the begining and last point of each group
% do your calculation - this line of code is perfectly fine,
% although, the data could be stored directly into the cell array
% instead of the temporary variable "a"
a = unwrap(B(G(1):G(2),:)/2^15*pi)*2^15/pi;
% this will set the output of your calculation directly into the cell array
x{i} = a;
% this will needlessly declare a new variable called "x_i"
% where i is the current index
eval(['x_' num2str(i) ' = a;']); % Splits the outputs of the unwrap into seperate batches
end
celldisp(x);
x{1} =
0
1.6535
3.3069
4.9604
x{2} =
6.6139
8.2673
9.9208
x{3} =
11.5743
13.2278
14.8812
16.5347
18.1882
19.8416
21.4951
x{4} =
23.1486
24.8020
26.4555
28.1090
29.7625
31.4159
for i = 1:count
fprintf('x_%d: ', i);
fprintf('%d,', eval(['x_' num2str(i)]));
disp(newline);
end
x_1: 0,1.653470e+00,3.306940e+00,4.960409e+00,
x_2: 6.613879e+00,8.267349e+00,9.920819e+00,
x_3: 1.157429e+01,1.322776e+01,1.488123e+01,1.653470e+01,1.818817e+01,1.984164e+01,2.149511e+01,
x_4: 2.314858e+01,2.480205e+01,2.645552e+01,2.810899e+01,2.976246e+01,3.141593e+01,
TADA
TADA on 21 Jul 2019
Edited: TADA on 21 Jul 2019
If you store data sets in arrays instead of indexed variables, you get only benefits:
  • Less code which is more readable:
x{i} = unwrap(B(G(1):G(2),:)/2^15*pi)*2^15/pi;
% instead of
count = count+1;
a = unwrap(B(G(1):G(2),:)/2^15*pi)*2^15/pi;
eval(['x_' num2str(count) ' = a;']);
  • No need to maintain a variable which counta your variables, simply use size(x) or numel(x)
  • No workspace spamming with 600 variables, theres only one cell array,matrix,table,etc. So you can actually see what variables you have in your workspace window.
  • Indexing performs way better than eval, several orders of magnitude better in fact
a = 1:100;
tic;
for i = 1:10000;
x{i} = a;
end;
toc;
Elapsed time 0.002012 seconds
tic;
for i = 1:10000;
eval(['x_' num2str(i) ' = a;']);
end;
toc;
Elapsed time is 3.508633 seconds

Sign in to comment.


TADA
TADA on 21 Jul 2019
please please please don't use eval to access varriable names
eval is not built for that, however, for some reason the first thing that new programmers of any scripting language learn is to use eval which results in code which is confusing, performs poorly and is impossible to decypher and maintain
remember the rule, eval is evil.
if you remember that and only result to using eval when you realy have to (i.e. never!), your programing would improve dramatically.
the good practice in that case would be to use matrices to store your data instead of separate variables (i.e X1 X2 X3), or if they are different sizes a cell array
% same size:
x = zeros(3, 100);
x(1,:) = 1:100;
x(2,:) = 101:200;
x(3,:) = 201:300;
% different sizes:
x = {};
x{1} = 1:100;
x{2} = 1:1000;
x{3} = 1:10000;
Now, if that piece of code was given to you by some blackbox script written by someone else and it requires hundreds of hours of rewriting, I agree the correct way to handle this would be to use eval and export the data into a reasonable format:
% code you got from someone else
X1 = 1:100;
X2 = 1:1000;
X3 = 1:10000;
% code that accesses these variables and fixes that
c = {};
for i = 1:3
c{i} = eval(['X' num2str(i)]);
end

Community Treasure Hunt

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

Start Hunting!