[MATH-474] Added Frequency#merge method, thanks to patch from Dan Checkoway.
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/math/trunk@1400683 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
ec6f1c8270
commit
1d02ff125d
|
@ -52,6 +52,10 @@ If the output is not quite correct, check for invisible trailing spaces!
|
|||
<body>
|
||||
<release version="3.1" date="TBD" description="
|
||||
">
|
||||
<action dev="tn" type="add" issue="MATH-474" due-to="Dan Checkoway">
|
||||
Added new methods "merge(Frequency)", "merge(Collection<Frequency>)",
|
||||
"incrementValue(Comparable<?>, long)" and "entrySetIterator()" to the "Frequency" class.
|
||||
</action>
|
||||
<action dev="tn" type="fix" issue="MATH-778" due-to="Sébastien Brisard">
|
||||
Allow unlimited input values for "Dfp#multiply(int)".
|
||||
</action>
|
||||
|
|
|
@ -18,8 +18,10 @@ package org.apache.commons.math3.stat;
|
|||
|
||||
import java.io.Serializable;
|
||||
import java.text.NumberFormat;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.Comparator;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
|
||||
import org.apache.commons.math3.exception.MathIllegalArgumentException;
|
||||
|
@ -108,16 +110,31 @@ public class Frequency implements Serializable {
|
|||
* @throws MathIllegalArgumentException if <code>v</code> is not comparable with previous entries
|
||||
*/
|
||||
public void addValue(Comparable<?> v) throws MathIllegalArgumentException {
|
||||
incrementValue(v, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Increments the frequency count for v.
|
||||
* <p>
|
||||
* If other objects have already been added to this Frequency, v must
|
||||
* be comparable to those that have already been added.
|
||||
* </p>
|
||||
*
|
||||
* @param v the value to add.
|
||||
* @param increment the amount by which the value should be incremented
|
||||
* @throws IllegalArgumentException if <code>v</code> is not comparable with previous entries
|
||||
*/
|
||||
public void incrementValue(Comparable<?> v, long increment){
|
||||
Comparable<?> obj = v;
|
||||
if (v instanceof Integer) {
|
||||
obj = Long.valueOf(((Integer) v).longValue());
|
||||
obj = Long.valueOf(((Integer) v).longValue());
|
||||
}
|
||||
try {
|
||||
Long count = freqTable.get(obj);
|
||||
if (count == null) {
|
||||
freqTable.put(obj, Long.valueOf(1));
|
||||
freqTable.put(obj, Long.valueOf(increment));
|
||||
} else {
|
||||
freqTable.put(obj, Long.valueOf(count.longValue() + 1));
|
||||
freqTable.put(obj, Long.valueOf(count.longValue() + increment));
|
||||
}
|
||||
} catch (ClassCastException ex) {
|
||||
//TreeMap will throw ClassCastException if v is not comparable
|
||||
|
@ -178,6 +195,22 @@ public class Frequency implements Serializable {
|
|||
return freqTable.keySet().iterator();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an Iterator over the set of keys and values that have been added.
|
||||
* Using the entry set to iterate is more efficient in the case where you
|
||||
* need to access respective counts as well as values, since it doesn't
|
||||
* require a "get" for every key...the value is provided in the Map.Entry.
|
||||
* <p>
|
||||
* If added values are integral (i.e., integers, longs, Integers, or Longs),
|
||||
* they are converted to Longs when they are added, so the values of the
|
||||
* map entries returned by the Iterator will in this case be Longs.</p>
|
||||
*
|
||||
* @return entry set Iterator
|
||||
*/
|
||||
public Iterator<Map.Entry<Comparable<?>, Long>> entrySetIterator() {
|
||||
return freqTable.entrySet().iterator();
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
|
@ -456,6 +489,37 @@ public class Frequency implements Serializable {
|
|||
return getCumPct(Character.valueOf(v));
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Merge another Frequency object's counts into this instance.
|
||||
* This Frequency's counts will be incremented (or set when not already set)
|
||||
* by the counts represented by other.
|
||||
*
|
||||
* @param other the other {@link Frequency} object to be merged
|
||||
*/
|
||||
public void merge(Frequency other) {
|
||||
for (Iterator<Map.Entry<Comparable<?>, Long>> iter = other.entrySetIterator(); iter.hasNext();) {
|
||||
Map.Entry<Comparable<?>, Long> entry = iter.next();
|
||||
incrementValue(entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Merge a {@link Collection} of {@link Frequency} objects into this instance.
|
||||
* This Frequency's counts will be incremented (or set when not already set)
|
||||
* by the counts represented by each of the others.
|
||||
*
|
||||
* @param others the other {@link Frequency} objects to be merged
|
||||
*/
|
||||
public void merge(Collection<Frequency> others) {
|
||||
for (Iterator<Frequency> iter = others.iterator(); iter.hasNext();) {
|
||||
merge(iter.next());
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* A Comparator that compares comparable objects using the
|
||||
* natural order. Copied from Commons Collections ComparableComparator.
|
||||
|
|
|
@ -18,7 +18,9 @@ package org.apache.commons.math3.stat;
|
|||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.StringReader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
import org.apache.commons.math3.TestUtils;
|
||||
|
@ -262,5 +264,73 @@ public final class FrequencyTest {
|
|||
f.addValue(twoI);
|
||||
Assert.assertEquals(2, f.getUniqueCount());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIncrement() {
|
||||
Assert.assertEquals(0, f.getUniqueCount());
|
||||
f.incrementValue(oneL, 1);
|
||||
Assert.assertEquals(1, f.getCount(oneL));
|
||||
|
||||
f.incrementValue(oneL, 4);
|
||||
Assert.assertEquals(5, f.getCount(oneL));
|
||||
|
||||
f.incrementValue(oneL, -5);
|
||||
Assert.assertEquals(0, f.getCount(oneL));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMerge() {
|
||||
Assert.assertEquals(0, f.getUniqueCount());
|
||||
f.addValue(oneL);
|
||||
f.addValue(twoL);
|
||||
f.addValue(oneI);
|
||||
f.addValue(twoI);
|
||||
|
||||
Assert.assertEquals(2, f.getUniqueCount());
|
||||
Assert.assertEquals(2, f.getCount(oneI));
|
||||
Assert.assertEquals(2, f.getCount(twoI));
|
||||
|
||||
Frequency g = new Frequency();
|
||||
g.addValue(oneL);
|
||||
g.addValue(threeL);
|
||||
g.addValue(threeI);
|
||||
|
||||
Assert.assertEquals(2, g.getUniqueCount());
|
||||
Assert.assertEquals(1, g.getCount(oneI));
|
||||
Assert.assertEquals(2, g.getCount(threeI));
|
||||
|
||||
f.merge(g);
|
||||
|
||||
Assert.assertEquals(3, f.getUniqueCount());
|
||||
Assert.assertEquals(3, f.getCount(oneI));
|
||||
Assert.assertEquals(2, f.getCount(twoI));
|
||||
Assert.assertEquals(2, f.getCount(threeI));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMergeCollection() {
|
||||
Assert.assertEquals(0, f.getUniqueCount());
|
||||
f.addValue(oneL);
|
||||
|
||||
Assert.assertEquals(1, f.getUniqueCount());
|
||||
Assert.assertEquals(1, f.getCount(oneI));
|
||||
Assert.assertEquals(0, f.getCount(twoI));
|
||||
|
||||
Frequency g = new Frequency();
|
||||
g.addValue(twoL);
|
||||
|
||||
Frequency h = new Frequency();
|
||||
h.addValue(threeL);
|
||||
|
||||
List<Frequency> coll = new ArrayList<Frequency>();
|
||||
coll.add(g);
|
||||
coll.add(h);
|
||||
f.merge(coll);
|
||||
|
||||
Assert.assertEquals(3, f.getUniqueCount());
|
||||
Assert.assertEquals(1, f.getCount(oneI));
|
||||
Assert.assertEquals(1, f.getCount(twoI));
|
||||
Assert.assertEquals(1, f.getCount(threeI));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue