MATLAB Answers

0

Looping a matrix to find determinant

Asked by Ashicka Banu Mubarak on 20 Mar 2019
Latest activity Edited by John D'Errico
on 20 Mar 2019
I have got a matrix with dimension 8267X4. I have to find the determinant for every 4X4 subset in the matrix to find coplanarity and i have to store the values. Kindly anyone suggest me with the solution. So another methods to find coplanarity of the points. I am looking forward for your help.

  0 Comments

Sign in to comment.

2 Answers

Answer by Birdman
on 20 Mar 2019
Edited by Birdman
on 20 Mar 2019

Following way can be a starting point:
A=randi([1 5],8267,4);%%random data
for i=1:max(size(A))-3
DetVal(i)=det(A(i:i+3,1:4));
end

  3 Comments

Torsten
2019 年 3 月 20 日
Note that the OP meant to find the determinant of every 4x4 subset in the matrix. This gives an array for DetVal with 8267 *8266 * 8265 * 8264/ 24 elements :-)
Birdman
on 20 Mar 2019
I updated the answer according to that :) I understood differently at the beginning.
John D'Errico
2019 年 3 月 20 日
I had a funny feeling you missed that point.

Sign in to comment.


Answer by John D'Errico
on 20 Mar 2019
Edited by John D'Errico
on 20 Mar 2019

An ambiguous question, and possibly, an ambitious question too. For example, do you feel it to be of importance to test the submatrix A([2 3 5 7],:) for singularity? My guess is the wording of your question indicates that is indeed a valid 4x4 submatrix, that you actually want to test every possible combination of 4 rows of that matrix.
Using det to test for coplanarity is a really bad idea however, but who am I to say? Well, I honestly don't care, I'll say it anyway.
Anyway, I have a funny feeling that you CAN'T want to test EVERY possible 4x4 subarray of an array with 8267 rows. Why not?
nchoosek(8267,4)
ans =
1.9448e+14
So you might be asking to create and store the results of det on roughly 200 trillion subarrays.
nchoosek(8267,4)*8/1024^3
ans =
1.449e+06
So since each output of det is a double precision number, a few million gigabytes of RAM will be sufficient to store the results, if that is your intention. Those petabyte RAM chips are so expensive. Worse, every time I try to draw enough power to drive my petabyte ram chips, it makes all the wiring in my house melt down from the current load. Then the power company starts complaining, because they need to ramp up another nukular (I gotta get a speel chcker one day) power plant whenever I use my computer.
So, possibly Birdman is correct in the assessment that you MUST therefore have intended to take consecutive 4x4 blocks of the rows. I think you actually intended to ask the question as I interpret it however, and you just underestimate the computational requirements of your goal.
In the event that you really do want to generate and test all combinations of 4 rows of a more reasonably sized array, then you can list out the row combinations to test using nchoosek:
nchoosek(1:numberOfRows,4)
Then just use a loop. Other vectorized solutions are possible too.
Perhaps there is a simpler solution. For example, consider the array A:
A = repmat(rand(4),3,1);
A is a 12x4 array. If we take all subsets of the first 11 out of 12 of those rows...
nchoosek(11,3)
ans =
165
There are 165 such subsets. Consider the subset of rows [2 3 5].
ind = [2 3 5];
>> rank(A(ind,:))
ans =
3
So, as long as the rank of some combination of 3 rows is exactly 3, then that set of rows is viable to test. Now, call qr ONCE for that subset.
[~,R] = qr(A([ind,max(ind)+1:12],:)')
R =
-1.8725 -0.15746 -0.83202 -1.8725 -0.15746 -1.2218 -0.83202 -1.8725 -0.15746 -1.2218
0 0.10811 0.14309 0 0.10811 0.049941 0.14309 0 0.10811 0.049941
0 0 0.55577 0 0 -0.33634 0.55577 0 0 -0.33634
0 0 0 0 0 0.17258 -5.5511e-17 0 0 0.17258
Ignore the first 3 columns of R, and the first three rows.
R(4,4:end)
ans =
0 0 0.17258 -5.5511e-17 0 0 0.17258
The vector R(4,4:end) corresponds to appending rows 6:12 to the inital set based on ind. So
[ind, max(ind)+1:end]
will effectively append all the rows below max(ind) to the set in question.
See that only the third and 7'th cases in that vector ended up as non-zero, since the number -5.5511e-17 is just floating point trash. That means that if we want to find all sets of rows that start with [2 3 5], then ONLY the subsets of rows [2 3 5 8] and [2 3 5 12] form linearly independent sets. Thus, the submatrices composed of rows [2 3 5], combined with any of the rows [6 7 9 10 11] are ALL linearly dependent. This claim is trivially verified of course, based on the way I created A in the first place.
Effectively, this allows you to test EVERY subset of 4 rows using only 165 calls to QR, instead of 495 calls to det.
nchoosek(11,3)
ans =
165
>> nchoosek(12,4)
ans =
495
More importantly, the calls to QR will be more numerically stable ways to test for linear independence, whereas det is a total piece of crap for that purpose. (I'll concede that a pivoted QR is more stable numerically than the unpivoted default QR.)
That will also mean you need only make
nchoosek(8266,3)
ans =
9.4097e+10
so only around 95 billion calls to QR, instead of 200 trillion calls to det. Clearly a vast improvement. Sigh.

  0 Comments

Sign in to comment.