# "Subscripted assignment dimension mismatch" when using "find" with a tolerance?

1 view (last 30 days)
Andrew Poissant on 21 Aug 2017
Commented: Walter Roberson on 23 Aug 2017
My code gets pretty in depth so I am not sure if posting it all would be helpful at all. Essentially I am using find with a tolerance to obtain the common numbers between two matrices. Matrix N_new is a 884x884x3 layered matrix and FGIF is a 801x2 matrix. I keep getting the error for the line in the for loop saying "Subscripted assignment dimension mismatch." Any speculation as to why I would be recieving this error? I have played with the tolerance and it does not make a difference. I am pretty sure that all of the values in FGIF are a part of matrix N within the tolerance specified. I have provided a little code to get an idea of what I am going for.
[FGIF_r, FGIF_c] = size(FGIF);
tol = 0.001;
for i = 1:FGIF_r
[row(i), col(i)] = find(abs(N_new(:,:,2)-FGIF(i,1))<=tol & abs(N_new(:,:,3)-FGIF(i,2))<=tol);
end

Steven Lord on 21 Aug 2017
As written, you're assuming that exactly 1 (no more, no fewer) of the elements of the expression inside the find function call are nonzero. From the fact that you're receiving an error it seems that assumption is violated. Set an error breakpoint and run your code. When MATLAB stops at the error breakpoint, run the find call with zero output arguments and see how many elements the ans output contains.
If you know that at least 1 element of the expression inside the find function call will be nonzero and you want to find the first such value, call find with two inputs where the second input (denoted by n in the documentation) is 1.
Walter Roberson on 23 Aug 2017
"Is there a way to tell matlab that if it runs into an empty set during find to just remove the entire row?"
No.
You can assign the output of find() to temporary variables, and test the variables before doing the assignment.
However, for efficiency, instead of doing the deletion immediately, it is better to keep track of which entries to save (or delete), and then after the loop, do the appropriate processing. This also reduces the chances of accidentally missing processing an entry or accidentally running off the end of the matrix by failing to take into account that all the entries after the one being deleted "fall down to fill the hole", Tetris-like.

Walter Roberson on 21 Aug 2017
For testing purposes, try
[FGIF_r, FGIF_c] = size(FGIF);
tol = 0.001;
for i = 1:FGIF_r
[row{i}, col{i}] = find(abs(N_new(:,:,2)-FGIF(i,1))<=tol & abs(N_new(:,:,3)-FGIF(i,2))<=tol);
end
I suspect that you will find that some entries are either empty or else have more than one result. In particular I suspect you might have entries that are duplicates to within tolerance.
I wonder if you should perhaps be using ismembertol() with the 'byrows' option.
Andrew Poissant on 22 Aug 2017
how would that look? I was reading about it but it outputs a matrix of 0s and 1s so how would I extract the respective values from the FGIF matrix?