]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.history/src/org/simantics/history/util/WeightedMedianBinding.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.history / src / org / simantics / history / util / WeightedMedianBinding.java
1 /*******************************************************************************\r
2  * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
3  * Industry THTH ry.\r
4  * All rights reserved. This program and the accompanying materials\r
5  * are made available under the terms of the Eclipse Public License v1.0\r
6  * which accompanies this distribution, and is available at\r
7  * http://www.eclipse.org/legal/epl-v10.html\r
8  *\r
9  * Contributors:\r
10  *     VTT Technical Research Centre of Finland - initial API and implementation\r
11  *******************************************************************************/\r
12 package org.simantics.history.util;\r
13 \r
14 import java.util.Iterator;\r
15 \r
16 import org.simantics.databoard.Bindings;\r
17 import org.simantics.databoard.binding.ArrayBinding;\r
18 import org.simantics.databoard.binding.error.BindingException;\r
19 import org.simantics.databoard.type.ArrayType;\r
20 \r
21 /**\r
22  * This class binds median class to as an array(double) where every second value\r
23  * represents value and odd weight.\r
24  */\r
25 public class WeightedMedianBinding extends ArrayBinding {\r
26 \r
27         public WeightedMedianBinding() {\r
28                 super(new ArrayType(Bindings.DOUBLE.type()), Bindings.DOUBLE);\r
29         }\r
30         \r
31         @Override\r
32         public Object create() {\r
33                 return new WeightedMedian();\r
34         }\r
35 \r
36         @Override\r
37         public Object create(int length, Iterator<Object> it) throws BindingException {         \r
38                 WeightedMedian result = new WeightedMedian( length );\r
39                 int count = length/2;\r
40                 WeightedMedian.Item[] items = new WeightedMedian.Item[count];           \r
41                 int index = 0;\r
42                 double value=0.0, weight=0.0;\r
43                 while (it.hasNext()) {\r
44                         double d = (Double) it.next();\r
45                         if ( index%2==0 ) {\r
46                                 value = d;\r
47                         } else {\r
48                                 weight = d;\r
49                                 WeightedMedian.Item i = new WeightedMedian.Item(weight, value);\r
50                                 items[ index/2 ] = i;\r
51                         }\r
52                         index++;\r
53                 }\r
54                 if ( count>0 ) {\r
55                         items[0].next = items[1];\r
56                         items[count-1].prev = items[count-2];\r
57                 }               \r
58                 for (index=1; index<count-1; index++) {\r
59                         items[index].next = items[index+1];\r
60                         items[index].prev = items[index-1];\r
61                 }\r
62                 result.median = items[count/2];\r
63                 result.itemCount = count;\r
64                 return result;\r
65         }\r
66 \r
67         @Override\r
68         public Object create(Object[] array) throws BindingException {\r
69                 int count = array.length/2;\r
70                 WeightedMedian result = new WeightedMedian();\r
71                 WeightedMedian.Item[] items = new WeightedMedian.Item[count];           \r
72                 double value=0.0, weight=0.0;\r
73                 for (int index=0; index<array.length; index++) {\r
74                         double d = (Double) array[index];\r
75                         if ( index%2==0 ) {\r
76                                 value = d;\r
77                         } else {\r
78                                 weight = d;\r
79                                 WeightedMedian.Item i = new WeightedMedian.Item(weight, value);\r
80                                 items[ index/2 ] = i;\r
81                         }\r
82                         index++;\r
83                 }\r
84                 if ( count>0 ) {\r
85                         items[0].next = items[1];\r
86                         items[count-1].prev = items[count-2];\r
87                 }               \r
88                 for (int index=1; index<count-1; index++) {\r
89                         items[index].next = items[index+1];\r
90                         items[index].prev = items[index-1];\r
91                 }\r
92                 result.median = items[count/2];\r
93                 result.itemCount = count;\r
94                 return result;\r
95         }\r
96 \r
97         @Override\r
98         public void add(Object array, int index, Object element) throws BindingException, IndexOutOfBoundsException {\r
99                 throw new BindingException("not implemented");\r
100         }\r
101 \r
102         @Override\r
103         public void remove(Object array, int index, int count) throws BindingException {\r
104                 throw new BindingException("not implemented");\r
105         }\r
106 \r
107         @Override\r
108         public Object get(Object array, int index) throws BindingException {\r
109                 int pos = index/2;\r
110                 WeightedMedian median = (WeightedMedian) array;\r
111                 int c = median.itemCount*2;\r
112                 if ( index<0 || index>=c ) throw new BindingException("Index "+index+" out of bounds "+c);\r
113                 WeightedMedian.Item i = median.head();\r
114                 for (int ix=1; ix<pos; ix++) i = i.next;\r
115                 return index%2==0?i.value:i.weight;\r
116         }\r
117 \r
118         @Override\r
119         public void getAll(Object array, Object[] result) throws BindingException {\r
120                 int c = size( array );\r
121                 if (result.length<c) throw new BindingException("Array too small");\r
122                 WeightedMedian median = (WeightedMedian) array;\r
123                 int ix = 0;\r
124                 WeightedMedian.Item i = median.head();\r
125                 while (i != null) {\r
126                         result[ix] = i.value; ix++;\r
127                         result[ix] = i.weight; ix++;\r
128                         i = i.next;\r
129                 }\r
130         }\r
131 \r
132         @Override\r
133         public void set(Object array, int index, Object value) throws BindingException {\r
134                 remove(array, index);\r
135                 add(array, value);\r
136         }\r
137 \r
138         @Override\r
139         public void setSize(Object array, int newSize) throws BindingException {\r
140                 int size = size(array);\r
141                 if (size<newSize) newSize = size;\r
142                 remove( array, size-newSize, newSize);\r
143         }\r
144 \r
145         @Override\r
146         public int size(Object array) throws BindingException {\r
147                 WeightedMedian median = (WeightedMedian) array;\r
148                 return median.itemCount*2;\r
149         }\r
150 \r
151         @Override\r
152         public boolean isInstance(Object obj) {\r
153                 return obj instanceof WeightedMedian;\r
154         }       \r
155 \r
156         @Override\r
157         public boolean isResizable() {\r
158                 return true;\r
159         }\r
160         \r
161 }\r
162 \r
163 \r