13 #ifndef MLPACK_CORE_TREE_RECTANGLE_TREE_DISCRETE_HILBERT_VALUE_IMPL_HPP 14 #define MLPACK_CORE_TREE_RECTANGLE_TREE_DISCRETE_HILBERT_VALUE_IMPL_HPP 21 template<
typename TreeElemType>
22 DiscreteHilbertValue<TreeElemType>::DiscreteHilbertValue() :
23 localHilbertValues(NULL),
24 ownsLocalHilbertValues(false),
27 ownsValueToInsert(false)
30 template<
typename TreeElemType>
31 DiscreteHilbertValue<TreeElemType>::~DiscreteHilbertValue()
33 if (ownsLocalHilbertValues)
34 delete localHilbertValues;
35 if (ownsValueToInsert)
39 template<
typename TreeElemType>
40 template<
typename TreeType>
41 DiscreteHilbertValue<TreeElemType>::DiscreteHilbertValue(
const TreeType* tree) :
42 localHilbertValues(NULL),
43 ownsLocalHilbertValues(false),
45 valueToInsert(tree->Parent() ?
46 tree->Parent()->AuxiliaryInfo().HilbertValue().ValueToInsert() :
47 new
arma::Col<HilbertElemType>(tree->Dataset().n_rows)),
48 ownsValueToInsert(tree->Parent() ? false : true)
52 ownsLocalHilbertValues =
true;
53 else if (tree->Parent()->Child(0).IsLeaf())
56 assert(tree->Parent()->NumChildren() > 0);
57 ownsLocalHilbertValues =
true;
60 if (ownsLocalHilbertValues)
62 localHilbertValues =
new arma::Mat<HilbertElemType>(tree->Dataset().n_rows,
63 tree->MaxLeafSize() + 1);
67 template<
typename TreeElemType>
68 template<
typename TreeType>
69 DiscreteHilbertValue<TreeElemType>::
70 DiscreteHilbertValue(
const DiscreteHilbertValue& other,
73 localHilbertValues(NULL),
74 ownsLocalHilbertValues(other.ownsLocalHilbertValues),
75 numValues(other.NumValues()),
77 ownsValueToInsert(other.ownsValueToInsert)
83 if (ownsLocalHilbertValues)
84 localHilbertValues =
new arma::Mat<HilbertElemType>(
85 *other.LocalHilbertValues());
87 localHilbertValues = NULL;
90 if (ownsValueToInsert)
91 valueToInsert =
new arma::Col<HilbertElemType>(
92 *other.ValueToInsert());
95 assert(tree->Parent() != NULL);
97 valueToInsert =
const_cast<arma::Col<HilbertElemType>*
> 98 (tree->Parent()->AuxiliaryInfo().HilbertValue().ValueToInsert());
101 if (tree->NumChildren() == 0)
105 TreeType* node = tree;
107 while (node->Parent() != NULL)
109 if (node->Parent()->NumChildren() > 1)
111 const std::vector<TreeType*> parentChildren =
112 node->AuxiliaryInfo().Children(node->Parent());
115 if (parentChildren[node->Parent()->NumChildren() - 2] == NULL)
118 node->Parent()->AuxiliaryInfo().HilbertValue().LocalHilbertValues() =
120 node = node->Parent();
126 localHilbertValues =
const_cast<arma::Mat<HilbertElemType>*
> 127 (other.LocalHilbertValues());
128 valueToInsert =
const_cast<arma::Col<HilbertElemType>*
> 129 (other.ValueToInsert());
133 template<
typename TreeElemType>
134 DiscreteHilbertValue<TreeElemType>::
135 DiscreteHilbertValue(DiscreteHilbertValue&& other) :
136 localHilbertValues(other.localHilbertValues),
137 ownsLocalHilbertValues(other.ownsLocalHilbertValues),
138 numValues(other.numValues),
139 valueToInsert(other.valueToInsert),
140 ownsValueToInsert(other.ownsValueToInsert)
142 other.localHilbertValues = NULL;
143 other.ownsLocalHilbertValues =
false;
145 other.valueToInsert = NULL;
146 other.ownsValueToInsert =
false;
149 template<
typename TreeElemType>
150 template<
typename VecType>
151 arma::Col<typename DiscreteHilbertValue<TreeElemType>::HilbertElemType>
152 DiscreteHilbertValue<TreeElemType>::
153 CalculateValue(
const VecType& pt,
156 typedef typename VecType::elem_type VecElemType;
157 arma::Col<HilbertElemType> res(pt.n_rows);
159 const int numExpBits = std::ceil(std::log2(
160 std::numeric_limits<VecElemType>::max_exponent -
161 std::numeric_limits<VecElemType>::min_exponent + 1.0));
164 const int numMantBits = order - numExpBits - 1;
166 for (
size_t i = 0; i < pt.n_rows; ++i)
169 VecElemType normalizedVal = std::frexp(pt(i), &e);
170 bool sgn = std::signbit(normalizedVal);
173 e = std::numeric_limits<VecElemType>::min_exponent;
176 normalizedVal = -normalizedVal;
178 if (e < std::numeric_limits<VecElemType>::min_exponent)
180 HilbertElemType tmp = (HilbertElemType) 1 <<
181 (std::numeric_limits<VecElemType>::min_exponent - e);
183 e = std::numeric_limits<VecElemType>::min_exponent;
184 normalizedVal /= tmp;
188 HilbertElemType tmp = (HilbertElemType) 1 << numMantBits;
189 res(i) = std::floor(normalizedVal * tmp);
192 assert(res(i) < ((HilbertElemType) 1 << numMantBits));
193 res(i) |= ((HilbertElemType)
194 (e - std::numeric_limits<VecElemType>::min_exponent)) << numMantBits;
196 assert(res(i) < ((HilbertElemType) 1 << (order - 1)) - 1);
201 res(i) = ((HilbertElemType) 1 << (order - 1)) - 1 - res(i);
202 assert((res(i) >> (order - 1)) == 0);
206 res(i) |= (HilbertElemType) 1 << (order - 1);
207 assert((res(i) >> (order - 1)) == 1);
211 HilbertElemType M = (HilbertElemType) 1 << (order - 1);
215 for (HilbertElemType Q = M; Q > 1; Q >>= 1)
217 HilbertElemType P = Q - 1;
219 for (
size_t i = 0; i < pt.n_rows; ++i)
225 HilbertElemType t = (res(0) ^ res(i)) & P;
233 for (
size_t i = 1; i < pt.n_rows; ++i)
234 res(i) ^= res(i - 1);
236 HilbertElemType t = 0;
239 for (HilbertElemType Q = M; Q > 1; Q >>= 1)
240 if (res(pt.n_rows - 1) & Q)
243 for (
size_t i = 0; i < pt.n_rows; ++i)
247 arma::Col<HilbertElemType> rearrangedResult(pt.n_rows, arma::fill::zeros);
249 for (
size_t i = 0; i < order; ++i)
250 for (
size_t j = 0; j < pt.n_rows; ++j)
252 size_t bit = (i * pt.n_rows + j) % order;
253 size_t row = (i * pt.n_rows + j) / order;
255 rearrangedResult(row) |= (((res(j) >> (order - 1 - i)) & 1) <<
259 return rearrangedResult;
262 template<
typename TreeElemType>
263 int DiscreteHilbertValue<TreeElemType>::
264 CompareValues(
const arma::Col<HilbertElemType>& value1,
265 const arma::Col<HilbertElemType>& value2)
267 for (
size_t i = 0; i < value1.n_rows; ++i)
269 if (value1(i) > value2(i))
271 else if (value1(i) < value2(i))
280 template<
typename TreeElemType>
281 template<
typename VecType1,
typename VecType2>
282 int DiscreteHilbertValue<TreeElemType>::
283 ComparePoints(
const VecType1& pt1,
288 arma::Col<HilbertElemType> val1 = CalculateValue(pt1);
289 arma::Col<HilbertElemType> val2 = CalculateValue(pt2);
291 return CompareValues(val1, val2);
294 template<
typename TreeElemType>
295 int DiscreteHilbertValue<TreeElemType>::
296 CompareValues(
const DiscreteHilbertValue& val1,
297 const DiscreteHilbertValue& val2)
299 if (val1.NumValues() > 0 && val2.NumValues() == 0)
301 else if (val1.NumValues() == 0 && val2.NumValues() > 0)
303 else if (val1.NumValues() == 0 && val2.NumValues() == 0)
306 return CompareValues(val1.LocalHilbertValues()->col(val1.NumValues() - 1),
307 val2.LocalHilbertValues()->col(val2.NumValues() - 1));
310 template<
typename TreeElemType>
311 int DiscreteHilbertValue<TreeElemType>::
312 CompareWith(
const DiscreteHilbertValue& val)
const 314 return CompareValues(*
this, val);
317 template<
typename TreeElemType>
318 template<
typename VecType>
319 int DiscreteHilbertValue<TreeElemType>::
320 CompareWith(
const VecType& pt,
323 arma::Col<HilbertElemType> val = CalculateValue(pt);
328 return CompareValues(localHilbertValues->col(numValues - 1), val);
331 template<
typename TreeElemType>
332 template<
typename VecType>
333 int DiscreteHilbertValue<TreeElemType>::
334 CompareWithCachedPoint(
const VecType& ,
340 return CompareValues(localHilbertValues->col(numValues - 1), *valueToInsert);
343 template<
typename TreeElemType>
344 template<
typename TreeType,
typename VecType>
345 size_t DiscreteHilbertValue<TreeElemType>::
346 InsertPoint(TreeType *node,
354 *valueToInsert = CalculateValue(pt);
358 for (i = 0; i < numValues; ++i)
359 if (CompareValues(localHilbertValues->col(i), *valueToInsert) > 0)
362 for (
size_t j = numValues; j > i; j--)
363 localHilbertValues->col(j) = localHilbertValues->col(j-1);
365 localHilbertValues->col(i) = *valueToInsert;
368 TreeType* root = node->Parent();
372 root->AuxiliaryInfo().HilbertValue().UpdateLargestValue(root);
374 root = root->Parent();
381 template<
typename TreeElemType>
382 template<
typename TreeType>
383 void DiscreteHilbertValue<TreeElemType>::InsertNode(TreeType* node)
385 DiscreteHilbertValue &val = node->AuxiliaryInfo().HilbertValue();
387 if (CompareWith(node, val) < 0)
389 localHilbertValues = val.LocalHilbertValues();
390 numValues = val.NumValues();
394 template<
typename TreeElemType>
395 template<
typename TreeType>
396 void DiscreteHilbertValue<TreeElemType>::
397 DeletePoint(TreeType* ,
const size_t localIndex)
400 for (
size_t i = numValues - 1; i > localIndex; i--)
401 localHilbertValues->col(i - 1) = localHilbertValues->col(i);
406 template<
typename TreeElemType>
407 template<
typename TreeType>
408 void DiscreteHilbertValue<TreeElemType>::
409 RemoveNode(TreeType* node,
const size_t nodeIndex)
411 if (node->NumChildren() <= 1)
413 localHilbertValues = NULL;
417 if (nodeIndex + 1 == node->NumChildren())
420 TreeType& child = node->Child(nodeIndex - 1);
421 if (child.AuxiliaryInfo.HilbertValue().NumValues() != 0)
423 numValues = child.AuxiliaryInfo.HilbertValue().NumValues();
425 child.AuxiliaryInfo.HilbertValue().LocalHilbertValues();
429 localHilbertValues = NULL;
435 template<
typename TreeElemType>
436 DiscreteHilbertValue<TreeElemType>& DiscreteHilbertValue<TreeElemType>::
437 operator=(
const DiscreteHilbertValue& other)
442 if (ownsLocalHilbertValues)
443 delete localHilbertValues;
445 localHilbertValues =
const_cast<arma::Mat<HilbertElemType>*
> 446 (other.LocalHilbertValues());
447 ownsLocalHilbertValues =
false;
448 numValues = other.NumValues();
453 template<
typename TreeElemType>
454 DiscreteHilbertValue<TreeElemType>& DiscreteHilbertValue<TreeElemType>::
455 operator=(DiscreteHilbertValue&& other)
459 localHilbertValues = other.localHilbertValues;
460 ownsLocalHilbertValues = other.ownsLocalHilbertValues;
461 numValues = other.numValues;
462 valueToInsert = other.valueToInsert;
463 ownsValueToInsert = other.ownsValueToInsert;
465 other.localHilbertValues =
nullptr;
466 other.ownsLocalHilbertValues =
false;
468 other.valueToInsert =
nullptr;
469 other.ownsValueToInsert =
false;
474 template<
typename TreeElemType>
475 void DiscreteHilbertValue<TreeElemType>::NullifyData()
477 ownsLocalHilbertValues =
false;
480 template<
typename TreeElemType>
481 template<
typename TreeType>
482 void DiscreteHilbertValue<TreeElemType>::UpdateLargestValue(TreeType* node)
487 localHilbertValues = node->Child(node->NumChildren() -
488 1).AuxiliaryInfo().HilbertValue().LocalHilbertValues();
489 numValues = node->Child(node->NumChildren() -
490 1).AuxiliaryInfo().HilbertValue().NumValues();
494 template<
typename TreeElemType>
495 template<
typename TreeType>
496 void DiscreteHilbertValue<TreeElemType>::RedistributeHilbertValues(
498 const size_t firstSibling,
499 const size_t lastSibling)
502 size_t numPoints = 0;
503 for (
size_t i = firstSibling; i <= lastSibling; ++i)
504 numPoints += parent->Child(i).NumPoints();
507 arma::Mat<HilbertElemType> tmp(localHilbertValues->n_rows, numPoints);
510 for (
size_t i = firstSibling; i<= lastSibling; ++i)
512 DiscreteHilbertValue<TreeElemType> &value =
513 parent->Child(i).AuxiliaryInfo().HilbertValue();
515 for (
size_t j = 0; j < value.NumValues(); ++j)
517 tmp.col(iPoint) = value.LocalHilbertValues()->col(j);
521 assert(iPoint == numPoints);
526 for (
size_t i = firstSibling; i <= lastSibling; ++i)
528 DiscreteHilbertValue<TreeElemType> &value =
529 parent->Child(i).AuxiliaryInfo().HilbertValue();
531 for (
size_t j = 0; j < parent->Child(i).NumPoints(); ++j)
533 value.LocalHilbertValues()->col(j) = tmp.col(iPoint);
536 value.NumValues() = parent->Child(i).NumPoints();
539 assert(iPoint == numPoints);
542 template<
typename TreeElemType>
543 template<
typename Archive>
544 void DiscreteHilbertValue<TreeElemType>::serialize(
549 ar(CEREAL_NVP(ownsLocalHilbertValues));
550 ar(CEREAL_NVP(numValues));
552 ar(CEREAL_NVP(ownsValueToInsert));
558 #endif // MLPACK_CORE_TREE_RECTANGLE_TREE_DISCRETE_HILBERT_VALUE_IMPL_HPP Linear algebra utility functions, generally performed on matrices or vectors.
Definition: cv.hpp:1
#define CEREAL_POINTER(T)
Cereal does not support the serialization of raw pointer.
Definition: pointer_wrapper.hpp:96
If value == true, then VecType is some sort of Armadillo vector or subview.
Definition: arma_traits.hpp:35