]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.history/src/org/simantics/history/util/ClassDistribution.java
Fixed all line endings of the repository
[simantics/platform.git] / bundles / org.simantics.history / src / org / simantics / history / util / ClassDistribution.java
index d6a5df81269af297f9408172e0cb739d1c2cb600..f20c6b6d7d18f4464a1f033f1c60a1a7d071f94a 100644 (file)
-/*******************************************************************************\r
- * Copyright (c) 2007 VTT Technical Research Centre of Finland and others.\r
- * All rights reserved. This program and the accompanying materials\r
- * are made available under the terms of the Eclipse Public License v1.0\r
- * which accompanies this distribution, and is available at\r
- * http://www.eclipse.org/legal/epl-v10.html\r
- *\r
- * Contributors:\r
- *     VTT Technical Research Centre of Finland - initial API and implementation\r
- *******************************************************************************/\r
-package org.simantics.history.util;\r
-\r
-import java.util.Formatter;\r
-import java.util.Map;\r
-import java.util.Map.Entry;\r
-import java.util.TreeMap;\r
-\r
-import org.simantics.databoard.primitives.MutableInteger;\r
-\r
-/**\r
- * This class gives a rough distribution classification for double values.  \r
- * \r
- * It calculates the frequency of values in each class. All values are \r
- * accounted. There is a value between two samples. \r
- *    n(sample intervals) = n(samples) - 1 <p>\r
- * \r
- * Classes are derieved using logarithmic scale. \r
- * Each class accounts all values within a range [ base ^ class .. base ^ (class-1) ).\r
- * \r
- * Example for classes of base number 2.0\r
- * \r
- * Class Ranges\r
- *   -10   [ 0,98ms .. 1,95ms )\r
- *    -9   [ 1,95ms .. 3,91ms )\r
- *    -8   [ 3,91ms .. 7,81ms )\r
- *    -7   [ 7,81ms .. 15,63ms )\r
- *    -6   [ 15,63ms .. 31,25ms )\r
- *    -5   [ 31,25ms .. 62,50ms )\r
- *    -4   [ 62,50ms .. 125,00ms )\r
- *    -3   [ 125,00ms .. 250,00ms )\r
- *    -2   [ 250,00ms .. 500,00ms )\r
- *    -1   [ 500,00ms .. 1 000,00ms )\r
- *     0   [ 1 000,00ms .. 2 000,00ms )\r
- *    +1   [ 2 000,00ms .. 4 000,00ms )\r
- *    +2   [ 4 000,00ms .. 8 000,00ms )\r
- *    +3   [ 8 000,00ms .. 16 000,00ms )\r
- *    +4   [ 16 000,00ms .. 32 000,00ms )\r
- *    +5   [ 32 000,00ms .. 64 000,00ms )\r
- *    +6   [ 64 000,00ms .. 128 000,00ms )\r
- *    +7   [ 128 000,00ms .. 256 000,00ms )\r
- *    +8   [ 256 000,00ms .. 512 000,00ms )\r
- *    +9   [ 512 000,00ms .. 1 024 000,00ms )\r
- *   +10   [ 1 024 000,00ms .. 2 048 000,00ms )  \r
- *\r
- * @author Toni Kalajainen <toni.kalajainen@vtt.fi>\r
- */\r
-public class ClassDistribution {\r
-       \r
-       // Optimization that tries to cirumvent slow Math.log\r
-       // previously entered value and its class is remembered\r
-       private transient double lastEnteredValue;\r
-       private transient int lastClass;\r
-       \r
-       double base;\r
-       private transient double log_base;\r
-\r
-       /** Distribution */\r
-       TreeMap<Integer, MutableInteger> distribution;  \r
-       \r
-       public ClassDistribution() {\r
-               this( 2.0 );\r
-       }\r
-       \r
-       public ClassDistribution(double base) {\r
-               this.base = base;\r
-               log_base = Math.log( base );\r
-               lastEnteredValue = 0.001;\r
-               lastClass = (int) Math.floor( Math.log( 0.001 ) / log_base );\r
-               distribution = new TreeMap<Integer, MutableInteger>();\r
-       }\r
-       \r
-       public ClassDistribution(double base, TreeMap<Integer, MutableInteger> initialBreakdown) {\r
-               this.base = base;\r
-               log_base = Math.log( base );\r
-               lastEnteredValue = 0.001;\r
-               lastClass = (int) Math.floor( Math.log( 0.001 ) / log_base );\r
-               distribution = new TreeMap<Integer, MutableInteger>( initialBreakdown );\r
-       }\r
-       \r
-       public double getBase() {\r
-               return base;\r
-       }\r
-       \r
-       public void setBase(double base) {\r
-               this.base = base;\r
-               log_base = Math.log( base );\r
-       }\r
-\r
-       public double getSmallest() {\r
-               if (distribution.isEmpty()) return 1.0;\r
-               int clazz = distribution.firstKey();\r
-               return getClassAvg(clazz);\r
-       }\r
-       \r
-       /**\r
-        * Get median value\r
-        * \r
-        * @return\r
-        */\r
-       public double getMedian() {\r
-               // Count total\r
-               int n = 0;\r
-               for (MutableInteger v : distribution.values()) n += v.value;\r
-               \r
-               double median = (double) n/2;\r
-               double sum = 0;\r
-               for (Entry<Integer, MutableInteger> e : distribution.entrySet()) {\r
-                       sum += e.getValue().value;\r
-                       if (sum==median) {                              \r
-                               int c = e.getKey();\r
-                               Integer nextC = distribution.higherKey( c );\r
-                               if (nextC == null)\r
-                                       return getClassMax( c );\r
-                                                               \r
-                               return ( getClassMax( c ) + getClassMin( nextC ) ) /2; \r
-                       }\r
-                       if (sum>median) {\r
-                               int c = e.getKey();\r
-                               return getClassAvg( c );\r
-                       }\r
-               }               \r
-               return 0;\r
-       }\r
-       \r
-       /**\r
-        * Get an index to the class with highest frequency.\r
-        *\r
-        * @return interval class or 0 if there are no samples\r
-        */\r
-       public int getLargestClassIndex() {\r
-               int result = 0;\r
-               int nResult = -1;\r
-               for (Entry<Integer, MutableInteger> e : distribution.entrySet()) {\r
-                       if (e.getValue().value > nResult) {\r
-                               nResult = e.getValue().value;\r
-                               result = e.getKey();\r
-                       }\r
-               }\r
-               return result;\r
-       }\r
-       \r
-       /**\r
-        * Write distribution with user given map.\r
-        * \r
-        * @param result map where breakdown is written to\r
-        */\r
-       public void getDistribution(Map<Integer, Integer> result) {\r
-               result.clear();\r
-               for (Entry<Integer, MutableInteger> e : distribution.entrySet()) {\r
-                       result.put( e.getKey(), Integer.valueOf(e.getValue().value));\r
-               }\r
-       }\r
-       \r
-       public void setDistribution(Map<Integer, Integer> map) {\r
-               this.distribution.clear();\r
-               for (Entry<Integer, Integer> e : map.entrySet()) {\r
-                       distribution.put( e.getKey(), new MutableInteger(e.getValue()) );\r
-               }\r
-       }\r
-       \r
-       /**\r
-        * Create a snapshot copy of the distribution.\r
-        * \r
-        * @return a histogram  \r
-        */\r
-       public TreeMap<Integer, Integer> getDistribution() {\r
-               TreeMap<Integer, Integer> result = new TreeMap<Integer, Integer>();\r
-               getDistribution(result);\r
-               return result;\r
-       }\r
-       \r
-       \r
-       /**\r
-        * Add new value to the distribution.\r
-        * \r
-        * @param value\r
-        */\r
-       public void addValue(double value) {            \r
-               Integer k = Integer.valueOf( getClassIndex(value) );\r
-               MutableInteger r = distribution.get(k);\r
-               if ( r == null ) {\r
-                       r = new MutableInteger();\r
-                       distribution.put(k, r);\r
-               }\r
-               r.value ++;\r
-       }\r
-\r
-       /**\r
-        * Get lowest value of a class\r
-        * \r
-        * @param intervalClass\r
-        * @return min value\r
-        */\r
-       public double getClassMin(int intervalClass) {\r
-               return Math.pow(base, intervalClass);\r
-       }\r
-\r
-       /**\r
-        * Get highest value of a class \r
-        * \r
-        * @param intervalClass\r
-        * @return max value\r
-        */\r
-       public double getClassMax(int intervalClass) {\r
-               return Math.pow(base, intervalClass+1);\r
-       }\r
-       \r
-       /**\r
-        * Get average value of a class\r
-        * \r
-        * @param intervalClass\r
-        * @return average interval\r
-        */\r
-       public double getClassAvg(int intervalClass) {\r
-               double min = getClassMin(intervalClass);\r
-               double max = getClassMax(intervalClass);\r
-               return (max-min)/2+min;\r
-       }\r
-               \r
-       /**\r
-        * Get class index for a value\r
-        * @param interval\r
-        * @return class index\r
-        */\r
-       public int getClassIndex(double interval) {\r
-               if (interval == lastEnteredValue) return lastClass;\r
-               lastClass = (int) Math.floor( Math.log(interval) / log_base );\r
-               lastEnteredValue = interval; \r
-               return lastClass;\r
-       }\r
-       \r
-       @Override\r
-       public String toString() {\r
-               StringBuilder sb = new StringBuilder();\r
-               Formatter f = new Formatter(sb);\r
-               sb.append("Index Range Count\n");\r
-               for (Entry<Integer, MutableInteger> e : distribution.entrySet()) {\r
-                       int ic = e.getKey();\r
-                       double start = getClassMin(ic);\r
-                       double end = getClassMax(ic);\r
-                       double avg = getClassAvg(ic);\r
-                       int count = e.getValue().value;\r
-                       String format;\r
-                       if (start<0.001) {\r
-                               start *= 1000.0;\r
-                               end *= 1000.0;\r
-                               avg *= 1000.0;\r
-                               format = "  %+3d   [ %(,8fm .. %(,8fm ) = %d, avg = %(,8fm\n";\r
-                       } else\r
-                       if (start<1) {\r
-                               start *= 1000.0;\r
-                               end *= 1000.0;\r
-                               avg *= 1000.0;\r
-                               format = "  %+3d   [ %(,8.2fm .. %(,8.2fm ) = %d, avg = %(,8.2fm\n";\r
-                       } else {\r
-                               format = "  %+3d   [ %(9.0f .. %(9.0f ) = %d, avg = %(8.1f\n";\r
-                       }\r
-                       f.format(format , ic, start, end, count, avg);\r
-               }\r
-               return sb.toString();\r
-       }\r
-       \r
-}\r
-\r
+/*******************************************************************************
+ * Copyright (c) 2007 VTT Technical Research Centre of Finland and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     VTT Technical Research Centre of Finland - initial API and implementation
+ *******************************************************************************/
+package org.simantics.history.util;
+
+import java.util.Formatter;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.TreeMap;
+
+import org.simantics.databoard.primitives.MutableInteger;
+
+/**
+ * This class gives a rough distribution classification for double values.  
+ * 
+ * It calculates the frequency of values in each class. All values are 
+ * accounted. There is a value between two samples. 
+ *    n(sample intervals) = n(samples) - 1 <p>
+ * 
+ * Classes are derieved using logarithmic scale. 
+ * Each class accounts all values within a range [ base ^ class .. base ^ (class-1) ).
+ * 
+ * Example for classes of base number 2.0
+ * 
+ * Class Ranges
+ *   -10   [ 0,98ms .. 1,95ms )
+ *    -9   [ 1,95ms .. 3,91ms )
+ *    -8   [ 3,91ms .. 7,81ms )
+ *    -7   [ 7,81ms .. 15,63ms )
+ *    -6   [ 15,63ms .. 31,25ms )
+ *    -5   [ 31,25ms .. 62,50ms )
+ *    -4   [ 62,50ms .. 125,00ms )
+ *    -3   [ 125,00ms .. 250,00ms )
+ *    -2   [ 250,00ms .. 500,00ms )
+ *    -1   [ 500,00ms .. 1 000,00ms )
+ *     0   [ 1 000,00ms .. 2 000,00ms )
+ *    +1   [ 2 000,00ms .. 4 000,00ms )
+ *    +2   [ 4 000,00ms .. 8 000,00ms )
+ *    +3   [ 8 000,00ms .. 16 000,00ms )
+ *    +4   [ 16 000,00ms .. 32 000,00ms )
+ *    +5   [ 32 000,00ms .. 64 000,00ms )
+ *    +6   [ 64 000,00ms .. 128 000,00ms )
+ *    +7   [ 128 000,00ms .. 256 000,00ms )
+ *    +8   [ 256 000,00ms .. 512 000,00ms )
+ *    +9   [ 512 000,00ms .. 1 024 000,00ms )
+ *   +10   [ 1 024 000,00ms .. 2 048 000,00ms )  
+ *
+ * @author Toni Kalajainen <toni.kalajainen@vtt.fi>
+ */
+public class ClassDistribution {
+       
+       // Optimization that tries to cirumvent slow Math.log
+       // previously entered value and its class is remembered
+       private transient double lastEnteredValue;
+       private transient int lastClass;
+       
+       double base;
+       private transient double log_base;
+
+       /** Distribution */
+       TreeMap<Integer, MutableInteger> distribution;  
+       
+       public ClassDistribution() {
+               this( 2.0 );
+       }
+       
+       public ClassDistribution(double base) {
+               this.base = base;
+               log_base = Math.log( base );
+               lastEnteredValue = 0.001;
+               lastClass = (int) Math.floor( Math.log( 0.001 ) / log_base );
+               distribution = new TreeMap<Integer, MutableInteger>();
+       }
+       
+       public ClassDistribution(double base, TreeMap<Integer, MutableInteger> initialBreakdown) {
+               this.base = base;
+               log_base = Math.log( base );
+               lastEnteredValue = 0.001;
+               lastClass = (int) Math.floor( Math.log( 0.001 ) / log_base );
+               distribution = new TreeMap<Integer, MutableInteger>( initialBreakdown );
+       }
+       
+       public double getBase() {
+               return base;
+       }
+       
+       public void setBase(double base) {
+               this.base = base;
+               log_base = Math.log( base );
+       }
+
+       public double getSmallest() {
+               if (distribution.isEmpty()) return 1.0;
+               int clazz = distribution.firstKey();
+               return getClassAvg(clazz);
+       }
+       
+       /**
+        * Get median value
+        * 
+        * @return
+        */
+       public double getMedian() {
+               // Count total
+               int n = 0;
+               for (MutableInteger v : distribution.values()) n += v.value;
+               
+               double median = (double) n/2;
+               double sum = 0;
+               for (Entry<Integer, MutableInteger> e : distribution.entrySet()) {
+                       sum += e.getValue().value;
+                       if (sum==median) {                              
+                               int c = e.getKey();
+                               Integer nextC = distribution.higherKey( c );
+                               if (nextC == null)
+                                       return getClassMax( c );
+                                                               
+                               return ( getClassMax( c ) + getClassMin( nextC ) ) /2; 
+                       }
+                       if (sum>median) {
+                               int c = e.getKey();
+                               return getClassAvg( c );
+                       }
+               }               
+               return 0;
+       }
+       
+       /**
+        * Get an index to the class with highest frequency.
+        *
+        * @return interval class or 0 if there are no samples
+        */
+       public int getLargestClassIndex() {
+               int result = 0;
+               int nResult = -1;
+               for (Entry<Integer, MutableInteger> e : distribution.entrySet()) {
+                       if (e.getValue().value > nResult) {
+                               nResult = e.getValue().value;
+                               result = e.getKey();
+                       }
+               }
+               return result;
+       }
+       
+       /**
+        * Write distribution with user given map.
+        * 
+        * @param result map where breakdown is written to
+        */
+       public void getDistribution(Map<Integer, Integer> result) {
+               result.clear();
+               for (Entry<Integer, MutableInteger> e : distribution.entrySet()) {
+                       result.put( e.getKey(), Integer.valueOf(e.getValue().value));
+               }
+       }
+       
+       public void setDistribution(Map<Integer, Integer> map) {
+               this.distribution.clear();
+               for (Entry<Integer, Integer> e : map.entrySet()) {
+                       distribution.put( e.getKey(), new MutableInteger(e.getValue()) );
+               }
+       }
+       
+       /**
+        * Create a snapshot copy of the distribution.
+        * 
+        * @return a histogram  
+        */
+       public TreeMap<Integer, Integer> getDistribution() {
+               TreeMap<Integer, Integer> result = new TreeMap<Integer, Integer>();
+               getDistribution(result);
+               return result;
+       }
+       
+       
+       /**
+        * Add new value to the distribution.
+        * 
+        * @param value
+        */
+       public void addValue(double value) {            
+               Integer k = Integer.valueOf( getClassIndex(value) );
+               MutableInteger r = distribution.get(k);
+               if ( r == null ) {
+                       r = new MutableInteger();
+                       distribution.put(k, r);
+               }
+               r.value ++;
+       }
+
+       /**
+        * Get lowest value of a class
+        * 
+        * @param intervalClass
+        * @return min value
+        */
+       public double getClassMin(int intervalClass) {
+               return Math.pow(base, intervalClass);
+       }
+
+       /**
+        * Get highest value of a class 
+        * 
+        * @param intervalClass
+        * @return max value
+        */
+       public double getClassMax(int intervalClass) {
+               return Math.pow(base, intervalClass+1);
+       }
+       
+       /**
+        * Get average value of a class
+        * 
+        * @param intervalClass
+        * @return average interval
+        */
+       public double getClassAvg(int intervalClass) {
+               double min = getClassMin(intervalClass);
+               double max = getClassMax(intervalClass);
+               return (max-min)/2+min;
+       }
+               
+       /**
+        * Get class index for a value
+        * @param interval
+        * @return class index
+        */
+       public int getClassIndex(double interval) {
+               if (interval == lastEnteredValue) return lastClass;
+               lastClass = (int) Math.floor( Math.log(interval) / log_base );
+               lastEnteredValue = interval; 
+               return lastClass;
+       }
+       
+       @Override
+       public String toString() {
+               StringBuilder sb = new StringBuilder();
+               Formatter f = new Formatter(sb);
+               sb.append("Index Range Count\n");
+               for (Entry<Integer, MutableInteger> e : distribution.entrySet()) {
+                       int ic = e.getKey();
+                       double start = getClassMin(ic);
+                       double end = getClassMax(ic);
+                       double avg = getClassAvg(ic);
+                       int count = e.getValue().value;
+                       String format;
+                       if (start<0.001) {
+                               start *= 1000.0;
+                               end *= 1000.0;
+                               avg *= 1000.0;
+                               format = "  %+3d   [ %(,8fm .. %(,8fm ) = %d, avg = %(,8fm\n";
+                       } else
+                       if (start<1) {
+                               start *= 1000.0;
+                               end *= 1000.0;
+                               avg *= 1000.0;
+                               format = "  %+3d   [ %(,8.2fm .. %(,8.2fm ) = %d, avg = %(,8.2fm\n";
+                       } else {
+                               format = "  %+3d   [ %(9.0f .. %(9.0f ) = %d, avg = %(8.1f\n";
+                       }
+                       f.format(format , ic, start, end, count, avg);
+               }
+               return sb.toString();
+       }
+       
+}
+