BinomialDistribution.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.checkProbability;
025 
026 import java.io.Serializable;
027 
028 import org.jenetics.util.Function;
029 import org.jenetics.util.Range;
030 
031 /**
032  * TODO: implement BinomialDistribution
033  *
034  @author <a href="mailto:franz.wilhelmstoetter@gmx.at">Franz Wilhelmstötter</a>
035  @since 1.0
036  @version 2.0 &mdash; <em>$Date: 2014-03-12 $</em>
037  */
038 class BinomialDistribution<
039     extends Number & Comparable<? super N>
040 >
041     implements Distribution<N>
042 {
043 
044     static final class PDF<N extends Number & Comparable<? super N>>
045         implements
046             Function<N, Double>,
047             Serializable
048     {
049         private static final long serialVersionUID = 2L;
050 
051         private final Range<N> _domain;
052 
053         private final long _N;
054         private final double _p;
055         private final double _q;
056 
057         public PDF(final Range<N> domain, final double p) {
058             _domain = domain;
059             _N = domain.getMax().longValue() - domain.getMin().longValue();
060             _p = p;
061             _q = 1.0 - p;
062         }
063 
064         @Override
065         public Double apply(final N value) {
066             final long x = value.longValue() - _domain.getMin().longValue();
067 
068             double result = 0.0;
069             if (_domain.contains(value)) {
070                 result = binomial(_N, x)*Math.pow(_p, x)*Math.pow(_q, _N - x);
071             }
072 
073             return result;
074         }
075 
076         @Override
077         public String toString() {
078             return format("p(x) = %s""");
079         }
080 
081     }
082 
083     static final class CDF<N extends Number & Comparable<? super N>>
084         implements
085             Function<N, Double>,
086             Serializable
087     {
088         private static final long serialVersionUID = 2L;
089 
090         private final Range<N> _domain;
091 
092         private final long _N;
093         private final double _p;
094         private final double _q;
095 
096         public CDF(final Range<N> domain, final double p) {
097             _domain = domain;
098             _N = domain.getMax().longValue() - domain.getMin().longValue();
099             _p = p;
100             _q = 1.0 - p;
101         }
102 
103         @Override
104         public Double apply(final N value) {
105             long x = value.longValue();
106 
107             double result = 0.0;
108             if (_domain.getMin().longValue() > x) {
109                 result = 0.0;
110             else if (_domain.getMax().longValue() < x) {
111                 result = 1.0;
112             else {
113                 x = x - _domain.getMin().longValue();
114                 double v = 0;
115                 for (long i = 0; i <= x; ++i) {
116                     v += binomial(_N, i)*Math.pow(_p, i)*Math.pow(_q, _N - i);
117                 }
118                 result = v;
119             }
120 
121             return result;
122         }
123 
124         @Override
125         public String toString() {
126             return format("p(x) = %s""");
127         }
128 
129     }
130 
131     private final Range<N> _domain;
132     private final double _p;
133 
134     public BinomialDistribution(final Range<N> domain, final double p) {
135         _domain = requireNonNull(domain, "Domain");
136         _p = checkProbability(p);
137     }
138 
139     @Override
140     public Range<N> getDomain() {
141         return _domain;
142     }
143 
144     @Override
145     public Function<N, Double> getCDF() {
146         return new CDF<>(_domain, _p);
147     }
148 
149     @Override
150     public Function<N, Double> getPDF() {
151         return new PDF<>(_domain, _p);
152     }
153 
154     private static double binomial(final long n, final long k) {
155         long b = 1;
156         for (long i = 1; i <= k; ++i) {
157             b *= (n - k + i)/i;
158         }
159         return b;
160     }
161 
162 }