38 namespace energybased {
90 void setPoint(
int i,
int d,
double coord);
165 : m_numPoints(numPoints)
166 , m_wspdSeparationFactor(1.0)
167 , m_wspdSeparationFactorPlus2Squared_cached(9.0) {
172 for (
int i = 0; i < Dim; i++) {
186 m_pTree =
new Tree(m_numPoints);
187 m_nodeData =
new NodeData[m_pTree->maxNumNodes()];
188 m_pointData =
new PointData[m_numPoints];
195 delete[] m_pointData;
204 updateTreeGridPoints();
210 updateTreeNodeGeometry();
218 const double s = (m_wspdSeparationFactor + 2.0);
221 m_wspdSeparationFactorPlus2Squared_cached = s * s;
224 wspdRecursive(m_pTree->rootIndex());
231 for (
int i = 0; i < m_pTree->numChilds(curr); i++) {
233 const int first_child = m_pTree->child(curr, i);
236 for (
int j = i + 1; j < m_pTree->numChilds(curr); j++) {
238 const int second_child = m_pTree->child(curr, j);
241 wspdRecursive(first_child, second_child);
245 wspdRecursive(first_child);
251 if (areWellSeparated(a, b)) {
254 m_pIWSPD->onWellSeparatedPair(a, b);
262 if (
node(small_node).radius_sq >
node(large_node).radius_sq) {
263 std::swap(small_node, large_node);
267 for (
int i = 0; i <
tree().numChilds(large_node); ++i) {
269 wspdRecursive(small_node,
tree().child(large_node, i));
277 double r_max_sq = std::max(
node(a).radius_sq,
node(b).radius_sq);
280 double dist_sq = 0.0;
283 for (
int d = 0; d < Dim; d++) {
284 double dx =
node(a).x[d] -
node(b).x[d];
296 const double s = (m_wspdSeparationFactor + 2.0);
297 return dist_sq > (m_wspdSeparationFactor * m_wspdSeparationFactor + 4.0 * m_wspdSeparationFactor + 4) * r_max * r_max;
299 return dist_sq > s * s * r_max_sq;
302 return dist_sq > m_wspdSeparationFactorPlus2Squared_cached * r_max_sq;
309 double r_max_sq = std::max(
node(a).radius_sq,
node(b).radius_sq);
312 double dx_0 =
node(a).x[0] -
node(b).x[0];
313 double dx_1 =
node(a).x[1] -
node(b).x[1];
314 double dist_sq = dx_0 * dx_0 + dx_1 * dx_1;
317 return dist_sq > m_wspdSeparationFactorPlus2Squared_cached * r_max_sq;
323 double r_max_sq = std::max(
node(a).radius_sq,
node(b).radius_sq);
326 double dx_0 =
node(a).x[0] -
node(b).x[0];
327 double dx_1 =
node(a).x[1] -
node(b).x[1];
328 double dx_2 =
node(a).x[2] -
node(b).x[2];
329 double dist_sq = dx_0 * dx_0 + dx_1 * dx_1 + dx_2 * dx_2;
332 return dist_sq > m_wspdSeparationFactorPlus2Squared_cached * r_max_sq;
338 m_pointData[i].x[d] = coord;
348 for (
int d = 0; d < Dim; d++) {
349 m_bboxMin[d] = m_bboxMax[d] = point(0).x[d];
353 for (
int i = 1; i < m_numPoints; i++) {
354 for (
int d = 0; d < Dim; d++) {
355 m_bboxMin[d] = std::min(m_bboxMin[d], point(i).x[d]);
356 m_bboxMax[d] = std::max(m_bboxMax[d], point(i).x[d]);
364 for (
int d = 0; d < Dim; d++) {
365 double noise_max = (m_bboxMax[d] - m_bboxMin[d]) * 0.25;
370 double quad_size = m_bboxMax[0] - m_bboxMin[0];
371 for (
int d = 1; d < Dim; d++) {
372 quad_size = std::max(quad_size, m_bboxMax[d] - m_bboxMin[d]);
375 const double factor = (double)(0xffffffff);
377 double scale = factor / quad_size;
379 for (
int i = 0; i < m_numPoints; i++) {
380 for (
int d = 0; d < Dim; d++) {
383 double nx = ((point(i).x[d] - m_bboxMin[d] + 0.01) / quad_size + 0.02);
385 double nx = ((point(i).x[d] - m_bboxMin[d]) * scale);
388 unsigned int ix =
static_cast<unsigned int>(nx);
391 m_pTree->setPoint(i, d, ix);
398 updateTreeNodeGeometry(m_pTree->rootIndex());
405 if (m_pTree->numChilds(curr)) {
409 for (
int i = 0; i < m_pTree->numChilds(curr); i++) {
411 const int child = m_pTree->child(curr, i);
414 updateTreeNodeGeometry(child);
418 for (
int d = 0; d < Dim; d++) {
419 node(curr).min_x[d] =
node(child).min_x[d];
420 node(curr).max_x[d] =
node(child).max_x[d];
423 for (
int d = 0; d < Dim; d++) {
424 node(curr).min_x[d] = std::min(
node(curr).min_x[d],
node(child).min_x[d]);
425 node(curr).max_x[d] = std::max(
node(curr).max_x[d],
node(child).max_x[d]);
431 for (
int d = 0; d < Dim; d++) {
432 node(curr).min_x[d] =
node(curr).max_x[d] = point(
tree().point(curr, 0)).x[d];
436 for (
int i = 1; i <
tree().numPoints(curr); ++i) {
437 for (
int d = 0; d < Dim; d++) {
438 node(curr).min_x[d] =
439 std::min(
node(curr).min_x[d], point(
tree().point(curr, i)).x[d]);
440 node(curr).max_x[d] =
441 std::max(
node(curr).max_x[d], point(
tree().point(curr, i)).x[d]);
447 node(curr).radius_sq = 0.0;
450 for (
int d = 0; d < Dim; d++) {
451 node(curr).x[d] = (
node(curr).min_x[d] +
node(curr).max_x[d]) * 0.5;
452 double s_x = (
node(curr).max_x[d] -
node(curr).min_x[d]);
453 node(curr).radius_sq += s_x * s_x;
457 node(curr).radius_sq *= 0.25;