Reputation: 3137
When I answered this question, my answer started with: "For starters, you can get rid of all the if-statements by storing all the names in a cell."
The "For starters" bit was because I thought that I could add an edit with a vectorized solution. But when I tried to do so I ran into trouble vectorizing the use of mrdivide (b/a).
My question (marked below in the code) is if it is possible to solve b(z,:)/a(z,:)
without using a loop. In other words, to solve b/a
independently for each row of the matrices.
person = [98 206 35 114;
60 206 28 52;
100 210 31 116;
69 217 26 35;
88 213 42 100];
person1 = [93 208 34 107];
allNames = {'Cameron'; 'David'; 'Mike'; 'Bill'; 'Joe'};
n = 5;
a = max(person,repmat(person1,n,1));
b = min(person,repmat(person1,n,1));
for z = 1:5
percent_error = b(z,:)/a(z,:); %// Here is my question
if percent_error >= 0.85
disp(['Match, its ', allNames{z} ,'!'])
end
end
Upvotes: 0
Views: 109
Reputation: 32930
You can indeed eliminate the loop by vectorizing the operation. The trick is working with diagonal block matrices. Each block is matrix with only one row (each time a different row). After you create such a block matrix for a
and for b
, you can use mrdivide
:
% # Without loop
tic
A = zeros(size(a) * size(a, 1));
B = zeros(size(b) * size(b, 1));
V = ones(size(a, 2), 1) * (1:size(a, 1));
idx = (0:size(A, 1):numel(A) - 1) + (V(:)' - 1) * size(a, 1) + 1;
A(idx) = a';
B(idx) = b';
X = diag(B / A);
percent_error1 = X(1:size(a, 1):end);
toc
% # With loop
tic
percent_error2 = zeros(5, 1);
for z = 1:5
percent_error2(z) = b(z,:) / a(z,:);
end
toc
The result is:
Elapsed time is 0.000160 seconds.
Elapsed time is 0.000048 seconds.
percent_error1 =
0.9741
0.8516
0.9670
0.8221
0.9611
percent_error2 =
0.9741
0.8516
0.9670
0.8221
0.9611
Note that this is one of those cases where matrix division of large arrays takes longer than a for
loop.
Upvotes: 1
Reputation: 12544
I was thinking about this:
person/person1
But this would only give good result when every index in person is bigger than the corresponding index in person1.
Upvotes: 0