001/*
002 * Copyright © 2025 CUI-OpenSource-Software (info@cuioss.de)
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package de.cuioss.test.generator.internal.net.java.quickcheck.generator.distribution;
017
018import static java.lang.Math.abs;
019
020/**
021 * <a href=
022 * "http://en.wikipedia.org/wiki/Image:Normal_distribution_pdf.png">Normal
023 * distribution</a> and <a href=
024 * "http://en.wikipedia.org/wiki/Image:Uniform_distribution_PDF.png">uniform
025 * distribution</a> distribution functions.
026 *
027 * @author $Id$
028 */
029public interface Distribution {
030
031    /**
032     * Right side of the bell curve. Values range from 0.0 to 1.0. Values near 0.0
033     * are the most probable.
034     */
035    Distribution POSITIV_NORMAL = new AbstractDistribution() {
036
037        @Override
038        public double nextRandomNumber() {
039            return abs(nextGausian());
040        }
041    };
042
043    /**
044     * Left side of the bell curve. Values range from 0.0 to 1.0. Values near 1.0
045     * are the most probable.
046     */
047    Distribution NEGATIV_NORMAL = new AbstractDistribution() {
048
049        @Override
050        public double nextRandomNumber() {
051            return abs(-1 + abs(nextGausian()));
052        }
053    };
054
055    /**
056     * An inverted bell curve. Values range from 0.0 to 1.0. Values near 0.0 and 1.0
057     * are the most probable.
058     */
059    Distribution INVERTED_NORMAL = new AbstractDistribution() {
060
061        @Override
062        public double nextRandomNumber() {
063            double next = nextGausian(N_SIGMA * 2);
064            return (next < 0) ? 1 + next : next;
065        }
066    };
067
068    /**
069     * A uniform distribution function. Values range from 0.0 to 1.0.
070     */
071    Distribution UNIFORM = new AbstractDistribution() {
072
073        @Override
074        public double nextRandomNumber() {
075            return RandomConfiguration.random.nextDouble();
076        }
077    };
078
079    /**
080     * Generate the next random number for this distribution function.
081     *
082     * @return double 0 &lt;= x &lt;= 1.0
083     */
084    double nextRandomNumber();
085
086    abstract class AbstractDistribution implements Distribution {
087
088        static final int N_SIGMA = 3;
089
090        double nextGausian() {
091            return nextGausian(N_SIGMA);
092        }
093
094        double nextGausian(int sigma) {
095            // n * sigma range normalized to 1.0
096            return (RandomConfiguration.random.nextGaussian() % sigma) / sigma;
097        }
098    }
099}