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

com.aliasi.matrix.MinkowskiDistance Maven / Gradle / Ivy

Go to download

This is the original Lingpipe: http://alias-i.com/lingpipe/web/download.html There were not made any changes to the source code.

There is a newer version: 4.1.2-JL1.0
Show newest version
/*
 * LingPipe v. 4.1.0
 * Copyright (C) 2003-2011 Alias-i
 *
 * This program is licensed under the Alias-i Royalty Free License
 * Version 1 WITHOUT ANY WARRANTY, without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the Alias-i
 * Royalty Free License Version 1 for more details.
 *
 * You should have received a copy of the Alias-i Royalty Free License
 * Version 1 along with this program; if not, visit
 * http://alias-i.com/lingpipe/licenses/lingpipe-license-1.txt or contact
 * Alias-i, Inc. at 181 North 11th Street, Suite 401, Brooklyn, NY 11211,
 * +1 (718) 290-9170.
 */

package com.aliasi.matrix;

import com.aliasi.util.Distance;

import java.io.Serializable;

/**
 * The MinkowskiDistance class implements Minkowski
 * distance of a fixed order between vectors.  or Manhattan distance
 * between vectors.  Minkowski distance of any order forms a metric.
 * The Minkowski distance of order p is often called
 * Lp or the p-norm distance.
 *
 * 

Minkowski distance generalizes taxicab and Euclidean distance, * which are just the Minkowski distances of order 1 and 2 * respectively. For orders 1 and 2, the taxicab and Euclidean * distance classes {@link TaxicabDistance} and {@link * EuclideanDistance} are more efficient in that they do not require * exponentiation to be calculated. * *

The definition of Minkowski distance of order p * over vectors v1 and v2 is: * *

 * distance(v1,v2,p) = (Σi abs(v1[i] - v2[i])p)(1/p)
* * with v1[i] standing for the method call * v1.value(i) and i ranging over the * dimensions of the vectors, which must be the same. * *

An understandable explanation of the Minkowski distances, * including the special cases of Taxicab (L1 norm) * and Euclidean (L2 norm) may be * found at: * *

* * @author Bob Carpenter * @version 3.8 * @since LingPipe3.1 */ public class MinkowskiDistance implements Distance, Serializable { static final long serialVersionUID = -3492306373950488519L; int mOrder; /** * Construct a new Minkowski distance of the specified order. * * @param order Order of metric. * @throws IllegalArgumentException If the order is not 1 or greater. */ public MinkowskiDistance(int order) { mOrder = order; } /** * Returns the order of this Minkowski distance. * * @return The order of this Minkowski distance. */ public int order() { return mOrder; } /** * Returns the Minkowski distance between the specified pair * of vectors. * * @param v1 First vector. * @param v2 Second vector. * @return The distance between the vectors. * @throws IllegalArgumentException If the vectors are not of the * same dimensionality. */ public double distance(Vector v1, Vector v2) { if (v1.numDimensions() != v2.numDimensions()) { String msg = "Vectors must have same dimensions." + " v1.numDimensions()=" + v1.numDimensions() + " v2.numDimensions()=" + v2.numDimensions(); throw new IllegalArgumentException(msg); } if (v1 instanceof SparseFloatVector && v2 instanceof SparseFloatVector) return sparseDistance((SparseFloatVector)v1, (SparseFloatVector)v2); double sum = 0.0; for (int i = v1.numDimensions(); --i >= 0; ) { double absDiff = Math.abs(v1.value(i) - v2.value(i)); sum += java.lang.Math.pow(absDiff,mOrder); } return java.lang.Math.pow(sum,1.0/mOrder); } double sparseDistance(SparseFloatVector v1, SparseFloatVector v2) { double sum = 0.0; int index1 = 0; int index2 = 0; int[] keys1 = v1.mKeys; int[] keys2 = v2.mKeys; float[] vals1 = v1.mValues; float[] vals2 = v2.mValues; while (index1 < keys1.length && index2 < keys2.length) { int comp = keys1[index1] - keys2[index2]; double diff = Math.abs((comp == 0) ? (vals1[index1++] - vals2[index2++]) : (comp < 0) ? vals1[index1++] : vals2[index2++]); sum += java.lang.Math.pow(diff,mOrder); } for ( ; index1 < keys1.length; ++index1) sum += java.lang.Math.pow(Math.abs(vals1[index1]),mOrder); for ( ; index2 < keys2.length; ++index2) sum += java.lang.Math.pow(Math.abs(vals2[index2]),mOrder); return java.lang.Math.pow(sum,1.0/mOrder); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy