Asked by Nikolaos Zafirakis
on 21 Jul 2019

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

Answer by Stephen Cobeldick
on 21 Jul 2019

Edited by Stephen Cobeldick
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.

Nikolaos Zafirakis
on 21 Jul 2019

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
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.

Answer by 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

Sign in to comment.

Opportunities for recent engineering grads.

Apply Today
## 0 Comments

Sign in to comment.