How to efficiently compare two matrix to get a single reference value?

1 view (last 30 days)
May I know how make the following code more efficient and compact. Specifically, I want to reduce the line
ConfMat (logical (((TrueVal==xx) .*(Predicted==xx))))=xx;
Here are the complete code and its output
TrueVal= [1 1 1 2 2 2 3 3 3 1 2]';
Predicted=[1 2 3 1 2 3 1 2 3 3 2]';
ConfMat = single(ones(length(TrueVal), 1));
ConfMat (logical (((TrueVal==1) .*(Predicted==2))))=4;
ConfMat (logical (((TrueVal==1) .*(Predicted==3))))=7;
ConfMat (logical (((TrueVal==2) .*(Predicted==1))))=2;
ConfMat (logical (((TrueVal==2) .*(Predicted==2))))=5;
ConfMat (logical (((TrueVal==2) .*(Predicted==3))))=8;
ConfMat (logical (((TrueVal==3) .*(Predicted==1))))=3;
ConfMat (logical (((TrueVal==3) .*(Predicted==2))))=6;
ConfMat (logical (((TrueVal==3) .*(Predicted==3))))=9;
% Final output
% ConfMat= [1;4;7;2;5;8;3;6;9;7;5]
Thanks in advance
  3 Comments
balandong
balandong on 15 Jan 2019
Thanks both of you, I have the same idea about using for loop. I just wonder if there is an elegant ways of doing it.

Sign in to comment.

Accepted Answer

Rik
Rik on 15 Jan 2019
Edited: Rik on 15 Jan 2019
I don't know if this is elegant enough for you, but it does work.
TrueVal= [1 1 1 2 2 2 3 3 3 1 2]';
Predicted=[1 2 3 1 2 3 1 2 3 3 2]';
%legend: TrueVal Predicted value
matrix=[1 2 4
1 3 7
2 1 2
2 2 5
2 3 8
3 1 3
3 2 6
3 3 9];
ConfMat = single(ones(numel(TrueVal), 1));
for n=1:size(matrix,1)
xx_TrueVal=matrix(n,1);
xx_Predicted=matrix(n,2);
L=((TrueVal==xx_TrueVal) & (Predicted==xx_Predicted));
ConfMat(L)=matrix(n,3);
end
isequal(ConfMat,single([1;4;7;2;5;8;3;6;9;7;5]))
Or maybe you think this is a more elegant method:
TrueVal= [1 1 1 2 2 2 3 3 3 1 2]';
Predicted=[1 2 3 1 2 3 1 2 3 3 2]';
% %legend: TrueVal Predicted value
% matrix=[1 2 4
% 1 3 7
% 2 1 2
% 2 2 5
% 2 3 8
% 3 1 3
% 3 2 6
% 3 3 9];
% matrix=accumarray(matrix(:,1:2),matrix(:,3),[],[],1);
matrix = [...
1 4 7
2 5 8
3 6 9];
ConfMat = single(ones(numel(TrueVal), 1));
for n_true=1:size(matrix,2)
for n_pred=1:size(matrix,1)
L=((TrueVal==n_true) & (Predicted==n_pred));
ConfMat(L)=matrix(n_true,n_pred);
end
end
clc
isequal(ConfMat,single([1;4;7;2;5;8;3;6;9;7;5]))
  3 Comments
balandong
balandong on 17 Jan 2019
Hi Rik,
Thanks for the insight. It does look smart than my initial idea. However, the proposal by Bruno is somewhat more compact. I had to accept his answer for this.
Rik
Rik on 17 Jan 2019
@balandong no problem. Both solutions have their own situation where they are the best option. It is your code, and your question, so it is on you to choose.
Just in case someone else prefers my solution, I'll keep my answer here.

Sign in to comment.

More Answers (1)

Bruno Luong
Bruno Luong on 15 Jan 2019
TrueVal= [1 1 1 2 2 2 3 3 3 1 2]';
Predicted=[1 2 3 1 2 3 1 2 3 3 2]';
[ut,~,it] = unique(TrueVal);
[up,~,ip] = unique(Predicted);
ConfM = [1 4 7;
2 5 8;
3 6 9];
assert(size(ConfM,1)==length(ut),'ConfM must have same #rows than #TrueVal');
assert(size(ConfM,2)==length(up),'ConfM must have same #rows than #Predicted');
ConfMat = ConfM(sub2ind(size(ConfM),it,ip))
returns
ConfMat =
1
4
7
2
5
8
3
6
9
7
5

Community Treasure Hunt

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

Start Hunting!