MATLAB Answers

How to calculate determinant of matrices without loop?

23 ビュー (過去 30 日間)
I am new to Matlab and this might seem very easy.
I have 2 matrices:
a = [1 1 1; 2 2 2 ; 3 3 3 ; 4 4 4 ; 5 5 5];
b = [4 4 4; 3 2 4 ; 1 5 7 ; 4 3 8 ; 2 4 7];
I wanted to calculate the determinant of each row of the two matrices added by a row of ones (a 3*3 matrix), and put all the determinants in another array. For example, first determinant (d(1)) would be from this matrix:
1 1 1
4 4 4
1 1 1
and the second one (d(2)) would be from this matrix:
2 2 2
3 2 4
1 1 1
and so on...
When I try this:
m = size(a,1);
ons = ones(m,3);
d = det([a(:,:) ; b(:,:) ; ons(:,:)]);
I get this error:
Error using det
Matrix must be square.
How can I calculate all the determinants at once without using loop?

  7 件のコメント

表示 4 件の古いコメント
James Tursa
James Tursa 2019 年 10 月 9 日
Well, for this particular example, the result is simply
d = [0,0,0,0,0];
because all the rows of a are multiples of [1 1 1]
Hadi Ghahremannezhad
Hadi Ghahremannezhad 2019 年 10 月 9 日
You are right. But when I use:
d = arrayfun(@(x)det([a(x,:);b(x,:);ones(1,3)]),1:length(a));
the result is:
1.0e-15 *
0 0 -0.3331 0 0.8327
Rik
Rik 2019 年 10 月 10 日
There are 16 orders of magnitude between input and output. That is fairly close to eps, so this could be a float rounding error (and it is).

サインイン to comment.

採用された回答

Bruno Luong
Bruno Luong 2019 年 10 月 10 日
a(:,1).*b(:,2)-a(:,2).*b(:,1)-a(:,1).*b(:,3)+a(:,3).*b(:,1)+a(:,2).*b(:,3)-a(:,3).*b(:,2)

  2 件のコメント

Bruno Luong
Bruno Luong 2019 年 10 月 10 日
Some timing
a=rand(1e6,3);
b=rand(1e6,3);
tic
d=arrayfun(@(x)det([a(x,:);b(x,:);ones(1,3)]),(1:length(a))');
toc % 5.066323 seconds.
tic
A = reshape(a.',1,3,[]);
B = reshape(b.',1,3,[]);
ABC = [A; B];
ABC(3,:,:) = 1;
d = zeros(size(a,1),1);
for k=1:size(a,1)
d(k) = det(ABC(:,:,k));
end
toc % Elapsed time is 1.533522 seconds.
tic
d = a(:,1).*b(:,2)-a(:,2).*b(:,1)-a(:,1).*b(:,3)+a(:,3).*b(:,1)+a(:,2).*b(:,3)-a(:,3).*b(:,2);
toc % Elapsed time is 0.060121 seconds.
I keep writing since day one that ARRAYFUN is mostly useless when speed is important.
Hadi Ghahremannezhad
Hadi Ghahremannezhad 2019 年 10 月 10 日
Great answer.

サインイン to comment.

その他の回答 (2 件)

David Hill
David Hill 2019 年 10 月 9 日
d=arrayfun(@(x)det([a(x,:);b(x,:);ones(1,3)]),1:length(a));

  3 件のコメント

Rik
Rik 2019 年 10 月 9 日
This is probably the solution OP is looking for, but I want to add that this still contains a loop. It just moves the loop internally, while adding a layer of complexity with the anonymous function.
Hadi Ghahremannezhad
Hadi Ghahremannezhad 2019 年 10 月 9 日
I know it is an internal loop, but this is what I was looking for and it is working well. Thank you.
Bruno Luong
Bruno Luong 2019 年 10 月 10 日
You have accepted the worse answer in term of runing time, see the tic/toc I made below

サインイン to comment.


Steven Lord
Steven Lord 2019 年 10 月 9 日
This line of code:
d = det([a(:,:) ; b(:,:) ; ons(:,:)]);
Stacks all of a on top of all of b, and stacks that on top of all of ons. It then tries to take the determinant of that array. Let's see the matrix you created.
d = [a(:,:) ; b(:,:) ; ons(:,:)]
d =
1 1 1
2 2 2
3 3 3
4 4 4
5 5 5
4 4 4
3 2 4
1 5 7
4 3 8
2 4 7
1 1 1
1 1 1
1 1 1
1 1 1
1 1 1
The easiest way to accomplish what you want is a for loop that iterates through the rows of the a and b matrices. It's hard to give an example of the technique on your data that doesn't just give you the solution (which I'd prefer not to do, since this sounds like a homework assignment.) So I'll just point to the array indexing documentation. You want to access all of one of the rows of a (and all of the same row of b) and use that accessed data to create the d matrix for that iteration of the for loop. Each iteration will have a different d.

  3 件のコメント

Hadi Ghahremannezhad
Hadi Ghahremannezhad 2019 年 10 月 9 日
Thahk you for the helpful answer. But I have to avoid loops here.
Steven Lord
Steven Lord 2019 年 10 月 9 日
Why? Because that's a condition of your assignment or because you have heard that loops are slow in MATLAB? If the latter, that's become less and less accurate (when the loop is written well) as time has progressed and MATLAB has improved.
Hadi Ghahremannezhad
Hadi Ghahremannezhad 2019 年 10 月 9 日
Both. This is a small part of an assignment. It says always use vectorization instead of loops because of higher speed. The assignment is about mesh processing and I am trying to calculate the area of each face (traingle) where I have the 3 points of each triangle.

サインイン to comment.

サインイン してこの質問に回答します。

タグ


Translated by