Issue 1:
(Numpy Version 1.8)

See the following example for the precision where it happens:

In [68]: numpy.histogramdd([0.9999995], bins=[[0, 0.5, 1]])
Out[68]: (array([ 1., 0.]), [array([ 0. , 0.5, 1. ])])

As you can see the entry lands in the wrong bin.

Lowering the value by 10^-7 suddenly makes the jump to the last bin (which is correct):

2)

In [69]: numpy.histogramdd([0.9999994], bins=[[0, 0.5, 1]])

Out[69]: (array([ 0., 1.]), [array([ 0. , 0.5, 1. ])])

Interestingly, increasing the 2nd to last edge value to a high precision also helps:

3)

In [88]: numpy.histogramdd([0.9999999997], bins=[[0, 0.99999, 1]])

Out[88]: (array([ 0., 1.]), [array([ 0. , 0.99999, 1. ])]

Standard numpy.histogram behaves as expected to arbitrary high values close to 1:

4)

In [71]: numpy.histogram(0.99999999999, bins=[0, 0.5, 1])

Out[71]: (array([0, 1]), array([ 0. , 0.5, 1. ]))

The whole issue is only there for the rightmost boundary, not for intermediate ones. But as you can see in snippet 3), it has to do with the 2nd to last edge-value aswell.

I hope it gets fixed soon. The precision is not that high (cosine of small angles can easily be in this regime - actually for my work it is) and a wrong bin is populated... if unnoticed wrong results are the outcome.

Issue 2:
My numpy version is 1.6.1-6 on ubuntu 12.04 64-bit with python 2.7.3.

I want to create histograms with the function histogramdd.

When I have data points that are very close to the rightmost bin-edge, they will land in the wrong bin, that is, in the second-to-right bin, instead of the rightmost bin!

Here is some code to reproduce this behavior:

>>> import numpy as np
>>> x = np.random.randint(0,3,100)
>>> edges = [[-0.5, 0.5, 1.5, 2+1e-7]]
>>> np.histogramdd(x,edges)
(array([ 33., 67., 0.]),
[array([-0.5 , 0.5 , 1.5 , 2.0000001])])

The last bin is empty and all data points with value 2 are in the second bin.

Note that the last bin edge is very close to 2 but not exactly 2!

This doesn't happen using the 1d function:

>>> np.histogram(x,edges[0])
(array([33, 37, 30]), array([-0.5 , 0.5 , 1.5 , 2.0000001]))

The problem seems to be in line 347 of function_base.py (in my version):

for i in arange(D):
Ncount[i] = digitize(sample[:,i], edges[i])

...together with the following code (line 356ff), where all the data points that fall on the rightmost edge are shifted one bin to the left:

if not np.isinf(mindiff):
decimal = int(-log10(mindiff)) + 6
# Find which points are on the rightmost edge.
on_edge = where(around(sample[:,i], decimal) == around(edges[i][-1],
decimal))[0]

What happens is that the data points that are 2 fall into the 3rd bin, because they are smaller then the last edge 2.0000001. The 'digitize' function would put all points that were exactly 2.0000001 into an outlier bin! Then, in order to correct for the edge-points that were classified as outliers, these are shifted one bin to the left. However, to find them the data points and edges are rounded to 'decimal' precision, which has not be done in the first 'digitize' operation. So this time all the 2s are thought to be on the edge and shifted to the 2nd bin, although they were already in the correct bin!

I recommend to change line 347 to round the edges already here to 'decimal' precision:

for i in arange(D):
if not np.isinf(mindiff):
decimal = int(-log10(mindiff)) + 6
Ncount[i] = digitize(sample[:,i], around(edges[i], decimal))
else:
Ncount[i] = digitize(sample[:,i], edges[i])

I hope I could make clear what the problem is. For now I found the error and can design my bin-edges to be far enough away or exactly at the maximum of the data. But it would be nice if this could be fixed in future releases.