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