MATH-1000 Add mode function to Frequency class

git-svn-id: https://svn.apache.org/repos/asf/commons/proper/math/trunk@1503286 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Sebastian Bazley 2013-07-15 15:05:41 +00:00
parent 91d280b730
commit e3bb2063e7
3 changed files with 63 additions and 14 deletions

View File

@ -51,6 +51,9 @@ If the output is not quite correct, check for invisible trailing spaces!
</properties>
<body>
<release version="x.y" date="TBD" description="TBD">
<action dev="sebb" type="add" issue="MATH-1000">
Add mode function to Frequency class.
</action>
<action dev="erans" type="fix" issue="MATH-1005" due-to="Roman Werpachowski">
Fixed "MathArrays.linearCombination" when array length is 1.
</action>

View File

@ -18,10 +18,13 @@ package org.apache.commons.math3.stat;
import java.io.Serializable;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.TreeMap;
import org.apache.commons.math3.exception.MathIllegalArgumentException;
@ -493,6 +496,39 @@ public class Frequency implements Serializable {
return getCumPct(Character.valueOf(v));
}
/**
* Returns the mode value(s) in comparator order.
*
* @return a list containing the value(s) which appear most often.
* @since 3.3
*/
public List<Comparable<?>> getMode() {
long mostPopular = 0; // frequencies are always positive
// Get the max count first, so we avoid having to recreate the List each time
for(Long l : freqTable.values()) {
long frequency = l.longValue();
if (frequency > mostPopular) {
mostPopular = frequency;
}
}
List<Comparable<?>> modeList = new ArrayList<Comparable<?>>();
for (Entry<Comparable<?>, Long> ent : freqTable.entrySet()) {
long frequency = ent.getValue().longValue();
if (frequency == mostPopular) {
modeList.add(ent.getKey());
// Alternatively, to avoid scanning the entries twice, keep recreating the set
// To use this approach, comment out the values() scan loop above and uncomment below
// } else if (frequency > mostPopular) {
// modeList.clear(); // the previous List is obsolete
// modeList.add(ent.getKey());
// mostPopular = frequency;
}
}
return modeList;
}
//----------------------------------------------------------------------------------------------
/**

View File

@ -334,18 +334,28 @@ public final class FrequencyTest {
Assert.assertEquals(1, f.getCount(THREEE));
}
// @Test
// public void testMode() {
// Assert.assertEquals(0, f.getMode().size());
// f.addValue("1");
// Assert.assertEquals(1, f.getMode().size());
// f.addValue("2");
// Assert.assertEquals(2, f.getMode().size());
// Assert.assertTrue(f.getMode().contains("1"));
// Assert.assertTrue(f.getMode().contains("2"));
// f.addValue("2");
// Assert.assertEquals(1, f.getMode().size());
// Assert.assertFalse(f.getMode().contains("1"));
// Assert.assertTrue(f.getMode().contains("2"));
// }
@Test
public void testMode() {
List<Comparable<?>> mode;
mode = f.getMode();
Assert.assertEquals(0, mode.size());
f.addValue("3");
mode = f.getMode();
Assert.assertEquals(1, mode.size());
Assert.assertEquals("3", mode.get(0));
f.addValue("2");
mode = f.getMode();
Assert.assertEquals(2, mode.size());
Assert.assertEquals("2", mode.get(0));
Assert.assertEquals("3",mode.get(1));
f.addValue("2");
mode = f.getMode();
Assert.assertEquals(1, mode.size());
Assert.assertEquals("2", mode.get(0));
Assert.assertFalse(mode.contains("1"));
Assert.assertTrue(mode.contains("2"));
}
}