public static ExponentialFamilyMixture fit(double[] x, Component... components) {
        return fit(x, components, 0.0, 500, 1E-4);
    }
@Test
    public void testEM() {
        System.out.println("EM");
        MathEx.setSeed(19650218); // to get repeatable results.

        // Mixture of Gaussian, Exponential, and Gamma.
        double[] data = new double[2000];

        GaussianDistribution gaussian = new GaussianDistribution(-2.0, 1.0);
        for (int i = 0; i < 500; i++)
            data[i] = gaussian.rand();

        ExponentialDistribution exponential = new ExponentialDistribution(0.8);
        for (int i = 500; i < 1000; i++)
            data[i] = exponential.rand();

        GammaDistribution gamma = new GammaDistribution(2.0, 3.0);
        for (int i = 1000; i < 2000; i++)
            data[i] = gamma.rand();

        ExponentialFamilyMixture mixture = ExponentialFamilyMixture.fit(data,
                new Mixture.Component(0.25, new GaussianDistribution(0.0, 1.0)),
                new Mixture.Component(0.25, new ExponentialDistribution(1.0)),
                new Mixture.Component(0.5, new GammaDistribution(1.0, 2.0))
                );
        System.out.println(mixture);

        assertEquals(0.30, mixture.components[0].priori, 1E-2);
        assertEquals(0.13, mixture.components[1].priori, 1E-2);
        assertEquals(0.57, mixture.components[2].priori, 1E-2);
    }