All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.ddogleg.nn.alg.searches.KdTreeSearch1Standard Maven / Gradle / Ivy

Go to download

DDogleg Numerics is a high performance Java library for non-linear optimization, robust model fitting, polynomial root finding, sorting, and more.

There is a newer version: 0.23.4
Show newest version
/*
 * Copyright (c) 2012-2018, Peter Abeles. All Rights Reserved.
 *
 * This file is part of DDogleg (http://ddogleg.org).
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.ddogleg.nn.alg.searches;

import org.ddogleg.nn.alg.KdTree;
import org.ddogleg.nn.alg.KdTreeDistance;
import org.ddogleg.nn.alg.KdTreeSearch1;

/**
 * Standard algorithm for searching a {@link KdTree} for the nearest-neighbor of a search.  This is the algorithm
 * which is typically described in books.  At each node it examines distance of the two children and investigates
 * the closer child.  After it reaches a leaf it steps back in the search and sees if the other child could produce
 * a better solution, if it can it is also investigated.  The search stops when no more nodes can produce a better
 * result.
 *
 * @author Peter Abeles
 */
public class KdTreeSearch1Standard

implements KdTreeSearch1

{ // the targeted tree private KdTree tree; // point being searched for private P target; // the maximum distance a neighbor is allowed to be private double maxDistanceSq = Double.MAX_VALUE; // the closest neighbor which has yet to be found private double bestDistanceSq; // the node which has been found to be the closest so far private KdTree.Node closest; KdTreeDistance

distance; public KdTreeSearch1Standard(KdTreeDistance

distance) { this.distance = distance; } @Override public void setTree( Object tree ) { this.tree = (KdTree) tree; } /** * Specifies the greatest distance it will search * * @param maxDistance Maximum distance (Euclidean squared) a closest point can be */ @Override public void setMaxDistance(double maxDistance ) { this.maxDistanceSq = maxDistance ; } /** * Finds the node which is closest to 'target' * * @param target A point * @return Closest node or null if none is within the minimum distance. */ @Override public KdTree.Node findNeighbor(P target) { if( tree.root == null ) return null; this.target = target; this.closest = null; this.bestDistanceSq = maxDistanceSq; stepClosest(tree.root); return closest; } @Override public double getDistance() { return bestDistanceSq; } @Override public KdTreeSearch1

copy() { return new KdTreeSearch1Standard<>(distance); } /** * Recursive step for finding the closest point */ private void stepClosest(KdTree.Node node) { if( node == null ) return; if( node.isLeaf() ) { // a leaf can be empty. if( node.point != null ) { double distSq = distance.distance((P)node.point,target); if( distSq <= bestDistanceSq ) { if( closest == null || distSq < bestDistanceSq ) { closest = node; bestDistanceSq = distSq; } } } return; } else { double distSq = distance.distance((P)node.point,target); if( distSq <= bestDistanceSq ) { if( closest == null || distSq < bestDistanceSq ) { closest = node; bestDistanceSq = distSq; } } } // select the most promising branch to investigate first KdTree.Node nearer,further; double splitValue = distance.valueAt((P)node.point,node.split); double targetAtSplit = distance.valueAt(target,node.split); if( targetAtSplit <= splitValue ) { nearer = node.left; further = node.right; } else { nearer = node.right; further = node.left; } stepClosest(nearer); // See if it is possible for 'further' to contain a better node double dx = splitValue - targetAtSplit; double dx2 = dx*dx; if( dx2 <= bestDistanceSq ) { if( closest == null || dx2 < bestDistanceSq ) stepClosest(further); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy