Having troubles with resizing matrices in 'for loop' and index search.

I have a logical array of 0s an 1s. I would like to extract indices of all the cells with the value of 1, but without loosing information on columns. This gives a single column of indices.
idx = find(logical_array)
I tried for loop, but I'm not sure how to define my array before the for loop. Since the number of values varies between the columns, it generates a dimension mismatch error.
data = logical(randi(2,[10 3])-1);
idx = zeros(x,y);
for i = 1:y
r_idx(:,i) = find(data(:,i));
end
It works when I generate separate vectors and concatenate them with padcat function. But is there an easier way?
data = logical(randi(2,[10 3])-1);
idx1 = find(data(:,1));
idx2 = find(data(:,2));
idx3 = find(data(:,3));
idx = padcat(idx1, idx2, idx3);

 Accepted Answer

[r, c] = find(logical_array)
This gives vectors of row and column indices.
I cannot tell what output you are hoping for.

9 Comments

Thank you, but this in not what I was looking for. The output that I need can be reached by the following:
data = logical(randi(2,[10 3])-1);
idx1 = find(data(:,1));
idx2 = find(data(:,2));
idx3 = find(data(:,3));
idx = padcat(idx1, idx2, idx3);
but I don't know how to loop it for n-number of indices.
I don't really see how Walter's answer isn't better than having a matrix padded out with NaN values. The c vector tells you from what column the index values in r came from. However, if you really want to add a loop your own code then this will work:
data = logical(randi(2,[10 3])-1);
for iter=1:size(data,2)
idx{iter} = find(data(:,iter));
end
Thank you very much, you are right, Walter's answer works. I was just too focused on the output that I initially imagined.
Dear Walter and David,
I do have a follow up question. Lets assume we do the following:
v = randi(50,100,10);
logical_array = logical(randi(2,[10 3])-1);
[r, c] = find(logical_array)
Now I have 2 vectors. Vector (c) contains information on the categories 1:3 and vector (r) contains indices of the vectors (v) that fall within the category (c). I need to generate a 3D array, where (1D = r), (2D = v), (3D = c). where numbers of (v) and (c) are constant while number of (r) varies for each (c). How can I do that? 1)generate a vector of all the r-values that have matching c-values (this is what I have been trying to do initially with my logical array); 2)assign corresponding v-vectors to the r-values. This will generate a 2D array with r-columns and 100 rows; 3)Add a 3rd dimension of c-values (1:3 in this case). This will generate a 3D array with c-sheets.
I recognize that perhaps there are way to many questions combined here. But I'm just starting to learn Matlab while trying to complete this analysis for the deadline. I would greatly appreciate if you can help me or refer me to the source where I can get help.
When the 3D array is accessed, what would the content be?
You can probably be using
accumarray([r, v(:), c], SOMETHING, [], [], nan)
where the SOMETHING is information to be stored at each corresponding location.
But before putting it together into a 3D array I need to split vector (r) into separate vectors based on the columns that the data was originally stored in in the logical array.
r = [1;4;5;1;5;1;2];
c = [1;1;1;2;2;3;3];
Vector (C) has repeating values 1,2,3. I need to extract all the values or (r) at which c = i (Ex: r1 = [1;4;5]; r2 = [1;5]; r3 = [1;2]). How can I do that?
It may be a stupid question (and don't feel pressed to answer it if it requires a lot of explanation), but what is the actual purpose of this 3D array that you are trying to build? It just seems that you've extracted all the indices of where the original matrix was logical 1, and now you're trying to put all that back together again to reconstruct what you originally had in a slightly less compact form. If all you want is a record of the position of each value in the original array, wouldn't it be easier to just have a two element cell array; the first cell holds the positional data of all the ones; the second cell holds the positional data of all the zeros.
I think you will find you do not need to do that when you use accumarray. But if you insist:
splits = splitapply(@(V) {V}, r, c );
Dear David and Walter, thank you so much for your help! David, you are right. As I started thinking about it more, I do not need to put it back together (i'm still getting used to the "code" type of thinking:-). Here is the whole idea briefly. I have multiple traces of (r) over time, and I apply several conditions (c) at certain time points. I calculate AUC following each condition for each trace and generate a logical array, which tells me which traces changed at which condition. At the end I want to make a box plot of AUCs for the responding traces only. So I guess I just need to extract the indices from the logical array and assign them an AUC value that was calculated before. I do not need to go back to the original trace and recalculate it again. Anyway, just by typing it out, I understand it better. Thank you very much for your help!

Sign in to comment.

More Answers (0)

Categories

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!