/* * Java Genetic Algorithm Library (@__identifier__@). * Copyright (c) @__year__@ Franz Wilhelmstötter * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * Author: * Franz Wilhelmstötter (franz.wilhelmstoetter@gmx.at) */ package org.jenetics.util; import static org.jenetics.internal.math.random.indexes; import java.util.PrimitiveIterator.OfInt; import java.util.Random; import org.testng.Assert; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; import org.jenetics.internal.math.probability; import org.jenetics.internal.util.IntRef; import org.jenetics.stat.Histogram; import org.jenetics.stat.LongMomentStatistics; /** * @author <a href="mailto:franz.wilhelmstoetter@gmx.at">Franz Wilhelmstötter</a> */ public class RandomIndexStreamTest { @Test public void compatibility() { final TestData data = TestData.of("/org/jenetics/util/IndexStream.Random"); for (String[] line : data) { final Random random = new LCG64ShiftRandom.ThreadSafe(0); final double p = Double.parseDouble(line[0]); final OfInt it = indexes(random, 500, p).iterator(); for (int i = 1; i < line.length; ++i) { final int index = Integer.parseInt(line[i]); Assert.assertEquals(it.nextInt(), index); } Assert.assertFalse(it.hasNext()); } } @Test public void reference() { final int size = 5000; final double p = 0.5; final Random random1 = new LCG64ShiftRandom(0); final Random random2 = new LCG64ShiftRandom(0); for (int j = 0; j < 1; ++j) { final OfInt it = indexes(random1, size, p).iterator(); final IndexStream stream2 = ReferenceRandomStream( size, p, random2 ); while (it.hasNext()) { Assert.assertEquals(it.nextInt(), stream2.next()); } Assert.assertFalse(it.hasNext()); Assert.assertEquals(stream2.next(), -1); } } @Test(dataProvider = "probabilities") public void distribution(final Integer n, final Double p) { final double mean = n*p; final double var = n*p*(1 - p); final Random random = new LCG64ShiftRandom(); final Range<Long> domain = new Range<>(0L, n.longValue()); final Histogram<Long> histogram = Histogram.ofLong(domain.getMin(), domain.getMax(), 10); final LongMomentStatistics variance = new LongMomentStatistics(); for (int i = 0; i < 2500; ++i) { final long k = k(n, p, random); histogram.accept(k); variance.accept(k); } // Normal distribution as approximation for binomial distribution. // TODO: Implement test //assertDistribution(histogram, new NormalDistribution<>(domain, mean, var)); } double var(final double p, final long N) { return N*p*(1.0 - p); } double mean(final double p, final long N) { return N*p; } long k(final int n, final double p, final Random random) { final IntRef kt = new IntRef(0); indexes(random, n, p).forEach(i -> { ++kt.value; }); return kt.value; } @DataProvider(name = "probabilities") public Object[][] probabilities() { return new Object[][] { // n, p {1115, 0.015}, {1150, 0.015}, {1160, 0.015}, {1170, 0.015}, {11100, 0.015}, {11200, 0.015}, {11500, 0.015}, {1115, 0.15}, {1150, 0.15}, {1160, 0.15}, {1170, 0.15}, {11100, 0.15}, {11200, 0.15}, {11500, 0.15}, {515, 0.5}, {1115, 0.5}, {1150, 0.5}, {1160, 0.5}, {1170, 0.5}, {11100, 0.5}, {11200, 0.5}, {11500, 0.5}, {515, 0.85}, {1115, 0.85}, {1150, 0.85}, {1160, 0.85}, {1170, 0.85}, {11100, 0.85}, {11200, 0.85}, {11500, 0.85}, {515, 0.99}, {1115, 0.99}, {1150, 0.99}, {1160, 0.99}, {1170, 0.99}, {11100, 0.99}, {11200, 0.99}, {11500, 0.99} }; } public static IndexStream ReferenceRandomStream( final int n, final double p, final Random random ) { return new IndexStream() { private final int P = probability.toInt(p); private int _pos = -1; @Override public int next() { while (_pos < n && random.nextInt() >= P) { ++_pos; } return (_pos < n - 1) ? ++_pos : -1; } }; } interface IndexStream { public int next(); } // public static void main(final String[] args) { // final int delta = 500; // // for (int i = 0; i <= delta; ++i) { // final double p = (double)(i)/(double)delta; // final Random random = new LCG64ShiftRandom.ThreadSafe(0); // final IndexStream stream = ReferenceRandomStream(delta, p, random); // // System.out.print(Double.toString(p)); // System.out.print(","); // for (int j = stream.next(); j != -1; j = stream.next()) { // System.out.print(j); // System.out.print(","); // } // System.out.println(); // } // } }