UniformDistribution.java
001 /*
002  * Java Genetic Algorithm Library (jenetics-2.0.2).
003  * Copyright (c) 2007-2014 Franz Wilhelmstötter
004  *
005  * Licensed under the Apache License, Version 2.0 (the "License");
006  * you may not use this file except in compliance with the License.
007  * You may obtain a copy of the License at
008  *
009  *      http://www.apache.org/licenses/LICENSE-2.0
010  *
011  * Unless required by applicable law or agreed to in writing, software
012  * distributed under the License is distributed on an "AS IS" BASIS,
013  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014  * See the License for the specific language governing permissions and
015  * limitations under the License.
016  *
017  * Author:
018  *    Franz Wilhelmstötter (franz.wilhelmstoetter@gmx.at)
019  */
020 package org.jenetics.stat;
021 
022 import static java.lang.String.format;
023 import static java.util.Objects.requireNonNull;
024 import static org.jenetics.internal.util.object.eq;
025 
026 import java.io.Serializable;
027 import java.util.Locale;
028 
029 import org.jenetics.internal.util.HashBuilder;
030 
031 import org.jenetics.util.Function;
032 import org.jenetics.util.Range;
033 
034 
035 /**
036  * <a href="http://en.wikipedia.org/wiki/Uniform_distribution_%28continuous%29">
037  * Uniform distribution</a> class.
038  *
039  @see LinearDistribution
040  *
041  @author <a href="mailto:franz.wilhelmstoetter@gmx.at">Franz Wilhelmstötter</a>
042  @since 1.0
043  @version 2.0 &mdash; <em>$Date: 2014-03-28 $</em>
044  */
045 public class UniformDistribution<
046     extends Number & Comparable<? super N>
047 >
048     implements Distribution<N>
049 {
050 
051     /**
052      <p>
053      <img
054      *     src="doc-files/uniform-pdf.gif"
055      *     alt="f(x)=\left\{\begin{matrix}
056      *          \frac{1}{max-min} & for & x \in [min, max] \\
057      *          0 & & otherwise \\
058      *          \end{matrix}\right."
059      * >
060      </p>
061      *
062      @author <a href="mailto:franz.wilhelmstoetter@gmx.at">Franz Wilhelmstötter</a>
063      @since 1.0
064      @version 2.0 &mdash; <em>$Date: 2014-03-28 $</em>
065      */
066     static final class PDF<N extends Number & Comparable<? super N>>
067         implements
068             Function<N, Double>,
069             Serializable
070     {
071         private static final long serialVersionUID = 2L;
072 
073         private final double _min;
074         private final double _max;
075         private final Double _probability;
076 
077         public PDF(final Range<N> domain) {
078             _min = domain.getMin().doubleValue();
079             _max = domain.getMax().doubleValue();
080             _probability = 1.0/(_max - _min);
081         }
082 
083         @Override
084         public Double apply(final N value) {
085             final double x = value.doubleValue();
086 
087             double result = 0.0;
088             if (x >= _min && x <= _max) {
089                 result = _probability;
090             }
091 
092             return result;
093         }
094 
095         @Override
096         public String toString() {
097             return format(Locale.ENGLISH, "p(x) = %s", _probability);
098         }
099 
100     }
101 
102     /**
103      <p>
104      <img
105      *     src="doc-files/uniform-cdf.gif"
106      *     alt="f(x)=\left\{\begin{matrix}
107      *         0 & for & x < min \\
108      *         \frac{x-min}{max-min} & for & x \in [min, max] \\
109      *         1 & for & x > max  \\
110      *         \end{matrix}\right."
111      * >
112      </p>
113      *
114      @author <a href="mailto:franz.wilhelmstoetter@gmx.at">Franz Wilhelmstötter</a>
115      @since 1.0
116      @version 2.0 &mdash; <em>$Date: 2014-03-28 $</em>
117      */
118     static final class CDF<N extends Number & Comparable<? super N>>
119         implements
120             Function<N, Double>,
121             Serializable
122     {
123         private static final long serialVersionUID = 2L;
124 
125 
126         private final double _min;
127         private final double _max;
128         private final double _divisor;
129 
130         public CDF(final Range<N> domain) {
131             _min = domain.getMin().doubleValue();
132             _max = domain.getMax().doubleValue();
133             _divisor = _max - _min;
134             assert (_divisor > 0);
135         }
136 
137         @Override
138         public Double apply(final N value) {
139             final double x = value.doubleValue();
140 
141             double result = 0.0;
142             if (x < _min) {
143                 result = 0.0;
144             else if (x > _max) {
145                 result = 1.0;
146             else {
147                 result = (x - _min)/_divisor;
148             }
149 
150             return result;
151         }
152 
153         @Override
154         public String toString() {
155             return format(
156                 Locale.ENGLISH,
157                 "P(x) = (x - %1$s)/(%2$s - %1$s)", _min, _max
158             );
159         }
160 
161     }
162 
163 
164     private final Range<N> _domain;
165     private final Function<N, Double> _cdf;
166     private final Function<N, Double> _pdf;
167 
168     /**
169      * Create a new uniform distribution with the given {@code domain}.
170      *
171      @param domain the domain of the distribution.
172      @throws NullPointerException if the {@code domain} is {@code null}.
173      */
174     public UniformDistribution(final Range<N> domain) {
175         _domain = requireNonNull(domain, "Domain");
176         _cdf = new CDF<>(_domain);
177         _pdf = new PDF<>(_domain);
178     }
179 
180     /**
181      * Create a new uniform distribution with the given min and max values.
182      *
183      @param min the minimum value of the domain.
184      @param max the maximum value of the domain.
185      @throws IllegalArgumentException if {@code min >= max}
186      @throws NullPointerException if one of the arguments is {@code null}.
187      */
188     public UniformDistribution(final N min, final N max) {
189         this(new Range<>(min, max));
190     }
191 
192     @Override
193     public Range<N> getDomain() {
194         return _domain;
195     }
196 
197     /**
198      * Return a new PDF object.
199      *
200      <p>
201      <img
202      *     src="doc-files/uniform-pdf.gif"
203      *     alt="f(x)=\left\{\begin{matrix}
204      *          \frac{1}{max-min} & for & x \in [min, max] \\
205      *          0 & & otherwise \\
206      *          \end{matrix}\right."
207      * >
208      </p>
209      *
210      */
211     @Override
212     public Function<N, Double> getPDF() {
213         return _pdf;
214     }
215 
216     /**
217      * Return a new CDF object.
218      *
219      <p>
220      <img
221      *     src="doc-files/uniform-cdf.gif"
222      *     alt="f(x)=\left\{\begin{matrix}
223      *         0 & for & x < min \\
224      *         \frac{x-min}{max-min} & for & x \in [min, max] \\
225      *         1 & for & x > max  \\
226      *         \end{matrix}\right."
227      * >
228      </p>
229      *
230      */
231     @Override
232     public Function<N, Double> getCDF() {
233         return _cdf;
234     }
235 
236     @Override
237     public int hashCode() {
238         return HashBuilder.of(getClass()).and(_domain).value();
239     }
240 
241     @Override
242     public boolean equals(final Object obj) {
243         if (obj == this) {
244             return true;
245         }
246         if (obj == null || getClass() != obj.getClass()) {
247             return false;
248         }
249 
250         final UniformDistribution<?> dist = (UniformDistribution<?>)obj;
251         return eq(_domain, dist._domain);
252     }
253 
254     @Override
255     public String toString() {
256         return format("UniformDistribution[%s]", _domain);
257     }
258 
259 }