Path: blob/master/test/jdk/java/util/Random/RandomTestMoments.java
41149 views
/*1* Copyright (c) 2012, 2021, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/22import java.util.ArrayList;23import java.util.List;2425import java.util.random.*;2627import java.util.Set;28import java.util.concurrent.CompletableFuture;29import java.util.concurrent.ExecutionException;30import java.util.concurrent.ThreadLocalRandom;31import java.util.concurrent.TimeUnit;32import java.util.concurrent.TimeoutException;33import java.util.function.DoubleSupplier;34import java.util.stream.Stream;3536import static java.util.stream.Collectors.toList;37import static java.util.stream.Collectors.toSet;3839/**40* @test41* @summary test bit sequences produced by clases that implement interface RandomGenerator42* @bug 824886243* @run main RandomTestMoments44* @author Guy Steele45* @key randomness46*/4748public class RandomTestMoments {4950static String currentRNG = "";51static int failCount = 0;5253static void exceptionOnFail() {54if (failCount != 0) {55throw new RuntimeException(failCount + " fails detected");56}57}5859static void setRNG(String rng) {60currentRNG = rng;61}6263static void fail(String format, Object... args) {64if (currentRNG.length() != 0) {65System.err.println(currentRNG);66currentRNG = "";67}6869System.err.format(" " + format, args);70failCount++;71}7273static final int SEQUENCE_SIZE = 50000;7475// Moment k of uniform distribution over [0.0,1.0) is 1.0/(1+k).7677static double[][] momentsUniform = {78{ 1.00000, 1.00000, 0.01000 },79{ 0.500000, 0.500000, 0.0266265 },80{ 0.333333, 0.333333, 0.0391128 },81{ 0.250000, 0.250000, 0.0477151 },82{ 0.200000, 0.200000, 0.0540496 },83{ 0.166667, 0.166667, 0.0589355 },84{ 0.142857, 0.142857, 0.0628462 },85{ 0.125000, 0.125000, 0.0660693 },86{ 0.111111, 0.111111, 0.0688036 },87{ 0.100000, 0.100000, 0.0712002 },88{ 0.0909091, 0.0909091, 0.0733755 },89{ 0.0833333, 0.0833333, 0.0754172 },90{ 0.0769231, 0.0769231, 0.0773868 },91{ 0.0714286, 0.0714286, 0.0793244 },92{ 0.0666667, 0.0666667, 0.0812526 },93{ 0.0625000, 0.0625000, 0.0831806 },94};9596// Moment k of exponential distribution with mean 1 is k!.9798static double[][] momentsExponential = {99{ 1.00000, 1.00000, 0.01000 },100{ 1.00000, 1.00000, 0.0718997 },101{ 2.00000, 2.00000, 0.153241 },102{ 6.00000, 6.00000, 0.282813 },103{ 24.0000, 24.0000, 0.503707 },104};105106107// Absolute moment k of Gaussian distribution with mean 0 and stddev 1 is108// pow(2.0,k/2.0)*gamma((k+1)/2.0)/sqrt(PI)109// https://arxiv.org/pdf/1209.4340.pdf, equation (18)110111static double[][] absoluteMomentsGaussian = {112{ 1.00000, 1.00000, 0.01 },113{ 0.797885, 0.797885, 0.1 },114{ 1.00000, 1.00000, 0.1 },115{ 1.59577, 1.59577, 0.2 },116{ 3.00000, 3.00000, 0.2 },117{ 6.38308, 6.38308, 0.2 },118{ 15.0000, 15.0000, 0.2 },119{ 38.2985, 38.2985, 0.2 },120{ 105.000, 105.000, 0.4 },121};122123static void checkMoments(String test, double[] measurements, double[][] standard) {124for (int j = 0; j < measurements.length; j++) {125double actual = measurements[j];126double expected = standard[j][0];127double basis = standard[j][1];128double tolerance = standard[j][2];129if (!(Math.abs(actual - expected)/basis < tolerance)) {130fail("%s fail: actual=%f, expected=%f, basis=%f, tolerance=%f\n",131test, actual, expected, basis, tolerance);132}133}134}135136static void testMomentsGaussian(DoubleSupplier theSupplier) {137int m = absoluteMomentsGaussian.length;138double[] absoluteMoments = new double[m];139for (int j = 0; j < SEQUENCE_SIZE; j++) {140double v = theSupplier.getAsDouble();141double z = 1.0;142for (int k = 0; k < m; k++) {143absoluteMoments[k] += Math.abs(z);144z *= v;145}146}147for (int k = 0; k < m; k++) {148absoluteMoments[k] /= SEQUENCE_SIZE;149}150checkMoments("Gaussian", absoluteMoments, absoluteMomentsGaussian);151}152153static void testMomentsExponential(DoubleSupplier theSupplier) {154int m = momentsExponential.length;155double[] moments = new double[m];156for (int j = 0; j < SEQUENCE_SIZE; j++) {157double v = theSupplier.getAsDouble();158double z = 1.0;159for (int k = 0; k < m; k++) {160moments[k] += z;161z *= v;162}163}164for (int k = 0; k < m; k++) {165moments[k] /= SEQUENCE_SIZE;166}167checkMoments("Exponential", moments, momentsExponential);168}169170static void testMomentsUniform(DoubleSupplier theSupplier) {171int m = momentsUniform.length;172double[] moments = new double[m];173for (int j = 0; j < SEQUENCE_SIZE; j++) {174double v = theSupplier.getAsDouble();175double z = 1.0;176for (int k = 0; k < m; k++) {177moments[k] += z;178z *= v;179}180}181for (int k = 0; k < m; k++) {182moments[k] /= SEQUENCE_SIZE;183}184checkMoments("Uniform", moments, momentsUniform);185}186187static void testOneRng(RandomGenerator rng) {188testMomentsGaussian(rng::nextGaussian);189testMomentsExponential(rng::nextExponential);190testMomentsUniform(rng::nextDouble);191testMomentsUniform(rng.doubles().iterator()::next);192}193194public static void main(String[] args) {195RandomGeneratorFactory.all()196.forEach(factory -> {197setRNG(factory.name());198testOneRng(factory.create(325) );199});200201exceptionOnFail();202}203204}205206207