Java tutorial
/* * Copyright 2014 by Yields. * * 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. */ package io.yields.math.framework.data; import org.apache.commons.math3.distribution.UniformRealDistribution; import org.apache.commons.math3.random.MersenneTwister; import org.apache.commons.math3.stat.descriptive.DescriptiveStatistics; import org.apache.commons.math3.stat.inference.KolmogorovSmirnovTest; import org.fest.assertions.Delta; import org.junit.Test; import org.junit.runner.RunWith; import java.util.function.Function; import io.yields.math.framework.Explorer; import io.yields.math.framework.Functional; import io.yields.math.framework.Variable; import io.yields.math.framework.junit.Exploration; import io.yields.math.framework.junit.ExplorationContext; import io.yields.math.framework.junit.Explore; import io.yields.math.framework.junit.ExploreRunner; import io.yields.math.framework.operator.Operators; import static org.fest.assertions.Assertions.assertThat; @RunWith(ExploreRunner.class) public class DataProvidersTest { public static class Pair { private double x1, x2; public Pair() { this(0d, 0d); } public Pair(double x1, double x2) { this.x1 = x1; this.x2 = x2; } public double getX1() { return x1; } public double getX2() { return x2; } } public static class TestFunction extends Functional<Pair> { @Variable("[0,1]") public double x; @Variable("[0,1]") public double y; @Override protected Pair compute() { return new Pair(x, y); } } public static class TestFunctionWithPairAsVariable extends Functional<Pair> { @Variable public Pair pair; @Override protected Pair compute() { return pair; } } public static class FunctionExplorerWithoutPropertiesWithPairGeneration implements ExplorationContext<Pair, Pair> { @Override public Functional<Pair> getFunctional() { return new TestFunctionWithPairAsVariable(); } @Override public Function<Pair, Pair> getOperator() { return Operators.identity(); } } public static class FunctionExplorerWithoutProperties implements ExplorationContext<Pair, Pair> { @Override public Functional<Pair> getFunctional() { return new TestFunction(); } @Override public Function<Pair, Pair> getOperator() { return Operators.identity(); } } public static class FunctionExplorer implements ExplorationContext<Double, Double> { @Override public Functional<Double> getFunctional() { return new OneDFunction(); } @Override public Function<Double, Double> getOperator() { return Operators.identity(); } } @Explore(name = "check distributional properties of random numbers", dataProvider = DataProviders.FixedMersenneTwisterDataProvider.class, nrOfRuns = 10000) @Exploration(name = "2D uniform samples", context = FunctionExplorerWithoutProperties.class, group = "data providers") public void testRandomDistribution(Explorer<Pair> explorer) { KolmogorovSmirnovTest ksTest = new KolmogorovSmirnovTest(); DescriptiveStatistics xStats = new DescriptiveStatistics(); DescriptiveStatistics yStats = new DescriptiveStatistics(); explorer.all().forEach(result -> { Pair pair = result.getFunctionOutcome().orElse(new Pair()); xStats.addValue(pair.getX1()); yStats.addValue(pair.getX2()); }); DescriptiveStatistics cross = new DescriptiveStatistics(); for (int i = 0; i < xStats.getN(); i++) { cross.addValue((xStats.getValues()[i] - .5) * (yStats.getValues()[i] - .5)); } /** * x and y should be uniformly distributed */ assertThat(ksTest.kolmogorovSmirnovStatistic(new UniformRealDistribution(0, 1), xStats.getValues())) .isEqualTo(0, Delta.delta(.015)); assertThat(ksTest.kolmogorovSmirnovStatistic(new UniformRealDistribution(0, 1), yStats.getValues())) .isEqualTo(0, Delta.delta(.015)); /** * and have zero correlation */ assertThat(cross.getMean()).isEqualTo(0, Delta.delta(.05)); } @Explore(name = "check that the random data series is fixed", dataProvider = DataProviders.FixedMersenneTwisterDataProvider.class, nrOfRuns = 100) @Exploration(name = "1D uniform samples", context = FunctionExplorer.class, group = "data provider") public void testFixedSeries(Explorer<Double> explorer) { RandomDoubleGenerator generator = new RandomDoubleGenerator( new CommonsMathDoubleRandomSequence(new MersenneTwister(0))); explorer.all().forEach(result -> assertThat(result.getFunctionOutcome().orElse(-1d)) .isEqualTo(generator.next(), Delta.delta(1.e-8))); } @Explore(name = "check that the correct randomizer is used", dataProvider = RandomPairProvider.class) @Exploration(name = "direct pair generation", context = FunctionExplorerWithoutPropertiesWithPairGeneration.class, group = "data provider") public void testPairRandomizer(Explorer<Pair> explorer) { assertThat(explorer.all().count()).isEqualTo(100); assertThat(explorer.valid().count()).isEqualTo(100); assertThat(explorer.invalid().count()).isEqualTo(0); } @Test(expected = UnsupportedOperationException.class) public void noRangeDefinedForPairGenerator() { new RandomPairProvider.RandomPairGenerator().withRange(null); } }