13 #ifndef MLPACK_CORE_TREE_BINARY_SPACE_TREE_UB_TREE_SPLIT_IMPL_HPP 14 #define MLPACK_CORE_TREE_BINARY_SPACE_TREE_UB_TREE_SPLIT_IMPL_HPP 22 template<
typename BoundType,
typename MatType>
23 bool UBTreeSplit<BoundType, MatType>::SplitNode(BoundType& bound,
29 constexpr
size_t order =
sizeof(AddressElemType) * CHAR_BIT;
30 if (begin == 0 && count == data.n_cols)
33 InitializeAddresses(data);
37 std::sort(addresses.begin(), addresses.end(), ComparePair);
40 splitInfo.addresses = &addresses;
45 splitInfo.addresses = NULL;
53 if (begin + count < data.n_cols)
57 arma::Col<AddressElemType>& lo = addresses[begin + count - 1].first;
58 const arma::Col<AddressElemType>& hi = addresses[begin + count].first;
60 for (; row < data.n_rows; row++)
61 if (lo[row] != hi[row])
66 for (; bit < order; bit++)
67 if ((lo[row] & ((AddressElemType) 1 << (order - 1 - bit))) !=
68 (hi[row] & ((AddressElemType) 1 << (order - 1 - bit))))
81 for (; bit < order; bit++)
82 lo[row] |= ((AddressElemType) 1 << (order - 1 - bit));
86 for (; row < data.n_rows; row++)
87 for (; bit < order; bit++)
88 lo[row] |= ((AddressElemType) 1 << (order - 1 - bit));
100 const arma::Col<AddressElemType>& lo = addresses[begin - 1].first;
101 arma::Col<AddressElemType>& hi = addresses[begin].first;
103 for (; row < data.n_rows; row++)
104 if (lo[row] != hi[row])
109 for (; bit < order; bit++)
110 if ((lo[row] & ((AddressElemType) 1 << (order - 1 - bit))) !=
111 (hi[row] & ((AddressElemType) 1 << (order - 1 - bit))))
124 for (; bit < order; bit++)
125 hi[row] &= ~((AddressElemType) 1 << (order - 1 - bit));
129 for (; row < data.n_rows; row++)
130 for (; bit < order; bit++)
131 hi[row] &= ~((AddressElemType) 1 << (order - 1 - bit));
135 for (
size_t k = 0; k < bound.Dim(); ++k)
137 bound.LoAddress()[k] = addresses[begin].first[k];
138 bound.HiAddress()[k] = addresses[begin + count - 1].first[k];
140 bound.UpdateAddressBounds(data.cols(begin, begin + count - 1));
145 template<
typename BoundType,
typename MatType>
146 void UBTreeSplit<BoundType, MatType>::InitializeAddresses(
const MatType& data)
148 addresses.resize(data.n_cols);
151 for (
size_t i = 0; i < data.n_cols; ++i)
153 addresses[i].first.zeros(data.n_rows);
154 bound::addr::PointToAddress(addresses[i].first, data.col(i));
155 addresses[i].second = i;
159 template<
typename BoundType,
typename MatType>
160 size_t UBTreeSplit<BoundType, MatType>::PerformSplit(
164 const SplitInfo& splitInfo)
167 if (splitInfo.addresses)
169 std::vector<size_t> newFromOld(data.n_cols);
170 std::vector<size_t> oldFromNew(data.n_cols);
172 for (
size_t i = 0; i < splitInfo.addresses->size(); ++i)
178 for (
size_t i = 0; i < splitInfo.addresses->size(); ++i)
180 size_t index = (*splitInfo.addresses)[i].second;
181 size_t oldI = oldFromNew[i];
182 size_t newIndex = newFromOld[index];
184 data.swap_cols(i, newFromOld[index]);
186 size_t tmp = newFromOld[index];
187 newFromOld[index] = i;
188 newFromOld[oldI] = tmp;
191 oldFromNew[i] = oldFromNew[newIndex];
192 oldFromNew[newIndex] = tmp;
197 return begin + count / 2;
200 template<
typename BoundType,
typename MatType>
201 size_t UBTreeSplit<BoundType, MatType>::PerformSplit(
205 const SplitInfo& splitInfo,
206 std::vector<size_t>& oldFromNew)
209 if (splitInfo.addresses)
211 std::vector<size_t> newFromOld(data.n_cols);
213 for (
size_t i = 0; i < splitInfo.addresses->size(); ++i)
216 for (
size_t i = 0; i < splitInfo.addresses->size(); ++i)
218 size_t index = (*splitInfo.addresses)[i].second;
219 size_t oldI = oldFromNew[i];
220 size_t newIndex = newFromOld[index];
222 data.swap_cols(i, newFromOld[index]);
224 size_t tmp = newFromOld[index];
225 newFromOld[index] = i;
226 newFromOld[oldI] = tmp;
229 oldFromNew[i] = oldFromNew[newIndex];
230 oldFromNew[newIndex] = tmp;
235 return begin + count / 2;
Linear algebra utility functions, generally performed on matrices or vectors.
Definition: cv.hpp:1
Bounds that are useful for binary space partitioning trees.