1dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond/*
2dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Licensed to the Apache Software Foundation (ASF) under one or more
3dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * contributor license agreements.  See the NOTICE file distributed with
4dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * this work for additional information regarding copyright ownership.
5dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * The ASF licenses this file to You under the Apache License, Version 2.0
6dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * (the "License"); you may not use this file except in compliance with
7dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * the License.  You may obtain a copy of the License at
8dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond *
9dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond *      http://www.apache.org/licenses/LICENSE-2.0
10dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond *
11dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Unless required by applicable law or agreed to in writing, software
12dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * distributed under the License is distributed on an "AS IS" BASIS,
13dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * See the License for the specific language governing permissions and
15dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * limitations under the License.
16dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */
17dee0849a9704d532af0b550146cbafbaa6ee1d19Raymondpackage org.apache.commons.math.stat;
18dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
19dee0849a9704d532af0b550146cbafbaa6ee1d19Raymondimport java.io.Serializable;
20dee0849a9704d532af0b550146cbafbaa6ee1d19Raymondimport java.text.NumberFormat;
21dee0849a9704d532af0b550146cbafbaa6ee1d19Raymondimport java.util.Iterator;
22dee0849a9704d532af0b550146cbafbaa6ee1d19Raymondimport java.util.Comparator;
23dee0849a9704d532af0b550146cbafbaa6ee1d19Raymondimport java.util.TreeMap;
24dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
25dee0849a9704d532af0b550146cbafbaa6ee1d19Raymondimport org.apache.commons.math.MathRuntimeException;
26dee0849a9704d532af0b550146cbafbaa6ee1d19Raymondimport org.apache.commons.math.exception.util.LocalizedFormats;
27dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
28dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond/**
29dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Maintains a frequency distribution.
30dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <p>
31dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Accepts int, long, char or Comparable values.  New values added must be
32dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * comparable to those that have been added, otherwise the add method will
33dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * throw an IllegalArgumentException.</p>
34dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <p>
35dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Integer values (int, long, Integer, Long) are not distinguished by type --
36dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * i.e. <code>addValue(Long.valueOf(2)), addValue(2), addValue(2l)</code> all have
37dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * the same effect (similarly for arguments to <code>getCount,</code> etc.).</p>
38dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <p>
39dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * char values are converted by <code>addValue</code> to Character instances.
40dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * As such, these values are not comparable to integral values, so attempts
41dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * to combine integral types with chars in a frequency distribution will fail.
42dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * </p>
43dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <p>
44dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * The values are ordered using the default (natural order), unless a
45dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <code>Comparator</code> is supplied in the constructor.</p>
46dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond *
47dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @version $Revision: 1054186 $ $Date: 2011-01-01 03:28:46 +0100 (sam. 01 janv. 2011) $
48dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */
49dee0849a9704d532af0b550146cbafbaa6ee1d19Raymondpublic class Frequency implements Serializable {
50dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
51dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** Serializable version identifier */
52dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    private static final long serialVersionUID = -3845586908418844111L;
53dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
54dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** underlying collection */
55dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    private final TreeMap<Comparable<?>, Long> freqTable;
56dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
57dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /**
58dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * Default constructor.
59dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
60dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public Frequency() {
61dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        freqTable = new TreeMap<Comparable<?>, Long>();
62dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
63dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
64dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /**
65dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * Constructor allowing values Comparator to be specified.
66dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     *
67dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param comparator Comparator used to order values
68dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
69dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    @SuppressWarnings("unchecked") // TODO is the cast OK?
70dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public Frequency(Comparator<?> comparator) {
71dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        freqTable = new TreeMap<Comparable<?>, Long>((Comparator<? super Comparable<?>>) comparator);
72dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
73dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
74dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /**
75dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * Return a string representation of this frequency
76dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * distribution.
77dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     *
78dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @return a string representation.
79dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
80dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    @Override
81dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public String toString() {
82dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        NumberFormat nf = NumberFormat.getPercentInstance();
83dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        StringBuilder outBuffer = new StringBuilder();
84dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        outBuffer.append("Value \t Freq. \t Pct. \t Cum Pct. \n");
85dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        Iterator<Comparable<?>> iter = freqTable.keySet().iterator();
86dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        while (iter.hasNext()) {
87dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            Comparable<?> value = iter.next();
88dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            outBuffer.append(value);
89dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            outBuffer.append('\t');
90dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            outBuffer.append(getCount(value));
91dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            outBuffer.append('\t');
92dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            outBuffer.append(nf.format(getPct(value)));
93dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            outBuffer.append('\t');
94dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            outBuffer.append(nf.format(getCumPct(value)));
95dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            outBuffer.append('\n');
96dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        }
97dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return outBuffer.toString();
98dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
99dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
100dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /**
101dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * Adds 1 to the frequency count for v.
102dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * <p>
103dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * If other objects have already been added to this Frequency, v must
104dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * be comparable to those that have already been added.
105dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * </p>
106dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     *
107dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param v the value to add.
108dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @throws IllegalArgumentException if <code>v</code> is not Comparable,
109dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     *         or is not comparable with previous entries
110dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @deprecated use {@link #addValue(Comparable)} instead
111dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
112dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    @Deprecated
113dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public void addValue(Object v) {
114dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        if (v instanceof Comparable<?>){
115dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            addValue((Comparable<?>) v);
116dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        } else {
117dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            throw MathRuntimeException.createIllegalArgumentException(
118dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                  LocalizedFormats.CLASS_DOESNT_IMPLEMENT_COMPARABLE,
119dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                  v.getClass().getName());
120dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        }
121dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
122dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
123dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /**
124dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * Adds 1 to the frequency count for v.
125dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * <p>
126dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * If other objects have already been added to this Frequency, v must
127dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * be comparable to those that have already been added.
128dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * </p>
129dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     *
130dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param v the value to add.
131dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @throws IllegalArgumentException if <code>v</code> is not comparable with previous entries
132dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
133dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public void addValue(Comparable<?> v){
134dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        Comparable<?> obj = v;
135dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        if (v instanceof Integer) {
136dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond           obj = Long.valueOf(((Integer) v).longValue());
137dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        }
138dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        try {
139dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            Long count = freqTable.get(obj);
140dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            if (count == null) {
141dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                freqTable.put(obj, Long.valueOf(1));
142dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            } else {
143dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                freqTable.put(obj, Long.valueOf(count.longValue() + 1));
144dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            }
145dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        } catch (ClassCastException ex) {
146dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            //TreeMap will throw ClassCastException if v is not comparable
147dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            throw MathRuntimeException.createIllegalArgumentException(
148dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                  LocalizedFormats.INSTANCES_NOT_COMPARABLE_TO_EXISTING_VALUES,
149dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                  v.getClass().getName());
150dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        }
151dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
152dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
153dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /**
154dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * Adds 1 to the frequency count for v.
155dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     *
156dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param v the value to add.
157dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
158dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public void addValue(int v) {
159dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        addValue(Long.valueOf(v));
160dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
161dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
162dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /**
163dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * Adds 1 to the frequency count for v.
164dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     *
165dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param v the value to add.
166dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @deprecated to be removed in math 3.0
167dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
168dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    @Deprecated
169dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public void addValue(Integer v) {
170dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        addValue(Long.valueOf(v.longValue()));
171dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
172dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
173dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /**
174dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * Adds 1 to the frequency count for v.
175dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     *
176dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param v the value to add.
177dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
178dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public void addValue(long v) {
179dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        addValue(Long.valueOf(v));
180dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
181dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
182dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /**
183dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * Adds 1 to the frequency count for v.
184dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     *
185dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param v the value to add.
186dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
187dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public void addValue(char v) {
188dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        addValue(Character.valueOf(v));
189dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
190dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
191dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** Clears the frequency table */
192dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public void clear() {
193dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        freqTable.clear();
194dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
195dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
196dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /**
197dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * Returns an Iterator over the set of values that have been added.
198dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * <p>
199dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * If added values are integral (i.e., integers, longs, Integers, or Longs),
200dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * they are converted to Longs when they are added, so the objects returned
201dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * by the Iterator will in this case be Longs.</p>
202dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     *
203dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @return values Iterator
204dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
205dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public Iterator<Comparable<?>> valuesIterator() {
206dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return freqTable.keySet().iterator();
207dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
208dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
209dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    //-------------------------------------------------------------------------
210dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
211dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /**
212dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * Returns the sum of all frequencies.
213dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     *
214dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @return the total frequency count.
215dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
216dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public long getSumFreq() {
217dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        long result = 0;
218dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        Iterator<Long> iterator = freqTable.values().iterator();
219dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        while (iterator.hasNext())  {
220dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            result += iterator.next().longValue();
221dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        }
222dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return result;
223dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
224dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
225dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /**
226dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * Returns the number of values = v.
227dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * Returns 0 if the value is not comparable.
228dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     *
229dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param v the value to lookup.
230dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @return the frequency of v.
231dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @deprecated replaced by {@link #getCount(Comparable)} as of 2.0
232dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
233dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    @Deprecated
234dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public long getCount(Object v) {
235dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return getCount((Comparable<?>) v);
236dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
237dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
238dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /**
239dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * Returns the number of values = v.
240dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * Returns 0 if the value is not comparable.
241dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     *
242dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param v the value to lookup.
243dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @return the frequency of v.
244dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
245dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public long getCount(Comparable<?> v) {
246dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        if (v instanceof Integer) {
247dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            return getCount(((Integer) v).longValue());
248dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        }
249dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        long result = 0;
250dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        try {
251dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            Long count =  freqTable.get(v);
252dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            if (count != null) {
253dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                result = count.longValue();
254dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            }
255dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        } catch (ClassCastException ex) {
256dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            // ignore and return 0 -- ClassCastException will be thrown if value is not comparable
257dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        }
258dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return result;
259dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
260dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
261dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /**
262dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * Returns the number of values = v.
263dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     *
264dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param v the value to lookup.
265dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @return the frequency of v.
266dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
267dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public long getCount(int v) {
268dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return getCount(Long.valueOf(v));
269dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
270dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
271dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /**
272dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * Returns the number of values = v.
273dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     *
274dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param v the value to lookup.
275dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @return the frequency of v.
276dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
277dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public long getCount(long v) {
278dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return getCount(Long.valueOf(v));
279dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
280dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
281dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /**
282dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * Returns the number of values = v.
283dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     *
284dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param v the value to lookup.
285dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @return the frequency of v.
286dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
287dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public long getCount(char v) {
288dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return getCount(Character.valueOf(v));
289dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
290dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
291dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /**
292dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * Returns the number of values in the frequency table.
293dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     *
294dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @return the number of unique values that have been added to the frequency table.
295dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @see #valuesIterator()
296dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
297dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public int getUniqueCount(){
298dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return freqTable.keySet().size();
299dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
300dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
301dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    //-------------------------------------------------------------
302dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
303dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /**
304dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond      * Returns the percentage of values that are equal to v
305dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * (as a proportion between 0 and 1).
306dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * <p>
307dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * Returns <code>Double.NaN</code> if no values have been added.</p>
308dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     *
309dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param v the value to lookup
310dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @return the proportion of values equal to v
311dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @deprecated replaced by {@link #getPct(Comparable)} as of 2.0
312dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
313dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    @Deprecated
314dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public double getPct(Object v) {
315dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return getPct((Comparable<?>) v);
316dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
317dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
318dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /**
319dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * Returns the percentage of values that are equal to v
320dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * (as a proportion between 0 and 1).
321dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * <p>
322dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * Returns <code>Double.NaN</code> if no values have been added.</p>
323dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     *
324dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param v the value to lookup
325dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @return the proportion of values equal to v
326dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
327dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public double getPct(Comparable<?> v) {
328dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        final long sumFreq = getSumFreq();
329dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        if (sumFreq == 0) {
330dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            return Double.NaN;
331dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        }
332dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return (double) getCount(v) / (double) sumFreq;
333dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
334dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
335dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /**
336dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * Returns the percentage of values that are equal to v
337dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * (as a proportion between 0 and 1).
338dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     *
339dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param v the value to lookup
340dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @return the proportion of values equal to v
341dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
342dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public double getPct(int v) {
343dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return getPct(Long.valueOf(v));
344dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
345dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
346dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /**
347dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * Returns the percentage of values that are equal to v
348dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * (as a proportion between 0 and 1).
349dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     *
350dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param v the value to lookup
351dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @return the proportion of values equal to v
352dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
353dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public double getPct(long v) {
354dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return getPct(Long.valueOf(v));
355dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
356dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
357dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /**
358dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * Returns the percentage of values that are equal to v
359dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * (as a proportion between 0 and 1).
360dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     *
361dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param v the value to lookup
362dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @return the proportion of values equal to v
363dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
364dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public double getPct(char v) {
365dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return getPct(Character.valueOf(v));
366dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
367dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
368dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    //-----------------------------------------------------------------------------------------
369dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
370dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /**
371dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * Returns the cumulative frequency of values less than or equal to v.
372dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * <p>
373dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * Returns 0 if v is not comparable to the values set.</p>
374dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     *
375dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param v the value to lookup.
376dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @return the proportion of values equal to v
377dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @deprecated replaced by {@link #getCumFreq(Comparable)} as of 2.0
378dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
379dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    @Deprecated
380dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public long getCumFreq(Object v) {
381dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return getCumFreq((Comparable<?>) v);
382dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
383dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
384dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /**
385dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * Returns the cumulative frequency of values less than or equal to v.
386dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * <p>
387dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * Returns 0 if v is not comparable to the values set.</p>
388dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     *
389dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param v the value to lookup.
390dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @return the proportion of values equal to v
391dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
392dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public long getCumFreq(Comparable<?> v) {
393dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        if (getSumFreq() == 0) {
394dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            return 0;
395dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        }
396dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        if (v instanceof Integer) {
397dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            return getCumFreq(((Integer) v).longValue());
398dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        }
399dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        @SuppressWarnings("unchecked") // OK, freqTable is Comparable<?>
400dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        Comparator<Comparable<?>> c = (Comparator<Comparable<?>>) freqTable.comparator();
401dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        if (c == null) {
402dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            c = new NaturalComparator();
403dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        }
404dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        long result = 0;
405dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
406dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        try {
407dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            Long value = freqTable.get(v);
408dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            if (value != null) {
409dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                result = value.longValue();
410dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            }
411dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        } catch (ClassCastException ex) {
412dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            return result;   // v is not comparable
413dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        }
414dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
415dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        if (c.compare(v, freqTable.firstKey()) < 0) {
416dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            return 0;  // v is comparable, but less than first value
417dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        }
418dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
419dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        if (c.compare(v, freqTable.lastKey()) >= 0) {
420dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            return getSumFreq();    // v is comparable, but greater than the last value
421dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        }
422dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
423dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        Iterator<Comparable<?>> values = valuesIterator();
424dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        while (values.hasNext()) {
425dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            Comparable<?> nextValue = values.next();
426dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            if (c.compare(v, nextValue) > 0) {
427dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                result += getCount(nextValue);
428dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            } else {
429dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                return result;
430dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            }
431dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        }
432dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return result;
433dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
434dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
435dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     /**
436dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * Returns the cumulative frequency of values less than or equal to v.
437dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * <p>
438dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * Returns 0 if v is not comparable to the values set.</p>
439dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     *
440dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param v the value to lookup
441dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @return the proportion of values equal to v
442dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
443dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public long getCumFreq(int v) {
444dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return getCumFreq(Long.valueOf(v));
445dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
446dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
447dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     /**
448dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * Returns the cumulative frequency of values less than or equal to v.
449dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * <p>
450dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * Returns 0 if v is not comparable to the values set.</p>
451dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     *
452dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param v the value to lookup
453dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @return the proportion of values equal to v
454dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
455dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public long getCumFreq(long v) {
456dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return getCumFreq(Long.valueOf(v));
457dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
458dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
459dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /**
460dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * Returns the cumulative frequency of values less than or equal to v.
461dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * <p>
462dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * Returns 0 if v is not comparable to the values set.</p>
463dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     *
464dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param v the value to lookup
465dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @return the proportion of values equal to v
466dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
467dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public long getCumFreq(char v) {
468dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return getCumFreq(Character.valueOf(v));
469dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
470dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
471dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    //----------------------------------------------------------------------------------------------
472dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
473dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /**
474dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * Returns the cumulative percentage of values less than or equal to v
475dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * (as a proportion between 0 and 1).
476dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * <p>
477dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * Returns <code>Double.NaN</code> if no values have been added.
478dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * Returns 0 if at least one value has been added, but v is not comparable
479dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * to the values set.</p>
480dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     *
481dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param v the value to lookup
482dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @return the proportion of values less than or equal to v
483dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @deprecated replaced by {@link #getCumPct(Comparable)} as of 2.0
484dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
485dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    @Deprecated
486dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public double getCumPct(Object v) {
487dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return getCumPct((Comparable<?>) v);
488dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
489dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
490dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
491dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /**
492dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * Returns the cumulative percentage of values less than or equal to v
493dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * (as a proportion between 0 and 1).
494dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * <p>
495dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * Returns <code>Double.NaN</code> if no values have been added.
496dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * Returns 0 if at least one value has been added, but v is not comparable
497dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * to the values set.</p>
498dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     *
499dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param v the value to lookup
500dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @return the proportion of values less than or equal to v
501dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
502dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public double getCumPct(Comparable<?> v) {
503dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        final long sumFreq = getSumFreq();
504dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        if (sumFreq == 0) {
505dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            return Double.NaN;
506dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        }
507dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return (double) getCumFreq(v) / (double) sumFreq;
508dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
509dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
510dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /**
511dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * Returns the cumulative percentage of values less than or equal to v
512dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * (as a proportion between 0 and 1).
513dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * <p>
514dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * Returns 0 if v is not comparable to the values set.</p>
515dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     *
516dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param v the value to lookup
517dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @return the proportion of values less than or equal to v
518dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
519dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public double getCumPct(int v) {
520dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return getCumPct(Long.valueOf(v));
521dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
522dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
523dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /**
524dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * Returns the cumulative percentage of values less than or equal to v
525dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * (as a proportion between 0 and 1).
526dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * <p>
527dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * Returns 0 if v is not comparable to the values set.</p>
528dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     *
529dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param v the value to lookup
530dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @return the proportion of values less than or equal to v
531dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
532dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public double getCumPct(long v) {
533dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return getCumPct(Long.valueOf(v));
534dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
535dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
536dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /**
537dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * Returns the cumulative percentage of values less than or equal to v
538dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * (as a proportion between 0 and 1).
539dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * <p>
540dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * Returns 0 if v is not comparable to the values set.</p>
541dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     *
542dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param v the value to lookup
543dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @return the proportion of values less than or equal to v
544dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
545dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public double getCumPct(char v) {
546dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return getCumPct(Character.valueOf(v));
547dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
548dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
549dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /**
550dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * A Comparator that compares comparable objects using the
551dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * natural order.  Copied from Commons Collections ComparableComparator.
552dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
553dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    private static class NaturalComparator<T extends Comparable<T>> implements Comparator<Comparable<T>>, Serializable {
554dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
555dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        /** Serializable version identifier */
556dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        private static final long serialVersionUID = -3852193713161395148L;
557dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
558dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        /**
559dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond         * Compare the two {@link Comparable Comparable} arguments.
560dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond         * This method is equivalent to:
561dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond         * <pre>(({@link Comparable Comparable})o1).{@link Comparable#compareTo compareTo}(o2)</pre>
562dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond         *
563dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond         * @param  o1 the first object
564dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond         * @param  o2 the second object
565dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond         * @return  result of comparison
566dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond         * @throws NullPointerException when <i>o1</i> is <code>null</code>,
567dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond         *         or when <code>((Comparable)o1).compareTo(o2)</code> does
568dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond         * @throws ClassCastException when <i>o1</i> is not a {@link Comparable Comparable},
569dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond         *         or when <code>((Comparable)o1).compareTo(o2)</code> does
570dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond         */
571dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        @SuppressWarnings("unchecked") // cast to (T) may throw ClassCastException, see Javadoc
572dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        public int compare(Comparable<T> o1, Comparable<T> o2) {
573dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            return o1.compareTo((T) o2);
574dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        }
575dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
576dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
577dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** {@inheritDoc} */
578dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    @Override
579dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public int hashCode() {
580dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        final int prime = 31;
581dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        int result = 1;
582dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        result = prime * result +
583dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                 ((freqTable == null) ? 0 : freqTable.hashCode());
584dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return result;
585dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
586dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
587dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** {@inheritDoc} */
588dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    @Override
589dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public boolean equals(Object obj) {
590dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        if (this == obj)
591dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            return true;
592dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        if (!(obj instanceof Frequency))
593dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            return false;
594dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        Frequency other = (Frequency) obj;
595dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        if (freqTable == null) {
596dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            if (other.freqTable != null)
597dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                return false;
598dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        } else if (!freqTable.equals(other.freqTable))
599dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            return false;
600dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return true;
601dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
602dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
603dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond}
604