package edu.hawaii.jmotif.distance; import edu.hawaii.jmotif.timeseries.TSException; /** * The Euclidean distance implementation for a variety of datatypes. * * @author Pavel Senin * */ public final class EuclideanDistance { /** * Constructor. */ private EuclideanDistance() { super(); } /** * Calculates the square of the Euclidean distance between two 1D points represented by real * values. * * @param p1 The first point. * @param p2 The second point. * @return The Square of Euclidean distance. */ private static double distance2(double p1, double p2) { return (p1 - p2) * (p1 - p2); } /** * Calculates the square of the Euclidean distance between two multidimensional points represented * by the real vectors. * * @param point1 The first point. * @param point2 The second point. * @return The Euclidean distance. * @throws TSException In the case of error. */ private static double distance2(double[] point1, double[] point2) throws TSException { if (point1.length == point2.length) { Double sum = 0D; for (int i = 0; i < point1.length; i++) { sum = sum + (point2[i] - point1[i]) * (point2[i] - point1[i]); } return sum; } else { throw new TSException("Exception in Euclidean distance: array lengths are not equal"); } } /** * Calculates the square of the Euclidean distance between two multidimensional points represented * by integer vectors. * * @param point1 The first point. * @param point2 The second point. * @return The Euclidean distance. * @throws TSException In the case of error. */ private static double distance2(int[] point1, int[] point2) throws TSException { if (point1.length == point2.length) { Double sum = 0D; for (int i = 0; i < point1.length; i++) { sum = sum + (Integer.valueOf(point2[i]).doubleValue() - Integer.valueOf(point1[i]).doubleValue()) * (Integer.valueOf(point2[i]).doubleValue() - Integer.valueOf(point1[i]).doubleValue()); } return sum; } else { throw new TSException("Exception in Euclidean distance: array lengths are not equal"); } } /** * Calculates the Euclidean distance between two points. * * @param p1 The first point. * @param p2 The second point. * @return The Euclidean distance. */ public static double distance(double p1, double p2) { double d = (p1 - p2) * (p1 - p2); return Math.sqrt(d); } /** * Calculates the Euclidean distance between two points. * * @param point1 The first point. * @param point2 The second point. * @return The Euclidean distance. * @throws TSException In the case of error. */ public static double distance(double[] point1, double[] point2) throws TSException { return Math.sqrt(distance2(point1, point2)); } /** * Calculates the Euclidean distance between two points. * * @param point1 The first point. * @param point2 The second point. * @return The Euclidean distance. * @throws TSException In the case of error. */ public static double distance(int[] point1, int[] point2) throws TSException { return Math.sqrt(distance2(point1, point2)); } /** * Calculates euclidean distance between two one-dimensional time-series of equal length. * * @param series1 The first series. * @param series2 The second series. * @return The eclidean distance. * @throws TSException if error occures. */ public static double seriesDistance(double[] series1, double[] series2) throws TSException { if (series1.length == series2.length) { Double res = 0D; for (int i = 0; i < series1.length; i++) { res = res + distance2(series1[i], series2[i]); } return Math.sqrt(res); } else { throw new TSException("Exception in Euclidean distance: array lengths are not equal"); } } /** * Calculates euclidean distance between two multi-dimensional time-series of equal length. * * @param series1 The first series. * @param series2 The second series. * @return The eclidean distance. * @throws TSException if error occures. */ public static double seriesDistance(double[][] series1, double[][] series2) throws TSException { if (series1.length == series2.length) { Double res = 0D; for (int i = 0; i < series1.length; i++) { res = res + distance2(series1[i], series2[i]); } return Math.sqrt(res); } else { throw new TSException("Exception in Euclidean distance: array lengths are not equal"); } } public static Double earlyAbandonedDistance(double[] series1, double[] series2, double bestDistance) throws TSException { double cutOff = bestDistance * bestDistance; if (series1.length == series2.length) { Double res = 0D; for (int i = 0; i < series1.length; i++) { res = res + distance2(series1[i], series2[i]); if (res > cutOff) { return null; } } return Math.sqrt(res); } else { throw new TSException("Exception in Euclidean distance: array lengths are not equal"); } } }