Reputation: 167
I have a cell array which each cell is an n-by-n matrix. I want to delete the cells for which inv(cell{i}'*cell{i})
gives warning that matrix is close to singular.
Thank you
Upvotes: 4
Views: 1974
Reputation: 20319
Assuming you have already defined a issingular
function defined you can use cellfun
to get the indices of the cells that contain the matrices you want to remove.
c; % cell arry
singularIdx = cellfun((@x) issingular( inv(x' * x)), c); %' added single quote for SO syntax
cFiltered = c(~singluarIdx);
You'll probably need to write your own function to check for singularity, for more information on that see this question: Fast method to check if a Matrix is singular? (non-invertible, det = 0)
Upvotes: 0
Reputation: 2333
Create a function that check for your condition:
function state = CheckElement(element)
if ([condition])
state = 1;
else
state = 0;
end
end
then do cellfun on all you cell array elements like the following:
indices = cellfun(@CheckElement,myCellArray);
cellArray(indices ) = [];
Upvotes: 1
Reputation: 32930
In general, removing elements is the easy part. If C
is your array, removing cells specified by the indices in vector idx
can be done by:
C(idx) = {};
Regarding your specific problem, to check if a matrix is "almost" singular or not can be done with rcond
(if the result is close to zero, it's probably singular). To apply it to all cells you can use cellfun
in the following way:
idx = cellfun(@(x)(rcond(x' * x) < 1e-12), C);
Adjust the threshold value to your liking. The resulting idx
is a logical array with 1
s at the location of singular matrices. Use idx
to remove these elements from C
as shown above.
Upvotes: 3