26 #ifndef MLPACK_CORE_TREE_ADDRESS_HPP 27 #define MLPACK_CORE_TREE_ADDRESS_HPP 56 template<
typename AddressType,
typename VecType>
59 typedef typename VecType::elem_type VecElemType;
61 typedef typename std::conditional<
sizeof(VecElemType) * CHAR_BIT <= 32,
63 uint64_t>::type AddressElemType;
65 static_assert(std::is_same<
typename AddressType::elem_type,
66 AddressElemType>::value ==
true,
"The vector element type does not " 67 "correspond to the address element type.");
68 arma::Col<AddressElemType> result(point.n_elem);
70 constexpr
size_t order =
sizeof(AddressElemType) * CHAR_BIT;
72 const int numExpBits = std::ceil(std::log2(
73 std::numeric_limits<VecElemType>::max_exponent -
74 std::numeric_limits<VecElemType>::min_exponent + 1.0));
77 const int numMantBits = order - numExpBits - 1;
79 assert(point.n_elem == address.n_elem);
80 assert(address.n_elem > 0);
82 for (
size_t i = 0; i < point.n_elem; ++i)
85 VecElemType normalizedVal = std::frexp(point(i), &e);
86 bool sgn = std::signbit(normalizedVal);
89 e = std::numeric_limits<VecElemType>::min_exponent;
92 normalizedVal = -normalizedVal;
94 if (e < std::numeric_limits<VecElemType>::min_exponent)
96 AddressElemType tmp = (AddressElemType) 1 <<
97 (std::numeric_limits<VecElemType>::min_exponent - e);
99 e = std::numeric_limits<VecElemType>::min_exponent;
100 normalizedVal /= tmp;
104 AddressElemType tmp = (AddressElemType) 1 << numMantBits;
105 result(i) = std::floor(normalizedVal * tmp);
108 assert(result(i) < ((AddressElemType) 1 << numMantBits));
109 result(i) |= ((AddressElemType)
110 (e - std::numeric_limits<VecElemType>::min_exponent)) << numMantBits;
112 assert(result(i) < ((AddressElemType) 1 << (order - 1)) - 1);
117 result(i) = ((AddressElemType) 1 << (order - 1)) - 1 - result(i);
118 assert((result(i) >> (order - 1)) == 0);
122 result(i) |= (AddressElemType) 1 << (order - 1);
123 assert((result(i) >> (order - 1)) == 1);
127 address.zeros(point.n_elem);
131 for (
size_t i = 0; i < order; ++i)
132 for (
size_t j = 0; j < point.n_elem; ++j)
134 size_t bit = (i * point.n_elem + j) % order;
135 size_t row = (i * point.n_elem + j) / order;
137 address(row) |= (((result(j) >> (order - 1 - i)) & 1) <<
152 template<
typename AddressType,
typename VecType>
155 typedef typename VecType::elem_type VecElemType;
157 typedef typename std::conditional<
sizeof(VecElemType) * CHAR_BIT <= 32,
159 uint64_t>::type AddressElemType;
161 static_assert(std::is_same<
typename AddressType::elem_type,
162 AddressElemType>::value ==
true,
"The vector element type does not " 163 "correspond to the address element type.");
165 constexpr
size_t order =
sizeof(AddressElemType) * CHAR_BIT;
167 const int numExpBits = std::ceil(std::log2(
168 std::numeric_limits<VecElemType>::max_exponent -
169 std::numeric_limits<VecElemType>::min_exponent + 1.0));
171 assert(point.n_elem == address.n_elem);
172 assert(address.n_elem > 0);
174 arma::Col<AddressElemType> rearrangedAddress(address.n_elem,
177 const int numMantBits = order - numExpBits - 1;
179 for (
size_t i = 0; i < order; ++i)
180 for (
size_t j = 0; j < address.n_elem; ++j)
182 size_t bit = (i * address.n_elem + j) % order;
183 size_t row = (i * address.n_elem + j) / order;
185 rearrangedAddress(j) |= (((address(row) >> (order - 1 - bit)) & 1) <<
189 for (
size_t i = 0; i < rearrangedAddress.n_elem; ++i)
191 bool sgn = rearrangedAddress(i) & ((AddressElemType) 1 << (order - 1));
195 rearrangedAddress(i) = ((AddressElemType) 1 << (order - 1)) - 1 -
196 rearrangedAddress(i);
200 AddressElemType tmp = (AddressElemType) 1 << numMantBits;
201 AddressElemType mantissa = rearrangedAddress(i) & (tmp - 1);
205 VecElemType normalizedVal = (VecElemType) mantissa / tmp;
208 normalizedVal = -normalizedVal;
211 tmp = (AddressElemType) 1 << numExpBits;
212 AddressElemType e = (rearrangedAddress(i) >> numMantBits) & (tmp - 1);
214 e += std::numeric_limits<VecElemType>::min_exponent;
216 point(i) = std::ldexp(normalizedVal, e);
217 if (std::isinf(point(i)))
220 point(i) = std::numeric_limits<VecElemType>::max();
222 point(i) = std::numeric_limits<VecElemType>::lowest();
232 template<
typename AddressType1,
typename AddressType2>
235 static_assert(std::is_same<
typename AddressType1::elem_type,
236 typename AddressType2::elem_type>::value ==
true,
"Can't compare " 237 "addresses of distinct types");
239 assert(addr1.n_elem == addr2.n_elem);
241 for (
size_t i = 0; i < addr1.n_elem; ++i)
243 if (addr1[i] < addr2[i])
245 else if (addr2[i] < addr1[i])
255 template<
typename AddressType1,
typename AddressType2,
typename AddressType3>
256 bool Contains(
const AddressType1& address,
const AddressType2& loBound,
257 const AddressType3& hiBound)
267 #endif // MLPACK_CORE_TREE_ADDRESS_HPP Linear algebra utility functions, generally performed on matrices or vectors.
void AddressToPoint(VecType &point, const AddressType &address)
Translate the address to the point.
void PointToAddress(AddressType &address, const VecType &point)
Calculate the address of a point.
bool Contains(const AddressType1 &address, const AddressType2 &loBound, const AddressType3 &hiBound)
Returns true if an address is contained between two other addresses.
int CompareAddresses(const AddressType1 &addr1, const AddressType2 &addr2)
Compare two addresses.