Question

Consider example

a=rand(5,1)
b=rand(5,1);
bs=sum(b);
B=b./bs;
cB=cumsum(B)

%OUTPUT

a =

0.7803
0.3897
0.2417
0.4039
0.0965


cB =

0.0495
0.4030
0.7617
0.9776
1.0000

now i want the position of the number in cB which is immediately greater than the number in a. that is to say i want 5 positions corresponding to each number in a. So my output should be

P= [4;2;2;3;2]

Please help.

Was it helpful?

Solution

The suggestions by the others are decent, but both miss the point as they are inefficient for large problems. This is a job best done by histc. (I admit that histc is not obviously the tool you would lookfor to solve this problem. I wish they had chosen some more obvious name, because few people seem to know about it. histc is used for histogramming, but also for the evaluation of splines.)

For your test case...

a = [0.7803 0.3897 0.2417 0.4039 0.0965];
cB = [0.0495 0.4030 0.7617 0.9776 1.0000];

[~,b] = histc(a,cB);
b = b + 1
b =
     4     2     2     3     2

Histc returns the index of the elements just UNDER your target, so you need to add 1.

Edit:

Eitan points out that IF cB is not monotonic, then there are problems. However, there are problems with ANY solution in that case, since the solution will not be unique. Without more information provided, such as do you desire the first or last qualifying index, there is no valid answer to the problem for completely general cB. For example, if we had:

cB = [1 3 2 4];
a = 2.5;

There are two possible solutions one might arrive at, thus an index of either 2 or 4. Note that I have had to provide solutions for exactly this problem in the past for clients, long before histc was provided as a tool in MATLAB. For example, in splines codes, the common problem is of locating the knot interval a point falls in. Of course then, the knots must lie in a sorted order. (I'll ignore the issue of replicated breaks.) There is also a case in splines codes where the bin edges are not in a sorted order, and this is the case of finding the inverse value for a spline, which then need not be monotonic at all. In that case, it may well be appropriate to solve for the rightmost solution. Only the customer would make that decision.

Since cB was generated in the example to be strictly monotone, I can only presume that monotonicity is part of the assumptions for this question.

OTHER TIPS

Try this:

pos = sum(bsxfun(@le, cB, a')) + 1

Another one (equivalent to a loop):

pos = arrayfun(@(x) find(x < cB, 1, 'first'), a)
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top