@Override
    public double rand() {
        if (rng == null) {
            int mm = m;
            int nn = n;
            if (mm > N / 2) {
                // invert mm
                mm = N - mm;
            }

            if (nn > N / 2) {
                // invert nn
                nn = N - nn;
            }

            if ((double) nn * mm >= 20 * N) {
                // use ratio-of-uniforms method
                rng = new Patchwork(N, m, n);
            } else {
                // inversion method, using chop-down search from mode
                rng = new Inversion(N, m, n);
            }
        }

        return rng.rand();
    }
@Test
    public void testSd() {
        System.out.println("sd");
        HyperGeometricDistribution instance = new HyperGeometricDistribution(100, 30, 70);
        instance.rand();
        assertEquals(2.110579, instance.sd(), 1E-6);
        instance = new HyperGeometricDistribution(100, 30, 80);
        instance.rand();
        assertEquals(1.842265, instance.sd(), 1E-6);
        instance = new HyperGeometricDistribution(100, 30, 60);
        instance.rand();
        assertEquals(2.256304, instance.sd(), 1E-6);
    }