I have a matrix A and want the matrix consisting of the first n rows of A, having the same rank as A, where n is minimal.
More generally, I want the shortest "start piece" of a list, such that some criterion on the start piece gives True.
For the more general problem, I wrote myTake below, but I'm very dissatisfied with the procedural nature of my implementation.
myTake[list_, crit_] := Catch[
Do[With[{candidate = list[[Range[i]]]},
If[crit[candidate], Throw[candidate]]]
, {i, Length[list]}];
"fail"
];
firstFullRank[matrix_] := With[{fullRank = MatrixRank[matrix]},
myTake[matrix, MatrixRank[#] == fullRank &]
];
firstFullRank[{{1,0,0},{0,1,0},{2,3,0},{1,2,3},{9,8,7}}]
(gives {{1, 0, 0}, {0, 1, 0}, {2, 3, 0}, {1, 2, 3}})
In short, I'm looking for a fast and functional one liner implementation of myTake and/or firstFullRank
Edit
Please assume that the matrix has lots of rows (> 1000) and not many columns (<10), and that the result has significantly fewer rows than the full matrix. Is there a way to do this functionally without using Range[Length[matrix]] or (even worse) a table of all start pieces.
TakeWhile[]
? $\endgroup$TakeWhile
by itself is not quite what is being asked, since the criteria must be applied to the taken list as a whole, not individual elements. $\endgroup$