How to make a matrix based on other values in a matrix that 'match'
6 vues (au cours des 30 derniers jours)
Afficher commentaires plus anciens
Hi, I'm trying to create a matrix that is based on the values of another matrix and based on the number positioning of it's current matrix.
Here is where we start (MatrixONE):
The above matrix was done with the help of Stephen Cobeldick.
These are the values I require (MatrixTWO):
[ 1 100 120 ; 2 200 240 ; 3 300 360 ; 4 400 480 ]
For example, in the first row, first column. There is a value of 2. This value needs to collect the value from the second row, second column of MatrixTWO (Which is 200). Now in the first row of the second column is also a value of 2. However that value needs to collect the value 240. With negative numbers, they do the exact same thing but make the number negative. I've provided a picture of what the output should look like.
This is what the output should look like (MatrixTHREE):
One final note: This cannot be hard coded and must work 'universally'. This is where I get completely thrown off course.
I look forward to reading some answers!
0 commentaires
Réponse acceptée
Stephen23
le 23 Avr 2018
Modifié(e) : Stephen23
le 23 Avr 2018
>> M1 = [1,2;2,3;3,4;1,3;1,4]
M1 =
1 2
2 3
3 4
1 3
1 4
>> M2 = [1,100,120;2,200,240;3,300,360;4,400,480]
M2 =
1 100 120
2 200 240
3 300 360
4 400 480
>> tmp = M1.'; % because MATLAB operates down columns
>> idx = tmp~=1; % input logical indices
>> [~,idc] = find(idx); % output column indices
>> idr = tmp(idx)-1; % output row indices
>> mat = zeros(max([idr,idc])); % preallocate the intermediate matrix
>> M3a = mat; % preallocate output matrix (a).
>> M3b = mat; % preallocate output matrix (b).
>> idi = sub2ind(size(mat),idr,idc); % output linear indices
>> tmp(1,:) = -tmp(1,:); % first row negative (first column of M)
>> mat(idi) = tmp(idx); % assign input values to intermediate matrix
>> idn = sign(mat); % get data signs.
>> [idm,idy] = ismember(abs(mat),M2(:,1)); % find indices of mat in M2.
>> idz = idy(idm);
>> M3a(idm) = M2(idz,2) % allocate M2 to output (a)
M3a =
200 200 0 0 0
0 300 300 300 0
0 0 400 0 400
>> M3b(idm) = M2(idz,3) % allocate M2 to output (b)
M3b =
240 240 0 0 0
0 360 360 360 0
0 0 480 0 480
>> M3 = reshape([M3a.*idn,M3b.*idn].',size(mat,2),[]) % concatenate and reshape
M3 =
200 240 0 0 0 0
-200 -240 300 360 0 0
0 0 -300 -360 400 480
0 0 300 360 0 0
0 0 0 0 400 480
Plus de réponses (1)
Jan
le 23 Avr 2018
Modifié(e) : Jan
le 23 Avr 2018
Let's call the matrices A, B, C.
B = [ 1 100 120 ; 2 200 240 ; 3 300 360 ; 4 400 480 ];
% Remove the sign at first:
negA = (A < 0);
A = abs(A);
C = zeros(size(A)); % Pre-allocate
odd = rem(1:size(A, 2), 2);
for iB = 1:size(B, 1)
index = (A == B(iB, 1));
C(index & odd) = B(iB, 2);
C(index & ~odd) = B(iB, 3);
end
% Consider the sign:
C(negA) = -C(negA);
2 commentaires
Jan
le 23 Avr 2018
This is impossible, when your input "MatrixONE" is a 5x6 matrix. Please post the data such that they can be used by copy&paste. The screenshot is nice, but it cannot be used directly.
A = [ 2, 2, 0, 0, 0, 0; ... -2, -2, 3, 3, 0, 0; ... 0, 0, -3, -3, 4, 4; ... 0, 0, 3, 3, 0, 0; ... 0, 0, 0, 0, 4, 4];
With this input I get exactly the wanted output:
C = 200 240 0 0 0 0 -200 -240 300 360 0 0 0 0 -300 -360 400 480 0 0 300 360 0 0 0 0 0 0 400 480
It seems like you have defined the input as
A = [1,2;2,3;3,4;1,3;1,4]
in opposite to your question.
Voir également
Catégories
En savoir plus sur Creating and Concatenating Matrices dans Help Center et File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!