MATLAB: Relatively complex matrix indexing question

large matriceslogical indexingmatrix indexing

Hi,
I have a reasonably complex matrix indexing question that I'm struggling to solve. I have an nxn matrix of float values. The matrix is fairly large (n~30000). The matrix is upper (or lower) triangular with the other values being NaN. Each of the rows represented has a vector associated with it, so the matrix rows has a secondary matrix associated with it that is nxk, where each row has k characteristics. Row 1 has the same characteristics as column 1, row 2 has the same characteristics as column2, etc.
I want to plot a histogram of all of the elements in the nxn matrix whose rows/columns match certain characteristics.
To illustrate, let's say I had the following 4×4 value matrix
Values = [...
NaN 4.0 3.1 2.3
NaN NaN 1.2 5.2
NaN NaN NaN 7.1
NaN NaN NaN NaN]
Each row/column has three characteristics and this characteristics matrix has the values
Charac = [...
4 2 3
1 4 5
-3 5 1
10 6 2]
I only want to get histogram elements for rows/columns that have the second characteristic greater than 1 and the third characteristic less than 4. In this case only the first, third and fourth rows would meet the criterion and the values that I would take from the matrix Values are 3.1, 2.3 and 7.1.
Is there a compact and computationally efficient way to logically index this?
Thanks in advance!

Best Answer

You are correct about sparse matrices, and I had completely misunderstood your setup! So the lower triangular part is NaN, but the upper part has a density of 1(?) If so, there is no point in using sparse matrices. Reading your last explanation, I think that what you are looking for is along the line of what follows.
EDIT - I provide a second approach (B), which could work if you had only non-NaN elements in a vector. It is just a quick test though and it would have to be tested/profiled.
values = [NaN 4.0 3.1 2.3; ...
NaN NaN 1.2 5.2; ...
NaN NaN NaN 7.1; ...
NaN NaN NaN NaN] ;
charac = [4 2 3; ...
1 4 5; ...
-3 5 1; ...
10 6 2] ;
%%%A. Values is square num. array with NaNs.
% - Find valid row IDs.
isValid = charac(:,2) > 1 & charac(:,3) < 4 ;
validId = find( isValid ) ;
% - Build all possible row/col pairs.
validRC = nchoosek( validId, 2 ) ;
isValid = validRC(:,2) > validRC(:,1) ;
validRC = validRC(isValid,:) ;
% - Extract relevant values.

validId = sub2ind( size(values), validRC(:,1), validRC(:,2)) ;
extract = values(validId) ;
%%%B. Values is lin num array with non-NaNs only.
% - Build what could be values if you were not storing NaNs. Makes little
% sense to build it this way (by creating the large, square array and
% reducing it), but maybe you can build this vector directly instead
% of the array.
valuesLin = values(~isnan(values)) ;
% - Build sub2linInd function.
cSum = [0, cumsum( 1 : (size(values,2)-1) )] ;
sub2linInd = @(row, col) row + cSum(col-1).' ;
% - Extract relevant values.
validId = sub2linInd( validRC(:,1), validRC(:,2) ) ;
extractLin = valuesLin(validId) ;