SSJ API Documentation
Stochastic Simulation in Java
Loading...
Searching...
No Matches
PiecewiseLinearEmpiricalDist.java
1/*
2 * Class: PiecewiseLinearEmpiricalDist
3 * Description: piecewise-linear empirical distribution
4 * Environment: Java
5 * Software: SSJ
6 * Copyright (C) 2001 Pierre L'Ecuyer and Universite de Montreal
7 * Organization: DIRO, Universite de Montreal
8 * @author
9 * @since
10 *
11 *
12 * Licensed under the Apache License, Version 2.0 (the "License");
13 * you may not use this file except in compliance with the License.
14 * You may obtain a copy of the License at
15 *
16 * http://www.apache.org/licenses/LICENSE-2.0
17 *
18 * Unless required by applicable law or agreed to in writing, software
19 * distributed under the License is distributed on an "AS IS" BASIS,
20 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21 * See the License for the specific language governing permissions and
22 * limitations under the License.
23 *
24 */
25package umontreal.ssj.probdist;
26
27import java.util.Formatter;
28import java.util.Locale;
29import umontreal.ssj.util.Num;
30import umontreal.ssj.util.PrintfFormat;
31import java.util.Arrays;
32import java.io.IOException;
33import java.io.Reader;
34import java.io.BufferedReader;
35
59 private double[] sortedObs;
60 private double[] diffObs;
61 private int n = 0;
62 private double sampleMean;
63 private double sampleVariance;
64 private double sampleStandardDeviation;
65
71 public PiecewiseLinearEmpiricalDist(double[] obs) {
72 if (obs.length <= 1)
73 throw new IllegalArgumentException("Two or more observations are needed");
74 // sortedObs = obs;
75 n = obs.length;
76 sortedObs = new double[n];
77 System.arraycopy(obs, 0, sortedObs, 0, n);
78 init();
79 }
80
88 public PiecewiseLinearEmpiricalDist(Reader in) throws IOException {
89 BufferedReader inb = new BufferedReader(in);
90 double[] data = new double[5];
91 String li;
92 while ((li = inb.readLine()) != null) {
93 // look for the first non-digit character on the read line
94 int index = 0;
95 while (index < li.length() && (li.charAt(index) == '+' || li.charAt(index) == '-' || li.charAt(index) == 'e'
96 || li.charAt(index) == 'E' || li.charAt(index) == '.' || Character.isDigit(li.charAt(index))))
97 ++index;
98
99 // truncate the line
100 li = li.substring(0, index);
101 if (!li.equals("")) {
102 try {
103 data[n++] = Double.parseDouble(li);
104 if (n >= data.length) {
105 double[] newData = new double[2 * n];
106 System.arraycopy(data, 0, newData, 0, data.length);
107 data = newData;
108 }
109 } catch (NumberFormatException nfe) {
110 }
111 }
112 }
113 sortedObs = new double[n];
114 System.arraycopy(data, 0, sortedObs, 0, n);
115 init();
116 }
117
118 public double density(double x) {
119 // This is implemented via a linear search: very inefficient!!!
120 if (x < sortedObs[0] || x >= sortedObs[n - 1])
121 return 0;
122 for (int i = 0; i < (n - 1); i++) {
123 if (x >= sortedObs[i] && x < sortedObs[i + 1])
124 return 1.0 / ((n - 1) * diffObs[i]);
125 }
126 throw new IllegalStateException();
127 }
128
129 public double cdf(double x) {
130 // This is implemented via a linear search: very inefficient!!!
131 if (x <= sortedObs[0])
132 return 0;
133 if (x >= sortedObs[n - 1])
134 return 1;
135 for (int i = 0; i < (n - 1); i++) {
136 if (x >= sortedObs[i] && x < sortedObs[i + 1])
137 return i / (n - 1.0) + (x - sortedObs[i]) / ((n - 1.0) * diffObs[i]);
138 }
139 throw new IllegalStateException();
140 }
141
142 public double barF(double x) {
143 // This is implemented via a linear search: very inefficient!!!
144 if (x <= sortedObs[0])
145 return 1;
146 if (x >= sortedObs[n - 1])
147 return 0;
148 for (int i = 0; i < (n - 1); i++) {
149 if (x >= sortedObs[i] && x < sortedObs[i + 1])
150 return (n - 1.0 - i) / (n - 1.0) - (x - sortedObs[i]) / ((n - 1.0) * diffObs[i]);
151 }
152 throw new IllegalStateException();
153 }
154
155 public double inverseF(double u) {
156 if (u < 0 || u > 1)
157 throw new IllegalArgumentException("u is not in [0,1]");
158 if (u <= 0.0)
159 return sortedObs[0];
160 if (u >= 1.0)
161 return sortedObs[n - 1];
162 double p = (n - 1) * u;
163 int i = (int) Math.floor(p);
164 if (i == (n - 1))
165 return sortedObs[n - 1];
166 else
167 return sortedObs[i] + (p - i) * diffObs[i];
168 }
169
170 public double getMean() {
171 return sampleMean;
172 }
173
174 public double getVariance() {
175 return sampleVariance;
176 }
177
178 public double getStandardDeviation() {
179 return sampleStandardDeviation;
180 }
181
182 private void init() {
183 Arrays.sort(sortedObs);
184 // n = sortedObs.length;
185 diffObs = new double[sortedObs.length];
186 double sum = 0.0;
187 for (int i = 0; i < diffObs.length - 1; i++) {
188 diffObs[i] = sortedObs[i + 1] - sortedObs[i];
189 sum += sortedObs[i];
190 }
191 diffObs[n - 1] = 0.0; // Can be useful in case i=n-1 in inverseF.
192 sum += sortedObs[n - 1];
193 sampleMean = sum / n;
194 sum = 0.0;
195 for (int i = 0; i < n; i++) {
196 double coeff = (sortedObs[i] - sampleMean);
197 sum += coeff * coeff;
198 }
199 sampleVariance = sum / (n - 1);
200 sampleStandardDeviation = Math.sqrt(sampleVariance);
201 supportA = sortedObs[0] * (1.0 - Num.DBL_EPSILON);
202 supportB = sortedObs[n - 1] * (1.0 + Num.DBL_EPSILON);
203 }
204
208 public int getN() {
209 return n;
210 }
211
215 public double getObs(int i) {
216 return sortedObs[i];
217 }
218
222 public double getSampleMean() {
223 return sampleMean;
224 }
225
229 public double getSampleVariance() {
230 return sampleVariance;
231 }
232
237 return sampleStandardDeviation;
238 }
239
243 public double[] getParams() {
244 double[] retour = new double[n];
245 System.arraycopy(sortedObs, 0, retour, 0, n);
246 return retour;
247 }
248
252 public String toString() {
253 StringBuilder sb = new StringBuilder();
254 Formatter formatter = new Formatter(sb, Locale.US);
255 formatter.format(getClass().getSimpleName() + PrintfFormat.NEWLINE);
256 for (int i = 0; i < n; i++) {
257 formatter.format("%f%n", sortedObs[i]);
258 }
259 return sb.toString();
260 }
261
262}
Classes implementing continuous distributions should inherit from this base class.
double getSampleVariance()
Returns the sample variance of the observations.
double density(double x)
Returns , the density evaluated at .
double[] getParams()
Return a table containing parameters of the current distribution.
double cdf(double x)
Returns the distribution function .
double getSampleMean()
Returns the sample mean of the observations.
PiecewiseLinearEmpiricalDist(Reader in)
Constructs a new empirical distribution using the observations read from the reader in.
double getSampleStandardDeviation()
Returns the sample standard deviation of the observations.
String toString()
Returns a String containing information about the current distribution.
PiecewiseLinearEmpiricalDist(double[] obs)
Constructs a new piecewise-linear distribution using all the observations stored in obs.
double barF(double x)
Returns the complementary distribution function.
double inverseF(double u)
Returns the inverse distribution function .
This class acts like a StringBuffer which defines new types of append methods.
static final String NEWLINE
End-of-line symbol or line separator.