Transfer values of Matrix to a specific Position in another Matrix

7 views (last 30 days)
Hello,
I have different matrices (all 4x4) that get created by a for loop. I want to add the values of these matrices to specific positions of another matrix (8x8). To give you thematic context: The 5 matrices (4x4) are stifness matrices of each element of a truss system and I want to add them up to get the stiffness matrix of the whole truss system (2D).
Here as an example on how I want to arange the values of the first matrix:
K_l = [1:4; 5:8; 9:12; 13:16]
K_test = zeros(8,8)
K_test(1:2,1:2)=K_l(1:2,1:2)
K_test(5:6,1:2)=K_l(3:4,1:2)
K_test(1:2,5:6)=K_l(1:2,3:4)
K_test(5:6,5:6)=K_l(3:4,3:4)
Is there a way to fill the matrix "smarter"? Maybe in the loop itself?
These are the 5 matrices I'm creating and all of those I want to rearange in a matrix of 8 x 8:
L = 13; % [m]
Theta_1 = 15; % [°]
Theta_2 = Theta_1+15;
A_hat = 500*10^-6; % [m^2]
A_AB = A_hat;
A_BD = A_AB;
A_AC = 2*A_hat;
A_CD = A_AC;
A_BC = 3*A_hat;
phi_v = [30; -30; -90; 15; -15] % [%]
A_v = [A_AC; A_CD; A_BC; A_AB; A_BD] % [m^2]
E = 2.1*10^11;
L_1 = L/(cosd(Theta_2)*2); % [m]
L_2 = L_1;
L_3 = L/2*(tand(Theta_2)-tand(Theta_1));
L_4 = L/(cosd(Theta_1)*2);
L_5 = L_4;
L_v = [L_1; L_2; L_3; L_4; L_5]
for i = 1:5
K_l = [cosd(phi_v(i))^2 cosd(phi_v(i))*sind(phi_v(i)) -cosd(phi_v(i))^2 -cosd(phi_v(i))*sind(phi_v(i));
cosd(phi_v(i))*sind(phi_v(i)) sind(phi_v(i))^2 -cosd(phi_v(i))*sind(phi_v(i)) -sind(phi_v(i))^2;
-cosd(phi_v(i))^2 -cosd(phi_v(i))*sind(phi_v(i)) cosd(phi_v(i))^2 cosd(phi_v(i))*sind(phi_v(i));
-cosd(phi_v(i))*sind(phi_v(i)) -sind(phi_v(i))^2 cosd(phi_v(i))*sind(phi_v(i)) sind(phi_v(i))^2];
K_l = ((E*A_v(i))/L_v(i))*K
end
Best Regards
  2 Comments
dpb
dpb on 7 Nov 2021
Create set of indices to the starting location of each to use as lookup in the loop.
Not exactly sure where each goes from the above description; looks like they may actually be split and not contiguous from the initial example? If that is so, then need to have the pointers to the subspaces, not just the start. In that case it might well be simpler to not generate the full array but the individual pieces that are contiguous instead...
K_l = ...
[cosd(p(i))^2 cosd(p(i))*sind(p(i)) -cosd(p(i))^2 -cosd(p(i))*sind(p(i));
cosd(p(i))*sind(p(i)) sind(p(i))^2 -cosd(p(i))*sind(p(i)) -sind(p(i))^2;
-cosd(p(i))^2 -cosd(p(i))*sind(p(i)) cosd(p(i))^2 cosd(p(i))*sind(p(i));
-cosd(p(i))*sind(p(i)) -sind(p(i))^2 cosd(p(i))*sind(p(i)) sind(p(i))^2];
I shortened variable name down to just p for the angle and lined the terms up for legibility -- now which pieces go where in the end?
One can also create temporaries for the terms that are recomputed; a first step in that direction is--
cd=cosd(p(i));
sd=sind(p(i));
K_l = ...
[sd.^2 cd*sd -cd.^2 -cd*sd;
cd*sd sd.^2 -cd*sd -sd.^2;
-cd.^2 -cd*sd cd.^2 cd*sd;
-cd*sd -sd.^2 cd*sd sd.^2];
The products and squared terms could also be precomputed and just substituted as well.
Sven Markus
Sven Markus on 8 Nov 2021
Edited: Sven Markus on 8 Nov 2021
Thank the suggestions you made makes it definitly more clear!
The arranegment of the 5 matrices should be like this (The values should also add up):
Row/Column Index of matrix 8x8
Matrix 1: 1 2 5 6
Matrix 2: 5 6 7 8
Matrix 3: 3 4 5 6
Matrix 4: 1 2 3 4
Matrix 5: 3 4 7 8

Sign in to comment.

Accepted Answer

Matt J
Matt J on 7 Nov 2021
Edited: Matt J on 7 Nov 2021
K_l = [1:4; 5:8; 9:12; 13:16];
K_test = zeros(8,8);
K_test([1,2,5,6], [1,2,5,6])=K_l
K_test = 8×8
1 2 0 0 3 4 0 0 5 6 0 0 7 8 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 9 10 0 0 11 12 0 0 13 14 0 0 15 16 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

More Answers (0)

Community Treasure Hunt

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

Start Hunting!