]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.history/src/org/simantics/history/util/WeightedMedian2.java
Fixed all line endings of the repository
[simantics/platform.git] / bundles / org.simantics.history / src / org / simantics / history / util / WeightedMedian2.java
index 51f71cf5f1f723e442be33331d35d3e4466eec49..669054d5299ab649db276a24166830fdd7b71a73 100644 (file)
-/*******************************************************************************\r
- * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
- * Industry THTH ry.\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 org.simantics.databoard.annotations.Optional;\r
-import org.simantics.databoard.annotations.Referable;\r
-\r
-/**\r
- * \r
- * @author toni.kalajainen\r
- */\r
-public class WeightedMedian2 {\r
-\r
-       public int maxItems;\r
-       public int itemCount;\r
-       @Optional public Item median;\r
-       \r
-       // Relative pos = pos - median.accumulated weight \r
-       public double rpos;\r
-       \r
-       public WeightedMedian2()\r
-       {\r
-               maxItems = Integer.MAX_VALUE;\r
-       }\r
-       \r
-       public WeightedMedian2(int maxItems)\r
-       {\r
-               this.maxItems = maxItems;\r
-       }\r
-       \r
-       public void clear() {\r
-               itemCount = 0;\r
-               median = null;\r
-               rpos = 0;\r
-       }\r
-       \r
-       public void add(double weight, double value)\r
-       {\r
-               if (weight<=0) return;\r
-               if (median == null) {\r
-                       median = new Item( weight, value );\r
-                       itemCount++;\r
-                       rpos = weight / 2;\r
-                       return;                 \r
-               }\r
-               \r
-               Item i = median;\r
-               while (true) {\r
-                       \r
-                       if (value>=i.low && value<=i.high) {\r
-                               double totWeight = i.weight+weight;\r
-                               i.value = ( i.value * i.weight + value * weight ) / totWeight;\r
-                               i.weight = totWeight;\r
-                               break;\r
-                       }\r
-                       \r
-                       if (value < i.low) {\r
-                               \r
-                               // i = 1st, add new item as first\r
-                               if (i.prev==null) {\r
-                                       i.prev = new Item( weight, value, null, i );\r
-                                       itemCount++;\r
-                                       break;\r
-                               }\r
-                               \r
-                               // value is between two items, add new item\r
-                               if (i.prev.high < value) {\r
-                                       Item n = new Item( weight, value, i.prev, i );\r
-                                       itemCount++;\r
-                                       i.prev.next = n;\r
-                                       i.prev = n;\r
-                                       break;\r
-                               }\r
-                               \r
-                               i = i.prev;\r
-                               continue;\r
-                       }                       \r
-                       \r
-                       if (value > i.high) {\r
-                               \r
-                               // i = last, add new item as last\r
-                               if (i.next==null) {\r
-                                       i.next = new Item( weight, value, i, null );                                    \r
-                                       itemCount++;\r
-                                       break;\r
-                               }\r
-                               \r
-                               // value is between two items, add new item\r
-                               if (i.next.low > value) {\r
-                                       Item n = new Item( weight, value, i, i.next );\r
-                                       itemCount++;\r
-                                       i.next.prev = n;\r
-                                       i.next = n;\r
-                                       break;\r
-                               }\r
-                               \r
-                               i = i.next;\r
-                               continue;\r
-                       }\r
-               }\r
-\r
-               rpos += (value<median.low?-1:1) * weight / 2;\r
-               while (rpos<0) {\r
-                       median = median.prev;\r
-                       rpos += median.weight;\r
-               }\r
-               while (rpos>=median.weight) {\r
-                       rpos -= median.weight;\r
-                       median = median.next;\r
-               }\r
-               \r
-               if (itemCount>maxItems) coalesce();\r
-       }\r
-       \r
-       public void coalesce() \r
-       {\r
-               Item i = median.next;\r
-               while (i!=null) {\r
-                       Item n = i.next;\r
-                       if (n==null) break;\r
-                       i.next = n.next;\r
-                       if (n.next!=null) n.next.prev = i;\r
-                       double totWeight = i.weight+n.weight;\r
-                       i.high = n.high;\r
-                       i.value = ( i.value * i.weight + n.value * n.weight ) / totWeight;\r
-                       i.weight = totWeight;\r
-                       i = i.next;\r
-               }\r
-               \r
-               i = median.prev;\r
-               while (i!=null) {\r
-                       Item p = i.prev;\r
-                       if (p==null) break;\r
-                       i.prev = p.prev;\r
-                       if (p.prev!=null) p.prev.next = i;\r
-                       double totWeight = i.weight+p.weight;\r
-                       i.low = p.low;\r
-                       i.value = ( i.value * i.weight + p.value * p.weight ) / totWeight;\r
-                       i.weight = totWeight;\r
-                       i = i.prev;\r
-               }               \r
-       }\r
-       \r
-       public double getMedian() \r
-       {\r
-               if (median==null) return Double.NaN;\r
-               if (median.low == median.high) return median.value;\r
-               double d = median.high - median.low;\r
-               double r = rpos/median.weight;\r
-               return median.low + d*r;\r
-       }\r
-       \r
-       @Override\r
-       public String toString() {\r
-               StringBuilder sb = new StringBuilder();\r
-               sb.append( "Median="+getMedian()+" ");\r
-               \r
-               Item i = first();\r
-               while (i!=null) {\r
-                       sb.append("(");\r
-                       sb.append("value=");\r
-                       if (i.low==i.high) sb.append(i.value); else \r
-                               sb.append(i.value+" ("+i.low+".."+i.high+")");\r
-                       sb.append(", w="+i.weight);\r
-                       if (i==median) {\r
-                               sb.append(", pos="+rpos);\r
-                       }\r
-                       sb.append(")");\r
-                       i = i.next;\r
-               }\r
-               \r
-               return sb.toString();\r
-       } \r
-       \r
-       Item first() {\r
-               if (median==null) return null;\r
-               Item i = median;\r
-               while (i.prev!=null) i = i.prev;\r
-               return i;\r
-       }\r
-       \r
-       @Referable\r
-       static public class Item {\r
-               public double weight;\r
-               public double low;\r
-               public double high;\r
-               public double value;\r
-               \r
-               public Item() {}\r
-               \r
-               public Item(double weight, double value) {\r
-                       this.weight = weight;\r
-                       this.low = this.high = value;\r
-               }\r
-\r
-               public Item(double weight, double value, Item prev, Item next) {\r
-                       this.weight = weight;\r
-                       this.value = this.low = this.high = value;\r
-                       this.prev = prev;\r
-                       this.next = next;\r
-               }\r
-               \r
-               @Optional\r
-               public Item prev;\r
-               \r
-               @Optional\r
-               public Item next;\r
-               \r
-               @Override\r
-               public String toString() {\r
-                       if (low==high) return "(value="+value+", w="+weight+")";\r
-                       return "(value="+value+" ("+low+".."+high+"), w="+weight+")";\r
-               }\r
-       }\r
-       \r
-}\r
+/*******************************************************************************
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in
+ * Industry THTH ry.
+ * 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 org.simantics.databoard.annotations.Optional;
+import org.simantics.databoard.annotations.Referable;
+
+/**
+ * 
+ * @author toni.kalajainen
+ */
+public class WeightedMedian2 {
+
+       public int maxItems;
+       public int itemCount;
+       @Optional public Item median;
+       
+       // Relative pos = pos - median.accumulated weight 
+       public double rpos;
+       
+       public WeightedMedian2()
+       {
+               maxItems = Integer.MAX_VALUE;
+       }
+       
+       public WeightedMedian2(int maxItems)
+       {
+               this.maxItems = maxItems;
+       }
+       
+       public void clear() {
+               itemCount = 0;
+               median = null;
+               rpos = 0;
+       }
+       
+       public void add(double weight, double value)
+       {
+               if (weight<=0) return;
+               if (median == null) {
+                       median = new Item( weight, value );
+                       itemCount++;
+                       rpos = weight / 2;
+                       return;                 
+               }
+               
+               Item i = median;
+               while (true) {
+                       
+                       if (value>=i.low && value<=i.high) {
+                               double totWeight = i.weight+weight;
+                               i.value = ( i.value * i.weight + value * weight ) / totWeight;
+                               i.weight = totWeight;
+                               break;
+                       }
+                       
+                       if (value < i.low) {
+                               
+                               // i = 1st, add new item as first
+                               if (i.prev==null) {
+                                       i.prev = new Item( weight, value, null, i );
+                                       itemCount++;
+                                       break;
+                               }
+                               
+                               // value is between two items, add new item
+                               if (i.prev.high < value) {
+                                       Item n = new Item( weight, value, i.prev, i );
+                                       itemCount++;
+                                       i.prev.next = n;
+                                       i.prev = n;
+                                       break;
+                               }
+                               
+                               i = i.prev;
+                               continue;
+                       }                       
+                       
+                       if (value > i.high) {
+                               
+                               // i = last, add new item as last
+                               if (i.next==null) {
+                                       i.next = new Item( weight, value, i, null );                                    
+                                       itemCount++;
+                                       break;
+                               }
+                               
+                               // value is between two items, add new item
+                               if (i.next.low > value) {
+                                       Item n = new Item( weight, value, i, i.next );
+                                       itemCount++;
+                                       i.next.prev = n;
+                                       i.next = n;
+                                       break;
+                               }
+                               
+                               i = i.next;
+                               continue;
+                       }
+               }
+
+               rpos += (value<median.low?-1:1) * weight / 2;
+               while (rpos<0) {
+                       median = median.prev;
+                       rpos += median.weight;
+               }
+               while (rpos>=median.weight) {
+                       rpos -= median.weight;
+                       median = median.next;
+               }
+               
+               if (itemCount>maxItems) coalesce();
+       }
+       
+       public void coalesce() 
+       {
+               Item i = median.next;
+               while (i!=null) {
+                       Item n = i.next;
+                       if (n==null) break;
+                       i.next = n.next;
+                       if (n.next!=null) n.next.prev = i;
+                       double totWeight = i.weight+n.weight;
+                       i.high = n.high;
+                       i.value = ( i.value * i.weight + n.value * n.weight ) / totWeight;
+                       i.weight = totWeight;
+                       i = i.next;
+               }
+               
+               i = median.prev;
+               while (i!=null) {
+                       Item p = i.prev;
+                       if (p==null) break;
+                       i.prev = p.prev;
+                       if (p.prev!=null) p.prev.next = i;
+                       double totWeight = i.weight+p.weight;
+                       i.low = p.low;
+                       i.value = ( i.value * i.weight + p.value * p.weight ) / totWeight;
+                       i.weight = totWeight;
+                       i = i.prev;
+               }               
+       }
+       
+       public double getMedian() 
+       {
+               if (median==null) return Double.NaN;
+               if (median.low == median.high) return median.value;
+               double d = median.high - median.low;
+               double r = rpos/median.weight;
+               return median.low + d*r;
+       }
+       
+       @Override
+       public String toString() {
+               StringBuilder sb = new StringBuilder();
+               sb.append( "Median="+getMedian()+" ");
+               
+               Item i = first();
+               while (i!=null) {
+                       sb.append("(");
+                       sb.append("value=");
+                       if (i.low==i.high) sb.append(i.value); else 
+                               sb.append(i.value+" ("+i.low+".."+i.high+")");
+                       sb.append(", w="+i.weight);
+                       if (i==median) {
+                               sb.append(", pos="+rpos);
+                       }
+                       sb.append(")");
+                       i = i.next;
+               }
+               
+               return sb.toString();
+       } 
+       
+       Item first() {
+               if (median==null) return null;
+               Item i = median;
+               while (i.prev!=null) i = i.prev;
+               return i;
+       }
+       
+       @Referable
+       static public class Item {
+               public double weight;
+               public double low;
+               public double high;
+               public double value;
+               
+               public Item() {}
+               
+               public Item(double weight, double value) {
+                       this.weight = weight;
+                       this.low = this.high = value;
+               }
+
+               public Item(double weight, double value, Item prev, Item next) {
+                       this.weight = weight;
+                       this.value = this.low = this.high = value;
+                       this.prev = prev;
+                       this.next = next;
+               }
+               
+               @Optional
+               public Item prev;
+               
+               @Optional
+               public Item next;
+               
+               @Override
+               public String toString() {
+                       if (low==high) return "(value="+value+", w="+weight+")";
+                       return "(value="+value+" ("+low+".."+high+"), w="+weight+")";
+               }
+       }
+       
+}