Balraj Boyal
Balraj Boyal

Reputation: 155

Splitting non-continuous sized matrix in vectors

I'm writing an piece of software within Matlab. Here, the user can define a dimension say 3.

This dimension is subsequently the number of iterations of a for loop. Within this loop, I construct a matrix to store the results which are generated during every iteration. So, the data of every iteration is stored in a row of a matrix.

Therefore, the size of the matrix depends on the size of the loop and thus the user input.

Now, I want to separate each row of this matrix (cl_matrix) and create separate vectors for every row automatically. How would one go on about? I am stuck here...

So far I have:

Angle = [1 7 15];
for i = 1:length(Angle)
    %% do some calculations here %%
    cl_matrix(i,:) = A.data(:,7);
end

I want to automate this based on the length of Angle:

length(Angle)
cl_1 = cl_matrix(1,:);
cl_7 = cl_matrix(2,:);
cl_15= cl_matrix(3,:);

Thanks!

Upvotes: 0

Views: 67

Answers (1)

il_raffa
il_raffa

Reputation: 5190

The only way to dynamically generate in the workspace variables variables whos name is built by aggregating string and numeric values (as in your question) is to use the eval function.

Nevertheless, eval is only one character far from "evil", seductive as it is and dangerous as it is as well.

A possible compromise between directly working with the cl_matrix and generating the set of array cl_1, cl_7 and cl_15 could be creating a structure whos fields are dynamically generated.

You can actually generate a struct whos field are cl_1, cl_7 and cl_15 this way:

cl_struct.(['cl_' num2str(Angle(i))])=cl_matrix(i,:)

(you might notice the field name, e. g. cl_1, is generated in the same way you could generate it by using eval).

Using this approach offers a remarkable advantage with respect to the generation of the arrays by using eval: you can access to the field od the struct (that is to their content) even not knowing their names.

In the following you can find a modified version of your script in which this approach has been implemented.

The script generate two structs:

  • the first one, cl_struct_same_length is used to store the rows of the cl_matrix
  • thesecond one, cl_struct_different_length is used to store arrays of different length

In the script there are examples on how to access to the fileds (that is the arrays) to perform some calculations (in the example, to evaluate the mean of each of then).

You can access to the struct fields by using the functions:

  • getfield to get the values stored in it
  • fieldnames to get the names (dynamically generated) of the field

Updated script

Angle = [1 7 15];
for i = 1:length(Angle)
   % do some calculations here %%
% % %   cl_matrix(i,:) = A.data(:,7);
   % Populate cl_matrix
    cl_matrix(i,:) = randi(10,1,10)*Angle(i);
    % Create a struct with dinamic filed names
    cl_struct_same_length.(['cl_' num2str(Angle(i))])=cl_matrix(i,:)
    cl_struct_different_length.(['cl_' num2str(Angle(i))])=randi(10,1,Angle(i))
end
% Use "fieldnames" to get the names of the dinamically generated struct's field
cl_fields=fieldnames(cl_struct_same_length)
% Loop through the struct's fileds to perform some calculation on the
% stored values
for i=1:length(cl_fields)
   cl_means(i)=mean(cl_struct_same_length.(cl_fields{i}))
end
% Assign the value stored in a struct's field to a variable
row_2_of_cl_matrix=getfield(cl_struct_different_length,(['cl_' num2str(Angle(2))]))

Hope this helps.

Upvotes: 2

Related Questions