X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;ds=sidebyside;f=bundles%2Forg.simantics.history%2Fsrc%2Forg%2Fsimantics%2Fhistory%2Futil%2FClassDistribution.java;h=f20c6b6d7d18f4464a1f033f1c60a1a7d071f94a;hb=99395a7780ef1626d3ae97183ef4ae717f32b215;hp=d6a5df81269af297f9408172e0cb739d1c2cb600;hpb=969bd23cab98a79ca9101af33334000879fb60c5;p=simantics%2Fplatform.git
diff --git a/bundles/org.simantics.history/src/org/simantics/history/util/ClassDistribution.java b/bundles/org.simantics.history/src/org/simantics/history/util/ClassDistribution.java
index d6a5df812..f20c6b6d7 100644
--- a/bundles/org.simantics.history/src/org/simantics/history/util/ClassDistribution.java
+++ b/bundles/org.simantics.history/src/org/simantics/history/util/ClassDistribution.java
@@ -1,274 +1,274 @@
-/*******************************************************************************
- * 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
- *
- * 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
- */
-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 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();
- }
-
- public ClassDistribution(double base, TreeMap 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( 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 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 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 result) {
- result.clear();
- for (Entry e : distribution.entrySet()) {
- result.put( e.getKey(), Integer.valueOf(e.getValue().value));
- }
- }
-
- public void setDistribution(Map map) {
- this.distribution.clear();
- for (Entry e : map.entrySet()) {
- distribution.put( e.getKey(), new MutableInteger(e.getValue()) );
- }
- }
-
- /**
- * Create a snapshot copy of the distribution.
- *
- * @return a histogram
- */
- public TreeMap getDistribution() {
- TreeMap result = new TreeMap();
- 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 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();
- }
-
-}
-
+/*******************************************************************************
+ * 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
+ *
+ * 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
+ */
+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 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();
+ }
+
+ public ClassDistribution(double base, TreeMap 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( 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 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 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 result) {
+ result.clear();
+ for (Entry e : distribution.entrySet()) {
+ result.put( e.getKey(), Integer.valueOf(e.getValue().value));
+ }
+ }
+
+ public void setDistribution(Map map) {
+ this.distribution.clear();
+ for (Entry e : map.entrySet()) {
+ distribution.put( e.getKey(), new MutableInteger(e.getValue()) );
+ }
+ }
+
+ /**
+ * Create a snapshot copy of the distribution.
+ *
+ * @return a histogram
+ */
+ public TreeMap getDistribution() {
+ TreeMap result = new TreeMap();
+ 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 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();
+ }
+
+}
+