2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
4 * Copyright (c) 2007 Sun Microsystems, Inc. All Rights Reserved.
6 * The contents of this file are subject to the terms of either the GNU Lesser
7 * General Public License Version 2.1 only ("LGPL") or the Common Development and
8 * Distribution License ("CDDL")(collectively, the "License"). You may not use this
9 * file except in compliance with the License. You can obtain a copy of the CDDL at
10 * http://www.opensource.org/licenses/cddl1.php and a copy of the LGPLv2.1 at
11 * http://www.opensource.org/licenses/lgpl-license.php. See the License for the
12 * specific language governing permissions and limitations under the License. When
13 * distributing the software, include this License Header Notice in each file and
14 * include the full text of the License in the License file as well as the
17 * NOTICE PURSUANT TO SECTION 9 OF THE COMMON DEVELOPMENT AND DISTRIBUTION LICENSE
19 * For Covered Software in this distribution, this License shall be governed by the
20 * laws of the State of California (excluding conflict-of-law provisions).
21 * Any litigation relating to this License shall be subject to the jurisdiction of
22 * the Federal Courts of the Northern District of California and the state courts
23 * of the State of California, with venue lying in Santa Clara County, California.
27 * If you wish your version of this file to be governed by only the CDDL or only
28 * the LGPL Version 2.1, indicate your decision by adding "[Contributor]" elects to
29 * include this software in this distribution under the [CDDL or LGPL Version 2.1]
30 * license." If you don't indicate a single choice of license, a recipient has the
31 * option to distribute your version of this file under either the CDDL or the LGPL
32 * Version 2.1, or to extend the choice of license to its licensees as provided
33 * above. However, if you add LGPL Version 2.1 code and therefore, elected the LGPL
34 * Version 2 license, then the option applies only if the new code is made subject
35 * to such option by the copyright holder.
44 #include "ValueCompress.h"
51 #define DBL_MAX (1E+300)
58 TVCArrItem(float val = 0.0, unsigned idx = 0)
59 : m_val(val), m_heapIdx(idx)
73 operator<(const TVCHeapItem& b) const
75 return m_appval < b.m_appval;
78 TVCHeapItem(unsigned first = 0, unsigned last = 0, unsigned count = 0,
79 double val = 0.0, double sum = 0.0, double dist = 0.0)
80 : m_first(first), m_last(last), m_count(count),
81 m_appval(val), m_sum(sum), m_dist(dist)
86 typedef std::vector<TVCArrItem> CVCArr;
87 typedef std::vector<TVCHeapItem> CVCHeap;
91 BubbleUpVal(CVCHeap& heap, CVCArr& arr, int idx)
94 int parent = (idx - 1) / 2;
95 if (heap[idx] < heap[parent])
97 for (int h = heap[idx].m_first, t = heap[idx].m_last; h < t; ++h)
98 arr[h].m_heapIdx = parent;
99 for (int h = heap[parent].m_first, t = heap[parent].m_last; h < t; ++h)
100 arr[h].m_heapIdx = idx;
101 TVCHeapItem hitem = heap[parent];
102 heap[parent] = heap[idx];
109 IronDownVal(CVCHeap& heap, CVCArr& arr, int idx, int bottom)
112 while ((left = 2 * idx + 1) < bottom) {
114 if (heap[max] < heap[left])
116 if (left + 1 < bottom && heap[max] < heap[left + 1])
118 if (max == idx) break;
120 for (int h = heap[idx].m_first, t = heap[idx].m_last; h < t; ++h)
121 arr[h].m_heapIdx = max;
122 for (int h = heap[max].m_first, t = heap[max].m_last; h < t; ++h)
123 arr[h].m_heapIdx = idx;
124 TVCHeapItem hitem = heap[max];
125 heap[max] = heap[idx];
134 * Bubble idx up according to distance
137 BubbleUp(CVCHeap& heap, CVCArr& arr, int idx)
140 int parent = (idx - 1) / 2;
141 if (heap[parent].m_dist <= heap[idx].m_dist)
143 for (int h = heap[idx].m_first, t = heap[idx].m_last; h < t; ++h)
144 arr[h].m_heapIdx = parent;
145 for (int h = heap[parent].m_first, t = heap[parent].m_last; h < t; ++h)
146 arr[h].m_heapIdx = idx;
147 TVCHeapItem hitem = heap[parent];
148 heap[parent] = heap[idx];
155 * Iron idx down, but do not let it lower than bottom (< bottom)
158 IronDown(CVCHeap& heap, CVCArr& arr, int idx, int bottom)
161 while ((left = 2 * idx + 1) < bottom) {
163 if (heap[left].m_dist < heap[min].m_dist)
165 if (left + 1 < bottom && heap[left + 1].m_dist < heap[min].m_dist)
167 if (min == idx) break;
169 for (int h = heap[idx].m_first, t = heap[idx].m_last; h < t; ++h)
170 arr[h].m_heapIdx = min;
171 for (int h = heap[min].m_first, t = heap[min].m_last; h < t; ++h)
172 arr[h].m_heapIdx = idx;
173 TVCHeapItem hitem = heap[min];
174 heap[min] = heap[idx];
182 CValueCompressor::operator()(std::map<float, int>& values,
183 std::map<float, int>& map,
184 std::vector<float>& table,
190 std::map<float, int>::const_iterator itv = values.begin();
191 std::map<float, int>::const_iterator itve = values.end();
192 for (; itv != itve; ++itv) {
193 arr.push_back(TVCArrItem(itv->first, arr.size()));
194 double sum = double(itv->first);
197 heap.push_back(TVCHeapItem(heap.size(), heap.size() + 1, itv->second,
201 for (int i = 0, sz = heap.size() - 1; i < sz; ++i) {
202 if (heap[i].m_count == 0 || heap[i + 1].m_count == 0) {
203 heap[i].m_dist = DBL_MAX;
205 heap[i].m_dist = heap[i + 1].m_appval - heap[i].m_appval;
207 BubbleUp(heap, arr, i);
209 if (heap.size() > 0) {
210 heap[heap.size() - 1].m_dist = DBL_MAX;
211 BubbleUp(heap, arr, heap.size() - 1);
214 int cur, next, hiprev, hinext;
216 while (heap.size() > N) {
217 cur = heap[0].m_first;
221 hiprev = arr[cur - 1].m_heapIdx;
223 next = heap[0].m_last;
224 hinext = arr[next].m_heapIdx;
226 for (int h = cur; h < next; ++h)
227 arr[h].m_heapIdx = hinext;
228 double newval = (heap[0].m_sum + heap[hinext].m_sum) /
229 (heap[0].m_count + heap[hinext].m_count);
231 heap[hiprev].m_dist += (newval - heap[0].m_appval);
232 heap[hinext].m_first = heap[0].m_first;
233 heap[hinext].m_count += heap[0].m_count;
234 heap[hinext].m_sum += heap[0].m_sum;
235 heap[hinext].m_dist += (heap[hinext].m_appval - newval);
236 heap[hinext].m_appval = newval;
239 cur = hiprev, hiprev = hinext, hinext = cur;
240 IronDown(heap, arr, hinext, heap.size());
242 IronDown(heap, arr, hiprev, heap.size());
244 heap[0] = heap[heap.size() - 1];
245 for (int h = heap[0].m_first, t = heap[0].m_last; h < t; ++h)
246 arr[h].m_heapIdx = 0;
248 IronDown(heap, arr, 0, heap.size());
251 for (int i = 1, sz = heap.size(); i < sz; ++i)
252 BubbleUpVal(heap, arr, i);
253 for (int i = heap.size() - 1; i > 0; --i) {
254 for (int h = heap[0].m_first, t = heap[0].m_last; h < t; ++h)
255 arr[h].m_heapIdx = i;
256 for (int h = heap[i].m_first, t = heap[i].m_last; h < t; ++h)
257 arr[h].m_heapIdx = 0;
258 TVCHeapItem hitem = heap[0];
261 IronDownVal(heap, arr, 0, i);
265 for (int i = 0, sz = arr.size(); i < sz; ++i)
266 map[arr[i].m_val] = arr[i].m_heapIdx;
269 table.reserve(heap.size());
270 for (int i = 0, sz = heap.size(); i < sz; ++i)
271 table.push_back(float(heap[i].m_appval));
274 for (int i = 0, sz = heap.size(); i < sz; ++i) {
275 printf("%12lf:\n", heap[i].m_appval);
276 for (int h = heap[i].m_first, t = heap[i].m_last; h < t; ++h) {
277 printf(" %12f\n", arr[h].m_val);
278 if (arr[h].m_heapIdx != i) {
279 printf("error, non-consistence found\n");
290 CValueCompressor::operator()(std::map<float, float>& eff2val,
291 std::map<float, int>& values,
292 std::map<float, int>& v2idx,
293 std::vector<float>& table,
296 std::map<float, int> tmp_map;
297 this->operator()(values, tmp_map, table, N);
300 std::map<float, int>::iterator itm = tmp_map.begin();
301 std::map<float, int>::iterator itme = tmp_map.end();
302 for (; itm != itme; ++itm) {
303 v2idx[eff2val[itm->first]] = itm->second;
306 /* // Can not be maped back, because some value could not be in the eff2val maps
307 std::vector<float>::iterator itt = table.begin();
308 std::vector<float>::iterator itte = table.end();
309 for (; itt != itte; ++itt)
310 *itt = eff2val[*itt];