Java examples for java.lang:Math Geometry Distance
compute Min Euclidean Distances
/*// www . jav a 2s . c o m * Java Information Dynamics Toolkit (JIDT) * Copyright (C) 2012, Joseph T. Lizier * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ public class Main{ public static int MAX_TIMESTEPS_FOR_FAST_DISTANCE = 2000; public static double[] computeMinEuclideanDistances( double[][] observations) { if (observations.length <= MAX_TIMESTEPS_FOR_FAST_DISTANCE) { return EuclideanUtils .computeMinEuclideanDistancesFast(observations); } else { return computeMinEuclideanDistancesNaive(observations); } } /** * Return the minimum Euclidean distance from each point to any other observation. * Computes this faster than using naive computation. * * Exposed as a public method for debugging purposes only. * * @param observations * @return */ public static double[] computeMinEuclideanDistancesFast( double[][] observations) { int dimensions = observations[0].length; int timeSteps = observations.length; // Hold the sqr distance from index1 to index2 ... double[][] sqrDistance = new double[timeSteps][timeSteps]; // ... computed over this many of the variables so far int[][] addedInUpToVariable = new int[timeSteps][timeSteps]; double[] minDistance = new double[timeSteps]; for (int t1 = 0; t1 < timeSteps; t1++) { // Current minimum distance from this index to another point: double minSqrDistance = Double.POSITIVE_INFINITY; // First grab the minimum distance from nodes for which the distance might // have already been measured for (int t2 = 0; t2 < t1; t2++) { if (addedInUpToVariable[t2][t1] == dimensions) { // We have previously computed this distance from t2 to t1 sqrDistance[t1][t2] = sqrDistance[t2][t1]; // unnecessary, since we won't be looking at [t1][t2] later: addedInUpToVariable[t1][t2] = dimensions; if (sqrDistance[t1][t2] < minSqrDistance) { minSqrDistance = sqrDistance[t1][t2]; } } } // Now check the previously considered source nodes which didn't have their full distance // computed in case we need to compute them for (int t2 = 0; t2 < t1; t2++) { if (addedInUpToVariable[t2][t1] != dimensions) { // We have not finished computing this distance from t1 addedInUpToVariable[t1][t2] = addedInUpToVariable[t2][t1]; sqrDistance[t1][t2] = sqrDistance[t2][t1]; for (; (sqrDistance[t1][t2] < minSqrDistance) && (addedInUpToVariable[t1][t2] < dimensions); addedInUpToVariable[t1][t2]++) { double distOnThisVar = observations[t1][addedInUpToVariable[t1][t2]] - observations[t2][addedInUpToVariable[t1][t2]]; sqrDistance[t1][t2] += distOnThisVar * distOnThisVar; } if (sqrDistance[t1][t2] < minSqrDistance) { // we finished the calculation and t2 is now the closest observation to t1 minSqrDistance = sqrDistance[t1][t2]; } } } // Now check any source nodes t2 for which there is no chance we've looked at the // the distance back to t1 yet for (int t2 = t1 + 1; t2 < timeSteps; t2++) { for (; (sqrDistance[t1][t2] < minSqrDistance) && (addedInUpToVariable[t1][t2] < dimensions); addedInUpToVariable[t1][t2]++) { double distOnThisVar = observations[t1][addedInUpToVariable[t1][t2]] - observations[t2][addedInUpToVariable[t1][t2]]; sqrDistance[t1][t2] += distOnThisVar * distOnThisVar; } if (sqrDistance[t1][t2] < minSqrDistance) { // we finished the calculation and t2 is now the closest observation to t1 minSqrDistance = sqrDistance[t1][t2]; } } minDistance[t1] = Math.sqrt(minSqrDistance); } return minDistance; } /** * Naive method for computing minimum distance - slower but needs less memory. * Made public for debugging only. O(d.n^2) speed * * @param observations * @return */ public static double[] computeMinEuclideanDistancesNaive( double[][] observations) { int numObservations = observations.length; int dimensions = observations[0].length; double[] distances = new double[numObservations]; for (int t = 0; t < numObservations; t++) { double minDistance = Double.POSITIVE_INFINITY; for (int t2 = 0; t2 < numObservations; t2++) { if (t == t2) { continue; } double thisDistance = 0.0; for (int d = 0; (d < dimensions) && (thisDistance < minDistance); d++) { double distanceOnThisVar = (observations[t][d] - observations[t2][d]); thisDistance += distanceOnThisVar * distanceOnThisVar; } // Now we need to sqrt the distance sum thisDistance = Math.sqrt(thisDistance); // Now check if this is a lower distance if (thisDistance < minDistance) { minDistance = thisDistance; } } distances[t] = minDistance; } return distances; } }