@Override
    public Neighbor<double[], E> nearest(double[] q) {
        int index = -1;
        double nearest = Double.MAX_VALUE;

        for (int i : getCandidates(q)) {
            double[] x = keys.get(i);
            if (q != x) {
                double distance = MathEx.distance(q, x);
                if (distance < nearest) {
                    index = i;
                    nearest = distance;
                }
            }
        }
        
        return index == -1 ? null : new Neighbor<>(keys.get(index), data.get(index), index, nearest);
    }
@Test
    public void testNearest() {
        System.out.println("nearest");

        int recall = 0;
        double error = 0.0;
        int hit = 0;
        for (double[] xi : testx) {
            Neighbor neighbor = lsh.nearest(xi);
            if (neighbor != null) {
                hit++;

                Neighbor truth = naive.nearest(xi);
                if (neighbor.index == truth.index) {
                    recall++;
                } else {
                    error += Math.abs(neighbor.distance - truth.distance) / truth.distance;
                }
            }
        }

        error /= (hit - recall);

        assertEquals(1154, recall);
        assertEquals(2007, hit);
        assertEquals(0.1305, error, 1E-4);
        System.out.format("recall is %.2f%%%n", 100.0 * recall / testx.length);
        System.out.format("error when miss is %.2f%%%n", 100.0 * error);
        System.out.format("null rate is %.2f%%%n", 100.0 - 100.0 * hit / testx.length);
    }