Store matrices under different variable names within a loop?

I have a 4 by 16 matrix, say mat, and it can be random for this example. I would like to convert it into four seperate 4 by 4 matricies, where the first row of mat is reshaped into the first 4 by 4 matrix.
At the moment I have this code...
mat = randi([0, 9], [4,16])
for k = 1:size(mat,1)
vec = mat(k,:);
A = reshape(vec,[4,4]);
end
This achieves what I would like it to, however it stores all four of the matricies under A, so after it has run I can only access the fourth matrix.
Is there an efficient way to title the four matricies seperately so I can access them all?

1 Comment

"Is there an efficient way to title the four matricies seperately so I can access them all?"
Yes, by allocating them explicitly to four variables:
A = ...
B = ...
C = ...
D = ...
Although some beginners use assignin, evalin, eval etc., none of these are efficient. Your basic concept of dynamically defining variable names is fundementally inefficient, slow, obfuscated, liable to bugs, and difficult to debug.
Usually the best solution is to NOT split up data, but to use MATOLAB efficient indexing, grouping, etc. methods.

Sign in to comment.

 Accepted Answer

Make A a 4x4x4 three-dimensional matrix instead of creating multiple 4x4 matrices:
mat = randi([0, 9], [4,16])
A = zeros(4,4,4); % allocate space for A and set the size
for k = 1:size(mat,1)
vec = mat(k,:);
A(:,:,k) = reshape(vec,[4,4]);
end
A % check results
Note that if you want the elements in the rows of A to be filled from mat in order, instead of filling first into the columns of A, transpose the output of the reshape command like this:
A(:,:,k) = reshape(vec,[4,4])';
Experiment to make sure you get what you want/expect.

4 Comments

Thank you for your answer Les Beckham, I have managed to achieve it using assignin.
Your tip for transposing the output using the appostrophy is very handy for me as well and now I can tidy up my code a bit :)
I'm glad that you are satisfied. However, there are a lot of reasons why using creating separately named variables is not the best way to do this.
As an example, what if you wanted to create a vector containing the averages of the first columns of each of your 4x4 matrices. Using the multiple dynamically named variables you will have to do something like this:
averages = [mean(A1(1,:)) mean(A2(1,:)) mean(A3(1,:)) mean(A4(1,:))]
Using a 3d array for A instead, it is easy
averages = squeeze(mean(A(1,:,:))) % squeeze collapses the result to a 1 dimensional vector
Hopefully you can see that the separately named variables don't scale well if you decide to change to five 4x4 matrices instead, for example. You will have to remember to change the above calculation of the averages to add the mean(A5(1,:)) term. Using the 3d array, you don't have to change anything but the code that constructs it. The code that uses/accesses it doesn't have to change.
I ran into problems down the line when using assignin within appdesigner and used your method instead. It worked great! Thank you :)
You are welcome. Glad I could help.

Sign in to comment.

More Answers (0)

Categories

Find more on Loops and Conditional Statements in Help Center and File Exchange

Products

Release

R2019a

Community Treasure Hunt

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

Start Hunting!