Asked by mr mo
on 6 Nov 2017

Hi. Suppose I have the matrix A of size (m*n).

A = [12 44

93 43

128 44

145 41

180 41

220 40

280 40];

also I have the vector V e.g.

V = [13 20 70 90 95 100 102 110 129 130 145 158 170 185 190 200 207 220 270 280 285 290];

I want to find which one of the rows of matrix A based on its first column values is right after and right before the values of vector V, and if one of the values of the first column of matrix A is equal to the values of vector V, I want to find that row.

For example :

A(2,1) is right before V(5) and V(6) and V(7) and V(8)

A(3,1) is right after V(5) and V(6) and V(7) and V(8)

and in case of equality I want to find this

A(4,1) = V(11)

A(5,1) = V(18)

A(7,1) = V(20)

In other words, I want to find exactly which members of vector V are between which members of first column of matrix A with their indices like this :

V(1) and V(2) and V(3) and V(4) is between A(1,1) and A(2,1)

Thanks for your help.

Answer by KL
on 6 Nov 2017

Edited by KL
on 6 Nov 2017

res = find(V>A(1,1) & V<A(2,1))

for all elements,

res = arrayfun(@(x,y) find(V>x & V<y), A(1:end-1,1), A(2:end,1),'uni',0)

KL
on 7 Nov 2017

You see, we can make a matrix if the number of elements is same for each row, if you take res, first two rows have 4 elements and then followed by 2 element rows and again 4 element row, finally just one element.

For this reason only we use cell array.

They are very easy to use. You just need to use {} braces. with the current "res", if you type on the command line,

res{1,1}

you will get the indices.

Anyway, if you need the values of A and V, we can create a cell array called out like,

out = arrayfun(@(x,y) [x, y, V(find(V>x & V<y))], A(1:end-1,1), A(2:end,1),'uni',0)

now if you want to access the contents of first row,

>> out{1,1}

ans =

12 93 13 20 70 90

mr mo
on 7 Nov 2017

mr mo
on 7 Nov 2017

Suppose I want to find that only V(10)=130 is lying between which two members of A(:,1). How can I do this process to have the out cell array like your last code?

And in case of equality how can I have the out cell array like the case of inequality? Thanks a lot.

Sign in to comment.

Answer by Guillaume
on 7 Nov 2017

An alternative method that does not involve loops (or arrayfun) but is not necessary faster than KL's:

comp = abs(A(:, 1) - V);

comp(A(:, 1) > V) = inf;

[~, beforeVidx] = min(comp, [], 2);

isequaltoV = A(:, 1) == V(beforeVidx)';

%for display only:

table(A, beforeVidx, isequaltoV)

Guillaume
on 7 Nov 2017

You're using an old version of matlab (<R2016b). It's always a good idea to mention such things. In pre-R2016b,

comp = bsxfun(@minus, A(:, 1), V);

mr mo
on 7 Nov 2017

Also this error was happened.

comp(A(:, 1) > V) = inf;

Error using >

Matrix dimensions must agree.

Guillaume
on 8 Nov 2017

Same issue, same solution, use bsxfun:

comp(bsxfun(@gt, A(:, 1), V)) = inf;

Sign in to comment.

Opportunities for recent engineering grads.

Apply Today
## 2 Comments

## KL (view profile)

## Direct link to this comment

https://ch.mathworks.com/matlabcentral/answers/365475-finding-the-values-right-after-and-right-before-some-values-in-a-matrix#comment_501842

## mr mo (view profile)

## Direct link to this comment

https://ch.mathworks.com/matlabcentral/answers/365475-finding-the-values-right-after-and-right-before-some-values-in-a-matrix#comment_501846

Sign in to comment.