001package stdlib;
002
003/* ***********************************************************************
004 *  Compilation:  javac StdStats.java
005 *  Execution:    java StdStats < input.txt
006 *
007 *  Library of statistical functions.
008 *
009 *  The test client reads an array of real numbers from standard
010 *  input, and computes the minimum, mean, maximum, and
011 *  standard deviation.
012 *
013 *  The functions all throw a NullPointerException if the array
014 *  passed in is null.
015
016 *  % more tiny.txt
017 *  5
018 *  3.0 1.0 2.0 5.0 4.0
019 *
020 *  % java StdStats < tiny.txt
021 *         min   1.000
022 *        mean   3.000
023 *         max   5.000
024 *     std dev   1.581
025 *
026 *************************************************************************/
027
028/**
029 *  <i>Standard statistics</i>. This class provides methods for computing
030 *  statistics such as min, max, mean, sample standard deviation, and
031 *  sample variance.
032 *  <p>
033 *  For additional documentation, see
034 *  <a href="http://introcs.cs.princeton.edu/22library">Section 2.2</a> of
035 *  <i>Introduction to Programming in Java: An Interdisciplinary Approach</i>
036 *  by Robert Sedgewick and Kevin Wayne.
037 */
038public final class StdStats {
039
040        private StdStats() { }
041
042        /**
043         * Return maximum value in array, -infinity if no such value.
044         */
045        public static double max(double[] a) {
046                double max = Double.NEGATIVE_INFINITY;
047                for (int i = 0; i < a.length; i++) {
048                        if (a[i] > max) max = a[i];
049                }
050                return max;
051        }
052
053        /**
054         * Return maximum value in subarray a[lo..hi], -infinity if no such value.
055         */
056        public static double max(double[] a, int lo, int hi) {
057                if (lo < 0 || hi >= a.length || lo > hi)
058                        throw new RuntimeException("Subarray indices out of bounds");
059                double max = Double.NEGATIVE_INFINITY;
060                for (int i = lo; i <= hi; i++) {
061                        if (a[i] > max) max = a[i];
062                }
063                return max;
064        }
065
066        /**
067         * Return maximum value of array, Integer.MIN_VALUE if no such value
068         */
069        public static int max(int[] a) {
070                int max = Integer.MIN_VALUE;
071                for (int i = 0; i < a.length; i++) {
072                        if (a[i] > max) max = a[i];
073                }
074                return max;
075        }
076
077        /**
078         * Return minimum value in array, +infinity if no such value.
079         */
080        public static double min(double[] a) {
081                double min = Double.POSITIVE_INFINITY;
082                for (int i = 0; i < a.length; i++) {
083                        if (a[i] < min) min = a[i];
084                }
085                return min;
086        }
087
088        /**
089         * Return minimum value in subarray a[lo..hi], +infinity if no such value.
090         */
091        public static double min(double[] a, int lo, int hi) {
092                if (lo < 0 || hi >= a.length || lo > hi)
093                        throw new RuntimeException("Subarray indices out of bounds");
094                double min = Double.POSITIVE_INFINITY;
095                for (int i = lo; i <= hi; i++) {
096                        if (a[i] < min) min = a[i];
097                }
098                return min;
099        }
100
101        /**
102         * Return minimum value of array, Integer.MAX_VALUE if no such value
103         */
104        public static int min(int[] a) {
105                int min = Integer.MAX_VALUE;
106                for (int i = 0; i < a.length; i++) {
107                        if (a[i] < min) min = a[i];
108                }
109                return min;
110        }
111
112        /**
113         * Return average value in array, NaN if no such value.
114         */
115        public static double mean(double[] a) {
116                if (a.length == 0) return Double.NaN;
117                double sum = sum(a);
118                return sum / a.length;
119        }
120
121        /**
122         * Return average value in subarray a[lo..hi], NaN if no such value.
123         */
124        public static double mean(double[] a, int lo, int hi) {
125                int length = hi - lo + 1;
126                if (lo < 0 || hi >= a.length || lo > hi)
127                        throw new RuntimeException("Subarray indices out of bounds");
128                if (length == 0) return Double.NaN;
129                double sum = sum(a, lo, hi);
130                return sum / length;
131        }
132
133        /**
134         * Return average value in array, NaN if no such value.
135         */
136        public static double mean(int[] a) {
137                if (a.length == 0) return Double.NaN;
138                double sum = 0.0;
139                for (int i = 0; i < a.length; i++) {
140                        sum = sum + a[i];
141                }
142                return sum / a.length;
143        }
144
145        /**
146         * Return sample variance of array, NaN if no such value.
147         */
148        public static double var(double[] a) {
149                if (a.length == 0) return Double.NaN;
150                double avg = mean(a);
151                double sum = 0.0;
152                for (int i = 0; i < a.length; i++) {
153                        sum += (a[i] - avg) * (a[i] - avg);
154                }
155                return sum / (a.length - 1);
156        }
157
158        /**
159         * Return sample variance of subarray a[lo..hi], NaN if no such value.
160         */
161        public static double var(double[] a, int lo, int hi) {
162                int length = hi - lo + 1;
163                if (lo < 0 || hi >= a.length || lo > hi)
164                        throw new RuntimeException("Subarray indices out of bounds");
165                if (length == 0) return Double.NaN;
166                double avg = mean(a, lo, hi);
167                double sum = 0.0;
168                for (int i = lo; i <= hi; i++) {
169                        sum += (a[i] - avg) * (a[i] - avg);
170                }
171                return sum / (length - 1);
172        }
173
174        /**
175         * Return sample variance of array, NaN if no such value.
176         */
177        public static double var(int[] a) {
178                if (a.length == 0) return Double.NaN;
179                double avg = mean(a);
180                double sum = 0.0;
181                for (int i = 0; i < a.length; i++) {
182                        sum += (a[i] - avg) * (a[i] - avg);
183                }
184                return sum / (a.length - 1);
185        }
186
187        /**
188         * Return population variance of array, NaN if no such value.
189         */
190        public static double varp(double[] a) {
191                if (a.length == 0) return Double.NaN;
192                double avg = mean(a);
193                double sum = 0.0;
194                for (int i = 0; i < a.length; i++) {
195                        sum += (a[i] - avg) * (a[i] - avg);
196                }
197                return sum / a.length;
198        }
199
200        /**
201         * Return population variance of subarray a[lo..hi],  NaN if no such value.
202         */
203        public static double varp(double[] a, int lo, int hi) {
204                int length = hi - lo + 1;
205                if (lo < 0 || hi >= a.length || lo > hi)
206                        throw new RuntimeException("Subarray indices out of bounds");
207                if (length == 0) return Double.NaN;
208                double avg = mean(a, lo, hi);
209                double sum = 0.0;
210                for (int i = lo; i <= hi; i++) {
211                        sum += (a[i] - avg) * (a[i] - avg);
212                }
213                return sum / length;
214        }
215
216
217        /**
218         * Return sample standard deviation of array, NaN if no such value.
219         */
220        public static double stddev(double[] a) {
221                return Math.sqrt(var(a));
222        }
223
224        /**
225         * Return sample standard deviation of subarray a[lo..hi], NaN if no such value.
226         */
227        public static double stddev(double[] a, int lo, int hi) {
228                return Math.sqrt(var(a, lo, hi));
229        }
230
231        /**
232         * Return sample standard deviation of array, NaN if no such value.
233         */
234        public static double stddev(int[] a) {
235                return Math.sqrt(var(a));
236        }
237
238        /**
239         * Return population standard deviation of array, NaN if no such value.
240         */
241        public static double stddevp(double[] a) {
242                return Math.sqrt(varp(a));
243        }
244
245        /**
246         * Return population standard deviation of subarray a[lo..hi], NaN if no such value.
247         */
248        public static double stddevp(double[] a, int lo, int hi) {
249                return Math.sqrt(varp(a, lo, hi));
250        }
251
252        /**
253         * Return sum of all values in array.
254         */
255        public static double sum(double[] a) {
256                double sum = 0.0;
257                for (int i = 0; i < a.length; i++) {
258                        sum += a[i];
259                }
260                return sum;
261        }
262
263        /**
264         * Return sum of all values in subarray a[lo..hi].
265         */
266        public static double sum(double[] a, int lo, int hi) {
267                if (lo < 0 || hi >= a.length || lo > hi)
268                        throw new RuntimeException("Subarray indices out of bounds");
269                double sum = 0.0;
270                for (int i = lo; i <= hi; i++) {
271                        sum += a[i];
272                }
273                return sum;
274        }
275
276        /**
277         * Return sum of all values in array.
278         */
279        public static int sum(int[] a) {
280                int sum = 0;
281                for (int i = 0; i < a.length; i++) {
282                        sum += a[i];
283                }
284                return sum;
285        }
286
287        /**
288         * Plot points (i, a[i]) to standard draw.
289         */
290        public static void plotPoints(double[] a) {
291                int N = a.length;
292                StdDraw.setXscale(0, N-1);
293                StdDraw.setPenRadius(1.0 / (3.0 * N));
294                for (int i = 0; i < N; i++) {
295                        StdDraw.point(i, a[i]);
296                }
297        }
298
299        /**
300         * Plot line segments connecting points (i, a[i]) to standard draw.
301         */
302        public static void plotLines(double[] a) {
303                int N = a.length;
304                StdDraw.setXscale(0, N-1);
305                StdDraw.setPenRadius();
306                for (int i = 1; i < N; i++) {
307                        StdDraw.line(i-1, a[i-1], i, a[i]);
308                }
309        }
310
311        /**
312         * Plot bars from (0, a[i]) to (i, a[i]) to standard draw.
313         */
314        public static void plotBars(double[] a) {
315                int N = a.length;
316                StdDraw.setXscale(0, N-1);
317                for (int i = 0; i < N; i++) {
318                        StdDraw.filledRectangle(i, a[i]/2, .25, a[i]/2);
319                }
320        }
321
322
323        /**
324         * Test client.
325         * Convert command-line arguments to array of doubles and call various methods.
326         */
327        public static void main(String[] args) {
328                double[] a = ArrayGenerator.readDouble1D(new In ());
329                StdOut.format("       min %7.3f\n", min(a));
330                StdOut.format("      mean %7.3f\n", mean(a));
331                StdOut.format("       max %7.3f\n", max(a));
332                StdOut.format("   std dev %7.3f\n", stddev(a));
333        }
334}