StableRandomGenerator implements NormalizedRandomGenerator { public double nextNormalizedDouble() { double omega = -FastMath.log(generator.nextDouble()); double phi = FastMath.PI * (generator.nextDouble() - 0.5); if (alpha == 2d) { return FastMath.sqrt(2d * omega) * FastMath.sin(phi); } double x; if (beta == 0d) { if (alpha == 1d) { x = FastMath.tan(phi); } else { x = FastMath.pow(omega * FastMath.cos((1 - alpha) * phi), 1d / alpha - 1d) * FastMath.sin(alpha * phi) / FastMath.pow(FastMath.cos(phi), 1d / alpha); } } else { double cosPhi = FastMath.cos(phi); if (FastMath.abs(alpha - 1d) > 1e-8) { double alphaPhi = alpha * phi; double invAlphaPhi = phi - alphaPhi; x = (FastMath.sin(alphaPhi) + zeta * FastMath.cos(alphaPhi)) / cosPhi * (FastMath.cos(invAlphaPhi) + zeta * FastMath.sin(invAlphaPhi)) / FastMath.pow(omega * cosPhi, (1 - alpha) / alpha); } else { double betaPhi = FastMath.PI / 2 + beta * phi; x = 2d / FastMath.PI * (betaPhi * FastMath.tan(phi) - beta * FastMath.log(FastMath.PI / 2d * omega * cosPhi / betaPhi)); if (alpha != 1d) { x += beta * FastMath.tan(FastMath.PI * alpha / 2); } } } return x; } StableRandomGenerator(final RandomGenerator generator,
                                 final double alpha, final double beta); double nextNormalizedDouble();  }
@Test public void testNextDouble() { StableRandomGenerator generator = new StableRandomGenerator(rg, 1.3, 0.1); double[] sample = new double[2 * sampleSize]; for (int i = 0; i < sample.length; ++i) { sample[i] = generator.nextNormalizedDouble(); } Assert.assertEquals(0.0, StatUtils.mean(sample), 0.3); }
@Test public void testGaussianCase() { StableRandomGenerator generator = new StableRandomGenerator(rg, 2d, 0.0); double[] sample = new double[sampleSize]; for (int i = 0; i < sample.length; ++i) { sample[i] = generator.nextNormalizedDouble(); } Assert.assertEquals(0.0, StatUtils.mean(sample), 0.02); Assert.assertEquals(1.0, StatUtils.variance(sample), 0.02); }
@Test public void testCauchyCase() { StableRandomGenerator generator = new StableRandomGenerator(rg, 1d, 0.0); DescriptiveStatistics summary = new DescriptiveStatistics(); for (int i = 0; i < sampleSize; ++i) { double sample = generator.nextNormalizedDouble(); summary.addValue(sample); } double median = summary.getPercentile(50); Assert.assertEquals(0.0, median, 0.2); }