How to make a matrix based on other values in a matrix that 'match'
조회 수: 6 (최근 30일)
이전 댓글 표시
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
채택된 답변
Stephen23
2018년 4월 23일
편집: Stephen23
2018년 4월 23일
>> 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
추가 답변 (1개)
Jan
2018년 4월 23일
편집: Jan
2018년 4월 23일
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
Jan
2018년 4월 23일
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.
참고 항목
카테고리
Help Center 및 File Exchange에서 Creating and Concatenating Matrices에 대해 자세히 알아보기
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!