diff options
Diffstat (limited to 'src/de/lmu/ifi/dbs/elki/math')
258 files changed, 4772 insertions, 1709 deletions
diff --git a/src/de/lmu/ifi/dbs/elki/math/DoubleMinMax.java b/src/de/lmu/ifi/dbs/elki/math/DoubleMinMax.java index 1dfdc75d..18ff8979 100644 --- a/src/de/lmu/ifi/dbs/elki/math/DoubleMinMax.java +++ b/src/de/lmu/ifi/dbs/elki/math/DoubleMinMax.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -31,6 +31,8 @@ import de.lmu.ifi.dbs.elki.utilities.pairs.DoubleDoublePair; * Class to find the minimum and maximum double values in data. * * @author Erich Schubert + * + * @apiviz.exclude DoubleMinMaxProcessor */ public class DoubleMinMax extends DoubleDoublePair { /** diff --git a/src/de/lmu/ifi/dbs/elki/math/IntegerMinMax.java b/src/de/lmu/ifi/dbs/elki/math/IntegerMinMax.java index 5804f057..ff292e45 100644 --- a/src/de/lmu/ifi/dbs/elki/math/IntegerMinMax.java +++ b/src/de/lmu/ifi/dbs/elki/math/IntegerMinMax.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/MathUtil.java b/src/de/lmu/ifi/dbs/elki/math/MathUtil.java index 9a7d4770..16f2d096 100644 --- a/src/de/lmu/ifi/dbs/elki/math/MathUtil.java +++ b/src/de/lmu/ifi/dbs/elki/math/MathUtil.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -106,6 +106,11 @@ public final class MathUtil { public static final double ONE_BY_SQRTTWOPI = 1. / SQRTTWOPI; /** + * 1. / log(2) + */ + public static final double ONE_BY_LOG2 = 1. / Math.log(2.); + + /** * Logarithm of 2 to the basis e, for logarithm conversion. */ public static final double LOG2 = Math.log(2.); @@ -131,6 +136,11 @@ public final class MathUtil { public static final double LOGPIHALF = LOGPI / 2.; /** + * Math.log(2*Math.PI). + */ + public static final double LOGTWOPI = Math.log(TWOPI); + + /** * Math.log(Math.sqrt(2*Math.PI)). */ public static final double LOGSQRTTWOPI = Math.log(SQRTTWOPI); @@ -158,6 +168,16 @@ public final class MathUtil { } /** + * Compute the base 2 logarithm. + * + * @param x X + * @return Logarithm base 2. + */ + public static double log2(double x) { + return Math.log(x) * ONE_BY_LOG2; + } + + /** * Computes the square root of the sum of the squared arguments without under * or overflow. * @@ -169,19 +189,21 @@ public final class MathUtil { * @return {@code sqrt(a<sup>2</sup> + b<sup>2</sup>)} */ public static double fastHypot(double a, double b) { - if (a < 0) { + if(a < 0) { a = -a; } - if (b < 0) { + if(b < 0) { b = -b; } - if (a > b) { + if(a > b) { final double r = b / a; return a * Math.sqrt(1 + r * r); - } else if (b != 0) { + } + else if(b != 0) { final double r = a / b; return b * Math.sqrt(1 + r * r); - } else { + } + else { return 0.0; } } @@ -199,17 +221,17 @@ public final class MathUtil { * @return {@code sqrt(a<sup>2</sup> + b<sup>2</sup> + c<sup>2</sup>)} */ public static double fastHypot3(double a, double b, double c) { - if (a < 0) { + if(a < 0) { a = -a; } - if (b < 0) { + if(b < 0) { b = -b; } - if (c < 0) { + if(c < 0) { c = -c; } double m = (a > b) ? ((a > c) ? a : c) : ((b > c) ? b : c); - if (m <= 0) { + if(m <= 0) { return 0.0; } a = a / m; @@ -227,7 +249,7 @@ public final class MathUtil { */ public static double mahalanobisDistance(Matrix weightMatrix, Vector o1_minus_o2) { double sqrDist = o1_minus_o2.transposeTimesTimes(weightMatrix, o1_minus_o2); - if (sqrDist < 0 && Math.abs(sqrDist) < 0.000000001) { + if(sqrDist < 0 && Math.abs(sqrDist) < 0.000000001) { sqrDist = Math.abs(sqrDist); } return Math.sqrt(sqrDist); @@ -242,97 +264,196 @@ public final class MathUtil { */ public static double mahalanobisDistance(double[][] weightMatrix, double[] o1_minus_o2) { double sqrDist = VMath.transposeTimesTimes(o1_minus_o2, weightMatrix, o1_minus_o2); - if (sqrDist < 0 && Math.abs(sqrDist) < 0.000000001) { + if(sqrDist < 0 && Math.abs(sqrDist) < 0.000000001) { sqrDist = Math.abs(sqrDist); } return Math.sqrt(sqrDist); } /** - * <p> - * Provides the Pearson product-moment correlation coefficient for two - * FeatureVectors. - * </p> + * Compute the Mahalanobis distance using the given weight matrix. * - * @param x first FeatureVector - * @param y second FeatureVector + * @param weightMatrix Weight Matrix + * @param o1 First vector + * @param o2 Center vector + * @return Mahalanobis distance + */ + public static double mahalanobisDistance(Matrix weightMatrix, Vector o1, Vector o2) { + double sqrDist = VMath.mahalanobisDistance(weightMatrix.getArrayRef(), o1.getArrayRef(), o2.getArrayRef()); + if(sqrDist < 0 && Math.abs(sqrDist) < 0.000000001) { + sqrDist = Math.abs(sqrDist); + } + return Math.sqrt(sqrDist); + } + + /** + * Compute the Mahalanobis distance using the given weight matrix. + * + * @param weightMatrix Weight Matrix + * @param o1 First vector + * @param o2 Center vector + * @return Mahalanobis distance + */ + public static double mahalanobisDistance(double[][] weightMatrix, double[] o1, double[] o2) { + double sqrDist = VMath.mahalanobisDistance(weightMatrix, o1, o2); + if(sqrDist < 0 && Math.abs(sqrDist) < 0.000000001) { + sqrDist = Math.abs(sqrDist); + } + return Math.sqrt(sqrDist); + } + + /** + * Compute the Pearson product-moment correlation coefficient for two + * NumberVectors. + * + * @param x first NumberVector + * @param y second NumberVector * @return the Pearson product-moment correlation coefficient for x and y */ - public static double pearsonCorrelationCoefficient(NumberVector<?> x, NumberVector<?> y) { + public static double pearsonCorrelationCoefficient(NumberVector x, NumberVector y) { final int xdim = x.getDimensionality(); final int ydim = y.getDimensionality(); - if (xdim != ydim) { - throw new IllegalArgumentException("Invalid arguments: feature vectors differ in dimensionality."); + if(xdim != ydim) { + throw new IllegalArgumentException("Invalid arguments: number vectors differ in dimensionality."); } - if (xdim <= 0) { - throw new IllegalArgumentException("Invalid arguments: dimensionality not positive."); + // Old code, using an instance: + // PearsonCorrelation pc = new PearsonCorrelation(); + // for(int i = 0; i < xdim; ++i) { + // final double xv = x.doubleValue(i), yv = y.doubleValue(i); + // pc.put(xv, yv, 1.); + // } + // return pc.getCorrelation(); + + // Inlined computation of Pearson correlation, to avoid allocating objects! + // This is a numerically stabilized version, avoiding sum-of-squares. + double sumXX = 0., sumYY = 0., sumXY = 0.; + double meanX = x.doubleValue(0), meanY = y.doubleValue(0); + int i = 1; + while(i < xdim) { + final double xv = x.doubleValue(i), yv = y.doubleValue(i); + // Delta to previous mean + final double deltaX = xv - meanX; + final double deltaY = yv - meanY; + // Increment count first + ++i; + // Update means + meanX += deltaX / i; + meanY += deltaY / i; + // Delta to new mean + final double neltaX = xv - meanX; + final double neltaY = yv - meanY; + // Update + sumXX += deltaX * neltaX; + sumYY += deltaY * neltaY; + // should equal deltaY * neltaX! + sumXY += deltaX * neltaY; } - PearsonCorrelation pc = new PearsonCorrelation(); - for (int i = 0; i < xdim; i++) { - pc.put(x.doubleValue(i), y.doubleValue(i), 1.0); + // One or both series were constant: + if(!(sumXX > 0. && sumYY > 0.)) { + return (sumXX == sumYY) ? 1. : 0.; } - return pc.getCorrelation(); + return sumXY / Math.sqrt(sumXX * sumYY); } /** - * <p> - * Provides the Pearson product-moment correlation coefficient for two - * FeatureVectors. - * </p> + * Compute the Pearson product-moment correlation coefficient for two + * NumberVectors. * - * @param x first FeatureVector - * @param y second FeatureVector + * @param x first NumberVector + * @param y second NumberVector * @param weights Weights * @return the Pearson product-moment correlation coefficient for x and y */ - public static double weightedPearsonCorrelationCoefficient(NumberVector<?> x, NumberVector<?> y, double[] weights) { + public static double weightedPearsonCorrelationCoefficient(NumberVector x, NumberVector y, double[] weights) { final int xdim = x.getDimensionality(); final int ydim = y.getDimensionality(); - if (xdim != ydim) { - throw new IllegalArgumentException("Invalid arguments: feature vectors differ in dimensionality."); + if(xdim != ydim) { + throw new IllegalArgumentException("Invalid arguments: number vectors differ in dimensionality."); } - if (xdim != weights.length) { + if(xdim != weights.length) { throw new IllegalArgumentException("Dimensionality doesn't agree to weights."); } - PearsonCorrelation pc = new PearsonCorrelation(); - for (int i = 0; i < xdim; i++) { - pc.put(x.doubleValue(i), y.doubleValue(i), weights[i]); + // Inlined computation of Pearson correlation, to avoid allocating objects! + // This is a numerically stabilized version, avoiding sum-of-squares. + double sumXX = 0., sumYY = 0., sumXY = 0., sumWe = weights[0]; + double meanX = x.doubleValue(0), meanY = y.doubleValue(0); + for(int i = 1; i < xdim; ++i) { + final double xv = x.doubleValue(i), yv = y.doubleValue(i), w = weights[i]; + // Delta to previous mean + final double deltaX = xv - meanX; + final double deltaY = yv - meanY; + // Increment weight first + sumWe += w; + // Update means + meanX += deltaX * w / sumWe; + meanY += deltaY * w / sumWe; + // Delta to new mean + final double neltaX = xv - meanX; + final double neltaY = yv - meanY; + // Update + sumXX += w * deltaX * neltaX; + sumYY += w * deltaY * neltaY; + // should equal weight * deltaY * neltaX! + sumXY += w * deltaX * neltaY; + } + // One or both series were constant: + if(!(sumXX > 0. && sumYY > 0.)) { + return (sumXX == sumYY) ? 1. : 0.; } - return pc.getCorrelation(); + return sumXY / Math.sqrt(sumXX * sumYY); } /** - * <p> - * Provides the Pearson product-moment correlation coefficient for two + * Compute the Pearson product-moment correlation coefficient for two * FeatureVectors. - * </p> * * @param x first FeatureVector * @param y second FeatureVector * @param weights Weights * @return the Pearson product-moment correlation coefficient for x and y */ - public static double weightedPearsonCorrelationCoefficient(NumberVector<?> x, NumberVector<?> y, NumberVector<?> weights) { + public static double weightedPearsonCorrelationCoefficient(NumberVector x, NumberVector y, NumberVector weights) { final int xdim = x.getDimensionality(); final int ydim = y.getDimensionality(); - if (xdim != ydim) { + if(xdim != ydim) { throw new IllegalArgumentException("Invalid arguments: feature vectors differ in dimensionality."); } - if (xdim != weights.getDimensionality()) { + if(xdim != weights.getDimensionality()) { throw new IllegalArgumentException("Dimensionality doesn't agree to weights."); } - PearsonCorrelation pc = new PearsonCorrelation(); - for (int i = 0; i < xdim; i++) { - pc.put(x.doubleValue(i), y.doubleValue(i), weights.doubleValue(i)); + // Inlined computation of Pearson correlation, to avoid allocating objects! + // This is a numerically stabilized version, avoiding sum-of-squares. + double sumXX = 0., sumYY = 0., sumXY = 0., sumWe = weights.doubleValue(0); + double meanX = x.doubleValue(0), meanY = y.doubleValue(0); + for(int i = 1; i < xdim; ++i) { + final double xv = x.doubleValue(i), yv = y.doubleValue(i), w = weights.doubleValue(i); + // Delta to previous mean + final double deltaX = xv - meanX; + final double deltaY = yv - meanY; + // Increment weight first + sumWe += w; + // Update means + meanX += deltaX * w / sumWe; + meanY += deltaY * w / sumWe; + // Delta to new mean + final double neltaX = xv - meanX; + final double neltaY = yv - meanY; + // Update + sumXX += w * deltaX * neltaX; + sumYY += w * deltaY * neltaY; + // should equal weight * deltaY * neltaX! + sumXY += w * deltaX * neltaY; + } + // One or both series were constant: + if(!(sumXX > 0. && sumYY > 0.)) { + return (sumXX == sumYY) ? 1. : 0.; } - return pc.getCorrelation(); + return sumXY / Math.sqrt(sumXX * sumYY); } /** - * <p> - * Provides the Pearson product-moment correlation coefficient for two + * Compute the Pearson product-moment correlation coefficient for two * FeatureVectors. - * </p> * * @param x first FeatureVector * @param y second FeatureVector @@ -341,21 +462,43 @@ public final class MathUtil { public static double pearsonCorrelationCoefficient(double[] x, double[] y) { final int xdim = x.length; final int ydim = y.length; - if (xdim != ydim) { - throw new IllegalArgumentException("Invalid arguments: feature vectors differ in dimensionality."); + if(xdim != ydim) { + throw new IllegalArgumentException("Invalid arguments: arrays differ in length."); } - PearsonCorrelation pc = new PearsonCorrelation(); - for (int i = 0; i < xdim; i++) { - pc.put(x[i], y[i], 1.0); + // Inlined computation of Pearson correlation, to avoid allocating objects! + // This is a numerically stabilized version, avoiding sum-of-squares. + double sumXX = 0., sumYY = 0., sumXY = 0.; + double meanX = x[0], meanY = y[0]; + int i = 1; + while(i < xdim) { + final double xv = x[i], yv = y[i]; + // Delta to previous mean + final double deltaX = xv - meanX; + final double deltaY = yv - meanY; + // Increment count first + ++i; + // Update means + meanX += deltaX / i; + meanY += deltaY / i; + // Delta to new mean + final double neltaX = xv - meanX; + final double neltaY = yv - meanY; + // Update + sumXX += deltaX * neltaX; + sumYY += deltaY * neltaY; + // should equal deltaY * neltaX! + sumXY += deltaX * neltaY; } - return pc.getCorrelation(); + // One or both series were constant: + if(!(sumXX > 0. && sumYY > 0.)) { + return (sumXX == sumYY) ? 1. : 0.; + } + return sumXY / Math.sqrt(sumXX * sumYY); } /** - * <p> - * Provides the Pearson product-moment correlation coefficient for two + * Compute the Pearson product-moment correlation coefficient for two * FeatureVectors. - * </p> * * @param x first FeatureVector * @param y second FeatureVector @@ -365,17 +508,40 @@ public final class MathUtil { public static double weightedPearsonCorrelationCoefficient(double[] x, double[] y, double[] weights) { final int xdim = x.length; final int ydim = y.length; - if (xdim != ydim) { - throw new IllegalArgumentException("Invalid arguments: feature vectors differ in dimensionality."); + if(xdim != ydim) { + throw new IllegalArgumentException("Invalid arguments: arrays differ in length."); } - if (xdim != weights.length) { + if(xdim != weights.length) { throw new IllegalArgumentException("Dimensionality doesn't agree to weights."); } - PearsonCorrelation pc = new PearsonCorrelation(); - for (int i = 0; i < xdim; i++) { - pc.put(x[i], y[i], weights[i]); + // Inlined computation of Pearson correlation, to avoid allocating objects! + // This is a numerically stabilized version, avoiding sum-of-squares. + double sumXX = 0., sumYY = 0., sumXY = 0., sumWe = weights[0]; + double meanX = x[0], meanY = y[0]; + for(int i = 1; i < xdim; ++i) { + final double xv = x[i], yv = y[i], w = weights[i]; + // Delta to previous mean + final double deltaX = xv - meanX; + final double deltaY = yv - meanY; + // Increment weight first + sumWe += w; + // Update means + meanX += deltaX * w / sumWe; + meanY += deltaY * w / sumWe; + // Delta to new mean + final double neltaX = xv - meanX; + final double neltaY = yv - meanY; + // Update + sumXX += w * deltaX * neltaX; + sumYY += w * deltaY * neltaY; + // should equal weight * deltaY * neltaX! + sumXY += w * deltaX * neltaY; + } + // One or both series were constant: + if(!(sumXX > 0. && sumYY > 0.)) { + return (sumXX == sumYY) ? 1. : 0.; } - return pc.getCorrelation(); + return sumXY / Math.sqrt(sumXX * sumYY); } /** @@ -390,10 +556,10 @@ public final class MathUtil { * @return n * (n-1) * (n-2) * ... * 1 */ public static BigInteger factorial(BigInteger n) { - BigInteger nFac = BigInteger.valueOf(1); - while (n.compareTo(BigInteger.valueOf(1)) > 0) { + BigInteger nFac = BigInteger.ONE; + while(n.compareTo(BigInteger.ONE) > 0) { nFac = nFac.multiply(n); - n = n.subtract(BigInteger.valueOf(1)); + n = n.subtract(BigInteger.ONE); } return nFac; } @@ -407,7 +573,7 @@ public final class MathUtil { */ public static long factorial(int n) { long nFac = 1; - for (long i = n; i > 0; i--) { + for(long i = n; i > 0; i--) { nFac *= i; } return nFac; @@ -426,7 +592,7 @@ public final class MathUtil { public static long binomialCoefficient(long n, long k) { final long m = Math.max(k, n - k); double temp = 1; - for (long i = n, j = 1; i > m; i--, j++) { + for(long i = n, j = 1; i > m; i--, j++) { temp = temp * i / j; } return (long) temp; @@ -441,7 +607,7 @@ public final class MathUtil { */ public static double approximateFactorial(int n) { double nFac = 1.0; - for (int i = n; i > 0; i--) { + for(int i = n; i > 0; i--) { nFac *= i; } return nFac; @@ -458,7 +624,7 @@ public final class MathUtil { public static double approximateBinomialCoefficient(int n, int k) { final int m = Math.max(k, n - k); long temp = 1; - for (int i = n, j = 1; i > m; i--, j++) { + for(int i = n, j = 1; i > m; i--, j++) { temp = temp * i / j; } return temp; @@ -493,7 +659,7 @@ public final class MathUtil { */ public static double[] randomDoubleArray(int len, Random r) { final double[] ret = new double[len]; - for (int i = 0; i < len; i++) { + for(int i = 0; i < len; i++) { ret[i] = r.nextDouble(); } return ret; @@ -549,18 +715,18 @@ public final class MathUtil { // v1.transposeTimes(v2) / (v1.euclideanLength() * v2.euclideanLength()); // We can just compute all three in parallel. double s = 0, e1 = 0, e2 = 0; - for (int k = 0; k < mindim; k++) { + for(int k = 0; k < mindim; k++) { final double r1 = v1[k]; final double r2 = v2[k]; s += r1 * r2; e1 += r1 * r1; e2 += r2 * r2; } - for (int k = mindim; k < v1.length; k++) { + for(int k = mindim; k < v1.length; k++) { final double r1 = v1[k]; e1 += r1 * r1; } - for (int k = mindim; k < v2.length; k++) { + for(int k = mindim; k < v2.length; k++) { final double r2 = v2[k]; e2 += r2 * r2; } @@ -594,7 +760,7 @@ public final class MathUtil { // v1'.transposeTimes(v2') / (v1'.euclideanLength()*v2'.euclideanLength()); // We can just compute all three in parallel. double s = 0, e1 = 0, e2 = 0; - for (int k = 0; k < mindim; k++) { + for(int k = 0; k < mindim; k++) { final double ok = (k < o.length) ? o[k] : 0; final double r1 = v1[k] - ok; final double r2 = v2[k] - ok; @@ -602,12 +768,12 @@ public final class MathUtil { e1 += r1 * r1; e2 += r2 * r2; } - for (int k = mindim; k < v1.length; k++) { + for(int k = mindim; k < v1.length; k++) { final double ok = (k < o.length) ? o[k] : 0; final double r1 = v1[k] - ok; e1 += r1 * r1; } - for (int k = mindim; k < v2.length; k++) { + for(int k = mindim; k < v2.length; k++) { final double ok = (k < o.length) ? o[k] : 0; final double r2 = v2[k] - ok; e2 += r2 * r2; @@ -623,11 +789,7 @@ public final class MathUtil { */ public static double normAngle(double x) { x %= TWOPI; - if (x > 0) { - return x; - } else { - return x + TWOPI; - } + return (x > 0) ? x : x + TWOPI; } /** @@ -639,15 +801,12 @@ public final class MathUtil { */ public static double sinToCos(double angle, double sin) { // Numerics of the formula below aren't too good. - if ((-1e-5 < sin && sin < 1e-5) || sin > 0.99999 || sin < -0.99999) { + if((-1e-5 < sin && sin < 1e-5) || sin > 0.99999 || sin < -0.99999) { return Math.cos(angle); } angle = normAngle(angle); - if (angle < HALFPI || angle > ONEHALFPI) { - return Math.sqrt(1 - sin * sin); - } else { - return -Math.sqrt(1 - sin * sin); - } + final double s = Math.sqrt(1 - sin * sin); + return (angle < HALFPI || angle > ONEHALFPI) ? s : -s; } /** @@ -659,15 +818,12 @@ public final class MathUtil { */ public static double cosToSin(double angle, double cos) { // Numerics of the formula below aren't too good. - if ((-1e-5 < cos && cos < 1e-5) || cos > 0.99999 || cos < -0.99999) { + if((-1e-5 < cos && cos < 1e-5) || cos > 0.99999 || cos < -0.99999) { return Math.sin(angle); } angle = normAngle(angle); - if (angle < Math.PI) { - return Math.sqrt(1 - cos * cos); - } else { - return -Math.sqrt(1 - cos * cos); - } + final double s = Math.sqrt(1 - cos * cos); + return (angle < Math.PI) ? s : -s; } /** @@ -754,48 +910,52 @@ public final class MathUtil { * @return Double value */ public static double floatToDoubleUpper(float f) { - if (Float.isNaN(f)) { + if(Float.isNaN(f)) { return Double.NaN; } - if (Float.isInfinite(f)) { - if (f > 0) { + if(Float.isInfinite(f)) { + if(f > 0) { return Double.POSITIVE_INFINITY; - } else { + } + else { return Double.longBitsToDouble(0xc7efffffffffffffL); } } long bits = Double.doubleToRawLongBits((double) f); - if ((bits & 0x8000000000000000L) == 0) { // Positive - if (bits == 0L) { + if((bits & 0x8000000000000000L) == 0) { // Positive + if(bits == 0L) { return Double.longBitsToDouble(0x3690000000000000L); } - if (f == Float.MIN_VALUE) { + if(f == Float.MIN_VALUE) { // bits += 0x7_ffff_ffff_ffffl; return Double.longBitsToDouble(0x36a7ffffffffffffL); } - if (Float.MIN_NORMAL > f && f >= Double.MIN_NORMAL) { + if(Float.MIN_NORMAL > f && f >= Double.MIN_NORMAL) { // The most tricky case: // a denormalized float, but a normalized double final long bits2 = Double.doubleToRawLongBits((double) Math.nextUp(f)); bits = (bits >>> 1) + (bits2 >>> 1) - 1L; - } else { + } + else { bits += 0xfffffffL; // 28 extra bits } return Double.longBitsToDouble(bits); - } else { - if (bits == 0x8000000000000000L) { + } + else { + if(bits == 0x8000000000000000L) { return -0.0d; } - if (f == -Float.MIN_VALUE) { + if(f == -Float.MIN_VALUE) { // bits -= 0xf_ffff_ffff_ffffl; return Double.longBitsToDouble(0xb690000000000001L); } - if (-Float.MIN_NORMAL < f && f <= -Double.MIN_NORMAL) { + if(-Float.MIN_NORMAL < f && f <= -Double.MIN_NORMAL) { // The most tricky case: // a denormalized float, but a normalized double final long bits2 = Double.doubleToRawLongBits((double) Math.nextUp(f)); bits = (bits >>> 1) + (bits2 >>> 1) + 1L; - } else { + } + else { bits -= 0xfffffffL; // 28 extra bits } return Double.longBitsToDouble(bits); @@ -812,48 +972,52 @@ public final class MathUtil { * @return Double value */ public static double floatToDoubleLower(float f) { - if (Float.isNaN(f)) { + if(Float.isNaN(f)) { return Double.NaN; } - if (Float.isInfinite(f)) { - if (f < 0) { + if(Float.isInfinite(f)) { + if(f < 0) { return Double.NEGATIVE_INFINITY; - } else { + } + else { return Double.longBitsToDouble(0x47efffffffffffffL); } } long bits = Double.doubleToRawLongBits((double) f); - if ((bits & 0x8000000000000000L) == 0) { // Positive - if (bits == 0L) { + if((bits & 0x8000000000000000L) == 0) { // Positive + if(bits == 0L) { return +0.0d; } - if (f == Float.MIN_VALUE) { + if(f == Float.MIN_VALUE) { // bits -= 0xf_ffff_ffff_ffffl; return Double.longBitsToDouble(0x3690000000000001L); } - if (Float.MIN_NORMAL > f /* && f >= Double.MIN_NORMAL */) { + if(Float.MIN_NORMAL > f /* && f >= Double.MIN_NORMAL */) { // The most tricky case: // a denormalized float, but a normalized double final long bits2 = Double.doubleToRawLongBits((double) -Math.nextUp(-f)); bits = (bits >>> 1) + (bits2 >>> 1) + 1L; // + (0xfff_ffffL << 18); - } else { + } + else { bits -= 0xfffffffL; // 28 extra bits } return Double.longBitsToDouble(bits); - } else { - if (bits == 0x8000000000000000L) { + } + else { + if(bits == 0x8000000000000000L) { return Double.longBitsToDouble(0xb690000000000000L); } - if (f == -Float.MIN_VALUE) { + if(f == -Float.MIN_VALUE) { // bits += 0x7_ffff_ffff_ffffl; return Double.longBitsToDouble(0xb6a7ffffffffffffL); } - if (-Float.MIN_NORMAL < f /* && f <= -Double.MIN_NORMAL */) { + if(-Float.MIN_NORMAL < f /* && f <= -Double.MIN_NORMAL */) { // The most tricky case: // a denormalized float, but a normalized double final long bits2 = Double.doubleToRawLongBits((double) -Math.nextUp(-f)); bits = (bits >>> 1) + (bits2 >>> 1) - 1L; - } else { + } + else { bits += 0xfffffffL; // 28 extra bits } return Double.longBitsToDouble(bits); @@ -878,12 +1042,12 @@ public final class MathUtil { * @return {@code Math.pow(x, p)} */ public static double powi(double x, int p) { - if (p < 0) { // Fallback for negative integers. + if(p < 0) { // Fallback for negative integers. return Math.pow(x, p); } double ret = 1.; - for (; p > 0; p >>= 1) { - if ((p & 1) == 1) { + for(; p > 0; p >>= 1) { + if((p & 1) == 1) { ret *= x; } x *= x; @@ -900,16 +1064,39 @@ public final class MathUtil { * @return {@code Math.pow(x, p)} */ public static int ipowi(int x, int p) { - if (p < 0) { // Fallback for negative integers. + if(p < 0) { // Fallback for negative integers. return (int) Math.pow(x, p); } int ret = 1; - for (; p > 0; p >>= 1) { - if ((p & 1) == 1) { + for(; p > 0; p >>= 1) { + if((p & 1) == 1) { ret *= x; } x *= x; } return ret; } + + /** + * Empty integer array. + */ + public static final int[] EMPTY_INTS = new int[0]; + + /** + * Generate an array of integers. + * + * @param start First integer + * @param end Last integer (exclusive!) + * @return Array of integers of length end-start + */ + public static int[] sequence(int start, int end) { + if(start >= end) { + return EMPTY_INTS; + } + int[] ret = new int[end - start]; + for(int j = 0; start < end; start++, j++) { + ret[j] = start; + } + return ret; + } } diff --git a/src/de/lmu/ifi/dbs/elki/math/Mean.java b/src/de/lmu/ifi/dbs/elki/math/Mean.java index 5e70938f..e6d89214 100644 --- a/src/de/lmu/ifi/dbs/elki/math/Mean.java +++ b/src/de/lmu/ifi/dbs/elki/math/Mean.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/MeanVariance.java b/src/de/lmu/ifi/dbs/elki/math/MeanVariance.java index b229d5d8..c9b8b15b 100644 --- a/src/de/lmu/ifi/dbs/elki/math/MeanVariance.java +++ b/src/de/lmu/ifi/dbs/elki/math/MeanVariance.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/MeanVarianceMinMax.java b/src/de/lmu/ifi/dbs/elki/math/MeanVarianceMinMax.java index 027a302d..22864c64 100644 --- a/src/de/lmu/ifi/dbs/elki/math/MeanVarianceMinMax.java +++ b/src/de/lmu/ifi/dbs/elki/math/MeanVarianceMinMax.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/MinMax.java b/src/de/lmu/ifi/dbs/elki/math/MinMax.java deleted file mode 100644 index d3ee45bd..00000000 --- a/src/de/lmu/ifi/dbs/elki/math/MinMax.java +++ /dev/null @@ -1,185 +0,0 @@ -package de.lmu.ifi.dbs.elki.math; - -/* - This file is part of ELKI: - Environment for Developing KDD-Applications Supported by Index-Structures - - Copyright (C) 2013 - Ludwig-Maximilians-Universität München - Lehr- und Forschungseinheit für Datenbanksysteme - ELKI Development Team - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero 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 Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -import java.util.SortedSet; - -import de.lmu.ifi.dbs.elki.utilities.ClassGenericsUtil; -import de.lmu.ifi.dbs.elki.utilities.pairs.Pair; - -/** - * Class to find the minimum and maximum double values in data. - * - * @author Erich Schubert - * - * Note: Unused, see {@link DoubleMinMax} specialization. - * - * @param <T> Data type - */ -public class MinMax<T extends Comparable<? super T>> extends Pair<T, T> { - /** - * Constructor without starting values. - * - * The minimum will be initialized to {@code null}. - * - * The maximum will be initialized to {@code null}. - */ - public MinMax() { - super(null, null); - } - - /** - * Constructor with predefined minimum and maximum values. - * - * @param min Minimum value - * @param max Maximum value - */ - public MinMax(T min, T max) { - super(min, max); - } - - /** - * Process a single value. - * - * If the new value is smaller than the current minimum, it will become the - * new minimum. - * - * If the new value is larger than the current maximum, it will become the new - * maximum. - * - * @param data New value - */ - public void put(T data) { - if(this.first == null || this.first.compareTo(data) > 0) { - this.first = data; - } - if(this.second == null || this.second.compareTo(data) < 0) { - this.second = data; - } - } - - /** - * Process a whole array of values. - * - * If any of the values is smaller than the current minimum, it will become - * the new minimum. - * - * If any of the values is larger than the current maximum, it will become the - * new maximum. - * - * @param data Data to process - */ - public void put(T[] data) { - for(T value : data) { - this.put(value); - } - } - - /** - * Process a whole collection of values. - * - * If any of the values is smaller than the current minimum, it will become - * the new minimum. - * - * If any of the values is larger than the current maximum, it will become the - * new maximum. - * - * @param data Data to process - */ - public void put(Iterable<T> data) { - for(T value : data) { - this.put(value); - } - } - - /** - * Process a whole collection of values. - * - * If any of the values is smaller than the current minimum, it will become - * the new minimum. - * - * If any of the values is larger than the current maximum, it will become the - * new maximum. - * - * @param data Data to process - */ - public void put(SortedSet<T> data) { - if(!data.isEmpty()) { - this.put(data.first()); - this.put(data.last()); - } - } - - /** - * Get the current minimum. - * - * @return current minimum. - */ - public T getMin() { - return this.getFirst(); - } - - /** - * Get the current maximum. - * - * @return current maximum. - */ - public T getMax() { - return this.getSecond(); - } - - /** - * Test if we have seen any data (and thus have a useful minimum and maximum). - * - * @return {@code true} iff min != null and max != null. - */ - public boolean isValid() { - return (this.getMin() != null) && (this.getMax() != null); - } - - /** - * Return minimum and maximum as array. - * - * @return Minimum, Maximum - */ - public Object[] asArray() { - return new Object[] { this.getMin(), this.getMax() }; - } - - /** - * New array of MinMax objects for a given type. - * - * @param <N> Number type. - * @param size Size. - * @return Initialized array. - */ - public static <N extends Comparable<N>> MinMax<N>[] newArray(int size) { - Class<MinMax<N>> mmcls = ClassGenericsUtil.uglyCastIntoSubclass(MinMax.class); - MinMax<N>[] mms = ClassGenericsUtil.newArrayOfNull(size, mmcls); - for(int i = 0; i < size; i++) { - mms[i] = new MinMax<>(); - } - return mms; - } -}
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/math/PearsonCorrelation.java b/src/de/lmu/ifi/dbs/elki/math/PearsonCorrelation.java index 4cd9c732..710ec0ae 100644 --- a/src/de/lmu/ifi/dbs/elki/math/PearsonCorrelation.java +++ b/src/de/lmu/ifi/dbs/elki/math/PearsonCorrelation.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -34,34 +34,19 @@ package de.lmu.ifi.dbs.elki.math; */ public class PearsonCorrelation { /** - * Sum for XX + * Aggregation for squared residuals - we are not using sum-of-squares! */ - private double sumXX = 0; + private double sumXX = 0., sumYY = 0., sumXY = 0.; /** - * Sum for YY + * Current mean for X and Y. */ - private double sumYY = 0; + private double meanX = 0., meanY = 0.; /** - * Sum for XY + * Weight sum. */ - private double sumXY = 0; - - /** - * Current mean for X - */ - private double meanX = 0; - - /** - * Current mean for Y - */ - private double meanY = 0; - - /** - * Weight sum - */ - private double sumWe = 0; + private double sumWe = 0.; /** * Constructor. @@ -78,7 +63,7 @@ public class PearsonCorrelation { * @param w Weight */ public void put(double x, double y, double w) { - if(sumWe <= 0.0) { + if(sumWe <= 0.) { meanX = x; meanY = y; sumWe = w; @@ -109,22 +94,19 @@ public class PearsonCorrelation { * @param y Value in Y */ public void put(double x, double y) { - put(x, y, 1.0); + put(x, y, 1.); } /** - * Get the pearson correlation value. + * Get the Pearson correlation value. * * @return Correlation value */ public double getCorrelation() { - final double popSdX = getNaiveStddevX(); - final double popSdY = getNaiveStddevY(); - final double covXY = getNaiveCovariance(); - if(popSdX == 0 || popSdY == 0) { - return 0; + if(!(sumXX > 0. && sumYY > 0.)) { + return (sumXX == sumYY) ? 1. : 0.; } - return covXY / (popSdX * popSdY); + return sumXY / Math.sqrt(sumXX * sumYY); } /** @@ -144,7 +126,7 @@ public class PearsonCorrelation { public double getMeanX() { return meanX; } - + /** * Return mean of Y * @@ -153,7 +135,7 @@ public class PearsonCorrelation { public double getMeanY() { return meanY; } - + /** * Get the covariance of X and Y (not taking sampling into account) * @@ -169,8 +151,8 @@ public class PearsonCorrelation { * @return Covariance */ public double getSampleCovariance() { - assert (sumWe > 1); - return sumXY / (sumWe - 1); + assert (sumWe > 1.); + return sumXY / (sumWe - 1.); } /** @@ -190,8 +172,8 @@ public class PearsonCorrelation { * @return sample variance */ public double getSampleVarianceX() { - assert (sumWe > 1); - return sumXX / (sumWe - 1); + assert (sumWe > 1.); + return sumXX / (sumWe - 1.); } /** @@ -199,7 +181,7 @@ public class PearsonCorrelation { * * Note: usually, you should be using {@link #getSampleStddevX} instead! * - * @return stddev + * @return standard deviation */ public double getNaiveStddevX() { return Math.sqrt(getNaiveVarianceX()); @@ -208,7 +190,7 @@ public class PearsonCorrelation { /** * Return standard deviation * - * @return stddev + * @return standard deviation */ public double getSampleStddevX() { return Math.sqrt(getSampleVarianceX()); @@ -231,8 +213,8 @@ public class PearsonCorrelation { * @return sample variance */ public double getSampleVarianceY() { - assert (sumWe > 1); - return sumYY / (sumWe - 1); + assert (sumWe > 1.); + return sumYY / (sumWe - 1.); } /** @@ -259,11 +241,11 @@ public class PearsonCorrelation { * Reset the value. */ public void reset() { - sumXX = 0; - sumXY = 0; - sumYY = 0; - meanX = 0; - meanY = 0; - sumWe = 0; + sumXX = 0.; + sumXY = 0.; + sumYY = 0.; + meanX = 0.; + meanY = 0.; + sumWe = 0.; } }
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/math/Primes.java b/src/de/lmu/ifi/dbs/elki/math/Primes.java index 5755df1a..71167c94 100644 --- a/src/de/lmu/ifi/dbs/elki/math/Primes.java +++ b/src/de/lmu/ifi/dbs/elki/math/Primes.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/SinCosTable.java b/src/de/lmu/ifi/dbs/elki/math/SinCosTable.java index 6cabb172..9d591651 100644 --- a/src/de/lmu/ifi/dbs/elki/math/SinCosTable.java +++ b/src/de/lmu/ifi/dbs/elki/math/SinCosTable.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/StatisticalMoments.java b/src/de/lmu/ifi/dbs/elki/math/StatisticalMoments.java index af42c2e5..76542a6e 100644 --- a/src/de/lmu/ifi/dbs/elki/math/StatisticalMoments.java +++ b/src/de/lmu/ifi/dbs/elki/math/StatisticalMoments.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/analysis/package-info.java b/src/de/lmu/ifi/dbs/elki/math/analysis/package-info.java new file mode 100644 index 00000000..dc4ab3ee --- /dev/null +++ b/src/de/lmu/ifi/dbs/elki/math/analysis/package-info.java @@ -0,0 +1,26 @@ +/** +<p>Analysis package</p> +*/ +/* +This file is part of ELKI: +Environment for Developing KDD-Applications Supported by Index-Structures + +Copyright (C) 2014 +Ludwig-Maximilians-Universität München +Lehr- und Forschungseinheit für Datenbanksysteme +ELKI Development Team + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero 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 Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ +package de.lmu.ifi.dbs.elki.math.analysis;
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/math/dimensionsimilarity/CovarianceDimensionSimilarity.java b/src/de/lmu/ifi/dbs/elki/math/dimensionsimilarity/CovarianceDimensionSimilarity.java index 59380a74..1dbf03dd 100644 --- a/src/de/lmu/ifi/dbs/elki/math/dimensionsimilarity/CovarianceDimensionSimilarity.java +++ b/src/de/lmu/ifi/dbs/elki/math/dimensionsimilarity/CovarianceDimensionSimilarity.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.dimensionsimilarity; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -34,7 +34,7 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer; * * @author Erich Schubert */ -public class CovarianceDimensionSimilarity implements DimensionSimilarity<NumberVector<?>> { +public class CovarianceDimensionSimilarity implements DimensionSimilarity<NumberVector> { /** * Static instance */ @@ -48,7 +48,7 @@ public class CovarianceDimensionSimilarity implements DimensionSimilarity<Number } @Override - public void computeDimensionSimilarites(Database database, Relation<? extends NumberVector<?>> relation, DBIDs subset, DimensionSimilarityMatrix matrix) { + public void computeDimensionSimilarites(Database database, Relation<? extends NumberVector> relation, DBIDs subset, DimensionSimilarityMatrix matrix) { final int dim = matrix.size(); // FIXME: Use only necessary dimensions! CovarianceMatrix covmat = CovarianceMatrix.make(relation, subset); diff --git a/src/de/lmu/ifi/dbs/elki/math/dimensionsimilarity/DimensionSimilarity.java b/src/de/lmu/ifi/dbs/elki/math/dimensionsimilarity/DimensionSimilarity.java index d0c1a0bc..253bdb85 100644 --- a/src/de/lmu/ifi/dbs/elki/math/dimensionsimilarity/DimensionSimilarity.java +++ b/src/de/lmu/ifi/dbs/elki/math/dimensionsimilarity/DimensionSimilarity.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.dimensionsimilarity; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -25,7 +25,6 @@ package de.lmu.ifi.dbs.elki.math.dimensionsimilarity; import de.lmu.ifi.dbs.elki.database.Database; import de.lmu.ifi.dbs.elki.database.ids.DBIDs; import de.lmu.ifi.dbs.elki.database.relation.Relation; -import de.lmu.ifi.dbs.elki.utilities.optionhandling.Parameterizable; /** * Interface for computing pairwise dimension similarities, used for arranging @@ -37,7 +36,7 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.Parameterizable; * * @param <V> Object type */ -public interface DimensionSimilarity<V> extends Parameterizable { +public interface DimensionSimilarity<V> { /** * Compute the dimension similarity matrix * diff --git a/src/de/lmu/ifi/dbs/elki/math/dimensionsimilarity/DimensionSimilarityMatrix.java b/src/de/lmu/ifi/dbs/elki/math/dimensionsimilarity/DimensionSimilarityMatrix.java index 70429de4..7972938e 100644 --- a/src/de/lmu/ifi/dbs/elki/math/dimensionsimilarity/DimensionSimilarityMatrix.java +++ b/src/de/lmu/ifi/dbs/elki/math/dimensionsimilarity/DimensionSimilarityMatrix.java @@ -7,7 +7,7 @@ import de.lmu.ifi.dbs.elki.math.linearalgebra.Matrix; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/dimensionsimilarity/HSMDimensionSimilarity.java b/src/de/lmu/ifi/dbs/elki/math/dimensionsimilarity/HSMDimensionSimilarity.java index e73d02af..02511047 100644 --- a/src/de/lmu/ifi/dbs/elki/math/dimensionsimilarity/HSMDimensionSimilarity.java +++ b/src/de/lmu/ifi/dbs/elki/math/dimensionsimilarity/HSMDimensionSimilarity.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.dimensionsimilarity; This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2012
+ Copyright (C) 2014
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
@@ -28,11 +28,10 @@ import de.lmu.ifi.dbs.elki.database.Database; import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
import de.lmu.ifi.dbs.elki.database.ids.DBIDs;
import de.lmu.ifi.dbs.elki.database.relation.Relation;
+import de.lmu.ifi.dbs.elki.database.relation.RelationUtil;
import de.lmu.ifi.dbs.elki.math.SinCosTable;
-import de.lmu.ifi.dbs.elki.utilities.DatabaseUtil;
import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
-import de.lmu.ifi.dbs.elki.utilities.pairs.Pair;
/**
* Compute the similarity of dimensions by using a hough transformation.
@@ -52,8 +51,11 @@ import de.lmu.ifi.dbs.elki.utilities.pairs.Pair; * @author Erich Schubert
* @author Robert Rödler
*/
-@Reference(authors = "A. Tatu, G. Albuquerque, M. Eisemann, P. Bak, H. Theisel, M. A. Magnor, and D. A. Keim.", title = "Automated Analytical Methods to Support Visual Exploration of High-Dimensional Data", booktitle = "IEEE Trans. Visualization and Computer Graphics, 2011", url = "http://dx.doi.org/10.1109/TVCG.2010.242")
-public class HSMDimensionSimilarity implements DimensionSimilarity<NumberVector<?>> {
+@Reference(authors = "A. Tatu, G. Albuquerque, M. Eisemann, P. Bak, H. Theisel, M. A. Magnor, and D. A. Keim", //
+title = "Automated Analytical Methods to Support Visual Exploration of High-Dimensional Data", //
+booktitle = "IEEE Trans. Visualization and Computer Graphics, 2011", //
+url = "http://dx.doi.org/10.1109/TVCG.2010.242")
+public class HSMDimensionSimilarity implements DimensionSimilarity<NumberVector> {
/**
* Static instance.
*/
@@ -79,36 +81,35 @@ public class HSMDimensionSimilarity implements DimensionSimilarity<NumberVector< }
@Override
- public void computeDimensionSimilarites(Database database, Relation<? extends NumberVector<?>> relation, DBIDs subset, DimensionSimilarityMatrix matrix) {
+ public void computeDimensionSimilarites(Database database, Relation<? extends NumberVector> relation, DBIDs subset, DimensionSimilarityMatrix matrix) {
final int dim = matrix.size();
final int resolution = 512;
boolean[][][][] pics = new boolean[dim][dim][][]; // [resolution][resolution];
// Initialize / allocate "pictures":
- for (int i = 0; i < dim - 1; i++) {
- for (int j = i + 1; j < dim; j++) {
+ for(int i = 0; i < dim - 1; i++) {
+ for(int j = i + 1; j < dim; j++) {
pics[i][j] = new boolean[resolution][resolution];
}
}
// FIXME: Get/keep these statistics in the relation, or compute for the
// sample only.
- double[] off = new double[dim], scale = new double[dim];
+ double[] off, scale;
{
- Pair<? extends NumberVector<?>, ? extends NumberVector<?>> mm = DatabaseUtil.computeMinMax(relation);
- NumberVector<?> min = mm.first;
- NumberVector<?> max = mm.second;
- for (int d = 0; d < dim; d++) {
- off[d] = min.doubleValue(matrix.dim(d));
- final double m = max.doubleValue(matrix.dim(d));
- scale[d] = (m > off[d]) ? 1. / (m - off[d]) : 1;
+ double[][] mm = RelationUtil.computeMinMax(relation);
+ off = mm[0];
+ scale = mm[1];
+ for(int d = 0; d < dim; d++) {
+ scale[d] -= off[d];
+ scale[d] = (scale[d] > 0.) ? 1. / scale[d] : 1.;
}
}
// Iterate dataset
- for (DBIDIter id = subset.iter(); id.valid(); id.advance()) {
- NumberVector<?> pvec = relation.get(id);
- for (int i = 0; i < dim - 1; i++) {
+ for(DBIDIter id = subset.iter(); id.valid(); id.advance()) {
+ NumberVector pvec = relation.get(id);
+ for(int i = 0; i < dim - 1; i++) {
double xi = (pvec.doubleValue(matrix.dim(i)) - off[i]) * scale[i];
- for (int j = i + 1; j < dim; j++) {
+ for(int j = i + 1; j < dim; j++) {
double xj = (pvec.doubleValue(matrix.dim(j)) - off[j]) * scale[j];
drawLine(0, (int) (resolution * xi), resolution - 1, (int) (resolution * xj), pics[i][j]);
}
@@ -116,8 +117,8 @@ public class HSMDimensionSimilarity implements DimensionSimilarity<NumberVector< }
final double stepsq = (double) STEPS * (double) STEPS;
- for (int x = 0; x < dim; x++) {
- for (int y = x + 1; y < dim; y++) {
+ for(int x = 0; x < dim; x++) {
+ for(int y = x + 1; y < dim; y++) {
int[][] hough = houghTransformation(pics[x][y]);
pics[x][y] = null; // Release picture
// The original publication said "median", but judging from the text,
@@ -139,9 +140,9 @@ public class HSMDimensionSimilarity implements DimensionSimilarity<NumberVector< */
private long sumMatrix(int[][] mat) {
long ret = 0;
- for (int i = 0; i < mat.length; i++) {
+ for(int i = 0; i < mat.length; i++) {
final int[] row = mat[i];
- for (int j = 0; j < row.length; j++) {
+ for(int j = 0; j < row.length; j++) {
ret += row[j];
}
}
@@ -157,10 +158,10 @@ public class HSMDimensionSimilarity implements DimensionSimilarity<NumberVector< */
private int countAboveThreshold(int[][] mat, double threshold) {
int ret = 0;
- for (int i = 0; i < mat.length; i++) {
+ for(int i = 0; i < mat.length; i++) {
int[] row = mat[i];
- for (int j = 0; j < row.length; j++) {
- if (row[j] >= threshold) {
+ for(int j = 0; j < row.length; j++) {
+ if(row[j] >= threshold) {
ret++;
}
}
@@ -179,12 +180,12 @@ public class HSMDimensionSimilarity implements DimensionSimilarity<NumberVector< final double tscale = STEPS * .5 / (xres + yres);
final int[][] ret = new int[STEPS][STEPS];
- for (int x = 0; x < mat.length; x++) {
- for (int y = 0; y < mat[0].length; y++) {
- if (mat[x][y]) {
- for (int i = 0; i < STEPS; i++) {
+ for(int x = 0; x < mat.length; x++) {
+ for(int y = 0; y < mat[0].length; y++) {
+ if(mat[x][y]) {
+ for(int i = 0; i < STEPS; i++) {
final int d = (STEPS >> 1) + (int) (tscale * (x * table.cos(i) + y * table.sin(i)));
- if (d > 0 && d < STEPS) {
+ if(d > 0 && d < STEPS) {
ret[d][i]++;
}
}
@@ -217,18 +218,18 @@ public class HSMDimensionSimilarity implements DimensionSimilarity<NumberVector< // Error counter
int err = dx + dy;
- for (;;) {
+ for(;;) {
pic[x0][y0] = true;
- if (x0 == x1 && y0 == y1) {
+ if(x0 == x1 && y0 == y1) {
break;
}
final int e2 = err << 1;
- if (e2 > dy) {
+ if(e2 > dy) {
err += dy;
x0 += sx;
}
- if (e2 < dx) {
+ if(e2 < dx) {
err += dx;
y0 += sy;
}
diff --git a/src/de/lmu/ifi/dbs/elki/math/dimensionsimilarity/HiCSDimensionSimilarity.java b/src/de/lmu/ifi/dbs/elki/math/dimensionsimilarity/HiCSDimensionSimilarity.java index 9168fe7e..0ef532dd 100644 --- a/src/de/lmu/ifi/dbs/elki/math/dimensionsimilarity/HiCSDimensionSimilarity.java +++ b/src/de/lmu/ifi/dbs/elki/math/dimensionsimilarity/HiCSDimensionSimilarity.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.dimensionsimilarity; This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2012
+ Copyright (C) 2014
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
@@ -39,9 +39,9 @@ import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil; import de.lmu.ifi.dbs.elki.database.ids.DBIDs;
import de.lmu.ifi.dbs.elki.database.ids.HashSetModifiableDBIDs;
import de.lmu.ifi.dbs.elki.database.relation.Relation;
+import de.lmu.ifi.dbs.elki.math.random.RandomFactory;
import de.lmu.ifi.dbs.elki.math.statistics.tests.GoodnessOfFitTest;
import de.lmu.ifi.dbs.elki.math.statistics.tests.KolmogorovSmirnovTest;
-import de.lmu.ifi.dbs.elki.utilities.RandomFactory;
import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints.CommonConstraints;
@@ -72,8 +72,11 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.RandomParameter; * @author Erich Schubert
* @author Robert Rödler
*/
-@Reference(authors = "Elke Achtert, Hans-Peter Kriegel, Erich Schubert, Arthur Zimek", title = "Interactive Data Mining with 3D-Parallel-Coordinate-Trees", booktitle = "Proc. of the 2013 ACM International Conference on Management of Data (SIGMOD)", url = "http://dx.doi.org/10.1145/2463676.2463696")
-public class HiCSDimensionSimilarity implements DimensionSimilarity<NumberVector<?>> {
+@Reference(authors = "Elke Achtert, Hans-Peter Kriegel, Erich Schubert, Arthur Zimek", //
+title = "Interactive Data Mining with 3D-Parallel-Coordinate-Trees", //
+booktitle = "Proc. of the 2013 ACM International Conference on Management of Data (SIGMOD)", //
+url = "http://dx.doi.org/10.1145/2463676.2463696")
+public class HiCSDimensionSimilarity implements DimensionSimilarity<NumberVector> {
/**
* Monte-Carlo iterations
*/
@@ -111,7 +114,7 @@ public class HiCSDimensionSimilarity implements DimensionSimilarity<NumberVector }
@Override
- public void computeDimensionSimilarites(Database database, Relation<? extends NumberVector<?>> relation, DBIDs subset, DimensionSimilarityMatrix matrix) {
+ public void computeDimensionSimilarites(Database database, Relation<? extends NumberVector> relation, DBIDs subset, DimensionSimilarityMatrix matrix) {
final Random random = rnd.getSingleThreadedRandom();
final int dim = matrix.size();
@@ -138,7 +141,7 @@ public class HiCSDimensionSimilarity implements DimensionSimilarity<NumberVector * @param matrix Matrix (for dimension subset)
* @return List of sorted objects
*/
- private ArrayList<ArrayDBIDs> buildOneDimIndexes(Relation<? extends NumberVector<?>> relation, DBIDs ids, DimensionSimilarityMatrix matrix) {
+ private ArrayList<ArrayDBIDs> buildOneDimIndexes(Relation<? extends NumberVector> relation, DBIDs ids, DimensionSimilarityMatrix matrix) {
final int dim = matrix.size();
ArrayList<ArrayDBIDs> subspaceIndex = new ArrayList<>(dim);
@@ -165,7 +168,7 @@ public class HiCSDimensionSimilarity implements DimensionSimilarity<NumberVector * @param random Random generator
* @return Contrast
*/
- private double calculateContrast(Relation<? extends NumberVector<?>> relation, DBIDs subset, ArrayDBIDs subspaceIndex1, ArrayDBIDs subspaceIndex2, int dim1, int dim2, Random random) {
+ private double calculateContrast(Relation<? extends NumberVector> relation, DBIDs subset, ArrayDBIDs subspaceIndex1, ArrayDBIDs subspaceIndex2, int dim1, int dim2, Random random) {
final double alpha1 = Math.sqrt(alpha);
final int windowsize = (int) (relation.size() * alpha1);
diff --git a/src/de/lmu/ifi/dbs/elki/math/dimensionsimilarity/MCEDimensionSimilarity.java b/src/de/lmu/ifi/dbs/elki/math/dimensionsimilarity/MCEDimensionSimilarity.java index b3e6bb76..b5e9be6b 100644 --- a/src/de/lmu/ifi/dbs/elki/math/dimensionsimilarity/MCEDimensionSimilarity.java +++ b/src/de/lmu/ifi/dbs/elki/math/dimensionsimilarity/MCEDimensionSimilarity.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.dimensionsimilarity; This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2012
+ Copyright (C) 2014
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
@@ -54,8 +54,11 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer; *
* @author Erich Schubert
*/
-@Reference(authors = "D. Guo", title = "Coordinating computational and visual approaches for interactive feature selection and multivariate clustering", booktitle = "Information Visualization, 2(4)", url = "http://dx.doi.org/10.1057/palgrave.ivs.9500053")
-public class MCEDimensionSimilarity implements DimensionSimilarity<NumberVector<?>> {
+@Reference(authors = "D. Guo", //
+title = "Coordinating computational and visual approaches for interactive feature selection and multivariate clustering", //
+booktitle = "Information Visualization, 2(4)", //
+url = "http://dx.doi.org/10.1057/palgrave.ivs.9500053")
+public class MCEDimensionSimilarity implements DimensionSimilarity<NumberVector> {
/**
* Static instance.
*/
@@ -77,11 +80,11 @@ public class MCEDimensionSimilarity implements DimensionSimilarity<NumberVector< }
@Override
- public void computeDimensionSimilarites(Database database, Relation<? extends NumberVector<?>> relation, DBIDs subset, DimensionSimilarityMatrix matrix) {
+ public void computeDimensionSimilarites(Database database, Relation<? extends NumberVector> relation, DBIDs subset, DimensionSimilarityMatrix matrix) {
final int dim = matrix.size();
// Find a number of bins as recommended by Cheng et al.
- double p = Math.log(subset.size() / (double) TARGET) / MathUtil.LOG2;
+ double p = MathUtil.log2(subset.size() / (double) TARGET);
// As we are in 2d, take the root (*.5) But let's use at least 1, too.
// Check: for 10000 this should give 4, for 150 it gives 1.
int power = Math.max(1, (int) Math.floor(p * .5));
@@ -92,18 +95,18 @@ public class MCEDimensionSimilarity implements DimensionSimilarity<NumberVector< // Partition sizes
int[][] psizes = new int[dim][gridsize];
- for (int d = 0; d < dim; d++) {
+ for(int d = 0; d < dim; d++) {
final ArrayList<DBIDs> partsd = parts.get(d);
final int[] sizesp = psizes[d];
- for (int i = 0; i < gridsize; i++) {
+ for(int i = 0; i < gridsize; i++) {
sizesp[i] = partsd.get(i).size();
}
}
int[][] res = new int[gridsize][gridsize];
- for (int x = 0; x < dim; x++) {
+ for(int x = 0; x < dim; x++) {
ArrayList<DBIDs> partsi = parts.get(x);
- for (int y = x + 1; y < dim; y++) {
+ for(int y = x + 1; y < dim; y++) {
ArrayList<DBIDs> partsj = parts.get(y);
// Fill the intersection matrix
intersectionMatrix(res, partsi, partsj, gridsize);
@@ -113,69 +116,6 @@ public class MCEDimensionSimilarity implements DimensionSimilarity<NumberVector< }
/**
- * Intersect the two 1d grid decompositions, to obtain a 2d matrix.
- *
- * @param res Output matrix to fill
- * @param partsx Partitions in first component
- * @param partsy Partitions in second component.
- * @param gridsize Size of partition decomposition
- */
- private void intersectionMatrix(int[][] res, ArrayList<? extends DBIDs> partsx, ArrayList<? extends DBIDs> partsy, int gridsize) {
- for (int x = 0; x < gridsize; x++) {
- final DBIDs px = partsx.get(x);
- final int[] rowx = res[x];
- for (int y = 0; y < gridsize; y++) {
- rowx[y] = DBIDUtil.intersectionSize(px, partsy.get(y));
- }
- }
- }
-
- /**
- * Compute the MCE entropy value.
- *
- * @param mat Partition size matrix
- * @param psizesx Partition sizes on X
- * @param psizesy Partition sizes on Y
- * @param size Data set size
- * @param gridsize Size of grids
- * @param loggrid Logarithm of grid sizes, for normalization
- * @return MCE score.
- */
- private double getMCEntropy(int[][] mat, int[] psizesx, int[] psizesy, int size, int gridsize, double loggrid) {
- // Margin entropies:
- double[] mx = new double[gridsize];
- double[] my = new double[gridsize];
-
- for (int i = 0; i < gridsize; i++) {
- // Note: indexes are a bit tricky here, because we compute both margin
- // entropies at the same time!
- final double sumx = (double) psizesx[i];
- final double sumy = (double) psizesy[i];
- for (int j = 0; j < gridsize; j++) {
- double px = mat[i][j] / sumx;
- double py = mat[j][i] / sumy;
-
- if (px > 0.) {
- mx[i] -= px * Math.log(px);
- }
- if (py > 0.) {
- my[i] -= py * Math.log(py);
- }
- }
- }
-
- // Weighted sums of margin entropies.
- double sumx = 0., sumy = 0.;
- for (int i = 0; i < gridsize; i++) {
- sumx += mx[i] * psizesx[i];
- sumy += my[i] * psizesy[i];
- }
-
- double max = ((sumx > sumy) ? sumx : sumy);
- return max / (size * loggrid);
- }
-
- /**
* Calculates "index structures" for every attribute, i.e. sorts a
* ModifiableArray of every DBID in the database for every dimension and
* stores them in a list.
@@ -185,14 +125,14 @@ public class MCEDimensionSimilarity implements DimensionSimilarity<NumberVector< * @param matrix Matrix for dimension information
* @return List of sorted objects
*/
- private ArrayList<ArrayList<DBIDs>> buildPartitions(Relation<? extends NumberVector<?>> relation, DBIDs ids, int depth, DimensionSimilarityMatrix matrix) {
+ private ArrayList<ArrayList<DBIDs>> buildPartitions(Relation<? extends NumberVector> relation, DBIDs ids, int depth, DimensionSimilarityMatrix matrix) {
final int dim = matrix.size();
ArrayList<ArrayList<DBIDs>> subspaceIndex = new ArrayList<>(dim);
SortDBIDsBySingleDimension comp = new VectorUtil.SortDBIDsBySingleDimension(relation);
double[] tmp = new double[ids.size()];
Mean mean = new Mean();
-
- for (int i = 0; i < dim; i++) {
+
+ for(int i = 0; i < dim; i++) {
final int d = matrix.dim(i);
// Index for a single dimension:
ArrayList<DBIDs> idx = new ArrayList<>(1 << depth);
@@ -202,7 +142,7 @@ public class MCEDimensionSimilarity implements DimensionSimilarity<NumberVector< sids.sort(comp);
// Now we build the temp array, and compute the first mean.
DBIDArrayIter it = sids.iter();
- for (int j = 0; j < tmp.length; j++, it.advance()) {
+ for(int j = 0; j < tmp.length; j++, it.advance()) {
assert (it.valid());
tmp[j] = relation.get(it).doubleValue(d);
}
@@ -210,7 +150,7 @@ public class MCEDimensionSimilarity implements DimensionSimilarity<NumberVector< assert (idx.size() == (1 << depth));
subspaceIndex.add(idx);
}
-
+
return subspaceIndex;
}
@@ -227,44 +167,50 @@ public class MCEDimensionSimilarity implements DimensionSimilarity<NumberVector< */
private void divide(DBIDArrayIter it, double[] data, ArrayList<DBIDs> idx, int start, int end, int depth, Mean mean) {
final int count = end - start;
- if (depth == 0) {
- if (count > 0) {
+ if(depth == 0) {
+ if(count > 0) {
ModifiableDBIDs out = DBIDUtil.newHashSet(count);
it.seek(start);
- for (int i = count; i > 0; i--, it.advance()) {
+ for(int i = count; i > 0; i--, it.advance()) {
out.add(it);
}
idx.add(out);
- } else {
+ }
+ else {
idx.add(DBIDUtil.EMPTYDBIDS);
}
return;
- } else {
- if (count > 0) {
+ }
+ else {
+ if(count > 0) {
mean.reset();
- for (int i = start; i < end; i++) {
+ for(int i = start; i < end; i++) {
mean.put(data[i]);
}
final double m = mean.getMean();
int pos = Arrays.binarySearch(data, start, end, m);
- if (pos >= 0) {
+ if(pos >= 0) {
// Ties: try to choose the most central element.
int opt = (start + end) >> 1;
- while (Double.compare(data[pos], m) == 0) {
- if (pos < opt) {
+ while(Double.compare(data[pos], m) == 0) {
+ if(pos < opt) {
pos++;
- } else if (pos > opt) {
+ }
+ else if(pos > opt) {
pos--;
- } else {
+ }
+ else {
break;
}
}
- } else {
+ }
+ else {
pos = (-pos - 1);
}
divide(it, data, idx, start, pos, depth - 1, mean);
divide(it, data, idx, pos, end, depth - 1, mean);
- } else {
+ }
+ else {
// Corner case, that should barely happen. But for ties, we currently
// Do not yet assure that it doesn't happen!
divide(it, data, idx, start, end, depth - 1, mean);
@@ -274,6 +220,69 @@ public class MCEDimensionSimilarity implements DimensionSimilarity<NumberVector< }
/**
+ * Intersect the two 1d grid decompositions, to obtain a 2d matrix.
+ *
+ * @param res Output matrix to fill
+ * @param partsx Partitions in first component
+ * @param partsy Partitions in second component.
+ * @param gridsize Size of partition decomposition
+ */
+ private void intersectionMatrix(int[][] res, ArrayList<? extends DBIDs> partsx, ArrayList<? extends DBIDs> partsy, int gridsize) {
+ for(int x = 0; x < gridsize; x++) {
+ final DBIDs px = partsx.get(x);
+ final int[] rowx = res[x];
+ for(int y = 0; y < gridsize; y++) {
+ rowx[y] = DBIDUtil.intersectionSize(px, partsy.get(y));
+ }
+ }
+ }
+
+ /**
+ * Compute the MCE entropy value.
+ *
+ * @param mat Partition size matrix
+ * @param psizesx Partition sizes on X
+ * @param psizesy Partition sizes on Y
+ * @param size Data set size
+ * @param gridsize Size of grids
+ * @param loggrid Logarithm of grid sizes, for normalization
+ * @return MCE score.
+ */
+ private double getMCEntropy(int[][] mat, int[] psizesx, int[] psizesy, int size, int gridsize, double loggrid) {
+ // Margin entropies:
+ double[] mx = new double[gridsize];
+ double[] my = new double[gridsize];
+
+ for(int i = 0; i < gridsize; i++) {
+ // Note: indexes are a bit tricky here, because we compute both margin
+ // entropies at the same time!
+ final double sumx = (double) psizesx[i];
+ final double sumy = (double) psizesy[i];
+ for(int j = 0; j < gridsize; j++) {
+ double px = mat[i][j] / sumx;
+ double py = mat[j][i] / sumy;
+
+ if(px > 0.) {
+ mx[i] -= px * Math.log(px);
+ }
+ if(py > 0.) {
+ my[i] -= py * Math.log(py);
+ }
+ }
+ }
+
+ // Weighted sums of margin entropies.
+ double sumx = 0., sumy = 0.;
+ for(int i = 0; i < gridsize; i++) {
+ sumx += mx[i] * psizesx[i];
+ sumy += my[i] * psizesy[i];
+ }
+
+ double max = ((sumx > sumy) ? sumx : sumy);
+ return max / (size * loggrid);
+ }
+
+ /**
* Parameterization class.
*
* @author Erich Schubert
diff --git a/src/de/lmu/ifi/dbs/elki/math/dimensionsimilarity/SURFINGDimensionSimilarity.java b/src/de/lmu/ifi/dbs/elki/math/dimensionsimilarity/SURFINGDimensionSimilarity.java index fd83d44b..70831a02 100644 --- a/src/de/lmu/ifi/dbs/elki/math/dimensionsimilarity/SURFINGDimensionSimilarity.java +++ b/src/de/lmu/ifi/dbs/elki/math/dimensionsimilarity/SURFINGDimensionSimilarity.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.dimensionsimilarity; This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2012
+ Copyright (C) 2014
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
@@ -23,8 +23,6 @@ package de.lmu.ifi.dbs.elki.math.dimensionsimilarity; along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-import java.util.BitSet;
-
import de.lmu.ifi.dbs.elki.data.NumberVector;
import de.lmu.ifi.dbs.elki.database.Database;
import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
@@ -33,8 +31,8 @@ import de.lmu.ifi.dbs.elki.database.query.distance.DistanceQuery; import de.lmu.ifi.dbs.elki.database.query.knn.KNNQuery;
import de.lmu.ifi.dbs.elki.database.relation.Relation;
import de.lmu.ifi.dbs.elki.distance.distancefunction.subspace.SubspaceEuclideanDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
import de.lmu.ifi.dbs.elki.math.Mean;
+import de.lmu.ifi.dbs.elki.utilities.BitsUtil;
import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
@@ -70,7 +68,7 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer; * @apiviz.uses SubspaceEuclideanDistanceFunction
*/
@Reference(authors = "Elke Achtert, Hans-Peter Kriegel, Erich Schubert, Arthur Zimek", title = "Interactive Data Mining with 3D-Parallel-Coordinate-Trees", booktitle = "Proc. of the 2013 ACM International Conference on Management of Data (SIGMOD)", url = "http://dx.doi.org/10.1145/2463676.2463696")
-public class SURFINGDimensionSimilarity implements DimensionSimilarity<NumberVector<?>> {
+public class SURFINGDimensionSimilarity implements DimensionSimilarity<NumberVector> {
/**
* Static instance.
*/
@@ -83,9 +81,12 @@ public class SURFINGDimensionSimilarity implements DimensionSimilarity<NumberVec super();
}
- @Reference(authors = "Christian Baumgartner, Claudia Plant, Karin Kailing, Hans-Peter Kriegel, and Peer Kröger", title = "Subspace Selection for Clustering High-Dimensional Data", booktitle = "IEEE International Conference on Data Mining, 2004", url = "http://dx.doi.org/10.1109/ICDM.2004.10112")
+ @Reference(authors = "Christian Baumgartner, Claudia Plant, Karin Kailing, Hans-Peter Kriegel, and Peer Kröger", //
+ title = "Subspace Selection for Clustering High-Dimensional Data", //
+ booktitle = "IEEE International Conference on Data Mining, 2004", //
+ url = "http://dx.doi.org/10.1109/ICDM.2004.10112")
@Override
- public void computeDimensionSimilarites(Database database, Relation<? extends NumberVector<?>> relation, DBIDs subset, DimensionSimilarityMatrix matrix) {
+ public void computeDimensionSimilarites(Database database, Relation<? extends NumberVector> relation, DBIDs subset, DimensionSimilarityMatrix matrix) {
final int dim = matrix.size();
Mean kdistmean = new Mean();
final int k = Math.max(1, subset.size() / 10);
@@ -93,20 +94,20 @@ public class SURFINGDimensionSimilarity implements DimensionSimilarity<NumberVec double[] knns = new double[subset.size()];
// TODO: optimize by using 1d indexes?
- for (int x = 0; x < dim; x++) {
+ for(int x = 0; x < dim; x++) {
final int i = matrix.dim(x);
- for (int y = x + 1; y < dim; y++) {
+ for(int y = x + 1; y < dim; y++) {
final int j = matrix.dim(y);
- BitSet dims = new BitSet(dim);
- dims.set(i);
- dims.set(j);
- DistanceQuery<? extends NumberVector<?>, DoubleDistance> dq = database.getDistanceQuery(relation, new SubspaceEuclideanDistanceFunction(dims));
- KNNQuery<? extends NumberVector<?>, DoubleDistance> knnq = database.getKNNQuery(dq, k);
+ long[] dims = BitsUtil.zero(dim);
+ BitsUtil.setI(dims, i);
+ BitsUtil.setI(dims, j);
+ DistanceQuery<? extends NumberVector> dq = database.getDistanceQuery(relation, new SubspaceEuclideanDistanceFunction(dims));
+ KNNQuery<? extends NumberVector> knnq = database.getKNNQuery(dq, k);
kdistmean.reset();
int knn = 0;
- for (DBIDIter id1 = subset.iter(); id1.valid(); id1.advance(), knn++) {
- final double kdist = knnq.getKNNForDBID(id1, k).getKNNDistance().doubleValue();
+ for(DBIDIter id1 = subset.iter(); id1.valid(); id1.advance(), knn++) {
+ final double kdist = knnq.getKNNForDBID(id1, k).getKNNDistance();
kdistmean.put(kdist);
knns[knn] = kdist;
}
@@ -114,9 +115,9 @@ public class SURFINGDimensionSimilarity implements DimensionSimilarity<NumberVec // Deviation from mean:
double diff = 0.;
int below = 0;
- for (int l = 0; l < knns.length; l++) {
+ for(int l = 0; l < knns.length; l++) {
diff += Math.abs(mean - knns[l]);
- if (knns[l] < mean) {
+ if(knns[l] < mean) {
below++;
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/math/dimensionsimilarity/SlopeDimensionSimilarity.java b/src/de/lmu/ifi/dbs/elki/math/dimensionsimilarity/SlopeDimensionSimilarity.java index 1eb62189..b48a2410 100644 --- a/src/de/lmu/ifi/dbs/elki/math/dimensionsimilarity/SlopeDimensionSimilarity.java +++ b/src/de/lmu/ifi/dbs/elki/math/dimensionsimilarity/SlopeDimensionSimilarity.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.dimensionsimilarity; This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2012
+ Copyright (C) 2014
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
@@ -28,10 +28,9 @@ import de.lmu.ifi.dbs.elki.database.Database; import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
import de.lmu.ifi.dbs.elki.database.ids.DBIDs;
import de.lmu.ifi.dbs.elki.database.relation.Relation;
-import de.lmu.ifi.dbs.elki.utilities.DatabaseUtil;
+import de.lmu.ifi.dbs.elki.database.relation.RelationUtil;
import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
-import de.lmu.ifi.dbs.elki.utilities.pairs.Pair;
/**
* Arrange dimensions based on the entropy of the slope spectrum.
@@ -43,12 +42,17 @@ import de.lmu.ifi.dbs.elki.utilities.pairs.Pair; * Proceedings of the 2013 ACM International Conference on Management of Data
* (SIGMOD), New York City, NY, 2013.
* </p>
- *
+ *
+ * TODO: shouldn't this be normalized by the single-dimension entropies or so?
+ *
* @author Erich Schubert
* @author Robert Rödler
*/
-@Reference(authors = "Elke Achtert, Hans-Peter Kriegel, Erich Schubert, Arthur Zimek", title = "Interactive Data Mining with 3D-Parallel-Coordinate-Trees", booktitle = "Proc. of the 2013 ACM International Conference on Management of Data (SIGMOD)", url = "http://dx.doi.org/10.1145/2463676.2463696")
-public class SlopeDimensionSimilarity implements DimensionSimilarity<NumberVector<?>> {
+@Reference(authors = "Elke Achtert, Hans-Peter Kriegel, Erich Schubert, Arthur Zimek", //
+title = "Interactive Data Mining with 3D-Parallel-Coordinate-Trees", //
+booktitle = "Proc. of the 2013 ACM International Conference on Management of Data (SIGMOD)", //
+url = "http://dx.doi.org/10.1145/2463676.2463696")
+public class SlopeDimensionSimilarity implements DimensionSimilarity<NumberVector> {
/**
* Static instance.
*/
@@ -77,21 +81,19 @@ public class SlopeDimensionSimilarity implements DimensionSimilarity<NumberVecto }
@Override
- public void computeDimensionSimilarites(Database database, Relation<? extends NumberVector<?>> relation, DBIDs subset, DimensionSimilarityMatrix matrix) {
+ public void computeDimensionSimilarites(Database database, Relation<? extends NumberVector> relation, DBIDs subset, DimensionSimilarityMatrix matrix) {
final int dim = matrix.size();
final int size = subset.size();
// FIXME: Get/keep these statistics in the relation, or compute for the
// sample only.
- double[] off = new double[dim], scale = new double[dim];
+ double[] off, scale;
{
- Pair<? extends NumberVector<?>, ? extends NumberVector<?>> mm = DatabaseUtil.computeMinMax(relation);
- NumberVector<?> min = mm.first;
- NumberVector<?> max = mm.second;
+ double[][] mm = RelationUtil.computeMinMax(relation);
+ off = mm[0]; scale = mm[1];
for (int d = 0; d < dim; d++) {
- off[d] = min.doubleValue(matrix.dim(d));
- final double m = max.doubleValue(matrix.dim(d));
- scale[d] = (m > off[d]) ? 1. / (m - off[d]) : 1;
+ scale[d] -= off[d];
+ scale[d] = (scale[d] > 0.) ? 1. / scale[d] : 1.;
}
}
@@ -102,7 +104,7 @@ public class SlopeDimensionSimilarity implements DimensionSimilarity<NumberVecto // Scratch buffer
double[] vec = new double[dim];
for (DBIDIter id = subset.iter(); id.valid(); id.advance()) {
- final NumberVector<?> obj = relation.get(id);
+ final NumberVector obj = relation.get(id);
// Map values to 0..1
for (int d = 0; d < dim; d++) {
vec[d] = (obj.doubleValue(matrix.dim(d)) - off[d]) * scale[d];
diff --git a/src/de/lmu/ifi/dbs/elki/math/dimensionsimilarity/SlopeInversionDimensionSimilarity.java b/src/de/lmu/ifi/dbs/elki/math/dimensionsimilarity/SlopeInversionDimensionSimilarity.java index 77408914..8ccb3597 100644 --- a/src/de/lmu/ifi/dbs/elki/math/dimensionsimilarity/SlopeInversionDimensionSimilarity.java +++ b/src/de/lmu/ifi/dbs/elki/math/dimensionsimilarity/SlopeInversionDimensionSimilarity.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.dimensionsimilarity; This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2012
+ Copyright (C) 2014
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
@@ -28,10 +28,9 @@ import de.lmu.ifi.dbs.elki.database.Database; import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
import de.lmu.ifi.dbs.elki.database.ids.DBIDs;
import de.lmu.ifi.dbs.elki.database.relation.Relation;
-import de.lmu.ifi.dbs.elki.utilities.DatabaseUtil;
+import de.lmu.ifi.dbs.elki.database.relation.RelationUtil;
import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
-import de.lmu.ifi.dbs.elki.utilities.pairs.Pair;
/**
* Arrange dimensions based on the entropy of the slope spectrum. In contrast to
@@ -51,7 +50,10 @@ import de.lmu.ifi.dbs.elki.utilities.pairs.Pair; * @author Erich Schubert
* @author Robert Rödler
*/
-@Reference(authors = "Elke Achtert, Hans-Peter Kriegel, Erich Schubert, Arthur Zimek", title = "Interactive Data Mining with 3D-Parallel-Coordinate-Trees", booktitle = "Proc. of the 2013 ACM International Conference on Management of Data (SIGMOD)", url = "http://dx.doi.org/10.1145/2463676.2463696")
+@Reference(authors = "Elke Achtert, Hans-Peter Kriegel, Erich Schubert, Arthur Zimek", //
+title = "Interactive Data Mining with 3D-Parallel-Coordinate-Trees", //
+booktitle = "Proc. of the 2013 ACM International Conference on Management of Data (SIGMOD)", //
+url = "http://dx.doi.org/10.1145/2463676.2463696")
public class SlopeInversionDimensionSimilarity extends SlopeDimensionSimilarity {
/**
* Static instance.
@@ -66,7 +68,7 @@ public class SlopeInversionDimensionSimilarity extends SlopeDimensionSimilarity }
@Override
- public void computeDimensionSimilarites(Database database, Relation<? extends NumberVector<?>> relation, DBIDs subset, DimensionSimilarityMatrix matrix) {
+ public void computeDimensionSimilarites(Database database, Relation<? extends NumberVector> relation, DBIDs subset, DimensionSimilarityMatrix matrix) {
final int dim = matrix.size();
final int size = subset.size();
@@ -77,28 +79,27 @@ public class SlopeInversionDimensionSimilarity extends SlopeDimensionSimilarity // FIXME: Get/keep these statistics in the relation, or compute for the
// sample only.
- double[] off = new double[dim], scale = new double[dim];
+ double[] off, scale;
{
- Pair<? extends NumberVector<?>, ? extends NumberVector<?>> mm = DatabaseUtil.computeMinMax(relation);
- NumberVector<?> min = mm.first;
- NumberVector<?> max = mm.second;
- for (int d = 0; d < dim; d++) {
- off[d] = min.doubleValue(matrix.dim(d));
- final double m = max.doubleValue(matrix.dim(d));
- scale[d] = (m > off[d]) ? 1. / (m - off[d]) : 1;
+ double[][] mm = RelationUtil.computeMinMax(relation);
+ off = mm[0];
+ scale = mm[1];
+ for(int d = 0; d < dim; d++) {
+ scale[d] -= off[d];
+ scale[d] = (scale[d] > 0.) ? 1. / scale[d] : 1.;
}
}
// Scratch buffer
double[] vec = new double[dim];
- for (DBIDIter id = subset.iter(); id.valid(); id.advance()) {
- final NumberVector<?> obj = relation.get(id);
+ for(DBIDIter id = subset.iter(); id.valid(); id.advance()) {
+ final NumberVector obj = relation.get(id);
// Map values to 0..1
- for (int d = 0; d < dim; d++) {
+ for(int d = 0; d < dim; d++) {
vec[d] = (obj.doubleValue(matrix.dim(d)) - off[d]) * scale[d];
}
- for (int i = 0; i < dim - 1; i++) {
- for (int j = i + 1; j < dim; j++) {
+ for(int i = 0; i < dim - 1; i++) {
+ for(int j = i + 1; j < dim; j++) {
{
// This will be on a scale of 0 .. 2:
final double delta = vec[j] - vec[i] + 1;
@@ -120,13 +121,13 @@ public class SlopeInversionDimensionSimilarity extends SlopeDimensionSimilarity }
// Compute entropy in each combination:
- for (int x = 0; x < dim; x++) {
- for (int y = x + 1; y < dim; y++) {
+ for(int x = 0; x < dim; x++) {
+ for(int y = x + 1; y < dim; y++) {
double entropy = 0., entropyI = 0;
{
int[] as = angles[x][y];
- for (int l = 0; l < PRECISION; l++) {
- if (as[l] > 0) {
+ for(int l = 0; l < PRECISION; l++) {
+ if(as[l] > 0) {
final double p = as[l] / (double) size;
entropy += p * Math.log(p);
}
@@ -134,17 +135,18 @@ public class SlopeInversionDimensionSimilarity extends SlopeDimensionSimilarity }
{
int[] as = angleI[x][y];
- for (int l = 0; l < PRECISION; l++) {
- if (as[l] > 0) {
+ for(int l = 0; l < PRECISION; l++) {
+ if(as[l] > 0) {
final double p = as[l] / (double) size;
entropyI += p * Math.log(p);
}
}
}
- if (entropy >= entropyI) {
+ if(entropy >= entropyI) {
entropy = 1 + entropy / LOG_PRECISION;
matrix.set(x, y, entropy);
- } else {
+ }
+ else {
entropyI = 1 + entropyI / LOG_PRECISION;
// Negative sign to indicate the axes might be inversely related
matrix.set(x, y, -entropyI);
diff --git a/src/de/lmu/ifi/dbs/elki/math/dimensionsimilarity/package-info.java b/src/de/lmu/ifi/dbs/elki/math/dimensionsimilarity/package-info.java index bcbd47d5..606a43ce 100644 --- a/src/de/lmu/ifi/dbs/elki/math/dimensionsimilarity/package-info.java +++ b/src/de/lmu/ifi/dbs/elki/math/dimensionsimilarity/package-info.java @@ -5,7 +5,7 @@ This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/geodesy/AbstractEarthModel.java b/src/de/lmu/ifi/dbs/elki/math/geodesy/AbstractEarthModel.java index d8eaa43f..9426f84e 100644 --- a/src/de/lmu/ifi/dbs/elki/math/geodesy/AbstractEarthModel.java +++ b/src/de/lmu/ifi/dbs/elki/math/geodesy/AbstractEarthModel.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.geodesy; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/geodesy/Clarke1858SpheroidEarthModel.java b/src/de/lmu/ifi/dbs/elki/math/geodesy/Clarke1858SpheroidEarthModel.java index c1d8a9af..d8842b30 100644 --- a/src/de/lmu/ifi/dbs/elki/math/geodesy/Clarke1858SpheroidEarthModel.java +++ b/src/de/lmu/ifi/dbs/elki/math/geodesy/Clarke1858SpheroidEarthModel.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.geodesy; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/geodesy/Clarke1880SpheroidEarthModel.java b/src/de/lmu/ifi/dbs/elki/math/geodesy/Clarke1880SpheroidEarthModel.java index 731cf9eb..e23f15fb 100644 --- a/src/de/lmu/ifi/dbs/elki/math/geodesy/Clarke1880SpheroidEarthModel.java +++ b/src/de/lmu/ifi/dbs/elki/math/geodesy/Clarke1880SpheroidEarthModel.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.geodesy; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/geodesy/EarthModel.java b/src/de/lmu/ifi/dbs/elki/math/geodesy/EarthModel.java index b27f2e3b..9cf76ac3 100644 --- a/src/de/lmu/ifi/dbs/elki/math/geodesy/EarthModel.java +++ b/src/de/lmu/ifi/dbs/elki/math/geodesy/EarthModel.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.geodesy; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/geodesy/GRS67SpheroidEarthModel.java b/src/de/lmu/ifi/dbs/elki/math/geodesy/GRS67SpheroidEarthModel.java index 81dc7565..33c7f243 100644 --- a/src/de/lmu/ifi/dbs/elki/math/geodesy/GRS67SpheroidEarthModel.java +++ b/src/de/lmu/ifi/dbs/elki/math/geodesy/GRS67SpheroidEarthModel.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.geodesy; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/geodesy/GRS80SpheroidEarthModel.java b/src/de/lmu/ifi/dbs/elki/math/geodesy/GRS80SpheroidEarthModel.java index 2499da0c..78bb396b 100644 --- a/src/de/lmu/ifi/dbs/elki/math/geodesy/GRS80SpheroidEarthModel.java +++ b/src/de/lmu/ifi/dbs/elki/math/geodesy/GRS80SpheroidEarthModel.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.geodesy; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/geodesy/SphereUtil.java b/src/de/lmu/ifi/dbs/elki/math/geodesy/SphereUtil.java index b8e57cc3..d53f9a62 100644 --- a/src/de/lmu/ifi/dbs/elki/math/geodesy/SphereUtil.java +++ b/src/de/lmu/ifi/dbs/elki/math/geodesy/SphereUtil.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.geodesy; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/geodesy/SphericalCosineEarthModel.java b/src/de/lmu/ifi/dbs/elki/math/geodesy/SphericalCosineEarthModel.java index f81757ac..9e66bd25 100644 --- a/src/de/lmu/ifi/dbs/elki/math/geodesy/SphericalCosineEarthModel.java +++ b/src/de/lmu/ifi/dbs/elki/math/geodesy/SphericalCosineEarthModel.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.geodesy; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/geodesy/SphericalHaversineEarthModel.java b/src/de/lmu/ifi/dbs/elki/math/geodesy/SphericalHaversineEarthModel.java index 5ed8c4ca..b4823341 100644 --- a/src/de/lmu/ifi/dbs/elki/math/geodesy/SphericalHaversineEarthModel.java +++ b/src/de/lmu/ifi/dbs/elki/math/geodesy/SphericalHaversineEarthModel.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.geodesy; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/geodesy/SphericalVincentyEarthModel.java b/src/de/lmu/ifi/dbs/elki/math/geodesy/SphericalVincentyEarthModel.java index e9a780cc..507218e7 100644 --- a/src/de/lmu/ifi/dbs/elki/math/geodesy/SphericalVincentyEarthModel.java +++ b/src/de/lmu/ifi/dbs/elki/math/geodesy/SphericalVincentyEarthModel.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.geodesy; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/geodesy/WGS72SpheroidEarthModel.java b/src/de/lmu/ifi/dbs/elki/math/geodesy/WGS72SpheroidEarthModel.java index 44d4f9d0..488006ae 100644 --- a/src/de/lmu/ifi/dbs/elki/math/geodesy/WGS72SpheroidEarthModel.java +++ b/src/de/lmu/ifi/dbs/elki/math/geodesy/WGS72SpheroidEarthModel.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.geodesy; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/geodesy/WGS84SpheroidEarthModel.java b/src/de/lmu/ifi/dbs/elki/math/geodesy/WGS84SpheroidEarthModel.java index 30ba02aa..07b8dab5 100644 --- a/src/de/lmu/ifi/dbs/elki/math/geodesy/WGS84SpheroidEarthModel.java +++ b/src/de/lmu/ifi/dbs/elki/math/geodesy/WGS84SpheroidEarthModel.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.geodesy; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/geometry/AlphaShape.java b/src/de/lmu/ifi/dbs/elki/math/geometry/AlphaShape.java index 11f24cb2..a2349b32 100644 --- a/src/de/lmu/ifi/dbs/elki/math/geometry/AlphaShape.java +++ b/src/de/lmu/ifi/dbs/elki/math/geometry/AlphaShape.java @@ -12,7 +12,7 @@ import de.lmu.ifi.dbs.elki.math.linearalgebra.Vector; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/geometry/GrahamScanConvexHull2D.java b/src/de/lmu/ifi/dbs/elki/math/geometry/GrahamScanConvexHull2D.java index c2945fde..27b8444f 100644 --- a/src/de/lmu/ifi/dbs/elki/math/geometry/GrahamScanConvexHull2D.java +++ b/src/de/lmu/ifi/dbs/elki/math/geometry/GrahamScanConvexHull2D.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.geometry; This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2011
+ Copyright (C) 2014
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team @@ -43,7 +43,9 @@ import de.lmu.ifi.dbs.elki.utilities.documentation.Reference; *
* @apiviz.has Polygon
*/
-@Reference(authors = "Paul Graham", title = "An Efficient Algorithm for Determining the Convex Hull of a Finite Planar Set", booktitle = "Information Processing Letters 1")
+@Reference(authors = "Paul Graham", //
+title = "An Efficient Algorithm for Determining the Convex Hull of a Finite Planar Set", //
+booktitle = "Information Processing Letters 1")
public class GrahamScanConvexHull2D {
/**
* The current set of points
diff --git a/src/de/lmu/ifi/dbs/elki/math/geometry/PrimsMinimumSpanningTree.java b/src/de/lmu/ifi/dbs/elki/math/geometry/PrimsMinimumSpanningTree.java index 887b5012..bc7380cd 100644 --- a/src/de/lmu/ifi/dbs/elki/math/geometry/PrimsMinimumSpanningTree.java +++ b/src/de/lmu/ifi/dbs/elki/math/geometry/PrimsMinimumSpanningTree.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.geometry; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -45,7 +45,9 @@ import de.lmu.ifi.dbs.elki.utilities.documentation.Reference; * * @apiviz.composedOf Adapter */ -@Reference(authors = "R. C. Prim", title = "Shortest connection networks and some generalizations", booktitle = "Bell System Technical Journal, 36 (1957)") +@Reference(authors = "R. C. Prim", // +title = "Shortest connection networks and some generalizations", // +booktitle = "Bell System Technical Journal, 36 (1957)") public class PrimsMinimumSpanningTree { /** * Adapter class for double[][] matrixes. @@ -99,18 +101,18 @@ public class PrimsMinimumSpanningTree { best[current] = 0; // Search - for (int i = n - 2; i >= 0; i--) { + for(int i = n - 2; i >= 0; i--) { // Update best and src from current: int newbesti = -1; double newbestd = Double.POSITIVE_INFINITY; // Note: we assume we started with 0, and can thus skip it - for (int j = in.nextClearBit(1); j < n && j > 0; j = in.nextClearBit(j + 1)) { + for(int j = in.nextClearBit(1); j < n && j > 0; j = in.nextClearBit(j + 1)) { final double dist = adapter.distance(data, current, j); - if (dist < best[j]) { + if(dist < best[j]) { best[j] = dist; src[j] = current; } - if (best[j] < newbestd) { + if(best[j] < newbestd) { newbestd = best[j]; newbesti = j; } @@ -128,6 +130,42 @@ public class PrimsMinimumSpanningTree { } /** + * Prune the minimum spanning tree, removing all edges to nodes that have a + * degree below {@code minDegree}. + * + * @param numnodes Number of nodes (MUST use numbers 0 to {@code numnodes-1}) + * @param tree Original spanning tree + * @param minDegree Minimum node degree + * @return Pruned spanning tree + */ + public static int[] pruneTree(int numnodes, int[] tree, int minDegree) { + // Compute node degrees + int[] deg = new int[numnodes]; + for(int i = 0; i < tree.length; i++) { + deg[tree[i]]++; + } + // Count nodes to be retained: + int keep = 0; + for(int i = 0; i < tree.length; i += 2) { + if(deg[tree[i]] >= minDegree && deg[tree[i + 1]] >= minDegree) { + keep++; + } + } + // Build reduced tree + int j = 0; + int[] ret = new int[keep]; + for(int i = 0; i < tree.length; i += 2) { + if(deg[tree[i]] >= minDegree && deg[tree[i + 1]] >= minDegree) { + ret[j] = tree[i]; + ret[j + 1] = tree[i + 1]; + j += 2; + } + } + assert (j == ret.length); + return ret; + } + + /** * Adapter interface to allow use with different data representations. * * @author Erich Schubert diff --git a/src/de/lmu/ifi/dbs/elki/math/geometry/SweepHullDelaunay2D.java b/src/de/lmu/ifi/dbs/elki/math/geometry/SweepHullDelaunay2D.java index ca6d0e5e..c45d8297 100644 --- a/src/de/lmu/ifi/dbs/elki/math/geometry/SweepHullDelaunay2D.java +++ b/src/de/lmu/ifi/dbs/elki/math/geometry/SweepHullDelaunay2D.java @@ -21,7 +21,7 @@ import de.lmu.ifi.dbs.elki.utilities.pairs.IntIntPair; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -49,7 +49,9 @@ import de.lmu.ifi.dbs.elki.utilities.pairs.IntIntPair; * * @apiviz.has Polygon */ -@Reference(authors = "David Sinclair", title = "S-hull: a fast sweep-hull routine for Delaunay triangulation", booktitle = "Online: http://s-hull.org/") +@Reference(authors = "David Sinclair", // +title = "S-hull: a fast sweep-hull routine for Delaunay triangulation", // +booktitle = "Online: http://s-hull.org/") public class SweepHullDelaunay2D { /** * Class logger @@ -655,7 +657,7 @@ public class SweepHullDelaunay2D { * @param a Starting point * @param b Reference point * @param d Test point - * @return true when on the left side + * @return true when on the left side */ boolean leftOf(Vector a, Vector b, Vector d) { final double bax = b.get(0) - a.get(0); @@ -700,7 +702,7 @@ public class SweepHullDelaunay2D { * Circumcircle parameters */ public double r2 = -1; - + /** * Center vector */ @@ -890,7 +892,7 @@ public class SweepHullDelaunay2D { // Compute D final double D = 2 * (abx * acy - aby * acx); - + // No circumcircle: if(D == 0) { return false; @@ -900,7 +902,6 @@ public class SweepHullDelaunay2D { final double offx = (acy * ablen - aby * aclen) / D; final double offy = (abx * aclen - acx * ablen) / D; - // Avoid degeneration: r2 = offx * offx + offy * offy; if((r2 > 1e10 * ablen || r2 > 1e10 * aclen)) { diff --git a/src/de/lmu/ifi/dbs/elki/math/geometry/XYCurve.java b/src/de/lmu/ifi/dbs/elki/math/geometry/XYCurve.java index 36ee7f23..35edd0cc 100644 --- a/src/de/lmu/ifi/dbs/elki/math/geometry/XYCurve.java +++ b/src/de/lmu/ifi/dbs/elki/math/geometry/XYCurve.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.geometry; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/geometry/package-info.java b/src/de/lmu/ifi/dbs/elki/math/geometry/package-info.java index d94ac05a..c4e932a8 100644 --- a/src/de/lmu/ifi/dbs/elki/math/geometry/package-info.java +++ b/src/de/lmu/ifi/dbs/elki/math/geometry/package-info.java @@ -5,7 +5,7 @@ This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures -Copyright (C) 2013 +Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/AffineTransformation.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/AffineTransformation.java index a4df5e80..745fbf4d 100644 --- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/AffineTransformation.java +++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/AffineTransformation.java @@ -8,7 +8,7 @@ import de.lmu.ifi.dbs.elki.math.MathUtil; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -270,7 +270,7 @@ public class AffineTransformation { * @return copy of the transformation matrix */ public Matrix getTransformation() { - return trans.copy(); + return trans; } /** @@ -282,7 +282,7 @@ public class AffineTransformation { if(inv == null) { updateInverse(); } - return inv.copy(); + return inv; } /** diff --git a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/Centroid.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/Centroid.java index 7650ecd2..4b38f556 100644 --- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/Centroid.java +++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/Centroid.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -114,7 +114,7 @@ public class Centroid extends Vector { * * @param val Value */ - public void put(NumberVector<?> val) { + public void put(NumberVector val) { assert (val.getDimensionality() == elements.length); wsum += 1.0; for (int i = 0; i < elements.length; i++) { @@ -129,7 +129,7 @@ public class Centroid extends Vector { * @param val data * @param weight weight */ - public void put(NumberVector<?> val, double weight) { + public void put(NumberVector val, double weight) { assert (val.getDimensionality() == elements.length); if (weight == 0) { return; // Skip zero weights. @@ -150,7 +150,7 @@ public class Centroid extends Vector { * @param <F> vector type * @return the data */ - public <F extends NumberVector<?>> F toVector(Relation<? extends F> relation) { + public <F extends NumberVector> F toVector(Relation<? extends F> relation) { return RelationUtil.getNumberVectorFactory(relation).newNumberVector(elements); } @@ -176,7 +176,7 @@ public class Centroid extends Vector { * @param relation Relation to use * @return Centroid of relation */ - public static Centroid make(Relation<? extends NumberVector<?>> relation) { + public static Centroid make(Relation<? extends NumberVector> relation) { Centroid c = new Centroid(RelationUtil.dimensionality(relation)); for (DBIDIter iditer = relation.iterDBIDs(); iditer.valid(); iditer.advance()) { c.put(relation.get(iditer)); @@ -191,7 +191,7 @@ public class Centroid extends Vector { * @param ids IDs to use * @return Centroid */ - public static Centroid make(Relation<? extends NumberVector<?>> relation, DBIDs ids) { + public static Centroid make(Relation<? extends NumberVector> relation, DBIDs ids) { Centroid c = new Centroid(RelationUtil.dimensionality(relation)); for (DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) { c.put(relation.get(iter)); diff --git a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/CholeskyDecomposition.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/CholeskyDecomposition.java index 6fa455ca..eb8bc0f9 100644 --- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/CholeskyDecomposition.java +++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/CholeskyDecomposition.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/CovarianceMatrix.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/CovarianceMatrix.java index 345f2a42..38a98b3c 100644 --- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/CovarianceMatrix.java +++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/CovarianceMatrix.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -23,6 +23,8 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra; along with this program. If not, see <http://www.gnu.org/licenses/>. */ +import java.util.Arrays; + import de.lmu.ifi.dbs.elki.data.NumberVector; import de.lmu.ifi.dbs.elki.database.ids.DBIDIter; import de.lmu.ifi.dbs.elki.database.ids.DBIDs; @@ -85,7 +87,16 @@ public class CovarianceMatrix { this.mean = new double[dim]; this.nmea = new double[dim]; this.elements = new double[dim][dim]; - this.wsum = 0.0; + this.wsum = 0.; + } + + /** + * Get the matrix dimensionality. + * + * @return Mean length. + */ + public int getDimensionality() { + return mean.length; } /** @@ -95,21 +106,21 @@ public class CovarianceMatrix { */ public void put(double[] val) { assert (val.length == mean.length); - final double nwsum = wsum + 1.0; + final double nwsum = wsum + 1.; // Compute new means - for (int i = 0; i < mean.length; i++) { + for(int i = 0; i < mean.length; i++) { final double delta = val[i] - mean[i]; nmea[i] = mean[i] + delta / nwsum; } // Update covariance matrix - for (int i = 0; i < mean.length; i++) { - for (int j = i; j < mean.length; j++) { + for(int i = 0; i < mean.length; i++) { + for(int j = i; j < mean.length; j++) { // We DO want to use the new mean once and the old mean once! // It does not matter which one is which. double delta = (val[i] - nmea[i]) * (val[j] - mean[j]); elements[i][j] = elements[i][j] + delta; // Optimize via symmetry - if (i != j) { + if(i != j) { elements[j][i] = elements[j][i] + delta; } } @@ -130,20 +141,20 @@ public class CovarianceMatrix { assert (val.length == mean.length); final double nwsum = wsum + weight; // Compute new means - for (int i = 0; i < mean.length; i++) { + for(int i = 0; i < mean.length; i++) { final double delta = val[i] - mean[i]; final double rval = delta * weight / nwsum; nmea[i] = mean[i] + rval; } // Update covariance matrix - for (int i = 0; i < mean.length; i++) { - for (int j = i; j < mean.length; j++) { + for(int i = 0; i < mean.length; i++) { + for(int j = i; j < mean.length; j++) { // We DO want to use the new mean once and the old mean once! // It does not matter which one is which. double delta = (val[i] - nmea[i]) * (val[j] - mean[j]) * weight; elements[i][j] = elements[i][j] + delta; // Optimize via symmetry - if (i != j) { + if(i != j) { elements[j][i] = elements[j][i] + delta; } } @@ -178,23 +189,23 @@ public class CovarianceMatrix { * * @param val Value */ - public void put(NumberVector<?> val) { + public void put(NumberVector val) { assert (val.getDimensionality() == mean.length); - final double nwsum = wsum + 1.0; + final double nwsum = wsum + 1.; // Compute new means - for (int i = 0; i < mean.length; i++) { + for(int i = 0; i < mean.length; i++) { final double delta = val.doubleValue(i) - mean[i]; nmea[i] = mean[i] + delta / nwsum; } // Update covariance matrix - for (int i = 0; i < mean.length; i++) { - for (int j = i; j < mean.length; j++) { + for(int i = 0; i < mean.length; i++) { + for(int j = i; j < mean.length; j++) { // We DO want to use the new mean once and the old mean once! // It does not matter which one is which. double delta = (val.doubleValue(i) - nmea[i]) * (val.doubleValue(j) - mean[j]); elements[i][j] = elements[i][j] + delta; // Optimize via symmetry - if (i != j) { + if(i != j) { elements[j][i] = elements[j][i] + delta; } } @@ -205,39 +216,29 @@ public class CovarianceMatrix { } /** - * Get the weight sum, to test whether the covariance matrix can be - * materialized. - * - * @return Weight sum. - */ - public double getWeight() { - return wsum; - } - - /** * Add data with a given weight. * * @param val data * @param weight weight */ - public void put(NumberVector<?> val, double weight) { + public void put(NumberVector val, double weight) { assert (val.getDimensionality() == mean.length); final double nwsum = wsum + weight; // Compute new means - for (int i = 0; i < mean.length; i++) { + for(int i = 0; i < mean.length; i++) { final double delta = val.doubleValue(i) - mean[i]; final double rval = delta * weight / nwsum; nmea[i] = mean[i] + rval; } // Update covariance matrix - for (int i = 0; i < mean.length; i++) { - for (int j = i; j < mean.length; j++) { + for(int i = 0; i < mean.length; i++) { + for(int j = i; j < mean.length; j++) { // We DO want to use the new mean once and the old mean once! // It does not matter which one is which. double delta = (val.doubleValue(i) - nmea[i]) * (val.doubleValue(j) - mean[j]) * weight; elements[i][j] = elements[i][j] + delta; // Optimize via symmetry - if (i != j) { + if(i != j) { elements[j][i] = elements[j][i] + delta; } } @@ -248,6 +249,16 @@ public class CovarianceMatrix { } /** + * Get the weight sum, to test whether the covariance matrix can be + * materialized. + * + * @return Weight sum. + */ + public double getWeight() { + return wsum; + } + + /** * Get the mean as vector. * * @return Mean vector @@ -263,7 +274,7 @@ public class CovarianceMatrix { * @param <F> vector type * @return Mean vector */ - public <F extends NumberVector<?>> F getMeanVector(Relation<? extends F> relation) { + public <F extends NumberVector> F getMeanVector(Relation<? extends F> relation) { return RelationUtil.getNumberVectorFactory(relation).newNumberVector(mean); } @@ -278,7 +289,7 @@ public class CovarianceMatrix { * @return New matrix */ public Matrix makeSampleMatrix() { - if (wsum <= 1.0) { + if(wsum <= 1.0) { throw new IllegalStateException(ERR_TOO_LITTLE_WEIGHT); } Matrix mat = new Matrix(elements); @@ -296,11 +307,11 @@ public class CovarianceMatrix { * @return New matrix */ public Matrix makeNaiveMatrix() { - if (wsum <= 0.0) { + if(wsum <= 0.) { throw new IllegalStateException(ERR_TOO_LITTLE_WEIGHT); } Matrix mat = new Matrix(elements); - return mat.times(1.0 / wsum); + return mat.times(1. / wsum); } /** @@ -314,10 +325,10 @@ public class CovarianceMatrix { * @return New matrix */ public Matrix destroyToSampleMatrix() { - if (wsum <= 1.0) { + if(wsum <= 1.) { throw new IllegalStateException(ERR_TOO_LITTLE_WEIGHT); } - Matrix mat = new Matrix(elements).timesEquals(1.0 / (wsum - 1)); + Matrix mat = new Matrix(elements).timesEquals(1. / (wsum - 1.)); this.elements = null; return mat; } @@ -333,15 +344,34 @@ public class CovarianceMatrix { * @return New matrix */ public Matrix destroyToNaiveMatrix() { - if (wsum <= 0.0) { + if(wsum <= 0.) { throw new IllegalStateException(ERR_TOO_LITTLE_WEIGHT); } - Matrix mat = new Matrix(elements).timesEquals(1.0 / wsum); + Matrix mat = new Matrix(elements).timesEquals(1. / wsum); this.elements = null; return mat; } /** + * Reset the covariance matrix. + * + * This function <em>may</em> be called after a "destroy". + */ + public void reset() { + Arrays.fill(mean, 0.); + Arrays.fill(nmea, 0.); + if(elements != null) { + for(int i = 0; i < elements.length; i++) { + Arrays.fill(elements[i], 0.); + } + } + else { + elements = new double[mean.length][mean.length]; + } + wsum = 0.; + } + + /** * Static Constructor. * * @param mat Matrix to use the columns of @@ -350,7 +380,7 @@ public class CovarianceMatrix { public static CovarianceMatrix make(Matrix mat) { CovarianceMatrix c = new CovarianceMatrix(mat.getRowDimensionality()); int n = mat.getColumnDimensionality(); - for (int i = 0; i < n; i++) { + for(int i = 0; i < n; i++) { // TODO: avoid constructing the vector objects? c.put(mat.getCol(i)); } @@ -363,9 +393,9 @@ public class CovarianceMatrix { * @param relation Relation to use. * @return Covariance matrix */ - public static CovarianceMatrix make(Relation<? extends NumberVector<?>> relation) { + public static CovarianceMatrix make(Relation<? extends NumberVector> relation) { CovarianceMatrix c = new CovarianceMatrix(RelationUtil.dimensionality(relation)); - for (DBIDIter iditer = relation.iterDBIDs(); iditer.valid(); iditer.advance()) { + for(DBIDIter iditer = relation.iterDBIDs(); iditer.valid(); iditer.advance()) { c.put(relation.get(iditer)); } return c; @@ -378,9 +408,9 @@ public class CovarianceMatrix { * @param ids IDs to add * @return Covariance matrix */ - public static CovarianceMatrix make(Relation<? extends NumberVector<?>> relation, DBIDs ids) { + public static CovarianceMatrix make(Relation<? extends NumberVector> relation, DBIDs ids) { CovarianceMatrix c = new CovarianceMatrix(RelationUtil.dimensionality(relation)); - for (DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) { + for(DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) { c.put(relation.get(iter)); } return c; diff --git a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/EigenPair.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/EigenPair.java index 3b65d99a..1ca999cc 100644 --- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/EigenPair.java +++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/EigenPair.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -101,6 +101,6 @@ public class EigenPair implements Comparable<EigenPair> { */ @Override public String toString() { - return "(ew = " + FormatUtil.format(eigenvalue) + ", ev = [" + FormatUtil.format(eigenvector) + "])"; + return "(ew = " + eigenvalue + ", ev = [" + FormatUtil.format(eigenvector) + "])"; } }
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/EigenvalueDecomposition.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/EigenvalueDecomposition.java index 61401b18..cf5dc8e9 100644 --- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/EigenvalueDecomposition.java +++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/EigenvalueDecomposition.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/LUDecomposition.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/LUDecomposition.java index 16fcf21c..9b76c489 100644 --- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/LUDecomposition.java +++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/LUDecomposition.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/LinearEquationSystem.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/LinearEquationSystem.java index f32ce410..0a837f0e 100644 --- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/LinearEquationSystem.java +++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/LinearEquationSystem.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -623,7 +623,7 @@ public class LinearEquationSystem { StringBuilder msg = new StringBuilder(); if (LOG.isDebugging()) { - msg.append("\nSpecial solution x_0 = [").append(FormatUtil.format(x_0, ",", 4)).append(']'); + msg.append("\nSpecial solution x_0 = [").append(FormatUtil.format(x_0, ",", FormatUtil.NF4)).append(']'); msg.append("\nbound Indices ").append(boundIndices); msg.append("\nfree Indices ").append(freeIndices); } @@ -651,7 +651,7 @@ public class LinearEquationSystem { if (LOG.isDebugging()) { msg.append("\nU"); for (double[] anU : u) { - msg.append('\n').append(FormatUtil.format(anU, ",", 4)); + msg.append('\n').append(FormatUtil.format(anU, ",", FormatUtil.NF4)); } LOG.debugFine(msg.toString()); } diff --git a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/Matrix.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/Matrix.java index 3f513720..6826f67d 100644 --- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/Matrix.java +++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/Matrix.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -31,7 +31,6 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.logging.Logger; -import de.lmu.ifi.dbs.elki.data.RationalNumber; import de.lmu.ifi.dbs.elki.logging.LoggingConfiguration; import de.lmu.ifi.dbs.elki.math.MathUtil; import de.lmu.ifi.dbs.elki.utilities.FormatUtil; @@ -58,9 +57,15 @@ public class Matrix { public static final double DELTA = 1E-3; /** - * Error: matrix not square. + * Small value to increment diagonally of a matrix in order to avoid + * singularity before building the inverse. */ - public static final String ERR_NOTSQUARE = "All rows must have the same length."; + public static final double SINGULARITY_CHEAT = 1E-9; + + /** + * Error: matrix not rectangular. + */ + public static final String ERR_NOTRECTANGULAR = "All rows must have the same length."; /** * Error: matrix indexes incorrect @@ -112,8 +117,8 @@ public class Matrix { public Matrix(final int m, final int n, final double s) { this.columndimension = n; elements = new double[m][n]; - for (int i = 0; i < m; i++) { - for (int j = 0; j < n; j++) { + for(int i = 0; i < m; i++) { + for(int j = 0; j < n; j++) { elements[i][j] = s; } } @@ -128,31 +133,15 @@ public class Matrix { */ public Matrix(final double[][] elements) { columndimension = elements[0].length; - for (int i = 0; i < elements.length; i++) { - if (elements[i].length != columndimension) { - throw new IllegalArgumentException(ERR_NOTSQUARE); + for(int i = 0; i < elements.length; i++) { + if(elements[i].length != columndimension) { + throw new IllegalArgumentException(ERR_NOTRECTANGULAR); } } this.elements = elements; } /** - * Constructs a Matrix for a given array of arrays of {@link RationalNumber}s. - * - * @param q an array of arrays of RationalNumbers. q is not checked for - * consistency (i.e. whether all rows are of equal length) - */ - public Matrix(final RationalNumber[][] q) { - columndimension = q[0].length; - elements = new double[q.length][columndimension]; - for (int row = 0; row < q.length; row++) { - for (int col = 0; col < q[row].length; col++) { - elements[row][col] = q[row][col].doubleValue(); - } - } - } - - /** * Construct a matrix from a one-dimensional packed array * * @param values One-dimensional array of doubles, packed by columns (ala @@ -162,12 +151,12 @@ public class Matrix { */ public Matrix(final double values[], final int m) { columndimension = (m != 0 ? values.length / m : 0); - if (m * columndimension != values.length) { + if(m * columndimension != values.length) { throw new IllegalArgumentException("Array length must be a multiple of m."); } elements = new double[m][columndimension]; - for (int i = 0; i < m; i++) { - for (int j = 0; j < columndimension; j++) { + for(int i = 0; i < m; i++) { + for(int j = 0; j < columndimension; j++) { elements[i][j] = values[i + j * m]; } } @@ -193,9 +182,9 @@ public class Matrix { final int m = A.length; final int n = A[0].length; final Matrix X = new Matrix(m, n); - for (int i = 0; i < m; i++) { - if (A[i].length != n) { - throw new IllegalArgumentException(ERR_NOTSQUARE); + for(int i = 0; i < m; i++) { + if(A[i].length != n) { + throw new IllegalArgumentException(ERR_NOTRECTANGULAR); } System.arraycopy(A[i], 0, X.elements[i], 0, n); } @@ -210,7 +199,7 @@ public class Matrix { */ public static final Matrix unitMatrix(final int dim) { final double[][] e = new double[dim][dim]; - for (int i = 0; i < dim; i++) { + for(int i = 0; i < dim; i++) { e[i][i] = 1; } return new Matrix(e); @@ -236,8 +225,8 @@ public class Matrix { */ public static final Matrix random(final int m, final int n) { final Matrix A = new Matrix(m, n); - for (int i = 0; i < m; i++) { - for (int j = 0; j < n; j++) { + for(int i = 0; i < m; i++) { + for(int j = 0; j < n; j++) { A.elements[i][j] = Math.random(); } } @@ -253,7 +242,7 @@ public class Matrix { */ public static final Matrix identity(final int m, final int n) { final Matrix A = new Matrix(m, n); - for (int i = 0; i < Math.min(m, n); i++) { + for(int i = 0; i < Math.min(m, n); i++) { A.elements[i][i] = 1.0; } return A; @@ -268,7 +257,7 @@ public class Matrix { */ public static final Matrix diagonal(final double[] diagonal) { final Matrix result = new Matrix(diagonal.length, diagonal.length); - for (int i = 0; i < diagonal.length; i++) { + for(int i = 0; i < diagonal.length; i++) { result.elements[i][i] = diagonal[i]; } return result; @@ -283,7 +272,7 @@ public class Matrix { */ public static final Matrix diagonal(final Vector diagonal) { final Matrix result = new Matrix(diagonal.elements.length, diagonal.elements.length); - for (int i = 0; i < diagonal.elements.length; i++) { + for(int i = 0; i < diagonal.elements.length; i++) { result.elements[i][i] = diagonal.elements[i]; } return result; @@ -296,7 +285,7 @@ public class Matrix { */ public final Matrix copy() { final Matrix X = new Matrix(elements.length, columndimension); - for (int i = 0; i < elements.length; i++) { + for(int i = 0; i < elements.length; i++) { System.arraycopy(elements[i], 0, X.elements[i], 0, columndimension); } return X; @@ -326,7 +315,7 @@ public class Matrix { */ public final double[][] getArrayCopy() { final double[][] C = new double[elements.length][]; - for (int i = 0; i < elements.length; i++) { + for(int i = 0; i < elements.length; i++) { C[i] = elements[i].clone(); } return C; @@ -397,7 +386,7 @@ public class Matrix { */ public final double[] getRowPackedCopy() { double[] vals = new double[elements.length * columndimension]; - for (int i = 0; i < elements.length; i++) { + for(int i = 0; i < elements.length; i++) { System.arraycopy(elements[i], 0, vals, i * columndimension, columndimension); } return vals; @@ -410,8 +399,8 @@ public class Matrix { */ public final double[] getColumnPackedCopy() { final double[] vals = new double[elements.length * columndimension]; - for (int i = 0; i < elements.length; i++) { - for (int j = 0; j < columndimension; j++) { + for(int i = 0; i < elements.length; i++) { + for(int j = 0; j < columndimension; j++) { vals[i + j * elements.length] = elements[i][j]; } } @@ -431,10 +420,11 @@ public class Matrix { public final Matrix getMatrix(final int i0, final int i1, final int j0, final int j1) { final Matrix X = new Matrix(i1 - i0 + 1, j1 - j0 + 1); try { - for (int i = i0; i <= i1; i++) { + for(int i = i0; i <= i1; i++) { System.arraycopy(elements[i], j0, X.elements[i - i0], 0, j1 - j0 + 1); } - } catch (ArrayIndexOutOfBoundsException e) { + } + catch(ArrayIndexOutOfBoundsException e) { throw new ArrayIndexOutOfBoundsException(ERR_REINDEX); } return X; @@ -451,12 +441,13 @@ public class Matrix { public final Matrix getMatrix(final int[] r, final int[] c) { final Matrix X = new Matrix(r.length, c.length); try { - for (int i = 0; i < r.length; i++) { - for (int j = 0; j < c.length; j++) { + for(int i = 0; i < r.length; i++) { + for(int j = 0; j < c.length; j++) { X.elements[i][j] = elements[r[i]][c[j]]; } } - } catch (ArrayIndexOutOfBoundsException e) { + } + catch(ArrayIndexOutOfBoundsException e) { throw new ArrayIndexOutOfBoundsException(ERR_REINDEX); } return X; @@ -474,10 +465,11 @@ public class Matrix { public final Matrix getMatrix(final int[] r, final int j0, final int j1) { final Matrix X = new Matrix(r.length, j1 - j0 + 1); try { - for (int i = 0; i < r.length; i++) { + for(int i = 0; i < r.length; i++) { System.arraycopy(elements[r[i]], j0, X.elements[i], 0, j1 - j0 + 1); } - } catch (ArrayIndexOutOfBoundsException e) { + } + catch(ArrayIndexOutOfBoundsException e) { throw new ArrayIndexOutOfBoundsException(ERR_REINDEX); } return X; @@ -495,12 +487,13 @@ public class Matrix { public final Matrix getMatrix(final int i0, final int i1, final int[] c) { final Matrix X = new Matrix(i1 - i0 + 1, c.length); try { - for (int i = i0; i <= i1; i++) { - for (int j = 0; j < c.length; j++) { + for(int i = i0; i <= i1; i++) { + for(int j = 0; j < c.length; j++) { X.elements[i - i0][j] = elements[i][c[j]]; } } - } catch (ArrayIndexOutOfBoundsException e) { + } + catch(ArrayIndexOutOfBoundsException e) { throw new ArrayIndexOutOfBoundsException(ERR_REINDEX); } return X; @@ -518,10 +511,11 @@ public class Matrix { */ public final void setMatrix(final int i0, final int i1, final int j0, final int j1, final Matrix X) { try { - for (int i = i0; i <= i1; i++) { + for(int i = i0; i <= i1; i++) { System.arraycopy(X.elements[i - i0], 0, elements[i], j0, j1 - j0 + 1); } - } catch (ArrayIndexOutOfBoundsException e) { + } + catch(ArrayIndexOutOfBoundsException e) { throw new ArrayIndexOutOfBoundsException(ERR_REINDEX); } } @@ -536,12 +530,13 @@ public class Matrix { */ public final void setMatrix(final int[] r, final int[] c, final Matrix X) { try { - for (int i = 0; i < r.length; i++) { - for (int j = 0; j < c.length; j++) { + for(int i = 0; i < r.length; i++) { + for(int j = 0; j < c.length; j++) { elements[r[i]][c[j]] = X.elements[i][j]; } } - } catch (ArrayIndexOutOfBoundsException e) { + } + catch(ArrayIndexOutOfBoundsException e) { throw new ArrayIndexOutOfBoundsException(ERR_REINDEX); } } @@ -557,10 +552,11 @@ public class Matrix { */ public final void setMatrix(final int[] r, final int j0, final int j1, final Matrix X) { try { - for (int i = 0; i < r.length; i++) { + for(int i = 0; i < r.length; i++) { System.arraycopy(X.elements[i], 0, elements[r[i]], j0, j1 - j0 + 1); } - } catch (ArrayIndexOutOfBoundsException e) { + } + catch(ArrayIndexOutOfBoundsException e) { throw new ArrayIndexOutOfBoundsException(ERR_REINDEX); } } @@ -576,12 +572,13 @@ public class Matrix { */ public final void setMatrix(final int i0, final int i1, final int[] c, final Matrix X) { try { - for (int i = i0; i <= i1; i++) { - for (int j = 0; j < c.length; j++) { + for(int i = i0; i <= i1; i++) { + for(int j = 0; j < c.length; j++) { elements[i][c[j]] = X.elements[i - i0][j]; } } - } catch (ArrayIndexOutOfBoundsException e) { + } + catch(ArrayIndexOutOfBoundsException e) { throw new ArrayIndexOutOfBoundsException(ERR_REINDEX); } } @@ -604,7 +601,7 @@ public class Matrix { * @param row the value of the column to be set */ public final void setRow(final int j, final Vector row) { - if (row.elements.length != columndimension) { + if(row.elements.length != columndimension) { throw new IllegalArgumentException(ERR_MATRIX_DIMENSIONS); } System.arraycopy(row.elements, 0, elements[j], 0, columndimension); @@ -618,7 +615,7 @@ public class Matrix { */ public final Vector getCol(final int j) { final Vector v = new Vector(elements.length); - for (int i = 0; i < elements.length; i++) { + for(int i = 0; i < elements.length; i++) { v.elements[i] = elements[i][j]; } return v; @@ -631,10 +628,10 @@ public class Matrix { * @param column the value of the column to be set */ public final void setCol(final int j, final Vector column) { - if (column.elements.length != elements.length) { + if(column.elements.length != elements.length) { throw new IllegalArgumentException(ERR_MATRIX_DIMENSIONS); } - for (int i = 0; i < elements.length; i++) { + for(int i = 0; i < elements.length; i++) { elements[i][j] = column.elements[i]; } } @@ -646,8 +643,8 @@ public class Matrix { */ public final Matrix transpose() { final Matrix X = new Matrix(columndimension, elements.length); - for (int i = 0; i < elements.length; i++) { - for (int j = 0; j < columndimension; j++) { + for(int i = 0; i < elements.length; i++) { + for(int j = 0; j < columndimension; j++) { X.elements[j][i] = elements[i][j]; } } @@ -665,6 +662,26 @@ public class Matrix { } /** + * C = A + s + * + * @param s scalar value + * @return A + s in a new Matrix + */ + public final Matrix plus(final double s) { + return copy().plusEquals(s); + } + + /** + * C = A + s + * + * @param s scalar value + * @return A + s * E in a new Matrix + */ + public final Matrix plusDiagonal(final double s) { + return copy().plusDiagonalEquals(s); + } + + /** * C = A + s * B * * @param B another matrix @@ -683,8 +700,8 @@ public class Matrix { */ public final Matrix plusEquals(final Matrix B) { checkMatrixDimensions(B); - for (int i = 0; i < elements.length; i++) { - for (int j = 0; j < columndimension; j++) { + for(int i = 0; i < elements.length; i++) { + for(int j = 0; j < columndimension; j++) { elements[i][j] += B.elements[i][j]; } } @@ -692,6 +709,34 @@ public class Matrix { } /** + * A = A + s + * + * @param s constant to add to every cell + * @return A + s in this Matrix + */ + public final Matrix plusEquals(final double s) { + for(int i = 0; i < elements.length; i++) { + for(int j = 0; j < columndimension; j++) { + elements[i][j] += s; + } + } + return this; + } + + /** + * A = A + s + * + * @param s constant to add to the diagonal + * @return A + s in this Matrix + */ + public final Matrix plusDiagonalEquals(final double s) { + for(int i = 0; i < elements.length && i < columndimension; i++) { + elements[i][i] += s; + } + return this; + } + + /** * A = A + s * B * * @param B another matrix @@ -700,8 +745,8 @@ public class Matrix { */ public final Matrix plusTimesEquals(final Matrix B, final double s) { checkMatrixDimensions(B); - for (int i = 0; i < elements.length; i++) { - for (int j = 0; j < columndimension; j++) { + for(int i = 0; i < elements.length; i++) { + for(int j = 0; j < columndimension; j++) { elements[i][j] += s * B.elements[i][j]; } } @@ -737,8 +782,8 @@ public class Matrix { */ public final Matrix minusEquals(final Matrix B) { checkMatrixDimensions(B); - for (int i = 0; i < elements.length; i++) { - for (int j = 0; j < columndimension; j++) { + for(int i = 0; i < elements.length; i++) { + for(int j = 0; j < columndimension; j++) { elements[i][j] -= B.elements[i][j]; } } @@ -754,8 +799,8 @@ public class Matrix { */ public final Matrix minusTimesEquals(final Matrix B, final double s) { checkMatrixDimensions(B); - for (int i = 0; i < elements.length; i++) { - for (int j = 0; j < columndimension; j++) { + for(int i = 0; i < elements.length; i++) { + for(int j = 0; j < columndimension; j++) { elements[i][j] -= s * B.elements[i][j]; } } @@ -779,8 +824,8 @@ public class Matrix { * @return replace A by s*A */ public final Matrix timesEquals(final double s) { - for (int i = 0; i < elements.length; i++) { - for (int j = 0; j < columndimension; j++) { + for(int i = 0; i < elements.length; i++) { + for(int j = 0; j < columndimension; j++) { elements[i][j] *= s; } } @@ -796,22 +841,22 @@ public class Matrix { */ public final Matrix times(final Matrix B) { // Optimized implementation, exploiting the storage layout - if (B.elements.length != this.columndimension) { + if(B.elements.length != this.columndimension) { throw new IllegalArgumentException(ERR_MATRIX_INNERDIM); } final Matrix X = new Matrix(this.elements.length, B.columndimension); // Optimized ala Jama. jik order. final double[] Bcolj = new double[this.columndimension]; - for (int j = 0; j < X.columndimension; j++) { + for(int j = 0; j < X.columndimension; j++) { // Make a linear copy of column j from B - for (int k = 0; k < this.columndimension; k++) { + for(int k = 0; k < this.columndimension; k++) { Bcolj[k] = B.elements[k][j]; } // multiply it with each row from A - for (int i = 0; i < this.elements.length; i++) { + for(int i = 0; i < this.elements.length; i++) { final double[] Arowi = this.elements[i]; double s = 0; - for (int k = 0; k < this.columndimension; k++) { + for(int k = 0; k < this.columndimension; k++) { s += Arowi[k] * Bcolj[k]; } X.elements[i][j] = s; @@ -828,15 +873,15 @@ public class Matrix { * @throws IllegalArgumentException Matrix inner dimensions must agree. */ public final Vector times(final Vector B) { - if (B.elements.length != this.columndimension) { + if(B.elements.length != this.columndimension) { throw new IllegalArgumentException(ERR_MATRIX_INNERDIM); } final Vector X = new Vector(this.elements.length); // multiply it with each row from A - for (int i = 0; i < this.elements.length; i++) { + for(int i = 0; i < this.elements.length; i++) { final double[] Arowi = this.elements[i]; double s = 0; - for (int k = 0; k < this.columndimension; k++) { + for(int k = 0; k < this.columndimension; k++) { s += Arowi[k] * B.elements[k]; } X.elements[i] = s; @@ -852,14 +897,14 @@ public class Matrix { * @throws IllegalArgumentException Matrix inner dimensions must agree. */ public final Vector transposeTimes(final Vector B) { - if (B.elements.length != elements.length) { + if(B.elements.length != elements.length) { throw new IllegalArgumentException(ERR_MATRIX_INNERDIM); } final Vector X = new Vector(this.columndimension); // multiply it with each row from A - for (int i = 0; i < this.columndimension; i++) { + for(int i = 0; i < this.columndimension; i++) { double s = 0; - for (int k = 0; k < elements.length; k++) { + for(int k = 0; k < elements.length; k++) { s += elements[k][i] * B.elements[k]; } X.elements[i] = s; @@ -875,20 +920,20 @@ public class Matrix { * @throws IllegalArgumentException Matrix inner dimensions must agree. */ public final Matrix transposeTimes(final Matrix B) { - if (B.elements.length != elements.length) { + if(B.elements.length != elements.length) { throw new IllegalArgumentException(ERR_MATRIX_INNERDIM); } final Matrix X = new Matrix(this.columndimension, B.columndimension); final double[] Bcolj = new double[elements.length]; - for (int j = 0; j < X.columndimension; j++) { + for(int j = 0; j < X.columndimension; j++) { // Make a linear copy of column j from B - for (int k = 0; k < elements.length; k++) { + for(int k = 0; k < elements.length; k++) { Bcolj[k] = B.elements[k][j]; } // multiply it with each row from A - for (int i = 0; i < this.columndimension; i++) { + for(int i = 0; i < this.columndimension; i++) { double s = 0; - for (int k = 0; k < elements.length; k++) { + for(int k = 0; k < elements.length; k++) { s += elements[k][i] * Bcolj[k]; } X.elements[i][j] = s; @@ -905,17 +950,17 @@ public class Matrix { * @throws IllegalArgumentException Matrix inner dimensions must agree. */ public final Matrix timesTranspose(final Matrix B) { - if (B.columndimension != this.columndimension) { + if(B.columndimension != this.columndimension) { throw new IllegalArgumentException(ERR_MATRIX_INNERDIM); } final Matrix X = new Matrix(this.elements.length, B.elements.length); - for (int j = 0; j < X.elements.length; j++) { + for(int j = 0; j < X.elements.length; j++) { final double[] Browj = B.elements[j]; // multiply it with each row from A - for (int i = 0; i < this.elements.length; i++) { + for(int i = 0; i < this.elements.length; i++) { final double[] Arowi = this.elements[i]; double s = 0; - for (int k = 0; k < this.columndimension; k++) { + for(int k = 0; k < this.columndimension; k++) { s += Arowi[k] * Browj[k]; } X.elements[i][j] = s; @@ -933,23 +978,23 @@ public class Matrix { */ public final Matrix transposeTimesTranspose(Matrix B) { // Optimized implementation, exploiting the storage layout - if (this.elements.length != B.columndimension) { + if(this.elements.length != B.columndimension) { throw new IllegalArgumentException("Matrix inner dimensions must agree: " + getRowDimensionality() + "," + getColumnDimensionality() + " * " + B.getRowDimensionality() + "," + B.getColumnDimensionality()); } final Matrix X = new Matrix(this.columndimension, B.elements.length); // Optimized ala Jama. jik order. final double[] Acolj = new double[this.elements.length]; - for (int j = 0; j < X.elements.length; j++) { + for(int j = 0; j < X.elements.length; j++) { // Make a linear copy of column j from B - for (int k = 0; k < this.elements.length; k++) { + for(int k = 0; k < this.elements.length; k++) { Acolj[k] = this.elements[k][j]; } final double[] Xrow = X.elements[j]; // multiply it with each row from A - for (int i = 0; i < B.elements.length; i++) { + for(int i = 0; i < B.elements.length; i++) { final double[] Browi = B.elements[i]; double s = 0; - for (int k = 0; k < B.columndimension; k++) { + for(int k = 0; k < B.columndimension; k++) { s += Browi[k] * Acolj[k]; } Xrow[i] = s; @@ -978,6 +1023,19 @@ public class Matrix { } /** + * Matrix inverse for square matrixes. + * + * @return inverse(A), or inverse(A + epsilon E) if singular. + */ + public final Matrix robustInverse() { + LUDecomposition d = new LUDecomposition(this); + if(!d.isNonsingular()) { + d = new LUDecomposition(plusDiagonal(SINGULARITY_CHEAT).getArrayRef(), elements.length, columndimension); + } + return d.solve(identity(elements.length, elements.length)); + } + + /** * Matrix determinant * * @return determinant @@ -1011,7 +1069,7 @@ public class Matrix { */ public final double trace() { double t = 0; - for (int i = 0; i < Math.min(elements.length, columndimension); i++) { + for(int i = 0; i < Math.min(elements.length, columndimension); i++) { t += elements[i][i]; } return t; @@ -1024,9 +1082,9 @@ public class Matrix { */ public final double norm1() { double f = 0; - for (int j = 0; j < columndimension; j++) { + for(int j = 0; j < columndimension; j++) { double s = 0; - for (int i = 0; i < elements.length; i++) { + for(int i = 0; i < elements.length; i++) { s += Math.abs(elements[i][j]); } f = Math.max(f, s); @@ -1050,9 +1108,9 @@ public class Matrix { */ public final double normInf() { double f = 0; - for (int i = 0; i < elements.length; i++) { + for(int i = 0; i < elements.length; i++) { double s = 0; - for (int j = 0; j < columndimension; j++) { + for(int j = 0; j < columndimension; j++) { s += Math.abs(elements[i][j]); } f = Math.max(f, s); @@ -1067,8 +1125,8 @@ public class Matrix { */ public final double normF() { double f = 0; - for (int i = 0; i < elements.length; i++) { - for (int j = 0; j < columndimension; j++) { + for(int i = 0; i < elements.length; i++) { + for(int j = 0; j < columndimension; j++) { f = MathUtil.fastHypot(f, elements[i][j]); } } @@ -1079,14 +1137,14 @@ public class Matrix { * Normalizes the columns of this matrix to length of 1.0. */ public final void normalizeColumns() { - for (int col = 0; col < columndimension; col++) { + for(int col = 0; col < columndimension; col++) { double norm = 0.0; - for (int row = 0; row < elements.length; row++) { + for(int row = 0; row < elements.length; row++) { norm = norm + (elements[row][col] * elements[row][col]); } norm = Math.sqrt(norm); - if (norm != 0) { - for (int row = 0; row < elements.length; row++) { + if(norm != 0) { + for(int row = 0; row < elements.length; row++) { elements[row][col] /= norm; } } @@ -1105,13 +1163,13 @@ public class Matrix { * columns of this matrix */ public final boolean linearlyIndependent(final Matrix columnMatrix) { - if (columnMatrix.columndimension != 1) { + if(columnMatrix.columndimension != 1) { throw new IllegalArgumentException("a.getColumnDimension() != 1"); } - if (this.elements.length != columnMatrix.elements.length) { + if(this.elements.length != columnMatrix.elements.length) { throw new IllegalArgumentException(ERR_MATRIX_DIMENSIONS); } - if (this.columndimension + columnMatrix.columndimension > this.elements.length) { + if(this.columndimension + columnMatrix.columndimension > this.elements.length) { return false; } final StringBuilder msg = LoggingConfiguration.DEBUG ? new StringBuilder() : null; @@ -1119,20 +1177,22 @@ public class Matrix { final double[][] a = new double[columndimension + 1][elements.length - 1]; final double[] b = new double[columndimension + 1]; - for (int i = 0; i < a.length; i++) { - for (int j = 0; j < a[i].length; j++) { - if (i < columndimension) { + for(int i = 0; i < a.length; i++) { + for(int j = 0; j < a[i].length; j++) { + if(i < columndimension) { a[i][j] = elements[j][i]; - } else { + } + else { a[i][j] = columnMatrix.elements[j][0]; } } } - for (int i = 0; i < b.length; i++) { - if (i < columndimension) { + for(int i = 0; i < b.length; i++) { + if(i < columndimension) { b[i] = elements[elements.length - 1][i]; - } else { + } + else { b[i] = columnMatrix.elements[i][0]; } } @@ -1143,7 +1203,7 @@ public class Matrix { final double[][] coefficients = les.getCoefficents(); final double[] rhs = les.getRHS(); - if (msg != null) { + if(msg != null) { msg.append("\na' ").append(FormatUtil.format(this.getArrayRef())); msg.append("\nb' ").append(FormatUtil.format(columnMatrix.getColumnPackedCopy())); @@ -1152,20 +1212,20 @@ public class Matrix { msg.append("\nleq ").append(les.equationsToString(4)); } - for (int i = 0; i < coefficients.length; i++) { + for(int i = 0; i < coefficients.length; i++) { boolean allCoefficientsZero = true; - for (int j = 0; j < coefficients[i].length; j++) { + for(int j = 0; j < coefficients[i].length; j++) { final double value = coefficients[i][j]; - if (Math.abs(value) > DELTA) { + if(Math.abs(value) > DELTA) { allCoefficientsZero = false; break; } } // allCoefficients=0 && rhs=0 -> linearly dependent - if (allCoefficientsZero) { + if(allCoefficientsZero) { final double value = rhs[i]; - if (Math.abs(value) < DELTA) { - if (msg != null) { + if(Math.abs(value) < DELTA) { + if(msg != null) { msg.append("\nvalue ").append(value).append('[').append(i).append(']'); msg.append("\nlinearly independent ").append(false); Logger.getLogger(this.getClass().getName()).fine(msg.toString()); @@ -1175,7 +1235,7 @@ public class Matrix { } } - if (msg != null) { + if(msg != null) { msg.append("\nlinearly independent ").append(true); Logger.getLogger(this.getClass().getName()).fine(msg.toString()); } @@ -1183,128 +1243,17 @@ public class Matrix { } /** - * Returns a matrix derived by Gauss-Jordan-elimination using RationalNumbers - * for the transformations. - * - * @return a matrix derived by Gauss-Jordan-elimination using RationalNumbers - * for the transformations - */ - public final Matrix exactGaussJordanElimination() { - final RationalNumber[][] gauss = exactGaussElimination(); - - // reduced form - for (int row = gauss.length - 1; row > 0; row--) { - int firstCol = -1; - for (int col = 0; col < gauss[row].length && firstCol == -1; col++) { - // if(gauss.get(row, col) != 0.0) // i.e. == 1 - if (gauss[row][col].equals(RationalNumber.ONE)) { - firstCol = col; - } - } - if (firstCol > -1) { - for (int currentRow = row - 1; currentRow >= 0; currentRow--) { - RationalNumber multiplier = gauss[currentRow][firstCol].copy(); - for (int col = firstCol; col < gauss[currentRow].length; col++) { - RationalNumber subtrahent = gauss[row][col].times(multiplier); - gauss[currentRow][col] = gauss[currentRow][col].minus(subtrahent); - } - } - } - } - return new Matrix(gauss); - } - - /** - * Perform an exact Gauss-elimination of this Matrix using RationalNumbers to - * yield highest possible accuracy. - * - * @return an array of arrays of RationalNumbers representing the - * Gauss-eliminated form of this Matrix - */ - private final RationalNumber[][] exactGaussElimination() { - final RationalNumber[][] gauss = new RationalNumber[elements.length][this.columndimension]; - for (int row = 0; row < elements.length; row++) { - for (int col = 0; col < this.columndimension; col++) { - gauss[row][col] = new RationalNumber(elements[row][col]); - } - } - return exactGaussElimination(gauss); - } - - /** - * Perform recursive Gauss-elimination on the given matrix of RationalNumbers. - * - * @param gauss an array of arrays of RationalNumber - * @return recursive derived Gauss-elimination-form of the given matrix of - * RationalNumbers - */ - private static final RationalNumber[][] exactGaussElimination(final RationalNumber[][] gauss) { - int firstCol = -1; - int firstRow = -1; - - // 1. find first column unequal to zero - for (int col = 0; col < gauss[0].length && firstCol == -1; col++) { - for (int row = 0; row < gauss.length && firstCol == -1; row++) { - // if(gauss.get(row, col) != 0.0) - if (!gauss[row][col].equals(RationalNumber.ZERO)) { - firstCol = col; - firstRow = row; - } - } - } - - // 2. set row as first row - if (firstCol != -1) { - if (firstRow != 0) { - final RationalNumber[] row = new RationalNumber[gauss[firstRow].length]; - System.arraycopy(gauss[firstRow], 0, row, 0, gauss[firstRow].length); - System.arraycopy(gauss[0], 0, gauss[firstRow], 0, gauss[firstRow].length); - System.arraycopy(row, 0, gauss[0], 0, row.length); - } - - // 3. create leading 1 - if (!gauss[0][firstCol].equals(RationalNumber.ONE)) { - final RationalNumber inverse = gauss[0][firstCol].multiplicativeInverse(); - for (int col = 0; col < gauss[0].length; col++) { - gauss[0][col] = gauss[0][col].times(inverse); - } - } - - // 4. eliminate values unequal to zero below leading 1 - for (int row = 1; row < gauss.length; row++) { - final RationalNumber multiplier = gauss[row][firstCol].copy(); - // if(multiplier != 0.0) - if (!multiplier.equals(RationalNumber.ZERO)) { - for (int col = firstCol; col < gauss[row].length; col++) { - final RationalNumber subtrahent = gauss[0][col].times(multiplier); - gauss[row][col] = gauss[row][col].minus(subtrahent); - } - } - } - - // 5. recursion - if (gauss.length > 1) { - final RationalNumber[][] subMatrix = new RationalNumber[gauss.length - 1][gauss[1].length]; - System.arraycopy(gauss, 1, subMatrix, 0, gauss.length - 1); - final RationalNumber[][] eliminatedSubMatrix = exactGaussElimination(subMatrix); - System.arraycopy(eliminatedSubMatrix, 0, gauss, 1, eliminatedSubMatrix.length); - } - } - return gauss; - } - - /** * Returns true, if this matrix is symmetric, false otherwise. * * @return true, if this matrix is symmetric, false otherwise */ public final boolean isSymmetric() { - if (elements.length != columndimension) { + if(elements.length != columndimension) { return false; } - for (int i = 0; i < elements.length; i++) { - for (int j = i + 1; j < columndimension; j++) { - if (elements[i][j] != elements[j][i]) { + for(int i = 0; i < elements.length; i++) { + for(int j = i + 1; j < columndimension; j++) { + if(elements[i][j] != elements[j][i]) { return false; } } @@ -1321,16 +1270,17 @@ public class Matrix { public final Matrix completeBasis() { Matrix basis = copy(); Matrix result = null; - for (int i = 0; i < elements.length; i++) { + for(int i = 0; i < elements.length; i++) { final Matrix e_i = new Matrix(elements.length, 1); e_i.elements[0][i] = 1.0; final boolean li = basis.linearlyIndependent(e_i); // TODO: efficiency - appendColumns is expensive. - if (li) { - if (result == null) { + if(li) { + if(result == null) { result = e_i.copy(); - } else { + } + else { result = result.appendColumns(e_i); } basis = basis.appendColumns(e_i); @@ -1348,16 +1298,17 @@ public class Matrix { public final Matrix completeToOrthonormalBasis() { Matrix basis = copy(); Matrix result = null; - for (int i = 0; i < elements.length; i++) { + for(int i = 0; i < elements.length; i++) { final Matrix e_i = new Matrix(elements.length, 1); e_i.elements[i][0] = 1.0; final boolean li = basis.linearlyIndependent(e_i); // TODO: efficiency - appendColumns is expensive. - if (li) { - if (result == null) { + if(li) { + if(result == null) { result = e_i.copy(); - } else { + } + else { result = result.appendColumns(e_i); } basis = basis.appendColumns(e_i); @@ -1374,16 +1325,17 @@ public class Matrix { * @return the new matrix with the appended columns */ public final Matrix appendColumns(final Matrix columns) { - if (elements.length != columns.elements.length) { + if(elements.length != columns.elements.length) { throw new IllegalArgumentException(ERR_MATRIX_DIMENSIONS); } final Matrix result = new Matrix(elements.length, columndimension + columns.columndimension); - for (int i = 0; i < result.columndimension; i++) { + for(int i = 0; i < result.columndimension; i++) { // FIXME: optimize - excess copying! - if (i < columndimension) { + if(i < columndimension) { result.setCol(i, getCol(i)); - } else { + } + else { result.setCol(i, columns.getCol(i - columndimension)); } } @@ -1399,10 +1351,10 @@ public class Matrix { Matrix v = copy(); // FIXME: optimize - excess copying! - for (int i = 1; i < columndimension; i++) { + for(int i = 1; i < columndimension; i++) { final Vector u_i = getCol(i); final Vector sum = new Vector(elements.length); - for (int j = 0; j < i; j++) { + for(int j = 0; j < i; j++) { final Vector v_j = v.getCol(j); double scalar = u_i.transposeTimes(v_j) / v_j.transposeTimes(v_j); sum.plusTimesEquals(v_j, scalar); @@ -1425,7 +1377,7 @@ public class Matrix { */ public final Matrix cheatToAvoidSingularity(final double constant) { final Matrix a = this.copy(); - for (int i = 0; i < a.columndimension && i < a.elements.length; i++) { + for(int i = 0; i < a.columndimension && i < a.elements.length; i++) { // if(a.get(i, i) < constant) { a.elements[i][i] += constant; @@ -1460,40 +1412,40 @@ public class Matrix { TDoubleArrayList v = new TDoubleArrayList(); // Ignore initial empty lines - while (tokenizer.nextToken() == StreamTokenizer.TT_EOL) { + while(tokenizer.nextToken() == StreamTokenizer.TT_EOL) { // ignore initial empty lines } - if (tokenizer.ttype == StreamTokenizer.TT_EOF) { + if(tokenizer.ttype == StreamTokenizer.TT_EOF) { throw new java.io.IOException("Unexpected EOF on matrix read."); } do { v.add(FormatUtil.parseDouble(tokenizer.sval)); // Read & store 1st // row. } - while (tokenizer.nextToken() == StreamTokenizer.TT_WORD); + while(tokenizer.nextToken() == StreamTokenizer.TT_WORD); int n = v.size(); // Now we've got the number of columns! double row[] = v.toArray(); ArrayList<double[]> rowV = new ArrayList<>(); rowV.add(row); // Start storing rows instead of columns. - while (tokenizer.nextToken() == StreamTokenizer.TT_WORD) { + while(tokenizer.nextToken() == StreamTokenizer.TT_WORD) { // While non-empty lines rowV.add(row = new double[n]); int j = 0; do { - if (j >= n) { + if(j >= n) { throw new java.io.IOException("Row " + v.size() + " is too long."); } row[j++] = FormatUtil.parseDouble(tokenizer.sval); } - while (tokenizer.nextToken() == StreamTokenizer.TT_WORD); - if (j < n) { + while(tokenizer.nextToken() == StreamTokenizer.TT_WORD); + if(j < n) { throw new java.io.IOException("Row " + v.size() + " is too short."); } } int m = rowV.size(); // Now we've got the number of rows. double[][] A = new double[m][]; - for (int i = 0; i < m; i++) { + for(int i = 0; i < m; i++) { A[i] = rowV.get(i); } return new Matrix(A); @@ -1503,7 +1455,7 @@ public class Matrix { * Check if size(A) == size(B) */ protected void checkMatrixDimensions(Matrix B) { - if (B.getRowDimensionality() != getRowDimensionality() || B.getColumnDimensionality() != getColumnDimensionality()) { + if(B.getRowDimensionality() != getRowDimensionality() || B.getColumnDimensionality() != getColumnDimensionality()) { throw new IllegalArgumentException("Matrix dimensions must agree."); } } @@ -1520,25 +1472,25 @@ public class Matrix { @Override public boolean equals(Object obj) { - if (this == obj) { + if(this == obj) { return true; } - if (obj == null) { + if(obj == null) { return false; } - if (getClass() != obj.getClass()) { + if(getClass() != obj.getClass()) { return false; } final Matrix other = (Matrix) obj; - if (this.elements.length != other.elements.length) { + if(this.elements.length != other.elements.length) { return false; } - if (this.columndimension != other.columndimension) { + if(this.columndimension != other.columndimension) { return false; } - for (int i = 0; i < this.elements.length; i++) { - for (int j = 0; j < this.columndimension; j++) { - if (this.elements[i][j] != other.elements[i][j]) { + for(int i = 0; i < this.elements.length; i++) { + for(int j = 0; j < this.columndimension; j++) { + if(this.elements[i][j] != other.elements[i][j]) { return false; } } @@ -1555,25 +1507,25 @@ public class Matrix { * @return true if delta smaller than maximum */ public boolean almostEquals(Object obj, double maxdelta) { - if (this == obj) { + if(this == obj) { return true; } - if (obj == null) { + if(obj == null) { return false; } - if (getClass() != obj.getClass()) { + if(getClass() != obj.getClass()) { return false; } final Matrix other = (Matrix) obj; - if (this.elements.length != other.elements.length) { + if(this.elements.length != other.elements.length) { return false; } - if (this.columndimension != other.columndimension) { + if(this.columndimension != other.columndimension) { return false; } - for (int i = 0; i < this.elements.length; i++) { - for (int j = 0; j < this.columndimension; j++) { - if (Math.abs(this.elements[i][j] - other.elements[i][j]) > maxdelta) { + for(int i = 0; i < this.elements.length; i++) { + for(int j = 0; j < this.columndimension; j++) { + if(Math.abs(this.elements[i][j] - other.elements[i][j]) > maxdelta) { return false; } } diff --git a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/ProjectedCentroid.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/ProjectedCentroid.java index a0a1e011..5622daf3 100644 --- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/ProjectedCentroid.java +++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/ProjectedCentroid.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -23,13 +23,12 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra; along with this program. If not, see <http://www.gnu.org/licenses/>. */ -import java.util.BitSet; - import de.lmu.ifi.dbs.elki.data.NumberVector; import de.lmu.ifi.dbs.elki.database.ids.DBIDIter; import de.lmu.ifi.dbs.elki.database.ids.DBIDs; import de.lmu.ifi.dbs.elki.database.relation.Relation; import de.lmu.ifi.dbs.elki.database.relation.RelationUtil; +import de.lmu.ifi.dbs.elki.utilities.BitsUtil; /** * Centroid only using a subset of dimensions. @@ -46,7 +45,7 @@ public class ProjectedCentroid extends Centroid { /** * The selected dimensions. */ - private BitSet dims; + private long[] dims; /** * Constructor for updating use. @@ -54,10 +53,9 @@ public class ProjectedCentroid extends Centroid { * @param dims Dimensions to use (indexed with 0) * @param dim Full dimensionality */ - public ProjectedCentroid(BitSet dims, int dim) { + public ProjectedCentroid(long[] dims, int dim) { super(dim); this.dims = dims; - assert (dims.length() <= dim) : (dims.length() + " > " + dim + " ?!?"); } /** @@ -69,7 +67,7 @@ public class ProjectedCentroid extends Centroid { public void put(double[] val) { assert (val.length == elements.length); wsum += 1.0; - for(int i = dims.nextSetBit(0); i >= 0; i = dims.nextSetBit(i + 1)) { + for(int i = BitsUtil.nextSetBit(dims, 0); i >= 0; i = BitsUtil.nextSetBit(dims, i + 1)) { final double delta = val[i] - elements[i]; elements[i] += delta / wsum; } @@ -84,11 +82,11 @@ public class ProjectedCentroid extends Centroid { @Override public void put(double[] val, double weight) { assert (val.length == elements.length); - if (weight == 0) { + if(weight == 0) { return; // Skip zero weights. } final double nwsum = weight + wsum; - for(int i = dims.nextSetBit(0); i >= 0; i = dims.nextSetBit(i + 1)) { + for(int i = BitsUtil.nextSetBit(dims, 0); i >= 0; i = BitsUtil.nextSetBit(dims, i + 1)) { final double delta = val[i] - elements[i]; final double rval = delta * weight / nwsum; elements[i] += rval; @@ -102,10 +100,10 @@ public class ProjectedCentroid extends Centroid { * @param val Value */ @Override - public void put(NumberVector<?> val) { + public void put(NumberVector val) { assert (val.getDimensionality() == elements.length); wsum += 1.0; - for(int i = dims.nextSetBit(0); i >= 0; i = dims.nextSetBit(i + 1)) { + for(int i = BitsUtil.nextSetBit(dims, 0); i >= 0; i = BitsUtil.nextSetBit(dims, i + 1)) { final double delta = val.doubleValue(i) - elements[i]; elements[i] += delta / wsum; } @@ -118,13 +116,13 @@ public class ProjectedCentroid extends Centroid { * @param weight weight */ @Override - public void put(NumberVector<?> val, double weight) { + public void put(NumberVector val, double weight) { assert (val.getDimensionality() == elements.length); - if (weight == 0) { + if(weight == 0) { return; // Skip zero weights. } final double nwsum = weight + wsum; - for(int i = dims.nextSetBit(0); i >= 0; i = dims.nextSetBit(i + 1)) { + for(int i = BitsUtil.nextSetBit(dims, 0); i >= 0; i = BitsUtil.nextSetBit(dims, i + 1)) { final double delta = val.doubleValue(i) - elements[i]; final double rval = delta * weight / nwsum; elements[i] += rval; @@ -139,9 +137,8 @@ public class ProjectedCentroid extends Centroid { * @param relation Relation to process * @return Centroid */ - public static ProjectedCentroid make(BitSet dims, Relation<? extends NumberVector<?>> relation) { + public static ProjectedCentroid make(long[] dims, Relation<? extends NumberVector> relation) { ProjectedCentroid c = new ProjectedCentroid(dims, RelationUtil.dimensionality(relation)); - assert (dims.size() <= RelationUtil.dimensionality(relation)); for(DBIDIter iditer = relation.iterDBIDs(); iditer.valid(); iditer.advance()) { c.put(relation.get(iditer)); } @@ -156,9 +153,8 @@ public class ProjectedCentroid extends Centroid { * @param ids IDs to process * @return Centroid */ - public static ProjectedCentroid make(BitSet dims, Relation<? extends NumberVector<?>> relation, DBIDs ids) { + public static ProjectedCentroid make(long[] dims, Relation<? extends NumberVector> relation, DBIDs ids) { ProjectedCentroid c = new ProjectedCentroid(dims, RelationUtil.dimensionality(relation)); - assert (dims.length() <= RelationUtil.dimensionality(relation)); for(DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) { c.put(relation.get(iter)); } diff --git a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/ProjectionResult.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/ProjectionResult.java index 901450c3..523908f3 100644 --- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/ProjectionResult.java +++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/ProjectionResult.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/QRDecomposition.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/QRDecomposition.java index 4b30bf5d..6732f8f8 100644 --- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/QRDecomposition.java +++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/QRDecomposition.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/SingularValueDecomposition.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/SingularValueDecomposition.java index dc94754a..0697acaa 100644 --- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/SingularValueDecomposition.java +++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/SingularValueDecomposition.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/SortedEigenPairs.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/SortedEigenPairs.java index 185ae612..61340433 100644 --- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/SortedEigenPairs.java +++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/SortedEigenPairs.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/SubspaceProjectionResult.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/SubspaceProjectionResult.java deleted file mode 100644 index 4e03bc78..00000000 --- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/SubspaceProjectionResult.java +++ /dev/null @@ -1,66 +0,0 @@ -package de.lmu.ifi.dbs.elki.math.linearalgebra; - -/* - This file is part of ELKI: - Environment for Developing KDD-Applications Supported by Index-Structures - - Copyright (C) 2013 - Ludwig-Maximilians-Universität München - Lehr- und Forschungseinheit für Datenbanksysteme - ELKI Development Team - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero 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 Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - - -/** - * Simple class wrapping the result of a subspace projection. - * - * @author Erich Schubert - * - * @apiviz.composedOf Matrix - */ -public class SubspaceProjectionResult implements ProjectionResult { - /** - * The correlation dimensionality - */ - private int correlationDimensionality; - - /** - * The similarity matrix - */ - private Matrix similarityMat; - - /** - * Constructor. - * - * @param correlationDimensionality dimensionality - * @param similarityMat projection matrix - */ - public SubspaceProjectionResult(int correlationDimensionality, Matrix similarityMat) { - super(); - this.correlationDimensionality = correlationDimensionality; - this.similarityMat = similarityMat; - } - - @Override - public int getCorrelationDimension() { - return correlationDimensionality; - } - - @Override - public Matrix similarityMatrix() { - return similarityMat; - } -} diff --git a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/VMath.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/VMath.java index 6b8cdc31..fc514a65 100644 --- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/VMath.java +++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/VMath.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -75,16 +75,17 @@ public final class VMath { */ public static final double[] randomNormalizedVector(final int dimensionality) { final double[] v = new double[dimensionality]; - for (int i = 0; i < dimensionality; i++) { + for(int i = 0; i < dimensionality; i++) { v[i] = Math.random(); } double norm = euclideanLength(v); - if (norm != 0) { - for (int row = 0; row < v.length; row++) { + if(norm != 0) { + for(int row = 0; row < v.length; row++) { v[row] /= norm; } return v; - } else { + } + else { return randomNormalizedVector(dimensionality); } } @@ -120,7 +121,7 @@ public final class VMath { */ public static final double[][] transpose(final double[] v) { double[][] re = new double[v.length][1]; - for (int i = 0; i < v.length; i++) { + for(int i = 0; i < v.length; i++) { re[i][0] = v[i]; } return re; @@ -136,7 +137,7 @@ public final class VMath { public static final double[] plus(final double[] v1, final double[] v2) { assert (v1.length == v2.length) : ERR_VEC_DIMENSIONS; final double[] result = new double[v1.length]; - for (int i = 0; i < result.length; i++) { + for(int i = 0; i < result.length; i++) { result[i] = v1[i] + v2[i]; } return result; @@ -153,7 +154,7 @@ public final class VMath { public static final double[] plusTimes(final double[] v1, final double[] v2, final double s2) { assert (v1.length == v2.length) : ERR_VEC_DIMENSIONS; final double[] result = new double[v1.length]; - for (int i = 0; i < result.length; i++) { + for(int i = 0; i < result.length; i++) { result[i] = v1[i] + v2[i] * s2; } return result; @@ -170,7 +171,7 @@ public final class VMath { public static final double[] timesPlus(final double[] v1, final double s1, final double[] v2) { assert (v1.length == v2.length) : ERR_VEC_DIMENSIONS; final double[] result = new double[v1.length]; - for (int i = 0; i < result.length; i++) { + for(int i = 0; i < result.length; i++) { result[i] = v1[i] * s1 + v2[i]; } return result; @@ -188,7 +189,7 @@ public final class VMath { public static final double[] timesPlusTimes(final double[] v1, final double s1, final double[] v2, final double s2) { assert (v1.length == v2.length) : ERR_VEC_DIMENSIONS; final double[] result = new double[v1.length]; - for (int i = 0; i < result.length; i++) { + for(int i = 0; i < result.length; i++) { result[i] = v1[i] * s1 + v2[i] * s2; } return result; @@ -203,7 +204,7 @@ public final class VMath { */ public static final double[] plusEquals(final double[] v1, final double[] v2) { assert (v1.length == v2.length) : ERR_VEC_DIMENSIONS; - for (int i = 0; i < v1.length; i++) { + for(int i = 0; i < v1.length; i++) { v1[i] += v2[i]; } return v1; @@ -219,7 +220,7 @@ public final class VMath { */ public static final double[] plusTimesEquals(final double[] v1, final double[] v2, final double s2) { assert (v1.length == v2.length) : ERR_VEC_DIMENSIONS; - for (int i = 0; i < v1.length; i++) { + for(int i = 0; i < v1.length; i++) { v1[i] += s2 * v2[i]; } return v1; @@ -235,7 +236,7 @@ public final class VMath { */ public static final double[] timesPlusEquals(final double[] v1, final double s1, final double[] v2) { assert (v1.length == v2.length) : ERR_VEC_DIMENSIONS; - for (int i = 0; i < v1.length; i++) { + for(int i = 0; i < v1.length; i++) { v1[i] = v1[i] * s1 + v2[i]; } return v1; @@ -252,7 +253,7 @@ public final class VMath { */ public static final double[] timesPlusTimesEquals(final double[] v1, final double s1, final double[] v2, final double s2) { assert (v1.length == v2.length) : ERR_VEC_DIMENSIONS; - for (int i = 0; i < v1.length; i++) { + for(int i = 0; i < v1.length; i++) { v1[i] = v1[i] * s1 + v2[i] * s2; } return v1; @@ -267,7 +268,7 @@ public final class VMath { */ public static final double[] plus(final double[] v1, final double d) { final double[] result = new double[v1.length]; - for (int i = 0; i < result.length; i++) { + for(int i = 0; i < result.length; i++) { result[i] = v1[i] + d; } return result; @@ -281,7 +282,7 @@ public final class VMath { * @return Modified vector */ public static final double[] plusEquals(final double[] v1, final double d) { - for (int i = 0; i < v1.length; i++) { + for(int i = 0; i < v1.length; i++) { v1[i] += d; } return v1; @@ -296,7 +297,7 @@ public final class VMath { */ public static final double[] minus(final double[] v1, final double[] v2) { final double[] sub = new double[v1.length]; - for (int i = 0; i < v1.length; i++) { + for(int i = 0; i < v1.length; i++) { sub[i] = v1[i] - v2[i]; } return sub; @@ -312,7 +313,7 @@ public final class VMath { */ public static final double[] minusTimes(final double[] v1, final double[] v2, final double s2) { final double[] sub = new double[v1.length]; - for (int i = 0; i < v1.length; i++) { + for(int i = 0; i < v1.length; i++) { sub[i] = v1[i] - v2[i] * s2; } return sub; @@ -328,7 +329,7 @@ public final class VMath { */ public static final double[] timesMinus(final double[] v1, final double s1, final double[] v2) { final double[] sub = new double[v1.length]; - for (int i = 0; i < v1.length; i++) { + for(int i = 0; i < v1.length; i++) { sub[i] = v1[i] * s1 - v2[i]; } return sub; @@ -345,7 +346,7 @@ public final class VMath { */ public static final double[] timesMinusTimes(final double[] v1, final double s1, final double[] v2, final double s2) { final double[] sub = new double[v1.length]; - for (int i = 0; i < v1.length; i++) { + for(int i = 0; i < v1.length; i++) { sub[i] = v1[i] * s1 - v2[i] * s2; } return sub; @@ -360,7 +361,7 @@ public final class VMath { */ public static final double[] minusEquals(final double[] v1, final double[] v2) { assert (v1.length == v2.length) : ERR_VEC_DIMENSIONS; - for (int i = 0; i < v1.length; i++) { + for(int i = 0; i < v1.length; i++) { v1[i] -= v2[i]; } return v1; @@ -376,7 +377,7 @@ public final class VMath { */ public static final double[] minusTimesEquals(final double[] v1, final double[] v2, final double s2) { assert (v1.length == v2.length) : ERR_VEC_DIMENSIONS; - for (int i = 0; i < v1.length; i++) { + for(int i = 0; i < v1.length; i++) { v1[i] -= v2[i] * s2; } return v1; @@ -392,7 +393,7 @@ public final class VMath { */ public static final double[] timesMinusEquals(final double[] v1, final double s1, final double[] v2) { assert (v1.length == v2.length) : ERR_VEC_DIMENSIONS; - for (int i = 0; i < v1.length; i++) { + for(int i = 0; i < v1.length; i++) { v1[i] = v1[i] * s1 - v2[i]; } return v1; @@ -409,7 +410,7 @@ public final class VMath { */ public static final double[] timesMinusTimesEquals(final double[] v1, final double s1, final double[] v2, final double s2) { assert (v1.length == v2.length) : ERR_VEC_DIMENSIONS; - for (int i = 0; i < v1.length; i++) { + for(int i = 0; i < v1.length; i++) { v1[i] = v1[i] * s1 - v2[i] * s2; } return v1; @@ -424,7 +425,7 @@ public final class VMath { */ public static final double[] minus(final double[] v1, final double d) { final double[] result = new double[v1.length]; - for (int i = 0; i < v1.length; i++) { + for(int i = 0; i < v1.length; i++) { result[i] = v1[i] - d; } return result; @@ -438,7 +439,7 @@ public final class VMath { * @return v1 = v1 - d */ public static final double[] minusEquals(final double[] v1, final double d) { - for (int i = 0; i < v1.length; i++) { + for(int i = 0; i < v1.length; i++) { v1[i] -= d; } return v1; @@ -453,7 +454,7 @@ public final class VMath { */ public static final double[] times(final double[] v1, final double s1) { final double[] v = new double[v1.length]; - for (int i = 0; i < v1.length; i++) { + for(int i = 0; i < v1.length; i++) { v[i] = v1[i] * s1; } return v; @@ -467,7 +468,7 @@ public final class VMath { * @return v1 = v1 * s1 */ public static final double[] timesEquals(final double[] v1, final double s) { - for (int i = 0; i < v1.length; i++) { + for(int i = 0; i < v1.length; i++) { v1[i] *= s; } return v1; @@ -484,8 +485,8 @@ public final class VMath { assert (m2.length == 1) : ERR_MATRIX_INNERDIM; final int columndimension = m2[0].length; final double[][] re = new double[v1.length][columndimension]; - for (int j = 0; j < columndimension; j++) { - for (int i = 0; i < v1.length; i++) { + for(int j = 0; j < columndimension; j++) { + for(int i = 0; i < v1.length; i++) { re[i][j] = v1[i] * m2[0][j]; } } @@ -503,9 +504,9 @@ public final class VMath { assert (m2.length == v1.length) : ERR_MATRIX_INNERDIM; final int columndimension = m2[0].length; final double[][] re = new double[1][columndimension]; - for (int j = 0; j < columndimension; j++) { + for(int j = 0; j < columndimension; j++) { double s = 0; - for (int k = 0; k < v1.length; k++) { + for(int k = 0; k < v1.length; k++) { s += v1[k] * m2[k][j]; } re[0][j] = s; @@ -523,7 +524,7 @@ public final class VMath { public static final double transposeTimes(final double[] v1, final double[] v2) { assert (v2.length == v1.length) : ERR_MATRIX_INNERDIM; double s = 0; - for (int k = 0; k < v1.length; k++) { + for(int k = 0; k < v1.length; k++) { s += v1[k] * v2[k]; } return s; @@ -540,8 +541,8 @@ public final class VMath { assert (m2[0].length == 1) : ERR_MATRIX_INNERDIM; final double[][] re = new double[v1.length][m2.length]; - for (int j = 0; j < m2.length; j++) { - for (int i = 0; i < v1.length; i++) { + for(int j = 0; j < m2.length; j++) { + for(int i = 0; i < v1.length; i++) { re[i][j] = v1[i] * m2[j][0]; } } @@ -557,8 +558,8 @@ public final class VMath { */ public static final double[][] timesTranspose(final double[] v1, final double[] v2) { final double[][] re = new double[v1.length][v2.length]; - for (int j = 0; j < v2.length; j++) { - for (int i = 0; i < v1.length; i++) { + for(int j = 0; j < v2.length; j++) { + for(int i = 0; i < v1.length; i++) { re[i][j] = v1[i] * v2[j]; } } @@ -566,7 +567,8 @@ public final class VMath { } /** - * Returns the scalar product (dot product) of this vector and the specified vector v. + * Returns the scalar product (dot product) of this vector and the specified + * vector v. * * This is the same as transposeTimes. * @@ -577,21 +579,36 @@ public final class VMath { public static final double scalarProduct(final double[] v1, final double[] v2) { assert (v1.length == v2.length) : ERR_VEC_DIMENSIONS; double scalarProduct = 0.0; - for (int row = 0; row < v1.length; row++) { + for(int row = 0; row < v1.length; row++) { scalarProduct += v1[row] * v2[row]; } return scalarProduct; } /** + * Squared Euclidean length of the vector + * + * @param v1 vector + * @return squared Euclidean length of this vector + */ + public static final double squareSum(final double[] v1) { + double acc = 0.0; + for(int row = 0; row < v1.length; row++) { + final double v = v1[row]; + acc += v * v; + } + return acc; + } + + /** * Euclidean length of the vector * * @param v1 vector - * @return euclidean length of this vector + * @return Euclidean length of this vector */ public static final double euclideanLength(final double[] v1) { double acc = 0.0; - for (int row = 0; row < v1.length; row++) { + for(int row = 0; row < v1.length; row++) { final double v = v1[row]; acc += v * v; } @@ -607,8 +624,8 @@ public final class VMath { public static final double[] normalize(final double[] v1) { double norm = euclideanLength(v1); double[] re = new double[v1.length]; - if (norm != 0) { - for (int row = 0; row < v1.length; row++) { + if(norm != 0) { + for(int row = 0; row < v1.length; row++) { re[row] = v1[row] / norm; } } @@ -623,8 +640,8 @@ public final class VMath { */ public static final double[] normalizeEquals(final double[] v1) { double norm = euclideanLength(v1); - if (norm != 0) { - for (int row = 0; row < v1.length; row++) { + if(norm != 0) { + for(int row = 0; row < v1.length; row++) { v1[row] /= norm; } } @@ -643,7 +660,7 @@ public final class VMath { final int columndimension = m2[0].length; double[] sum = new double[v1.length]; - for (int i = 0; i < columndimension; i++) { + for(int i = 0; i < columndimension; i++) { // TODO: optimize - copy less. double[] v_i = getCol(m2, i); plusTimesEquals(sum, v_i, scalarProduct(v1, v_i)); @@ -705,7 +722,7 @@ public final class VMath { */ public static final double[][] unitMatrix(final int dim) { final double[][] e = new double[dim][dim]; - for (int i = 0; i < dim; i++) { + for(int i = 0; i < dim; i++) { e[i][i] = 1; } return e; @@ -731,8 +748,8 @@ public final class VMath { */ public static final double[][] random(final int m, final int n) { final double[][] A = new double[m][n]; - for (int i = 0; i < m; i++) { - for (int j = 0; j < n; j++) { + for(int i = 0; i < m; i++) { + for(int j = 0; j < n; j++) { A[i][j] = Math.random(); } } @@ -748,7 +765,7 @@ public final class VMath { */ public static final double[][] identity(final int m, final int n) { final double[][] A = new double[m][n]; - for (int i = 0; i < Math.min(m, n); i++) { + for(int i = 0; i < Math.min(m, n); i++) { A[i][i] = 1.0; } return A; @@ -763,7 +780,7 @@ public final class VMath { */ public static final double[][] diagonal(final double[] v1) { final double[][] result = new double[v1.length][v1.length]; - for (int i = 0; i < v1.length; i++) { + for(int i = 0; i < v1.length; i++) { result[i][i] = v1[i]; } return result; @@ -778,7 +795,7 @@ public final class VMath { public static final double[][] copy(final double[][] m1) { final int columndimension = m1[0].length; final double[][] X = new double[m1.length][columndimension]; - for (int i = 0; i < m1.length; i++) { + for(int i = 0; i < m1.length; i++) { System.arraycopy(m1[i], 0, X[i], 0, columndimension); } return X; @@ -793,7 +810,7 @@ public final class VMath { public static final double[] rowPackedCopy(final double[][] m1) { final int columndimension = m1[0].length; double[] vals = new double[m1.length * columndimension]; - for (int i = 0; i < m1.length; i++) { + for(int i = 0; i < m1.length; i++) { System.arraycopy(m1[i], 0, vals, i * columndimension, columndimension); } return vals; @@ -808,8 +825,8 @@ public final class VMath { public static final double[] columnPackedCopy(final double[][] m1) { final int columndimension = m1[0].length; final double[] vals = new double[m1.length * columndimension]; - for (int i = 0; i < m1.length; i++) { - for (int j = 0; j < columndimension; j++) { + for(int i = 0; i < m1.length; i++) { + for(int j = 0; j < columndimension; j++) { vals[i + j * m1.length] = m1[i][j]; } } @@ -828,7 +845,7 @@ public final class VMath { */ public static final double[][] getMatrix(final double[][] m1, final int r0, final int r1, final int c0, final int c1) { final double[][] X = new double[r1 - r0 + 1][c1 - c0 + 1]; - for (int i = r0; i <= r1; i++) { + for(int i = r0; i <= r1; i++) { System.arraycopy(m1[i], c0, X[i - r0], 0, c1 - c0 + 1); } return X; @@ -844,8 +861,8 @@ public final class VMath { */ public static final double[][] getMatrix(final double[][] m1, final int[] r, final int[] c) { final double[][] X = new double[r.length][c.length]; - for (int i = 0; i < r.length; i++) { - for (int j = 0; j < c.length; j++) { + for(int i = 0; i < r.length; i++) { + for(int j = 0; j < c.length; j++) { X[i][j] = m1[r[i]][c[j]]; } } @@ -863,7 +880,7 @@ public final class VMath { */ public static final double[][] getMatrix(final double[][] m1, final int[] r, final int c0, final int c1) { final double[][] X = new double[r.length][c1 - c0 + 1]; - for (int i = 0; i < r.length; i++) { + for(int i = 0; i < r.length; i++) { System.arraycopy(m1[r[i]], c0, X[i], 0, c1 - c0 + 1); } return X; @@ -880,8 +897,8 @@ public final class VMath { */ public static final double[][] getMatrix(final double[][] m1, final int r0, final int r1, final int[] c) { final double[][] X = new double[r1 - r0 + 1][c.length]; - for (int i = r0; i <= r1; i++) { - for (int j = 0; j < c.length; j++) { + for(int i = r0; i <= r1; i++) { + for(int j = 0; j < c.length; j++) { X[i - r0][j] = m1[i][c[j]]; } } @@ -899,7 +916,7 @@ public final class VMath { * @param m2 New values for m1(r0:r1,c0:c1) */ public static final void setMatrix(final double[][] m1, final int r0, final int r1, final int c0, final int c1, final double[][] m2) { - for (int i = r0; i <= r1; i++) { + for(int i = r0; i <= r1; i++) { System.arraycopy(m2[i - r0], 0, m1[i], c0, c1 - c0 + 1); } } @@ -913,8 +930,8 @@ public final class VMath { * @param m2 New values for m1(r(:),c(:)) */ public static final void setMatrix(final double[][] m1, final int[] r, final int[] c, final double[][] m2) { - for (int i = 0; i < r.length; i++) { - for (int j = 0; j < c.length; j++) { + for(int i = 0; i < r.length; i++) { + for(int j = 0; j < c.length; j++) { m1[r[i]][c[j]] = m2[i][j]; } } @@ -930,7 +947,7 @@ public final class VMath { * @param m2 New values for m1(r(:),c0:c1) */ public static final void setMatrix(final double[][] m1, final int[] r, final int c0, final int c1, final double[][] m2) { - for (int i = 0; i < r.length; i++) { + for(int i = 0; i < r.length; i++) { System.arraycopy(m2[i], 0, m1[r[i]], c0, c1 - c0 + 1); } } @@ -945,8 +962,8 @@ public final class VMath { * @param m2 New values for m1(r0:r1,c(:)) */ public static final void setMatrix(final double[][] m1, final int r0, final int r1, final int[] c, final double[][] m2) { - for (int i = r0; i <= r1; i++) { - for (int j = 0; j < c.length; j++) { + for(int i = r0; i <= r1; i++) { + for(int j = 0; j < c.length; j++) { m1[i][c[j]] = m2[i - r0][j]; } } @@ -985,7 +1002,7 @@ public final class VMath { */ public static final double[] getCol(double[][] m1, int col) { double[] ret = new double[m1.length]; - for (int i = 0; i < ret.length; i++) { + for(int i = 0; i < ret.length; i++) { ret[i] = m1[i][col]; } return ret; @@ -1000,7 +1017,7 @@ public final class VMath { */ public static final void setCol(final double[][] m1, final int c, final double[] column) { assert (column.length == m1.length) : ERR_DIMENSIONS; - for (int i = 0; i < m1.length; i++) { + for(int i = 0; i < m1.length; i++) { m1[i][c] = column[i]; } } @@ -1014,8 +1031,8 @@ public final class VMath { public static final double[][] transpose(final double[][] m1) { final int columndimension = getColumnDimensionality(m1); final double[][] re = new double[columndimension][m1.length]; - for (int i = 0; i < m1.length; i++) { - for (int j = 0; j < columndimension; j++) { + for(int i = 0; i < m1.length; i++) { + for(int j = 0; j < columndimension; j++) { re[j][i] = m1[i][j]; } } @@ -1055,8 +1072,8 @@ public final class VMath { public static final double[][] plusEquals(final double[][] m1, final double[][] m2) { final int columndimension = getColumnDimensionality(m1); assert (getRowDimensionality(m1) == getRowDimensionality(m2) && columndimension == getColumnDimensionality(m2)) : ERR_MATRIX_DIMENSIONS; - for (int i = 0; i < m1.length; i++) { - for (int j = 0; j < columndimension; j++) { + for(int i = 0; i < m1.length; i++) { + for(int j = 0; j < columndimension; j++) { m1[i][j] += m2[i][j]; } } @@ -1074,8 +1091,8 @@ public final class VMath { public static final double[][] plusTimesEquals(final double[][] m1, final double[][] m2, final double s2) { final int columndimension = getColumnDimensionality(m1); assert (getRowDimensionality(m1) == getRowDimensionality(m2) && columndimension == getColumnDimensionality(m2)) : ERR_MATRIX_DIMENSIONS; - for (int i = 0; i < m1.length; i++) { - for (int j = 0; j < columndimension; j++) { + for(int i = 0; i < m1.length; i++) { + for(int j = 0; j < columndimension; j++) { m1[i][j] += s2 * m2[i][j]; } } @@ -1115,8 +1132,8 @@ public final class VMath { public static final double[][] minusEquals(final double[][] m1, final double[][] m2) { final int columndimension = getColumnDimensionality(m1); assert (getRowDimensionality(m1) == getRowDimensionality(m2) && columndimension == getColumnDimensionality(m2)) : ERR_MATRIX_DIMENSIONS; - for (int i = 0; i < m1.length; i++) { - for (int j = 0; j < columndimension; j++) { + for(int i = 0; i < m1.length; i++) { + for(int j = 0; j < columndimension; j++) { m1[i][j] -= m2[i][j]; } } @@ -1133,10 +1150,10 @@ public final class VMath { */ public static final double[][] minusTimesEquals(final double[][] m1, final double[][] m2, final double s2) { assert (getRowDimensionality(m1) == getRowDimensionality(m2) && getColumnDimensionality(m1) == getColumnDimensionality(m2)) : ERR_MATRIX_DIMENSIONS; - for (int i = 0; i < m1.length; i++) { + for(int i = 0; i < m1.length; i++) { final double[] row1 = m1[i]; final double[] row2 = m2[i]; - for (int j = 0; j < row1.length; j++) { + for(int j = 0; j < row1.length; j++) { row1[j] -= s2 * row2[j]; } } @@ -1162,9 +1179,9 @@ public final class VMath { * @return m1 = s1 * m1, overwriting m1 */ public static final double[][] timesEquals(final double[][] m1, final double s1) { - for (int i = 0; i < m1.length; i++) { + for(int i = 0; i < m1.length; i++) { final double[] row = m1[i]; - for (int j = 0; j < row.length; j++) { + for(int j = 0; j < row.length; j++) { row[j] *= s1; } } @@ -1186,17 +1203,17 @@ public final class VMath { final double[][] r2 = new double[m1.length][bcolumndimension]; // Optimized ala Jama. jik order. final double[] Bcolj = new double[columndimension]; - for (int j = 0; j < bcolumndimension; j++) { + for(int j = 0; j < bcolumndimension; j++) { // Make a linear copy of column j from B // TODO: use column getter from B? - for (int k = 0; k < columndimension; k++) { + for(int k = 0; k < columndimension; k++) { Bcolj[k] = m2[k][j]; } // multiply it with each row from A - for (int i = 0; i < m1.length; i++) { + for(int i = 0; i < m1.length; i++) { final double[] Arowi = m1[i]; double s = 0; - for (int k = 0; k < columndimension; k++) { + for(int k = 0; k < columndimension; k++) { s += Arowi[k] * Bcolj[k]; } r2[i][j] = s; @@ -1216,10 +1233,10 @@ public final class VMath { assert (v2.length == getColumnDimensionality(m1)) : ERR_MATRIX_INNERDIM; final double[] re = new double[m1.length]; // multiply it with each row from A - for (int i = 0; i < m1.length; i++) { + for(int i = 0; i < m1.length; i++) { final double[] Arowi = m1[i]; double s = 0; - for (int k = 0; k < Arowi.length; k++) { + for(int k = 0; k < Arowi.length; k++) { s += Arowi[k] * v2[k]; } re[i] = s; @@ -1239,9 +1256,9 @@ public final class VMath { assert (v2.length == m1.length) : ERR_MATRIX_INNERDIM; final double[] re = new double[columndimension]; // multiply it with each row from A - for (int i = 0; i < columndimension; i++) { + for(int i = 0; i < columndimension; i++) { double s = 0; - for (int k = 0; k < m1.length; k++) { + for(int k = 0; k < m1.length; k++) { s += m1[k][i] * v2[k]; } re[i] = s; @@ -1262,15 +1279,15 @@ public final class VMath { assert (m2.length == m1.length) : ERR_MATRIX_INNERDIM; final double[][] re = new double[coldim1][coldim2]; final double[] Bcolj = new double[m1.length]; - for (int j = 0; j < coldim2; j++) { + for(int j = 0; j < coldim2; j++) { // Make a linear copy of column j from B - for (int k = 0; k < m1.length; k++) { + for(int k = 0; k < m1.length; k++) { Bcolj[k] = m2[k][j]; } // multiply it with each row from A - for (int i = 0; i < coldim1; i++) { + for(int i = 0; i < coldim1; i++) { double s = 0; - for (int k = 0; k < m1.length; k++) { + for(int k = 0; k < m1.length; k++) { s += m1[k][i] * Bcolj[k]; } re[i][j] = s; @@ -1282,6 +1299,7 @@ public final class VMath { /** * Linear algebraic matrix multiplication, a<sup>T</sup> * B * c * + * @param a vector on the left * @param B matrix * @param c vector on the right * @return Matrix product, a<sup>T</sup> * B * c @@ -1289,10 +1307,10 @@ public final class VMath { public static double transposeTimesTimes(final double[] a, final double[][] B, final double[] c) { assert (B.length == a.length) : ERR_MATRIX_INNERDIM; double sum = 0.0; - for (int j = 0; j < B[0].length; j++) { + for(int j = 0; j < B[0].length; j++) { // multiply it with each row from A double s = 0; - for (int k = 0; k < a.length; k++) { + for(int k = 0; k < a.length; k++) { s += a[k] * B[k][j]; } sum += s * c[j]; @@ -1310,13 +1328,13 @@ public final class VMath { public static final double[][] timesTranspose(final double[][] m1, final double[][] m2) { assert (getColumnDimensionality(m2) == getColumnDimensionality(m1)) : ERR_MATRIX_INNERDIM; final double[][] re = new double[m1.length][m2.length]; - for (int j = 0; j < re.length; j++) { + for(int j = 0; j < re.length; j++) { final double[] Browj = m2[j]; // multiply it with each row from A - for (int i = 0; i < m1.length; i++) { + for(int i = 0; i < m1.length; i++) { final double[] Arowi = m1[i]; double s = 0; - for (int k = 0; k < Browj.length; k++) { + for(int k = 0; k < Browj.length; k++) { s += Arowi[k] * Browj[k]; } re[i][j] = s; @@ -1338,17 +1356,17 @@ public final class VMath { final double[][] re = new double[getColumnDimensionality(m1)][m2.length]; // Optimized ala Jama. jik order. final double[] Acolj = new double[m1.length]; - for (int j = 0; j < re.length; j++) { + for(int j = 0; j < re.length; j++) { // Make a linear copy of column j from B - for (int k = 0; k < m1.length; k++) { + for(int k = 0; k < m1.length; k++) { Acolj[k] = m1[k][j]; } final double[] Xrow = re[j]; // multiply it with each row from A - for (int i = 0; i < m2.length; i++) { + for(int i = 0; i < m2.length; i++) { final double[] Browi = m2[i]; double s = 0; - for (int k = 0; k < m1.length; k++) { + for(int k = 0; k < m1.length; k++) { s += Browi[k] * Acolj[k]; } Xrow[i] = s; @@ -1358,6 +1376,28 @@ public final class VMath { } /** + * Linear algebraic matrix multiplication, (a-c)<sup>T</sup> * B * (a-c) + * + * @param B matrix + * @param a First vector + * @param c Center vector + * @return Matrix product, (a-c)<sup>T</sup> * B * (a-c) + */ + public static double mahalanobisDistance(final double[][] B, final double[] a, final double[] c) { + assert (B.length == a.length && a.length == c.length) : ERR_MATRIX_INNERDIM; + double sum = 0.0; + for(int j = 0; j < B[0].length; j++) { + // multiply it with each row from A + double s = 0; + for(int k = 0; k < a.length; k++) { + s += (a[k] - c[k]) * B[k][j]; + } + sum += s * (a[j] - c[j]); + } + return sum; + } + + /** * getDiagonal returns array of diagonal-elements. * * @param m1 Input matrix @@ -1366,7 +1406,7 @@ public final class VMath { public static final double[] getDiagonal(final double[][] m1) { final int dim = Math.min(getColumnDimensionality(m1), m1.length); final double[] diagonal = new double[dim]; - for (int i = 0; i < dim; i++) { + for(int i = 0; i < dim; i++) { diagonal[i] = m1[i][i]; } return diagonal; @@ -1379,17 +1419,18 @@ public final class VMath { */ public static final void normalizeColumns(final double[][] m1) { final int columndimension = getColumnDimensionality(m1); - for (int col = 0; col < columndimension; col++) { + for(int col = 0; col < columndimension; col++) { double norm = 0.0; - for (int row = 0; row < m1.length; row++) { + for(int row = 0; row < m1.length; row++) { norm = norm + (m1[row][col] * m1[row][col]); } norm = Math.sqrt(norm); - if (norm != 0) { - for (int row = 0; row < m1.length; row++) { + if(norm != 0) { + for(int row = 0; row < m1.length; row++) { m1[row][col] /= norm; } - } else { + } + else { // TODO: else: throw an exception? } } @@ -1409,11 +1450,12 @@ public final class VMath { final int rcolumndimension = columndimension + ccolumndimension; final double[][] result = new double[m1.length][rcolumndimension]; - for (int i = 0; i < rcolumndimension; i++) { + for(int i = 0; i < rcolumndimension; i++) { // FIXME: optimize - excess copying! - if (i < columndimension) { + if(i < columndimension) { setCol(result, i, getCol(m1, i)); - } else { + } + else { setCol(result, i, getCol(m2, i - columndimension)); } } @@ -1431,10 +1473,10 @@ public final class VMath { double[][] v = copy(m1); // FIXME: optimize - excess copying! - for (int i = 1; i < columndimension; i++) { + for(int i = 1; i < columndimension; i++) { final double[] u_i = getCol(m1, i); final double[] sum = new double[m1.length]; - for (int j = 0; j < i; j++) { + for(int j = 0; j < i; j++) { final double[] v_j = getCol(v, j); double scalar = scalarProduct(u_i, v_j) / scalarProduct(v_j, v_j); plusEquals(sum, times(v_j, scalar)); @@ -1478,25 +1520,25 @@ public final class VMath { * @return true if delta smaller than maximum */ public static final boolean almostEquals(final double[][] m1, final double[][] m2, final double maxdelta) { - if (m1 == m2) { + if(m1 == m2) { return true; } - if (m2 == null) { + if(m2 == null) { return false; } - if (m1.getClass() != m2.getClass()) { + if(m1.getClass() != m2.getClass()) { return false; } - if (m1.length != m2.length) { + if(m1.length != m2.length) { return false; } final int columndimension = getColumnDimensionality(m1); - if (columndimension != getColumnDimensionality(m2)) { + if(columndimension != getColumnDimensionality(m2)) { return false; } - for (int i = 0; i < m1.length; i++) { - for (int j = 0; j < columndimension; j++) { - if (Math.abs(m1[i][j] - m2[i][j]) > maxdelta) { + for(int i = 0; i < m1.length; i++) { + for(int j = 0; j < columndimension; j++) { + if(Math.abs(m1[i][j] - m2[i][j]) > maxdelta) { return false; } } diff --git a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/Vector.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/Vector.java index eca1dbea..36ab94dc 100644 --- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/Vector.java +++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/Vector.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -23,19 +23,46 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra; along with this program. If not, see <http://www.gnu.org/licenses/>. */ +import java.io.IOException; +import java.nio.ByteBuffer; import java.util.Arrays; import de.lmu.ifi.dbs.elki.data.NumberVector; import de.lmu.ifi.dbs.elki.utilities.FormatUtil; +import de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike.ArrayAdapter; +import de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike.ArrayLikeUtil; +import de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike.NumberArrayAdapter; +import de.lmu.ifi.dbs.elki.utilities.io.ByteArrayUtil; +import de.lmu.ifi.dbs.elki.utilities.io.ByteBufferSerializer; /** - * Provides a vector object that encapsulates an m x 1 - matrix object. + * A mathematical vector object, along with mathematical operations. * * @author Elke Achtert * * @apiviz.landmark */ -public class Vector implements NumberVector<Double> { +public class Vector implements NumberVector { + /** + * Static vector factory. + */ + public static final Factory FACTORY = new Factory(); + + /** + * Serializer for up to 127 dimensions. + */ + public static final ByteBufferSerializer<Vector> BYTE_SERIALIZER = new SmallSerializer(); + + /** + * Serializer for up to 2^15-1 dimensions. + */ + public static final ByteBufferSerializer<Vector> SHORT_SERIALIZER = new ShortSerializer(); + + /** + * Serializer using varint encoding. + */ + public static final ByteBufferSerializer<Vector> VARIABLE_SERIALIZER = new VariableSerializer(); + /** * Array for internal storage of elements. * @@ -68,7 +95,7 @@ public class Vector implements NumberVector<Double> { } /** - * Provides an m x 1 vector. + * Constructor * * @param m the number of rows */ @@ -85,13 +112,13 @@ public class Vector implements NumberVector<Double> { public static final Vector randomNormalizedVector(final int dimensionality) { final Vector v = new Vector(dimensionality); double norm = 0; - while (norm <= 0) { - for (int i = 0; i < dimensionality; i++) { + while(norm <= 0) { + for(int i = 0; i < dimensionality; i++) { v.elements[i] = Math.random(); } norm = v.euclideanLength(); } - for (int row = 0; row < dimensionality; row++) { + for(int row = 0; row < dimensionality; row++) { v.elements[row] /= norm; } return v; @@ -185,7 +212,7 @@ public class Vector implements NumberVector<Double> { public final Vector plus(final Vector v) { assert (this.elements.length == v.elements.length) : ERR_VEC_DIMENSIONS; final Vector result = new Vector(elements.length); - for (int i = 0; i < elements.length; i++) { + for(int i = 0; i < elements.length; i++) { result.elements[i] = elements[i] + v.elements[i]; } return result; @@ -202,7 +229,7 @@ public class Vector implements NumberVector<Double> { public final Vector plusTimes(final Vector v, final double s) { assert (this.elements.length == v.elements.length) : ERR_VEC_DIMENSIONS; final Vector result = new Vector(elements.length); - for (int i = 0; i < elements.length; i++) { + for(int i = 0; i < elements.length; i++) { result.elements[i] = elements[i] + v.elements[i] * s; } return result; @@ -216,7 +243,7 @@ public class Vector implements NumberVector<Double> { */ public final Vector plusEquals(final Vector b) { assert (this.elements.length == b.elements.length) : ERR_VEC_DIMENSIONS; - for (int i = 0; i < elements.length; i++) { + for(int i = 0; i < elements.length; i++) { elements[i] += b.elements[i]; } return this; @@ -231,7 +258,7 @@ public class Vector implements NumberVector<Double> { */ public final Vector plusTimesEquals(final Vector b, final double s) { assert (this.elements.length == b.elements.length) : ERR_VEC_DIMENSIONS; - for (int i = 0; i < elements.length; i++) { + for(int i = 0; i < elements.length; i++) { elements[i] += s * b.elements[i]; } return this; @@ -244,7 +271,7 @@ public class Vector implements NumberVector<Double> { * @return Modified vector */ public final Vector plusEquals(final double d) { - for (int i = 0; i < elements.length; i++) { + for(int i = 0; i < elements.length; i++) { elements[i] += d; } return this; @@ -258,7 +285,7 @@ public class Vector implements NumberVector<Double> { */ public final Vector minus(final Vector v) { final Vector sub = new Vector(elements.length); - for (int i = 0; i < elements.length; i++) { + for(int i = 0; i < elements.length; i++) { sub.elements[i] = elements[i] - v.elements[i]; } return sub; @@ -273,7 +300,7 @@ public class Vector implements NumberVector<Double> { */ public final Vector minusTimes(final Vector v, final double s) { final Vector sub = new Vector(elements.length); - for (int i = 0; i < elements.length; i++) { + for(int i = 0; i < elements.length; i++) { sub.elements[i] = elements[i] - v.elements[i] * s; } return sub; @@ -287,7 +314,7 @@ public class Vector implements NumberVector<Double> { */ public final Vector minusEquals(final Vector b) { assert (this.elements.length == b.elements.length) : ERR_VEC_DIMENSIONS; - for (int i = 0; i < elements.length; i++) { + for(int i = 0; i < elements.length; i++) { elements[i] -= b.elements[i]; } return this; @@ -302,7 +329,7 @@ public class Vector implements NumberVector<Double> { */ public final Vector minusTimesEquals(final Vector b, final double s) { assert (this.elements.length == b.elements.length) : ERR_VEC_DIMENSIONS; - for (int i = 0; i < elements.length; i++) { + for(int i = 0; i < elements.length; i++) { elements[i] -= s * b.elements[i]; } return this; @@ -315,7 +342,7 @@ public class Vector implements NumberVector<Double> { * @return Modified vector */ public final Vector minusEquals(final double d) { - for (int i = 0; i < elements.length; i++) { + for(int i = 0; i < elements.length; i++) { elements[i] -= d; } return this; @@ -330,7 +357,7 @@ public class Vector implements NumberVector<Double> { */ public final Vector times(final double s) { final Vector v = new Vector(elements.length); - for (int i = 0; i < elements.length; i++) { + for(int i = 0; i < elements.length; i++) { v.elements[i] = elements[i] * s; } return v; @@ -343,7 +370,7 @@ public class Vector implements NumberVector<Double> { * @return replace A by s*A */ public final Vector timesEquals(final double s) { - for (int i = 0; i < elements.length; i++) { + for(int i = 0; i < elements.length; i++) { elements[i] *= s; } return this; @@ -358,8 +385,8 @@ public class Vector implements NumberVector<Double> { public final Matrix times(final Matrix B) { assert (B.elements.length == 1) : ERR_MATRIX_INNERDIM; final Matrix X = new Matrix(this.elements.length, B.columndimension); - for (int j = 0; j < B.columndimension; j++) { - for (int i = 0; i < this.elements.length; i++) { + for(int j = 0; j < B.columndimension; j++) { + for(int i = 0; i < this.elements.length; i++) { X.elements[i][j] = elements[i] * B.elements[0][j]; } } @@ -375,10 +402,10 @@ public class Vector implements NumberVector<Double> { public final Matrix transposeTimes(final Matrix B) { assert (B.elements.length == this.elements.length) : ERR_MATRIX_INNERDIM; final Matrix X = new Matrix(1, B.columndimension); - for (int j = 0; j < B.columndimension; j++) { + for(int j = 0; j < B.columndimension; j++) { // multiply it with each row from A double s = 0; - for (int k = 0; k < this.elements.length; k++) { + for(int k = 0; k < this.elements.length; k++) { s += this.elements[k] * B.elements[k][j]; } X.elements[0][j] = s; @@ -396,10 +423,10 @@ public class Vector implements NumberVector<Double> { public final double transposeTimesTimes(final Matrix B, final Vector c) { assert (B.elements.length == this.elements.length) : ERR_MATRIX_INNERDIM; double sum = 0.0; - for (int j = 0; j < B.columndimension; j++) { + for(int j = 0; j < B.columndimension; j++) { // multiply it with each row from A double s = 0; - for (int k = 0; k < this.elements.length; k++) { + for(int k = 0; k < this.elements.length; k++) { s += this.elements[k] * B.elements[k][j]; } sum += s * c.elements[j]; @@ -416,7 +443,7 @@ public class Vector implements NumberVector<Double> { public final double transposeTimes(final Vector B) { assert (B.elements.length == this.elements.length) : ERR_MATRIX_INNERDIM; double s = 0; - for (int k = 0; k < this.elements.length; k++) { + for(int k = 0; k < this.elements.length; k++) { s += this.elements[k] * B.elements[k]; } return s; @@ -431,8 +458,8 @@ public class Vector implements NumberVector<Double> { public final Matrix timesTranspose(final Matrix B) { assert (B.columndimension == 1) : ERR_MATRIX_INNERDIM; final Matrix X = new Matrix(this.elements.length, B.elements.length); - for (int j = 0; j < B.elements.length; j++) { - for (int i = 0; i < this.elements.length; i++) { + for(int j = 0; j < B.elements.length; j++) { + for(int i = 0; i < this.elements.length; i++) { X.elements[i][j] = elements[i] * B.elements[j][0]; } } @@ -447,8 +474,8 @@ public class Vector implements NumberVector<Double> { */ public final Matrix timesTranspose(final Vector B) { final Matrix X = new Matrix(this.elements.length, B.elements.length); - for (int j = 0; j < B.elements.length; j++) { - for (int i = 0; i < this.elements.length; i++) { + for(int j = 0; j < B.elements.length; j++) { + for(int i = 0; i < this.elements.length; i++) { X.elements[i][j] = elements[i] * B.elements[j]; } } @@ -462,7 +489,7 @@ public class Vector implements NumberVector<Double> { */ public final double euclideanLength() { double acc = 0.0; - for (int row = 0; row < elements.length; row++) { + for(int row = 0; row < elements.length; row++) { final double v = elements[row]; acc += v * v; } @@ -476,8 +503,8 @@ public class Vector implements NumberVector<Double> { */ public final Vector normalize() { double norm = euclideanLength(); - if (norm != 0) { - for (int row = 0; row < elements.length; row++) { + if(norm != 0) { + for(int row = 0; row < elements.length; row++) { elements[row] /= norm; } } @@ -494,7 +521,7 @@ public class Vector implements NumberVector<Double> { public final Vector projection(final Matrix v) { assert (elements.length == v.elements.length) : ERR_DIMENSIONS; Vector sum = new Vector(elements.length); - for (int i = 0; i < v.columndimension; i++) { + for(int i = 0; i < v.columndimension; i++) { // TODO: optimize - copy less? Vector v_i = v.getCol(i); sum.plusTimesEquals(v_i, this.transposeTimes(v_i)); @@ -509,17 +536,17 @@ public class Vector implements NumberVector<Double> { @Override public boolean equals(Object obj) { - if (this == obj) { + if(this == obj) { return true; } - if (obj == null) { + if(obj == null) { return false; } - if (getClass() != obj.getClass()) { + if(getClass() != obj.getClass()) { return false; } final Vector other = (Vector) obj; - if (this.elements.length != other.elements.length) { + if(this.elements.length != other.elements.length) { return false; } return Arrays.equals(this.elements, other.elements); @@ -632,4 +659,159 @@ public class Vector implements NumberVector<Double> { public Vector getColumnVector() { return copy(); } + + /** + * Vector factory for Vectors. + * + * @author Erich Schubert + * + * @apiviz.exclude + */ + private static class Factory implements NumberVector.Factory<Vector> { + @Override + public <A> Vector newFeatureVector(A array, ArrayAdapter<? extends Number, A> adapter) { + if(adapter instanceof NumberArrayAdapter) { + return new Vector(ArrayLikeUtil.toPrimitiveDoubleArray(array, (NumberArrayAdapter<?, ? super A>) adapter)); + } + double[] data = new double[adapter.size(array)]; + for(int i = 0; i < data.length; i++) { + data[i] = adapter.get(array, i).doubleValue(); + } + return new Vector(data); + } + + @Override + public ByteBufferSerializer<Vector> getDefaultSerializer() { + return VARIABLE_SERIALIZER; + } + + @Override + public Class<? super Vector> getRestrictionClass() { + return Vector.class; + } + + @Override + public Vector newNumberVector(double[] values) { + return new Vector(values.clone()); + } + + @Override + public <A> Vector newNumberVector(A array, NumberArrayAdapter<?, ? super A> adapter) { + return new Vector(ArrayLikeUtil.toPrimitiveDoubleArray(array, adapter)); + } + + @Override + public Vector newNumberVector(NumberVector values) { + return new Vector(ArrayLikeUtil.toPrimitiveDoubleArray(values)); + } + } + + /** + * Serialization class for dense double vectors with up to 127 dimensions, by + * using a byte for storing the dimensionality. + * + * @author Erich Schubert + * + * @apiviz.exclude + */ + public static class SmallSerializer implements ByteBufferSerializer<Vector> { + @Override + public Vector fromByteBuffer(ByteBuffer buffer) throws IOException { + final byte dimensionality = buffer.get(); + assert (buffer.remaining() >= ByteArrayUtil.SIZE_DOUBLE * dimensionality); + final double[] values = new double[dimensionality]; + for(int i = 0; i < dimensionality; i++) { + values[i] = buffer.getDouble(); + } + return new Vector(values); + } + + @Override + public void toByteBuffer(ByteBuffer buffer, Vector vec) throws IOException { + assert (vec.elements.length < Byte.MAX_VALUE) : "This serializer only supports a maximum dimensionality of " + Byte.MAX_VALUE + "!"; + assert (buffer.remaining() >= ByteArrayUtil.SIZE_DOUBLE * vec.elements.length); + buffer.put((byte) vec.elements.length); + for(int i = 0; i < vec.elements.length; i++) { + buffer.putDouble(vec.elements[i]); + } + } + + @Override + public int getByteSize(Vector vec) { + assert (vec.elements.length < Byte.MAX_VALUE) : "This serializer only supports a maximum dimensionality of " + Byte.MAX_VALUE + "!"; + return ByteArrayUtil.SIZE_BYTE + ByteArrayUtil.SIZE_DOUBLE * vec.getDimensionality(); + } + } + + /** + * Serialization class for dense double vectors with up to + * {@link Short#MAX_VALUE} dimensions, by using a short for storing the + * dimensionality. + * + * @author Erich Schubert + * + * @apiviz.exclude + */ + public static class ShortSerializer implements ByteBufferSerializer<Vector> { + @Override + public Vector fromByteBuffer(ByteBuffer buffer) throws IOException { + final short dimensionality = buffer.getShort(); + assert (buffer.remaining() >= ByteArrayUtil.SIZE_DOUBLE * dimensionality); + final double[] values = new double[dimensionality]; + for(int i = 0; i < dimensionality; i++) { + values[i] = buffer.getDouble(); + } + return new Vector(values); + } + + @Override + public void toByteBuffer(ByteBuffer buffer, Vector vec) throws IOException { + assert (vec.elements.length < Short.MAX_VALUE) : "This serializer only supports a maximum dimensionality of " + Short.MAX_VALUE + "!"; + assert (buffer.remaining() >= ByteArrayUtil.SIZE_DOUBLE * vec.elements.length); + buffer.putShort((short) vec.elements.length); + for(int i = 0; i < vec.elements.length; i++) { + buffer.putDouble(vec.elements[i]); + } + } + + @Override + public int getByteSize(Vector vec) { + assert (vec.elements.length < Short.MAX_VALUE) : "This serializer only supports a maximum dimensionality of " + Short.MAX_VALUE + "!"; + return ByteArrayUtil.SIZE_SHORT + ByteArrayUtil.SIZE_DOUBLE * vec.getDimensionality(); + } + } + + /** + * Serialization class for variable dimensionality by using VarInt encoding. + * + * @author Erich Schubert + * + * @apiviz.exclude + */ + protected static class VariableSerializer implements ByteBufferSerializer<Vector> { + @Override + public Vector fromByteBuffer(ByteBuffer buffer) throws IOException { + final int dimensionality = ByteArrayUtil.readUnsignedVarint(buffer); + assert (buffer.remaining() >= ByteArrayUtil.SIZE_DOUBLE * dimensionality); + final double[] values = new double[dimensionality]; + for(int i = 0; i < dimensionality; i++) { + values[i] = buffer.getDouble(); + } + return new Vector(values); + } + + @Override + public void toByteBuffer(ByteBuffer buffer, Vector vec) throws IOException { + assert (buffer.remaining() >= ByteArrayUtil.SIZE_DOUBLE * vec.elements.length); + ByteArrayUtil.writeUnsignedVarint(buffer, vec.elements.length); + for(int i = 0; i < vec.elements.length; i++) { + buffer.putDouble(vec.elements[i]); + } + } + + @Override + public int getByteSize(Vector vec) { + return ByteArrayUtil.getUnsignedVarintSize(vec.elements.length) + ByteArrayUtil.SIZE_DOUBLE * vec.elements.length; + } + } } diff --git a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/fitting/FittingFunction.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/fitting/FittingFunction.java index 48e90c00..6128bd8d 100644 --- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/fitting/FittingFunction.java +++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/fitting/FittingFunction.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra.fitting; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/fitting/FittingFunctionResult.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/fitting/FittingFunctionResult.java index 96d5381b..6a104ea5 100644 --- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/fitting/FittingFunctionResult.java +++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/fitting/FittingFunctionResult.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra.fitting; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/fitting/GaussianFittingFunction.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/fitting/GaussianFittingFunction.java index 239d51c6..75eea676 100644 --- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/fitting/GaussianFittingFunction.java +++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/fitting/GaussianFittingFunction.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra.fitting; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/fitting/LevenbergMarquardtMethod.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/fitting/LevenbergMarquardtMethod.java index 1f2aa913..b855ffe2 100644 --- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/fitting/LevenbergMarquardtMethod.java +++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/fitting/LevenbergMarquardtMethod.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra.fitting; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/fitting/package-info.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/fitting/package-info.java index 100f36e2..5264b1ec 100644 --- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/fitting/package-info.java +++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/fitting/package-info.java @@ -7,7 +7,7 @@ This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures -Copyright (C) 2013 +Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/package-info.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/package-info.java index 4806b2d6..004575e5 100644 --- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/package-info.java +++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/package-info.java @@ -38,27 +38,29 @@ can be found at <a href="http://math.nist.gov/javanumerics/jama/">http://math.ni Here, for the adaption some classes and methods convenient for data mining applications within ELKI were added. Furthermore some erroneous comments were corrected and the coding-style was subtly changed to a more Java-typical style. -*/ + + * @apiviz.exclude ^java\.(io|lang)\..* + */ /* -This file is part of ELKI: -Environment for Developing KDD-Applications Supported by Index-Structures + This file is part of ELKI: + Environment for Developing KDD-Applications Supported by Index-Structures -Copyright (C) 2013 -Ludwig-Maximilians-Universität München -Lehr- und Forschungseinheit für Datenbanksysteme -ELKI Development Team + Copyright (C) 2014 + Ludwig-Maximilians-Universität München + Lehr- und Forschungseinheit für Datenbanksysteme + ELKI Development Team -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU Affero 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 free software: you can redistribute it and/or modify + it under the terms of the GNU Affero 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 Affero General Public License for more details. + 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 Affero General Public License for more details. -You should have received a copy of the GNU Affero General Public License -along with this program. If not, see <http://www.gnu.org/licenses/>. -*/ + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ package de.lmu.ifi.dbs.elki.math.linearalgebra;
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/AbstractCovarianceMatrixBuilder.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/AbstractCovarianceMatrixBuilder.java index 7079f5e1..42c0f493 100644 --- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/AbstractCovarianceMatrixBuilder.java +++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/AbstractCovarianceMatrixBuilder.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra.pca; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -27,32 +27,28 @@ import de.lmu.ifi.dbs.elki.data.NumberVector; import de.lmu.ifi.dbs.elki.database.ids.DBIDIter; import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil; import de.lmu.ifi.dbs.elki.database.ids.DBIDs; +import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDList; import de.lmu.ifi.dbs.elki.database.ids.ModifiableDBIDs; -import de.lmu.ifi.dbs.elki.database.ids.distance.DistanceDBIDList; import de.lmu.ifi.dbs.elki.database.relation.Relation; -import de.lmu.ifi.dbs.elki.distance.distancevalue.NumberDistance; import de.lmu.ifi.dbs.elki.math.linearalgebra.Matrix; -import de.lmu.ifi.dbs.elki.utilities.optionhandling.Parameterizable; /** * Abstract class with the task of computing a Covariance matrix to be used in PCA. * Mostly the specification of an interface. * * @author Erich Schubert - * - * @param <V> Vector class in use */ -public abstract class AbstractCovarianceMatrixBuilder<V extends NumberVector<?>> implements Parameterizable, CovarianceMatrixBuilder<V> { +public abstract class AbstractCovarianceMatrixBuilder implements CovarianceMatrixBuilder { @Override - public Matrix processDatabase(Relation<? extends V> database) { + public Matrix processDatabase(Relation<? extends NumberVector> database) { return processIds(database.getDBIDs(), database); } @Override - public abstract Matrix processIds(DBIDs ids, Relation<? extends V> database); + public abstract Matrix processIds(DBIDs ids, Relation<? extends NumberVector> database); @Override - public <D extends NumberDistance<D, ?>> Matrix processQueryResults(DistanceDBIDList<D> results, Relation<? extends V> database, int k) { + public Matrix processQueryResults(DoubleDBIDList results, Relation<? extends NumberVector> database, int k) { ModifiableDBIDs ids = DBIDUtil.newArray(k); int have = 0; for(DBIDIter it = results.iter(); it.valid() && have < k; it.advance(), have++) { @@ -62,7 +58,7 @@ public abstract class AbstractCovarianceMatrixBuilder<V extends NumberVector<?>> } @Override - public final <D extends NumberDistance<D, ?>> Matrix processQueryResults(DistanceDBIDList<D> results, Relation<? extends V> database) { + public final Matrix processQueryResults(DoubleDBIDList results, Relation<? extends NumberVector> database) { return processQueryResults(results, database, results.size()); } }
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/CompositeEigenPairFilter.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/CompositeEigenPairFilter.java index eb725400..d177c73c 100644 --- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/CompositeEigenPairFilter.java +++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/CompositeEigenPairFilter.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra.pca; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/CovarianceMatrixBuilder.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/CovarianceMatrixBuilder.java index d819c839..7bcf487d 100644 --- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/CovarianceMatrixBuilder.java +++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/CovarianceMatrixBuilder.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra.pca; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -25,26 +25,23 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra.pca; import de.lmu.ifi.dbs.elki.data.NumberVector; import de.lmu.ifi.dbs.elki.database.ids.DBIDs; -import de.lmu.ifi.dbs.elki.database.ids.distance.DistanceDBIDList; +import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDList; import de.lmu.ifi.dbs.elki.database.relation.Relation; -import de.lmu.ifi.dbs.elki.distance.distancevalue.NumberDistance; import de.lmu.ifi.dbs.elki.math.linearalgebra.Matrix; /** * Interface for computing covariance matrixes on a data set. * * @author Erich Schubert - * - * @param <V> Vector base type */ -public interface CovarianceMatrixBuilder<V extends NumberVector<?>> { +public interface CovarianceMatrixBuilder { /** * Compute Covariance Matrix for a complete database. * * @param database the database used * @return Covariance Matrix */ - Matrix processDatabase(Relation<? extends V> database); + Matrix processDatabase(Relation<? extends NumberVector> database); /** * Compute Covariance Matrix for a collection of database IDs. @@ -53,7 +50,7 @@ public interface CovarianceMatrixBuilder<V extends NumberVector<?>> { * @param database the database used * @return Covariance Matrix */ - Matrix processIds(DBIDs ids, Relation<? extends V> database); + Matrix processIds(DBIDs ids, Relation<? extends NumberVector> database); /** * Compute Covariance Matrix for a QueryResult Collection. @@ -63,10 +60,9 @@ public interface CovarianceMatrixBuilder<V extends NumberVector<?>> { * @param results a collection of QueryResults * @param database the database used * @param k the number of entries to process - * @param <D> distance type * @return Covariance Matrix */ - <D extends NumberDistance<D, ?>> Matrix processQueryResults(DistanceDBIDList<D> results, Relation<? extends V> database, int k); + Matrix processQueryResults(DoubleDBIDList results, Relation<? extends NumberVector> database, int k); /** * Compute Covariance Matrix for a QueryResult Collection. @@ -75,8 +71,7 @@ public interface CovarianceMatrixBuilder<V extends NumberVector<?>> { * * @param results a collection of QueryResults * @param database the database used - * @param <D> distance type * @return Covariance Matrix */ - <D extends NumberDistance<D, ?>> Matrix processQueryResults(DistanceDBIDList<D> results, Relation<? extends V> database); + Matrix processQueryResults(DoubleDBIDList results, Relation<? extends NumberVector> database); }
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/DropEigenPairFilter.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/DropEigenPairFilter.java index 7a2917c5..e30be31f 100644 --- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/DropEigenPairFilter.java +++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/DropEigenPairFilter.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra.pca; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/EigenPairFilter.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/EigenPairFilter.java index a3f506e1..9ce56274 100644 --- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/EigenPairFilter.java +++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/EigenPairFilter.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra.pca; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -24,7 +24,6 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra.pca; */ import de.lmu.ifi.dbs.elki.math.linearalgebra.SortedEigenPairs; -import de.lmu.ifi.dbs.elki.utilities.optionhandling.Parameterizable; /** * The eigenpair filter is used to filter eigenpairs (i.e. eigenvectors @@ -39,7 +38,7 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.Parameterizable; * @apiviz.uses SortedEigenPairs oneway - - reads * @apiviz.uses FilteredEigenPairs oneway - - «create» */ -public interface EigenPairFilter extends Parameterizable { +public interface EigenPairFilter { /** * Filters the specified eigenpairs into strong and weak eigenpairs, * where strong eigenpairs having high variances diff --git a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/FilteredEigenPairs.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/FilteredEigenPairs.java index 6cb6f07c..cad1a7b2 100644 --- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/FilteredEigenPairs.java +++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/FilteredEigenPairs.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra.pca; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/FirstNEigenPairFilter.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/FirstNEigenPairFilter.java index 79ee4ea6..e8bb6b7f 100644 --- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/FirstNEigenPairFilter.java +++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/FirstNEigenPairFilter.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra.pca; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/LimitEigenPairFilter.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/LimitEigenPairFilter.java index 4d9e7331..a63a89ce 100644 --- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/LimitEigenPairFilter.java +++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/LimitEigenPairFilter.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra.pca; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/NormalizingEigenPairFilter.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/NormalizingEigenPairFilter.java index 1d74d307..3b9865db 100644 --- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/NormalizingEigenPairFilter.java +++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/NormalizingEigenPairFilter.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra.pca; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -48,9 +48,7 @@ public class NormalizingEigenPairFilter implements EigenPairFilter { private static final Logging LOG = Logging.getLogger(NormalizingEigenPairFilter.class); /** - * Provides a new EigenPairFilter that normalizes all eigenvectors s.t. - * eigenvalue * <eigenvector, eigenvector> = 1, where <,> is the standard dot - * product + * Constructor. */ public NormalizingEigenPairFilter() { super(); diff --git a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/PCAFilteredAutotuningRunner.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/PCAFilteredAutotuningRunner.java index 4a36036a..8537ff65 100644 --- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/PCAFilteredAutotuningRunner.java +++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/PCAFilteredAutotuningRunner.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra.pca; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -29,21 +29,21 @@ import java.util.List; import de.lmu.ifi.dbs.elki.data.NumberVector; import de.lmu.ifi.dbs.elki.database.ids.DBIDIter; +import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil; import de.lmu.ifi.dbs.elki.database.ids.DBIDs; -import de.lmu.ifi.dbs.elki.database.ids.distance.DistanceDBIDList; -import de.lmu.ifi.dbs.elki.database.ids.distance.DistanceDBIDListIter; -import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceDBIDPairList; -import de.lmu.ifi.dbs.elki.database.ids.distance.ModifiableDistanceDBIDList; +import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDList; +import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDListIter; +import de.lmu.ifi.dbs.elki.database.ids.ModifiableDoubleDBIDList; import de.lmu.ifi.dbs.elki.database.relation.Relation; import de.lmu.ifi.dbs.elki.database.relation.RelationUtil; import de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.EuclideanDistanceFunction; -import de.lmu.ifi.dbs.elki.distance.distancevalue.NumberDistance; import de.lmu.ifi.dbs.elki.logging.LoggingUtil; import de.lmu.ifi.dbs.elki.math.linearalgebra.Centroid; import de.lmu.ifi.dbs.elki.math.linearalgebra.EigenPair; import de.lmu.ifi.dbs.elki.math.linearalgebra.EigenvalueDecomposition; import de.lmu.ifi.dbs.elki.math.linearalgebra.Matrix; import de.lmu.ifi.dbs.elki.math.linearalgebra.SortedEigenPairs; +import de.lmu.ifi.dbs.elki.math.linearalgebra.Vector; import de.lmu.ifi.dbs.elki.utilities.documentation.Reference; /** @@ -55,10 +55,12 @@ import de.lmu.ifi.dbs.elki.utilities.documentation.Reference; * exhibit the clearest correlation. * * @author Erich Schubert - * @param <V> vector type */ -@Reference(authors = "H.-P. Kriegel, P. Kröger, E. Schubert, A. Zimek", title = "A General Framework for Increasing the Robustness of PCA-based Correlation Clustering Algorithms", booktitle = "Proceedings of the 20th International Conference on Scientific and Statistical Database Management (SSDBM), Hong Kong, China, 2008", url = "http://dx.doi.org/10.1007/978-3-540-69497-7_27") -public class PCAFilteredAutotuningRunner<V extends NumberVector<?>> extends PCAFilteredRunner<V> { +@Reference(authors = "Hans-Peter Kriegel, Peer Kröger, Erich Schubert, Arthur Zimek", // +title = "A General Framework for Increasing the Robustness of PCA-based Correlation Clustering Algorithms",// +booktitle = "Proceedings of the 20th International Conference on Scientific and Statistical Database Management (SSDBM), Hong Kong, China, 2008",// +url = "http://dx.doi.org/10.1007/978-3-540-69497-7_27") +public class PCAFilteredAutotuningRunner extends PCAFilteredRunner { /** * Constructor. * @@ -67,18 +69,18 @@ public class PCAFilteredAutotuningRunner<V extends NumberVector<?>> extends PCAF * @param big Replacement for large values * @param small Replacement for small values */ - public PCAFilteredAutotuningRunner(CovarianceMatrixBuilder<V> covarianceMatrixBuilder, EigenPairFilter eigenPairFilter, double big, double small) { + public PCAFilteredAutotuningRunner(CovarianceMatrixBuilder covarianceMatrixBuilder, EigenPairFilter eigenPairFilter, double big, double small) { super(covarianceMatrixBuilder, eigenPairFilter, big, small); } @Override - public PCAFilteredResult processIds(DBIDs ids, Relation<? extends V> database) { + public PCAFilteredResult processIds(DBIDs ids, Relation<? extends NumberVector> database) { // Assume Euclidean distance. In the context of PCA, the neighborhood should // be L2-spherical to be unbiased. - V center = Centroid.make(database, ids).toVector(database); - DoubleDistanceDBIDPairList dres = new DoubleDistanceDBIDPairList(ids.size()); - for (DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) { - final double dist = EuclideanDistanceFunction.STATIC.doubleDistance(center, database.get(iter)); + Vector center = Centroid.make(database, ids); + ModifiableDoubleDBIDList dres = DBIDUtil.newDistanceDBIDList(ids.size()); + for(DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) { + final double dist = EuclideanDistanceFunction.STATIC.distance(center, database.get(iter)); dres.add(dist, iter); } dres.sort(); @@ -117,16 +119,16 @@ public class PCAFilteredAutotuningRunner<V extends NumberVector<?>> extends PCAF } @Override - public <D extends NumberDistance<D, ?>> PCAFilteredResult processQueryResult(DistanceDBIDList<D> results, Relation<? extends V> database) { + public PCAFilteredResult processQueryResult(DoubleDBIDList results, Relation<? extends NumberVector> database) { assertSortedByDistance(results); final int dim = RelationUtil.dimensionality(database); List<Matrix> best = new LinkedList<>(); - for (int i = 0; i < dim; i++) { + for(int i = 0; i < dim; i++) { best.add(null); } double[] beststrength = new double[dim]; - for (int i = 0; i < dim; i++) { + for(int i = 0; i < dim; i++) { beststrength[i] = -1; } int[] bestk = new int[dim]; @@ -135,11 +137,11 @@ public class PCAFilteredAutotuningRunner<V extends NumberVector<?>> extends PCAF // TODO: starting parameter shouldn't be hardcoded... int smooth = 3; int startk = 4; - if (startk > results.size() - 1) { + if(startk > results.size() - 1) { startk = results.size() - 1; } // TODO: add smoothing options, handle border cases better. - for (int k = startk; k < results.size(); k++) { + for(int k = startk; k < results.size(); k++) { // sorted eigenpairs, eigenvectors, eigenvalues Matrix covMat = covarianceMatrixBuilder.processQueryResults(results, database); EigenvalueDecomposition evd = new EigenvalueDecomposition(covMat); @@ -155,23 +157,23 @@ public class PCAFilteredAutotuningRunner<V extends NumberVector<?>> extends PCAF prev.add(new Cand(covMat, thisexplain, thisdim)); - if (prev.size() >= 2 * smooth + 1) { + if(prev.size() >= 2 * smooth + 1) { // all the same dimension? boolean samedim = true; - for (Iterator<Cand> it = prev.iterator(); it.hasNext();) { - if (it.next().dim != thisdim) { + for(Iterator<Cand> it = prev.iterator(); it.hasNext();) { + if(it.next().dim != thisdim) { samedim = false; } } - if (samedim) { + if(samedim) { // average their explain values double avgexplain = 0.0; - for (Iterator<Cand> it = prev.iterator(); it.hasNext();) { + for(Iterator<Cand> it = prev.iterator(); it.hasNext();) { avgexplain += it.next().explain; } avgexplain /= prev.size(); - if (avgexplain > beststrength[thisdim - 1]) { + if(avgexplain > beststrength[thisdim - 1]) { beststrength[thisdim - 1] = avgexplain; best.set(thisdim - 1, prev.get(smooth).m); bestk[thisdim - 1] = k - smooth; @@ -181,13 +183,13 @@ public class PCAFilteredAutotuningRunner<V extends NumberVector<?>> extends PCAF } } // Try all dimensions, lowest first. - for (int i = 0; i < dim; i++) { - if (beststrength[i] > 0.0) { + for(int i = 0; i < dim; i++) { + if(beststrength[i] > 0.0) { // If the best was the lowest or the biggest k, skip it! - if (bestk[i] == startk + smooth) { + if(bestk[i] == startk + smooth) { continue; } - if (bestk[i] == results.size() - smooth - 1) { + if(bestk[i] == results.size() - smooth - 1) { continue; } Matrix covMat = best.get(i); @@ -212,10 +214,10 @@ public class PCAFilteredAutotuningRunner<V extends NumberVector<?>> extends PCAF private double computeExplainedVariance(FilteredEigenPairs filteredEigenPairs) { double strongsum = 0.0; double weaksum = 0.0; - for (EigenPair ep : filteredEigenPairs.getStrongEigenPairs()) { + for(EigenPair ep : filteredEigenPairs.getStrongEigenPairs()) { strongsum += ep.getEigenvalue(); } - for (EigenPair ep : filteredEigenPairs.getWeakEigenPairs()) { + for(EigenPair ep : filteredEigenPairs.getWeakEigenPairs()) { weaksum += ep.getEigenvalue(); } return strongsum / (strongsum / weaksum); @@ -225,25 +227,26 @@ public class PCAFilteredAutotuningRunner<V extends NumberVector<?>> extends PCAF * Ensure that the results are sorted by distance. * * @param results Results to process - * @param <D> distance type */ - private <D extends NumberDistance<D, ?>> void assertSortedByDistance(DistanceDBIDList<D> results) { + private void assertSortedByDistance(DoubleDBIDList results) { // TODO: sort results instead? double dist = -1.0; boolean sorted = true; - for (DistanceDBIDListIter<D> it = results.iter(); it.valid(); it.advance()) { - double qr = it.getDistance().doubleValue(); - if (qr < dist) { + for(DoubleDBIDListIter it = results.iter(); it.valid(); it.advance()) { + double qr = it.doubleValue(); + if(qr < dist) { sorted = false; } dist = qr; } - if (!sorted) { + if(!sorted) { try { - ModifiableDistanceDBIDList.class.cast(results).sort(); - } catch (ClassCastException e) { + ModifiableDoubleDBIDList.class.cast(results).sort(); + } + catch(ClassCastException e) { LoggingUtil.warning("WARNING: results not sorted by distance!", e); - } catch (UnsupportedOperationException e) { + } + catch(UnsupportedOperationException e) { LoggingUtil.warning("WARNING: results not sorted by distance!", e); } } @@ -256,10 +259,10 @@ public class PCAFilteredAutotuningRunner<V extends NumberVector<?>> extends PCAF * * @apiviz.exclude */ - public static class Parameterizer<V extends NumberVector<?>> extends PCAFilteredRunner.Parameterizer<V> { + public static class Parameterizer extends PCAFilteredRunner.Parameterizer { @Override - protected PCAFilteredAutotuningRunner<V> makeInstance() { - return new PCAFilteredAutotuningRunner<>(covarianceMatrixBuilder, eigenPairFilter, big, small); + protected PCAFilteredAutotuningRunner makeInstance() { + return new PCAFilteredAutotuningRunner(covarianceMatrixBuilder, eigenPairFilter, big, small); } } } diff --git a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/PCAFilteredResult.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/PCAFilteredResult.java index 7303f530..47a8bef0 100644 --- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/PCAFilteredResult.java +++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/PCAFilteredResult.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra.pca; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/PCAFilteredRunner.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/PCAFilteredRunner.java index 670b4559..6c0a417d 100644 --- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/PCAFilteredRunner.java +++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/PCAFilteredRunner.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra.pca; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -25,9 +25,8 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra.pca; import de.lmu.ifi.dbs.elki.data.NumberVector; import de.lmu.ifi.dbs.elki.database.ids.DBIDs; -import de.lmu.ifi.dbs.elki.database.ids.distance.DistanceDBIDList; +import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDList; import de.lmu.ifi.dbs.elki.database.relation.Relation; -import de.lmu.ifi.dbs.elki.distance.distancevalue.NumberDistance; import de.lmu.ifi.dbs.elki.math.linearalgebra.EigenvalueDecomposition; import de.lmu.ifi.dbs.elki.math.linearalgebra.Matrix; import de.lmu.ifi.dbs.elki.math.linearalgebra.SortedEigenPairs; @@ -47,59 +46,21 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter; * @apiviz.landmark * @apiviz.has PCAFilteredResult oneway - - «create» * @apiviz.composedOf EigenPairFilter - * - * @param <V> Vector class to use */ -public class PCAFilteredRunner<V extends NumberVector<?>> extends PCARunner<V> { - /** - * Parameter to specify the filter for determination of the strong and weak - * eigenvectors, must be a subclass of {@link EigenPairFilter}. - * <p> - * Default value: {@link PercentageEigenPairFilter} - * </p> - * <p> - * Key: {@code -pca.filter} - * </p> - */ - public static final OptionID PCA_EIGENPAIR_FILTER = new OptionID("pca.filter", "Filter class to determine the strong and weak eigenvectors."); - - /** - * Parameter to specify a constant big value to reset high eigenvalues, must - * be a double greater than 0. - * <p> - * Default value: {@code 1.0} - * </p> - * <p> - * Key: {@code -pca.big} - * </p> - */ - public static final OptionID BIG_ID = new OptionID("pca.big", "A constant big value to reset high eigenvalues."); - - /** - * Parameter to specify a constant small value to reset low eigenvalues, must - * be a double greater than 0. - * <p> - * Default value: {@code 0.0} - * </p> - * <p> - * Key: {@code -pca.small} - * </p> - */ - public static final OptionID SMALL_ID = new OptionID("pca.small", "A constant small value to reset low eigenvalues."); - +public class PCAFilteredRunner extends PCARunner { /** * Holds the instance of the EigenPairFilter specified by - * {@link #PCA_EIGENPAIR_FILTER}. + * {@link Parameterizer#PCA_EIGENPAIR_FILTER}. */ private EigenPairFilter eigenPairFilter; /** - * Holds the value of {@link #BIG_ID}. + * Holds the value of {@link Parameterizer#BIG_ID}. */ private double big; /** - * Holds the value of {@link #SMALL_ID}. + * Holds the value of {@link Parameterizer#SMALL_ID}. */ private double small; @@ -111,7 +72,7 @@ public class PCAFilteredRunner<V extends NumberVector<?>> extends PCARunner<V> { * @param big Replacement for large eigenvalues * @param small Replacement for small eigenvalues */ - public PCAFilteredRunner(CovarianceMatrixBuilder<V> covarianceMatrixBuilder, EigenPairFilter eigenPairFilter, double big, double small) { + public PCAFilteredRunner(CovarianceMatrixBuilder covarianceMatrixBuilder, EigenPairFilter eigenPairFilter, double big, double small) { super(covarianceMatrixBuilder); this.eigenPairFilter = eigenPairFilter; this.big = big; @@ -126,7 +87,7 @@ public class PCAFilteredRunner<V extends NumberVector<?>> extends PCARunner<V> { * @return PCA result */ @Override - public PCAFilteredResult processIds(DBIDs ids, Relation<? extends V> database) { + public PCAFilteredResult processIds(DBIDs ids, Relation<? extends NumberVector> database) { return processCovarMatrix(covarianceMatrixBuilder.processIds(ids, database)); } @@ -135,11 +96,10 @@ public class PCAFilteredRunner<V extends NumberVector<?>> extends PCARunner<V> { * * @param results a collection of QueryResults * @param database the database used - * @param <D> distance type * @return PCA result */ @Override - public <D extends NumberDistance<D, ?>> PCAFilteredResult processQueryResult(DistanceDBIDList<D> results, Relation<? extends V> database) { + public PCAFilteredResult processQueryResult(DoubleDBIDList results, Relation<? extends NumberVector> database) { return processCovarMatrix(covarianceMatrixBuilder.processQueryResults(results, database)); } @@ -185,7 +145,43 @@ public class PCAFilteredRunner<V extends NumberVector<?>> extends PCARunner<V> { * * @apiviz.exclude */ - public static class Parameterizer<V extends NumberVector<?>> extends PCARunner.Parameterizer<V> { + public static class Parameterizer extends PCARunner.Parameterizer { + /** + * Parameter to specify the filter for determination of the strong and weak + * eigenvectors, must be a subclass of {@link EigenPairFilter}. + * <p> + * Default value: {@link PercentageEigenPairFilter} + * </p> + * <p> + * Key: {@code -pca.filter} + * </p> + */ + public static final OptionID PCA_EIGENPAIR_FILTER = new OptionID("pca.filter", "Filter class to determine the strong and weak eigenvectors."); + + /** + * Parameter to specify a constant big value to reset high eigenvalues, must + * be a double greater than 0. + * <p> + * Default value: {@code 1.0} + * </p> + * <p> + * Key: {@code -pca.big} + * </p> + */ + public static final OptionID BIG_ID = new OptionID("pca.big", "A constant big value to reset high eigenvalues."); + + /** + * Parameter to specify a constant small value to reset low eigenvalues, must + * be a double greater than 0. + * <p> + * Default value: {@code 0.0} + * </p> + * <p> + * Key: {@code -pca.small} + * </p> + */ + public static final OptionID SMALL_ID = new OptionID("pca.small", "A constant small value to reset low eigenvalues."); + /** * Holds the instance of the EigenPairFilter specified by * {@link #PCA_EIGENPAIR_FILTER}. @@ -228,8 +224,8 @@ public class PCAFilteredRunner<V extends NumberVector<?>> extends PCARunner<V> { } @Override - protected PCAFilteredRunner<V> makeInstance() { - return new PCAFilteredRunner<>(covarianceMatrixBuilder, eigenPairFilter, big, small); + protected PCAFilteredRunner makeInstance() { + return new PCAFilteredRunner(covarianceMatrixBuilder, eigenPairFilter, big, small); } } } diff --git a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/PCAResult.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/PCAResult.java index 1634cbf0..b75600d6 100644 --- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/PCAResult.java +++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/PCAResult.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra.pca; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/PCARunner.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/PCARunner.java index 91447024..2bfbaa8d 100644 --- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/PCARunner.java +++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/PCARunner.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra.pca; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -23,18 +23,15 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra.pca; along with this program. If not, see <http://www.gnu.org/licenses/>. */ - import de.lmu.ifi.dbs.elki.data.NumberVector; import de.lmu.ifi.dbs.elki.database.ids.DBIDs; -import de.lmu.ifi.dbs.elki.database.ids.distance.DistanceDBIDList; +import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDList; import de.lmu.ifi.dbs.elki.database.relation.Relation; -import de.lmu.ifi.dbs.elki.distance.distancevalue.NumberDistance; import de.lmu.ifi.dbs.elki.math.linearalgebra.EigenvalueDecomposition; import de.lmu.ifi.dbs.elki.math.linearalgebra.Matrix; import de.lmu.ifi.dbs.elki.math.linearalgebra.SortedEigenPairs; import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer; import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID; -import de.lmu.ifi.dbs.elki.utilities.optionhandling.Parameterizable; import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization; import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter; @@ -53,10 +50,8 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter; * @apiviz.landmark * @apiviz.uses PCAResult oneway - - «create» * @apiviz.composedOf CovarianceMatrixBuilder - * - * @param <V> Vector type */ -public class PCARunner<V extends NumberVector<?>> implements Parameterizable { +public class PCARunner { /** * Parameter to specify the class to compute the covariance matrix, must be a * subclass of {@link CovarianceMatrixBuilder}. @@ -72,14 +67,14 @@ public class PCARunner<V extends NumberVector<?>> implements Parameterizable { /** * The covariance computation class. */ - protected CovarianceMatrixBuilder<V> covarianceMatrixBuilder; + protected CovarianceMatrixBuilder covarianceMatrixBuilder; /** * Constructor. * * @param covarianceMatrixBuilder Class for computing the covariance matrix */ - public PCARunner(CovarianceMatrixBuilder<V> covarianceMatrixBuilder) { + public PCARunner(CovarianceMatrixBuilder covarianceMatrixBuilder) { super(); this.covarianceMatrixBuilder = covarianceMatrixBuilder; } @@ -90,7 +85,7 @@ public class PCARunner<V extends NumberVector<?>> implements Parameterizable { * @param database the database used * @return PCA result */ - public PCAResult processDatabase(Relation<? extends V> database) { + public PCAResult processDatabase(Relation<? extends NumberVector> database) { return processCovarMatrix(covarianceMatrixBuilder.processDatabase(database)); } @@ -101,7 +96,7 @@ public class PCARunner<V extends NumberVector<?>> implements Parameterizable { * @param database the database used * @return PCA result */ - public PCAResult processIds(DBIDs ids, Relation<? extends V> database) { + public PCAResult processIds(DBIDs ids, Relation<? extends NumberVector> database) { return processCovarMatrix(covarianceMatrixBuilder.processIds(ids, database)); } @@ -110,10 +105,9 @@ public class PCARunner<V extends NumberVector<?>> implements Parameterizable { * * @param results a collection of QueryResults * @param database the database used - * @param <D> distance type * @return PCA result */ - public <D extends NumberDistance<D, ?>> PCAResult processQueryResult(DistanceDBIDList<D> results, Relation<? extends V> database) { + public PCAResult processQueryResult(DoubleDBIDList results, Relation<? extends NumberVector> database) { return processCovarMatrix(covarianceMatrixBuilder.processQueryResults(results, database)); } @@ -145,7 +139,7 @@ public class PCARunner<V extends NumberVector<?>> implements Parameterizable { * * @return covariance matrix builder in use */ - public CovarianceMatrixBuilder<V> getCovarianceMatrixBuilder() { + public CovarianceMatrixBuilder getCovarianceMatrixBuilder() { return covarianceMatrixBuilder; } @@ -154,7 +148,7 @@ public class PCARunner<V extends NumberVector<?>> implements Parameterizable { * * @param covarianceBuilder New covariance matrix builder. */ - public void setCovarianceMatrixBuilder(CovarianceMatrixBuilder<V> covarianceBuilder) { + public void setCovarianceMatrixBuilder(CovarianceMatrixBuilder covarianceBuilder) { this.covarianceMatrixBuilder = covarianceBuilder; } @@ -165,24 +159,24 @@ public class PCARunner<V extends NumberVector<?>> implements Parameterizable { * * @apiviz.exclude */ - public static class Parameterizer<V extends NumberVector<?>> extends AbstractParameterizer { + public static class Parameterizer extends AbstractParameterizer { /** * The covariance computation class. */ - protected CovarianceMatrixBuilder<V> covarianceMatrixBuilder; + protected CovarianceMatrixBuilder covarianceMatrixBuilder; @Override protected void makeOptions(Parameterization config) { super.makeOptions(config); - ObjectParameter<CovarianceMatrixBuilder<V>> covarianceP = new ObjectParameter<>(PCA_COVARIANCE_MATRIX, CovarianceMatrixBuilder.class, StandardCovarianceMatrixBuilder.class); + ObjectParameter<CovarianceMatrixBuilder> covarianceP = new ObjectParameter<>(PCA_COVARIANCE_MATRIX, CovarianceMatrixBuilder.class, StandardCovarianceMatrixBuilder.class); if(config.grab(covarianceP)) { covarianceMatrixBuilder = covarianceP.instantiateClass(config); } } @Override - protected PCARunner<V> makeInstance() { - return new PCARunner<>(covarianceMatrixBuilder); + protected PCARunner makeInstance() { + return new PCARunner(covarianceMatrixBuilder); } } }
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/PercentageEigenPairFilter.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/PercentageEigenPairFilter.java index 5602228e..02814d74 100644 --- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/PercentageEigenPairFilter.java +++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/PercentageEigenPairFilter.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra.pca; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/ProgressiveEigenPairFilter.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/ProgressiveEigenPairFilter.java index 4f412257..9ea532f9 100644 --- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/ProgressiveEigenPairFilter.java +++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/ProgressiveEigenPairFilter.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra.pca; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/RANSACCovarianceMatrixBuilder.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/RANSACCovarianceMatrixBuilder.java index 2b369a32..f5bff525 100644 --- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/RANSACCovarianceMatrixBuilder.java +++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/RANSACCovarianceMatrixBuilder.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra.pca; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -33,8 +33,8 @@ import de.lmu.ifi.dbs.elki.database.relation.RelationUtil; import de.lmu.ifi.dbs.elki.math.linearalgebra.CovarianceMatrix; import de.lmu.ifi.dbs.elki.math.linearalgebra.Matrix; import de.lmu.ifi.dbs.elki.math.linearalgebra.Vector; +import de.lmu.ifi.dbs.elki.math.random.RandomFactory; import de.lmu.ifi.dbs.elki.math.statistics.distribution.ChiSquaredDistribution; -import de.lmu.ifi.dbs.elki.utilities.RandomFactory; import de.lmu.ifi.dbs.elki.utilities.documentation.Reference; import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer; import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID; @@ -72,11 +72,11 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.RandomParameter; * </p> * * @author Erich Schubert - * - * @param <V> Vector type */ -@Reference(authors = "Hans-Peter Kriegel, Peer Kröger, Erich Schubert, Arthur Zimek", title = "Outlier Detection in Arbitrarily Oriented Subspaces", booktitle = "Proc. IEEE International Conference on Data Mining (ICDM 2012)") -public class RANSACCovarianceMatrixBuilder<V extends NumberVector<?>> extends AbstractCovarianceMatrixBuilder<V> { +@Reference(authors = "Hans-Peter Kriegel, Peer Kröger, Erich Schubert, Arthur Zimek", // +title = "Outlier Detection in Arbitrarily Oriented Subspaces", // +booktitle = "Proc. IEEE International Conference on Data Mining (ICDM 2012)") +public class RANSACCovarianceMatrixBuilder extends AbstractCovarianceMatrixBuilder { /** * Number of iterations to perform */ @@ -101,7 +101,7 @@ public class RANSACCovarianceMatrixBuilder<V extends NumberVector<?>> extends Ab @Reference(title = "Random sample consensus: a paradigm for model fitting with applications to image analysis and automated cartography", authors = "M.A. Fischler, R.C. Bolles", booktitle = "Communications of the ACM, Vol. 24 Issue 6", url = "http://dx.doi.org/10.1145/358669.358692") @Override - public Matrix processIds(DBIDs ids, Relation<? extends V> relation) { + public Matrix processIds(DBIDs ids, Relation<? extends NumberVector> relation) { final int dim = RelationUtil.dimensionality(relation); DBIDs best = DBIDUtil.EMPTYDBIDS; @@ -144,10 +144,8 @@ public class RANSACCovarianceMatrixBuilder<V extends NumberVector<?>> extends Ab * @author Erich Schubert * * @apiviz.exclude - * - * @param <V> Vector type */ - public static class Parameterizer<V extends NumberVector<?>> extends AbstractParameterizer { + public static class Parameterizer extends AbstractParameterizer { /** * Number of iterations. */ @@ -183,8 +181,8 @@ public class RANSACCovarianceMatrixBuilder<V extends NumberVector<?>> extends Ab } @Override - protected RANSACCovarianceMatrixBuilder<V> makeInstance() { - return new RANSACCovarianceMatrixBuilder<>(iterations, rnd); + protected RANSACCovarianceMatrixBuilder makeInstance() { + return new RANSACCovarianceMatrixBuilder(iterations, rnd); } } } diff --git a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/RelativeEigenPairFilter.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/RelativeEigenPairFilter.java index 32092ce9..fd80c93f 100644 --- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/RelativeEigenPairFilter.java +++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/RelativeEigenPairFilter.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra.pca; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/SignificantEigenPairFilter.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/SignificantEigenPairFilter.java index 6219f77f..9daaefa0 100644 --- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/SignificantEigenPairFilter.java +++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/SignificantEigenPairFilter.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra.pca; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/StandardCovarianceMatrixBuilder.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/StandardCovarianceMatrixBuilder.java index 90dd59c1..ec889bcb 100644 --- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/StandardCovarianceMatrixBuilder.java +++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/StandardCovarianceMatrixBuilder.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra.pca; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -36,10 +36,8 @@ import de.lmu.ifi.dbs.elki.math.linearalgebra.Matrix; * @author Erich Schubert * * @apiviz.uses CovarianceMatrix - * - * @param <V> Vector class to use. */ -public class StandardCovarianceMatrixBuilder<V extends NumberVector<?>> extends AbstractCovarianceMatrixBuilder<V> { +public class StandardCovarianceMatrixBuilder extends AbstractCovarianceMatrixBuilder { /** * Compute Covariance Matrix for a complete database. * @@ -47,7 +45,7 @@ public class StandardCovarianceMatrixBuilder<V extends NumberVector<?>> extends * @return Covariance Matrix */ @Override - public Matrix processDatabase(Relation<? extends V> database) { + public Matrix processDatabase(Relation<? extends NumberVector> database) { return CovarianceMatrix.make(database).destroyToNaiveMatrix(); } @@ -59,7 +57,7 @@ public class StandardCovarianceMatrixBuilder<V extends NumberVector<?>> extends * @return Covariance Matrix */ @Override - public Matrix processIds(DBIDs ids, Relation<? extends V> database) { + public Matrix processIds(DBIDs ids, Relation<? extends NumberVector> database) { return CovarianceMatrix.make(database, ids).destroyToNaiveMatrix(); } }
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/WeakEigenPairFilter.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/WeakEigenPairFilter.java index 92e1e32e..2315bd8b 100644 --- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/WeakEigenPairFilter.java +++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/WeakEigenPairFilter.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra.pca; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/WeightedCovarianceMatrixBuilder.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/WeightedCovarianceMatrixBuilder.java index 236a24bc..801decd7 100644 --- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/WeightedCovarianceMatrixBuilder.java +++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/WeightedCovarianceMatrixBuilder.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra.pca; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -26,19 +26,16 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra.pca; import de.lmu.ifi.dbs.elki.data.NumberVector; import de.lmu.ifi.dbs.elki.database.ids.DBIDIter; import de.lmu.ifi.dbs.elki.database.ids.DBIDs; -import de.lmu.ifi.dbs.elki.database.ids.distance.DistanceDBIDList; -import de.lmu.ifi.dbs.elki.database.ids.distance.DistanceDBIDPair; -import de.lmu.ifi.dbs.elki.database.ids.distance.DistanceDBIDListIter; -import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceDBIDPair; +import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDList; +import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDListIter; import de.lmu.ifi.dbs.elki.database.relation.Relation; import de.lmu.ifi.dbs.elki.database.relation.RelationUtil; import de.lmu.ifi.dbs.elki.distance.distancefunction.PrimitiveDistanceFunction; import de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.EuclideanDistanceFunction; -import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance; -import de.lmu.ifi.dbs.elki.distance.distancevalue.NumberDistance; import de.lmu.ifi.dbs.elki.math.linearalgebra.Centroid; import de.lmu.ifi.dbs.elki.math.linearalgebra.CovarianceMatrix; import de.lmu.ifi.dbs.elki.math.linearalgebra.Matrix; +import de.lmu.ifi.dbs.elki.math.linearalgebra.Vector; import de.lmu.ifi.dbs.elki.math.linearalgebra.pca.weightfunctions.ConstantWeight; import de.lmu.ifi.dbs.elki.math.linearalgebra.pca.weightfunctions.WeightFunction; import de.lmu.ifi.dbs.elki.utilities.documentation.Description; @@ -67,13 +64,14 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter; * @apiviz.has WeightFunction * @apiviz.has PrimitiveDistanceFunction * @apiviz.uses CovarianceMatrix - * - * @param <V> Vector class to use */ @Title("Weighted Covariance Matrix / PCA") @Description("A PCA modification by using weights while building the covariance matrix, to obtain more stable results") -@Reference(authors = "H.-P. Kriegel, P. Kröger, E. Schubert, A. Zimek", title = "A General Framework for Increasing the Robustness of PCA-based Correlation Clustering Algorithms", booktitle = "Proceedings of the 20th International Conference on Scientific and Statistical Database Management (SSDBM), Hong Kong, China, 2008", url = "http://dx.doi.org/10.1007/978-3-540-69497-7_27") -public class WeightedCovarianceMatrixBuilder<V extends NumberVector<?>> extends AbstractCovarianceMatrixBuilder<V> { +@Reference(authors = "Hans-Peter Kriegel, Peer Kröger, Erich Schubert, Arthur Zimek", // +title = "A General Framework for Increasing the Robustness of PCA-based Correlation Clustering Algorithms",// +booktitle = "Proceedings of the 20th International Conference on Scientific and Statistical Database Management (SSDBM), Hong Kong, China, 2008",// +url = "http://dx.doi.org/10.1007/978-3-540-69497-7_27") +public class WeightedCovarianceMatrixBuilder extends AbstractCovarianceMatrixBuilder { /** * Parameter to specify the weight function to use in weighted PCA, must * implement @@ -93,8 +91,7 @@ public class WeightedCovarianceMatrixBuilder<V extends NumberVector<?>> extends /** * Holds the distance function used for weight calculation. */ - // TODO: make configurable? - private PrimitiveDistanceFunction<? super V, DoubleDistance> weightDistance = EuclideanDistanceFunction.STATIC; + private PrimitiveDistanceFunction<? super NumberVector> weightDistance = EuclideanDistanceFunction.STATIC; /** * Constructor. @@ -117,18 +114,18 @@ public class WeightedCovarianceMatrixBuilder<V extends NumberVector<?>> extends * @return Covariance matrix */ @Override - public Matrix processIds(DBIDs ids, Relation<? extends V> relation) { + public Matrix processIds(DBIDs ids, Relation<? extends NumberVector> relation) { final int dim = RelationUtil.dimensionality(relation); final CovarianceMatrix cmat = new CovarianceMatrix(dim); - final V centroid = Centroid.make(relation, ids).toVector(relation); + final Vector centroid = Centroid.make(relation, ids); // find maximum distance double maxdist = 0.0; double stddev = 0.0; { - for (DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) { - V obj = relation.get(iter); - double distance = weightDistance.distance(centroid, obj).doubleValue(); + for(DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) { + NumberVector obj = relation.get(iter); + double distance = weightDistance.distance(centroid, obj); stddev += distance * distance; if(distance > maxdist) { maxdist = distance; @@ -141,9 +138,9 @@ public class WeightedCovarianceMatrixBuilder<V extends NumberVector<?>> extends stddev = Math.sqrt(stddev / ids.size()); } - for (DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) { - V obj = relation.get(iter); - double distance = weightDistance.distance(centroid, obj).doubleValue(); + for(DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) { + NumberVector obj = relation.get(iter); + double distance = weightDistance.distance(centroid, obj); double weight = weightfunction.getWeight(distance, maxdist, stddev); cmat.put(obj, weight); } @@ -158,11 +155,10 @@ public class WeightedCovarianceMatrixBuilder<V extends NumberVector<?>> extends * @param results a collection of QueryResults * @param database the database used * @param k number of elements to process - * @param <D> distance type * @return Covariance Matrix */ @Override - public <D extends NumberDistance<D, ?>> Matrix processQueryResults(DistanceDBIDList<D> results, Relation<? extends V> database, int k) { + public Matrix processQueryResults(DoubleDBIDList results, Relation<? extends NumberVector> database, int k) { final int dim = RelationUtil.dimensionality(database); final CovarianceMatrix cmat = new CovarianceMatrix(dim); @@ -176,15 +172,8 @@ public class WeightedCovarianceMatrixBuilder<V extends NumberVector<?>> extends double stddev = 0.0; { int i = 0; - for (DistanceDBIDListIter<D> it = results.iter(); it.valid() && i < k; it.advance(), k++) { - DistanceDBIDPair<D> res = it.getDistancePair(); - final double dist; - if(res instanceof DoubleDistanceDBIDPair) { - dist = ((DoubleDistanceDBIDPair) res).doubleDistance(); - } - else { - dist = res.getDistance().doubleValue(); - } + for(DoubleDBIDListIter it = results.iter(); it.valid() && i < k; it.advance(), k++) { + final double dist = it.doubleValue(); stddev += dist * dist; if(dist > maxdist) { maxdist = dist; @@ -198,17 +187,9 @@ public class WeightedCovarianceMatrixBuilder<V extends NumberVector<?>> extends // calculate weighted PCA int i = 0; - for (DistanceDBIDListIter<D> it = results.iter(); it.valid() && i < k; it.advance(), k++) { - DistanceDBIDPair<D> res = it.getDistancePair(); - final double dist; - if(res instanceof DoubleDistanceDBIDPair) { - dist = ((DoubleDistanceDBIDPair) res).doubleDistance(); - } - else { - dist = res.getDistance().doubleValue(); - } - - V obj = database.get(res); + for(DoubleDBIDListIter it = results.iter(); it.valid() && i < k; it.advance(), k++) { + final double dist = it.doubleValue(); + NumberVector obj = database.get(it); double weight = weightfunction.getWeight(dist, maxdist, stddev); cmat.put(obj, weight); } @@ -222,7 +203,7 @@ public class WeightedCovarianceMatrixBuilder<V extends NumberVector<?>> extends * * @apiviz.exclude */ - public static class Parameterizer<V extends NumberVector<?>> extends AbstractParameterizer { + public static class Parameterizer extends AbstractParameterizer { /** * Weight function. */ @@ -238,8 +219,8 @@ public class WeightedCovarianceMatrixBuilder<V extends NumberVector<?>> extends } @Override - protected WeightedCovarianceMatrixBuilder<V> makeInstance() { - return new WeightedCovarianceMatrixBuilder<>(weightfunction); + protected WeightedCovarianceMatrixBuilder makeInstance() { + return new WeightedCovarianceMatrixBuilder(weightfunction); } } }
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/package-info.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/package-info.java index 2606234b..8ca349d0 100644 --- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/package-info.java +++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/package-info.java @@ -1,11 +1,15 @@ /** - * <p>Principal Component Analysis (PCA) and Eigenvector processing.</p> + * <p>Principal Component Analysis (PCA) and Eigenvector processing.</p> + * + * @apiviz.exclude de.lmu.ifi.dbs.elki.datasource.filter.transform + * @apiviz.exclude de.lmu.ifi.dbs.elki.index + * @apiviz.exclude de.lmu.ifi.dbs.elki.algorithm */ /* This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures -Copyright (C) 2013 +Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/weightfunctions/ConstantWeight.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/weightfunctions/ConstantWeight.java index 2252b512..f326e60b 100644 --- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/weightfunctions/ConstantWeight.java +++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/weightfunctions/ConstantWeight.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra.pca.weightfunctions; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/weightfunctions/ErfcStddevWeight.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/weightfunctions/ErfcStddevWeight.java index 645eff29..08e2fb8a 100644 --- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/weightfunctions/ErfcStddevWeight.java +++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/weightfunctions/ErfcStddevWeight.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra.pca.weightfunctions; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/weightfunctions/ErfcWeight.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/weightfunctions/ErfcWeight.java index be7626a3..3cd6096a 100644 --- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/weightfunctions/ErfcWeight.java +++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/weightfunctions/ErfcWeight.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra.pca.weightfunctions; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/weightfunctions/ExponentialStddevWeight.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/weightfunctions/ExponentialStddevWeight.java index 7495805d..c99c4e9b 100644 --- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/weightfunctions/ExponentialStddevWeight.java +++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/weightfunctions/ExponentialStddevWeight.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra.pca.weightfunctions; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/weightfunctions/ExponentialWeight.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/weightfunctions/ExponentialWeight.java index 13653ac8..eadb2c21 100644 --- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/weightfunctions/ExponentialWeight.java +++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/weightfunctions/ExponentialWeight.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra.pca.weightfunctions; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/weightfunctions/GaussStddevWeight.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/weightfunctions/GaussStddevWeight.java index 698cd50d..1bc57b21 100644 --- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/weightfunctions/GaussStddevWeight.java +++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/weightfunctions/GaussStddevWeight.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra.pca.weightfunctions; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/weightfunctions/GaussWeight.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/weightfunctions/GaussWeight.java index bdb1d9d9..cd14ae3a 100644 --- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/weightfunctions/GaussWeight.java +++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/weightfunctions/GaussWeight.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra.pca.weightfunctions; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/weightfunctions/InverseLinearWeight.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/weightfunctions/InverseLinearWeight.java index e82b51c9..6bcbee2e 100644 --- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/weightfunctions/InverseLinearWeight.java +++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/weightfunctions/InverseLinearWeight.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra.pca.weightfunctions; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/weightfunctions/InverseProportionalStddevWeight.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/weightfunctions/InverseProportionalStddevWeight.java index b8577617..7f17c063 100644 --- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/weightfunctions/InverseProportionalStddevWeight.java +++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/weightfunctions/InverseProportionalStddevWeight.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra.pca.weightfunctions; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/weightfunctions/InverseProportionalWeight.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/weightfunctions/InverseProportionalWeight.java index b51c85fa..21e673b3 100644 --- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/weightfunctions/InverseProportionalWeight.java +++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/weightfunctions/InverseProportionalWeight.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra.pca.weightfunctions; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/weightfunctions/LinearWeight.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/weightfunctions/LinearWeight.java index 68448433..45657631 100644 --- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/weightfunctions/LinearWeight.java +++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/weightfunctions/LinearWeight.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra.pca.weightfunctions; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/weightfunctions/QuadraticStddevWeight.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/weightfunctions/QuadraticStddevWeight.java index 1279b22d..52188952 100644 --- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/weightfunctions/QuadraticStddevWeight.java +++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/weightfunctions/QuadraticStddevWeight.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra.pca.weightfunctions; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/weightfunctions/QuadraticWeight.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/weightfunctions/QuadraticWeight.java index b23713a6..0b4577e4 100644 --- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/weightfunctions/QuadraticWeight.java +++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/weightfunctions/QuadraticWeight.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra.pca.weightfunctions; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/weightfunctions/WeightFunction.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/weightfunctions/WeightFunction.java index 0c9f8ae0..e67f6b73 100644 --- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/weightfunctions/WeightFunction.java +++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/weightfunctions/WeightFunction.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra.pca.weightfunctions; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/weightfunctions/package-info.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/weightfunctions/package-info.java index 7869427b..19bfd4dc 100644 --- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/weightfunctions/package-info.java +++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/weightfunctions/package-info.java @@ -5,7 +5,7 @@ This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures -Copyright (C) 2013 +Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/randomprojections/AbstractRandomProjectionFamily.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/randomprojections/AbstractRandomProjectionFamily.java index e7f8198a..b20a9aed 100644 --- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/randomprojections/AbstractRandomProjectionFamily.java +++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/randomprojections/AbstractRandomProjectionFamily.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra.randomprojections; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -29,7 +29,7 @@ import de.lmu.ifi.dbs.elki.data.NumberVector; import de.lmu.ifi.dbs.elki.data.VectorUtil; import de.lmu.ifi.dbs.elki.math.linearalgebra.Matrix; import de.lmu.ifi.dbs.elki.math.linearalgebra.Vector; -import de.lmu.ifi.dbs.elki.utilities.RandomFactory; +import de.lmu.ifi.dbs.elki.math.random.RandomFactory; import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer; import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID; import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization; @@ -116,7 +116,7 @@ public abstract class AbstractRandomProjectionFamily implements RandomProjection } @Override - public double[] project(NumberVector<?> in) { + public double[] project(NumberVector in) { for (int d = 0; d < vals.length; d++) { vals[d] = in.doubleValue(d); } diff --git a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/randomprojections/AchlioptasRandomProjectionFamily.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/randomprojections/AchlioptasRandomProjectionFamily.java index c07a9590..69e68e19 100644 --- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/randomprojections/AchlioptasRandomProjectionFamily.java +++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/randomprojections/AchlioptasRandomProjectionFamily.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra.randomprojections; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -23,7 +23,7 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra.randomprojections; along with this program. If not, see <http://www.gnu.org/licenses/>. */ import de.lmu.ifi.dbs.elki.math.linearalgebra.Matrix; -import de.lmu.ifi.dbs.elki.utilities.RandomFactory; +import de.lmu.ifi.dbs.elki.math.random.RandomFactory; import de.lmu.ifi.dbs.elki.utilities.documentation.Reference; import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID; import de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints.CommonConstraints; diff --git a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/randomprojections/CauchyRandomProjectionFamily.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/randomprojections/CauchyRandomProjectionFamily.java index 0e7aa7e1..20892ff4 100644 --- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/randomprojections/CauchyRandomProjectionFamily.java +++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/randomprojections/CauchyRandomProjectionFamily.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra.randomprojections; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -23,7 +23,7 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra.randomprojections; along with this program. If not, see <http://www.gnu.org/licenses/>. */ import de.lmu.ifi.dbs.elki.math.linearalgebra.Matrix; -import de.lmu.ifi.dbs.elki.utilities.RandomFactory; +import de.lmu.ifi.dbs.elki.math.random.RandomFactory; import de.lmu.ifi.dbs.elki.utilities.documentation.Reference; /** diff --git a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/randomprojections/GaussianRandomProjectionFamily.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/randomprojections/GaussianRandomProjectionFamily.java index 722c8454..7fa8863a 100644 --- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/randomprojections/GaussianRandomProjectionFamily.java +++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/randomprojections/GaussianRandomProjectionFamily.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra.randomprojections; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -23,7 +23,7 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra.randomprojections; along with this program. If not, see <http://www.gnu.org/licenses/>. */ import de.lmu.ifi.dbs.elki.math.linearalgebra.Matrix; -import de.lmu.ifi.dbs.elki.utilities.RandomFactory; +import de.lmu.ifi.dbs.elki.math.random.RandomFactory; import de.lmu.ifi.dbs.elki.utilities.documentation.Reference; /** diff --git a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/randomprojections/RandomProjectionFamily.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/randomprojections/RandomProjectionFamily.java index aa796383..267770d5 100644 --- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/randomprojections/RandomProjectionFamily.java +++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/randomprojections/RandomProjectionFamily.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra.randomprojections; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -54,7 +54,7 @@ public interface RandomProjectionFamily { * @param in Input vector * @return Projected vector */ - double[] project(NumberVector<?> in); + double[] project(NumberVector in); /** * Get the output dimensionality. diff --git a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/randomprojections/RandomSubsetProjectionFamily.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/randomprojections/RandomSubsetProjectionFamily.java index 94a4a29c..b5f282dd 100644 --- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/randomprojections/RandomSubsetProjectionFamily.java +++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/randomprojections/RandomSubsetProjectionFamily.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra.randomprojections; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -26,7 +26,7 @@ import java.util.Arrays; import java.util.Random; import de.lmu.ifi.dbs.elki.data.NumberVector; -import de.lmu.ifi.dbs.elki.utilities.RandomFactory; +import de.lmu.ifi.dbs.elki.math.random.RandomFactory; import de.lmu.ifi.dbs.elki.utilities.documentation.Reference; /** @@ -137,7 +137,7 @@ public class RandomSubsetProjectionFamily extends AbstractRandomProjectionFamily } @Override - public double[] project(NumberVector<?> in) { + public double[] project(NumberVector in) { double[] buf = new double[dims.length]; for (int i = 0; i < dims.length; i++) { buf[i] = in.doubleValue(dims[i]); diff --git a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/randomprojections/package-info.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/randomprojections/package-info.java index 3ddd4a5c..ea22ccef 100644 --- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/randomprojections/package-info.java +++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/randomprojections/package-info.java @@ -5,7 +5,7 @@ This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/package-info.java b/src/de/lmu/ifi/dbs/elki/math/package-info.java index 5a5f168f..33468cae 100644 --- a/src/de/lmu/ifi/dbs/elki/math/package-info.java +++ b/src/de/lmu/ifi/dbs/elki/math/package-info.java @@ -5,7 +5,7 @@ This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures -Copyright (C) 2013 +Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/random/FastNonThreadsafeRandom.java b/src/de/lmu/ifi/dbs/elki/math/random/FastNonThreadsafeRandom.java new file mode 100644 index 00000000..da1c01fa --- /dev/null +++ b/src/de/lmu/ifi/dbs/elki/math/random/FastNonThreadsafeRandom.java @@ -0,0 +1,76 @@ +package de.lmu.ifi.dbs.elki.math.random; + +/* + This file is part of ELKI: + Environment for Developing KDD-Applications Supported by Index-Structures + + Copyright (C) 2014 + Ludwig-Maximilians-Universität München + Lehr- und Forschungseinheit für Datenbanksysteme + ELKI Development Team + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero 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 Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +import java.util.Random; + +/** + * Drop-in replacement for {@link java.util.Random}, but not using atomic long + * seeds. This implementation is <em>no longer thread-safe</em> (but faster)! + * + * @author Erich Schubert + */ +public class FastNonThreadsafeRandom extends Random { + /** + * Serial version number. + */ + private static final long serialVersionUID = 1L; + + // These are the same constants as in {@link java.util.Random} + // since we want to leave the random sequence unchanged. + private static final long multiplier = 0x5DEECE66DL, addend = 0xBL, + mask = (1L << 48) - 1; + + /** + * The random seed. We can't use super.seed. + */ + private long seed; + + /** + * Constructor called only by localRandom.initialValue. + */ + public FastNonThreadsafeRandom() { + super(); + } + + /** + * Constructor. + * + * @param seed Random generator seed. + */ + public FastNonThreadsafeRandom(long seed) { + this.seed = (seed ^ multiplier) & mask; + } + + @Override + public void setSeed(long seed) { + this.seed = (seed ^ multiplier) & mask; + } + + @Override + protected int next(int bits) { + // Linear Congruential Generator: + seed = (seed * multiplier + addend) & mask; + return (int) (seed >>> (48 - bits)); + } +} diff --git a/src/de/lmu/ifi/dbs/elki/math/random/RandomFactory.java b/src/de/lmu/ifi/dbs/elki/math/random/RandomFactory.java new file mode 100644 index 00000000..09e7202f --- /dev/null +++ b/src/de/lmu/ifi/dbs/elki/math/random/RandomFactory.java @@ -0,0 +1,103 @@ +package de.lmu.ifi.dbs.elki.math.random; + +/* + This file is part of ELKI: + Environment for Developing KDD-Applications Supported by Index-Structures + + Copyright (C) 2014 + Ludwig-Maximilians-Universität München + Lehr- und Forschungseinheit für Datenbanksysteme + ELKI Development Team + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero 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 Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +import java.util.Random; + +/** + * RandomFactory is responsible for creating {@link Random} generator objects. + * It does not provide individual random numbers, but will create a random + * generator; either using a fixed seed or random seeded (default). + * + * TODO: allow global fixing of seed, to make whole experiments reproducible, + * without having to set every single seed. + * + * @author Erich Schubert + * + * @apiviz.has Random + */ +public class RandomFactory { + /** + * Global default factory + */ + public static RandomFactory DEFAULT = new RandomFactory(null); + + /** + * Seed + */ + private Long seed = null; + + /** + * Factory method: Get a random factory for the given seed. + * + * @param seed Seed + * @return Instance + */ + public static RandomFactory get(Long seed) { + if(seed == null) { + return DEFAULT; + } + else { + return new RandomFactory(seed); + } + } + + /** + * Constructor. + * + * @param seed Random seed + */ + public RandomFactory(Long seed) { + super(); + this.seed = seed; + } + + /** + * Get a random generator. + * + * @return Random generator + */ + public Random getRandom() { + if(seed != null) { + return new Random(seed.longValue()); + } + else { + return new Random(); + } + } + + /** + * Get a <em>non-threadsafe</em> random generator. + * + * @return Random generator + */ + public Random getSingleThreadedRandom() { + if(seed != null) { + return new FastNonThreadsafeRandom(seed.longValue()); + } + else { + return new FastNonThreadsafeRandom(); + } + } +}
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/math/random/XorShift1024NonThreadsafeRandom.java b/src/de/lmu/ifi/dbs/elki/math/random/XorShift1024NonThreadsafeRandom.java new file mode 100644 index 00000000..df07d9aa --- /dev/null +++ b/src/de/lmu/ifi/dbs/elki/math/random/XorShift1024NonThreadsafeRandom.java @@ -0,0 +1,110 @@ +package de.lmu.ifi.dbs.elki.math.random; + +/* + This file is part of ELKI: + Environment for Developing KDD-Applications Supported by Index-Structures + + Copyright (C) 2014 + Ludwig-Maximilians-Universität München + Lehr- und Forschungseinheit für Datenbanksysteme + ELKI Development Team + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero 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 Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +import java.util.Random; + +import de.lmu.ifi.dbs.elki.utilities.documentation.Reference; + +/** + * Replacement for Java's {@link java.util.Random} class, using a different + * random number generation strategy. Java's random generator is optimized for + * speed, but may lack the randomness needed for more complex experiments. + * + * This approach is based on the work on XorShift1024* by Sebastiano Vigna, with + * the original copyright statement: + * <p> + * Written in 2014 by Sebastiano Vigna (vigna@acm.org) + * + * To the extent possible under law, the author has dedicated all copyright and + * related and neighboring rights to this software to the public domain + * worldwide. This software is distributed without any warranty. + * + * See http://creativecommons.org/publicdomain/zero/1.0/ + * </p> + * + * @author Erich Schubert + */ +@Reference(authors = "S. Vigna", // +title = "An experimental exploration of Marsaglia's xorshift generators, scrambled", // +booktitle = "", url = "http://vigna.di.unimi.it/ftp/papers/xorshift.pdf") +public class XorShift1024NonThreadsafeRandom extends Random { + /** + * Serial version number. + */ + private static final long serialVersionUID = 1L; + + /** + * State of random number generator. + */ + private long[] x; + + /** + * For rotating amongst states + */ + int p = 0; + + /** + * Constructor called only by localRandom.initialValue. + */ + public XorShift1024NonThreadsafeRandom() { + super(); + } + + /** + * Constructor. + * + * @param seed Random generator seed. + */ + public XorShift1024NonThreadsafeRandom(long seed) { + super(seed); + } + + @Override + public void setSeed(long seed) { + this.x = new long[16]; + long xor64 = seed != 0 ? seed : 4101842887655102017L; + // XorShift64* generator to seed: + for(int i = 0; i < 16; i++) { + xor64 ^= xor64 >>> 12; // a + xor64 ^= xor64 << 25; // b + xor64 ^= xor64 >>> 27; // c + x[i] = xor64 * 2685821657736338717L; + } + } + + @Override + public long nextLong() { + long s0 = x[p]; + long s1 = x[p = (p + 1) & 15]; + s1 ^= s1 << 31; // a + s1 ^= s1 >>> 11; // b + s0 ^= s0 >>> 30; // c + return (x[p] = s0 ^ s1) * 1181783497276652981L; + } + + @Override + protected int next(int bits) { + return (int) (nextLong() >>> (64 - bits)); + } +} diff --git a/src/de/lmu/ifi/dbs/elki/math/random/XorShift64NonThreadsafeRandom.java b/src/de/lmu/ifi/dbs/elki/math/random/XorShift64NonThreadsafeRandom.java new file mode 100644 index 00000000..15d9cbff --- /dev/null +++ b/src/de/lmu/ifi/dbs/elki/math/random/XorShift64NonThreadsafeRandom.java @@ -0,0 +1,95 @@ +package de.lmu.ifi.dbs.elki.math.random; + +/* + This file is part of ELKI: + Environment for Developing KDD-Applications Supported by Index-Structures + + Copyright (C) 2014 + Ludwig-Maximilians-Universität München + Lehr- und Forschungseinheit für Datenbanksysteme + ELKI Development Team + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero 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 Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +import java.util.Random; + +import de.lmu.ifi.dbs.elki.utilities.documentation.Reference; + +/** + * Replacement for Java's {@link java.util.Random} class, using a different + * random number generation strategy. Java's random generator is optimized for + * speed, but may lack the randomness needed for more complex experiments. + * + * This approach is based on the work on XorShift64* by Sebastiano Vigna, with + * the original copyright statement: + * <p> + * Written in 2014 by Sebastiano Vigna (vigna@acm.org) + * + * To the extent possible under law, the author has dedicated all copyright and + * related and neighboring rights to this software to the public domain + * worldwide. This software is distributed without any warranty. + * + * See http://creativecommons.org/publicdomain/zero/1.0/ + * </p> + * + * @author Erich Schubert + */ +@Reference(authors = "S. Vigna", // +title = "An experimental exploration of Marsaglia's xorshift generators, scrambled", // +booktitle = "", url = "http://vigna.di.unimi.it/ftp/papers/xorshift.pdf") +public class XorShift64NonThreadsafeRandom extends Random { + /** + * Serial version number. + */ + private static final long serialVersionUID = 1L; + + /** + * State of random number generator. + */ + private long x = 4101842887655102017L; + + /** + * Constructor called only by localRandom.initialValue. + */ + public XorShift64NonThreadsafeRandom() { + super(); + } + + /** + * Constructor. + * + * @param seed Random generator seed. + */ + public XorShift64NonThreadsafeRandom(long seed) { + super(seed); + } + + @Override + public void setSeed(long seed) { + x = seed != 0 ? seed : 4101842887655102017L; + } + + @Override + public long nextLong() { + x ^= x >>> 12; // a + x ^= x << 25; // b + x ^= x >>> 27; // c + return x * 2685821657736338717L; + } + + @Override + protected int next(int bits) { + return (int) (nextLong() >>> (64 - bits)); + } +} diff --git a/src/de/lmu/ifi/dbs/elki/math/random/package-info.java b/src/de/lmu/ifi/dbs/elki/math/random/package-info.java new file mode 100644 index 00000000..7026a516 --- /dev/null +++ b/src/de/lmu/ifi/dbs/elki/math/random/package-info.java @@ -0,0 +1,27 @@ +/** + * Random number generation. + */ +package de.lmu.ifi.dbs.elki.math.random; + +/* + This file is part of ELKI: + Environment for Developing KDD-Applications Supported by Index-Structures + + Copyright (C) 2014 + Ludwig-Maximilians-Universität München + Lehr- und Forschungseinheit für Datenbanksysteme + ELKI Development Team + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero 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 Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ diff --git a/src/de/lmu/ifi/dbs/elki/math/scales/LinearScale.java b/src/de/lmu/ifi/dbs/elki/math/scales/LinearScale.java index 07191d61..899095d1 100644 --- a/src/de/lmu/ifi/dbs/elki/math/scales/LinearScale.java +++ b/src/de/lmu/ifi/dbs/elki/math/scales/LinearScale.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.scales; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/scales/Scales.java b/src/de/lmu/ifi/dbs/elki/math/scales/Scales.java index bf258d99..4c3a27d1 100644 --- a/src/de/lmu/ifi/dbs/elki/math/scales/Scales.java +++ b/src/de/lmu/ifi/dbs/elki/math/scales/Scales.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.scales; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -50,12 +50,11 @@ public final class Scales { /** * Compute a linear scale for each dimension. * - * @param <O> vector type * @param db Database * @return Scales, indexed starting with 0 (like Vector, not database * objects!) */ - public static <O extends NumberVector<? extends Number>> LinearScale[] calcScales(Relation<O> db) { + public static LinearScale[] calcScales(Relation<? extends NumberVector> db) { if (db == null) { throw new AbortException("No database was given to Scales.calcScales."); } @@ -65,7 +64,7 @@ public final class Scales { // analyze data for (DBIDIter iditer = db.iterDBIDs(); iditer.valid(); iditer.advance()) { - O v = db.get(iditer); + NumberVector v = db.get(iditer); for (int d = 0; d < dim; d++) { final double val = v.doubleValue(d); if(val != val) { diff --git a/src/de/lmu/ifi/dbs/elki/math/scales/package-info.java b/src/de/lmu/ifi/dbs/elki/math/scales/package-info.java index 17465485..120eac84 100644 --- a/src/de/lmu/ifi/dbs/elki/math/scales/package-info.java +++ b/src/de/lmu/ifi/dbs/elki/math/scales/package-info.java @@ -6,7 +6,7 @@ This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures -Copyright (C) 2013 +Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/spacefillingcurves/AbstractSpatialSorter.java b/src/de/lmu/ifi/dbs/elki/math/spacefillingcurves/AbstractSpatialSorter.java index 347af4a7..99381206 100644 --- a/src/de/lmu/ifi/dbs/elki/math/spacefillingcurves/AbstractSpatialSorter.java +++ b/src/de/lmu/ifi/dbs/elki/math/spacefillingcurves/AbstractSpatialSorter.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.spacefillingcurves; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/spacefillingcurves/BinarySplitSpatialSorter.java b/src/de/lmu/ifi/dbs/elki/math/spacefillingcurves/BinarySplitSpatialSorter.java index 742fae07..914c4390 100644 --- a/src/de/lmu/ifi/dbs/elki/math/spacefillingcurves/BinarySplitSpatialSorter.java +++ b/src/de/lmu/ifi/dbs/elki/math/spacefillingcurves/BinarySplitSpatialSorter.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.spacefillingcurves; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/spacefillingcurves/HilbertSpatialSorter.java b/src/de/lmu/ifi/dbs/elki/math/spacefillingcurves/HilbertSpatialSorter.java index 231e8637..dd0e729c 100644 --- a/src/de/lmu/ifi/dbs/elki/math/spacefillingcurves/HilbertSpatialSorter.java +++ b/src/de/lmu/ifi/dbs/elki/math/spacefillingcurves/HilbertSpatialSorter.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.spacefillingcurves; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/spacefillingcurves/PeanoSpatialSorter.java b/src/de/lmu/ifi/dbs/elki/math/spacefillingcurves/PeanoSpatialSorter.java index 3519e75d..ae2e3fa7 100644 --- a/src/de/lmu/ifi/dbs/elki/math/spacefillingcurves/PeanoSpatialSorter.java +++ b/src/de/lmu/ifi/dbs/elki/math/spacefillingcurves/PeanoSpatialSorter.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.spacefillingcurves; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/spacefillingcurves/SpatialSorter.java b/src/de/lmu/ifi/dbs/elki/math/spacefillingcurves/SpatialSorter.java index 30e6e019..a8c6166e 100644 --- a/src/de/lmu/ifi/dbs/elki/math/spacefillingcurves/SpatialSorter.java +++ b/src/de/lmu/ifi/dbs/elki/math/spacefillingcurves/SpatialSorter.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.spacefillingcurves; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/spacefillingcurves/ZCurveSpatialSorter.java b/src/de/lmu/ifi/dbs/elki/math/spacefillingcurves/ZCurveSpatialSorter.java index d30f88d6..66a94c90 100644 --- a/src/de/lmu/ifi/dbs/elki/math/spacefillingcurves/ZCurveSpatialSorter.java +++ b/src/de/lmu/ifi/dbs/elki/math/spacefillingcurves/ZCurveSpatialSorter.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.spacefillingcurves; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/spacefillingcurves/ZCurveTransformer.java b/src/de/lmu/ifi/dbs/elki/math/spacefillingcurves/ZCurveTransformer.java index 7474a00d..3f51c45d 100644 --- a/src/de/lmu/ifi/dbs/elki/math/spacefillingcurves/ZCurveTransformer.java +++ b/src/de/lmu/ifi/dbs/elki/math/spacefillingcurves/ZCurveTransformer.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.spacefillingcurves; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -23,7 +23,6 @@ package de.lmu.ifi.dbs.elki.math.spacefillingcurves; along with this program. If not, see <http://www.gnu.org/licenses/>. */ -import java.math.BigInteger; import java.util.Arrays; import de.lmu.ifi.dbs.elki.data.NumberVector; @@ -59,7 +58,7 @@ public class ZCurveTransformer { * @param relation Relation to transform * @param ids IDs subset to process */ - public ZCurveTransformer(Relation<? extends NumberVector<?>> relation, DBIDs ids) { + public ZCurveTransformer(Relation<? extends NumberVector> relation, DBIDs ids) { this.dimensionality = RelationUtil.dimensionality(relation); this.minValues = new double[dimensionality]; this.maxValues = new double[dimensionality]; @@ -68,7 +67,7 @@ public class ZCurveTransformer { Arrays.fill(minValues, Double.POSITIVE_INFINITY); Arrays.fill(maxValues, Double.NEGATIVE_INFINITY); for (DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) { - NumberVector<?> vector = relation.get(iter); + NumberVector vector = relation.get(iter); for(int dim = 0; dim < dimensionality; ++dim) { double dimValue = vector.doubleValue(dim); minValues[dim] = Math.min(minValues[dim], dimValue); @@ -81,20 +80,9 @@ public class ZCurveTransformer { * Transform a single vector. * * @param vector Vector to transform - * @return Z curve value as bigint - */ - @Deprecated - public BigInteger asBigInteger(NumberVector<?> vector) { - return new BigInteger(asByteArray(vector)); - } - - /** - * Transform a single vector. - * - * @param vector Vector to transform * @return Z curve value as byte array */ - public byte[] asByteArray(NumberVector<?> vector) { + public byte[] asByteArray(NumberVector vector) { final long[] longValueList = new long[dimensionality]; for(int dim = 0; dim < dimensionality; ++dim) { diff --git a/src/de/lmu/ifi/dbs/elki/math/spacefillingcurves/package-info.java b/src/de/lmu/ifi/dbs/elki/math/spacefillingcurves/package-info.java index a658d747..5e13c6b1 100644 --- a/src/de/lmu/ifi/dbs/elki/math/spacefillingcurves/package-info.java +++ b/src/de/lmu/ifi/dbs/elki/math/spacefillingcurves/package-info.java @@ -5,7 +5,7 @@ This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures -Copyright (C) 2013 +Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/KernelDensityEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/KernelDensityEstimator.java index de756520..6bb162b0 100644 --- a/src/de/lmu/ifi/dbs/elki/math/statistics/KernelDensityEstimator.java +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/KernelDensityEstimator.java @@ -8,7 +8,7 @@ import de.lmu.ifi.dbs.elki.math.statistics.kernelfunctions.KernelDensityFunction This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/LinearRegression.java b/src/de/lmu/ifi/dbs/elki/math/statistics/LinearRegression.java index 00999245..3f55373f 100644 --- a/src/de/lmu/ifi/dbs/elki/math/statistics/LinearRegression.java +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/LinearRegression.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/MultipleLinearRegression.java b/src/de/lmu/ifi/dbs/elki/math/statistics/MultipleLinearRegression.java index 37718358..4d786d8d 100644 --- a/src/de/lmu/ifi/dbs/elki/math/statistics/MultipleLinearRegression.java +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/MultipleLinearRegression.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -86,8 +86,7 @@ public class MultipleLinearRegression { private final double sst; /** - * Provides a new multiple linear regression model with the specified - * parameters. + * Constructor. * * @param y the (n x 1) - vector holding the response values (y1, ..., yn)^T. * @param x the (n x p+1)-matrix holding the explanatory values, where the @@ -144,7 +143,7 @@ public class MultipleLinearRegression { msg.append("\ny = ").append(FormatUtil.format(y, 9, 4)); msg.append("\nb = ").append(FormatUtil.format(b, 9, 4)); msg.append("\ne = ").append(FormatUtil.format(e, 9, 4)); - msg.append("error variance = ").append(FormatUtil.format(variance, 4)); + msg.append("error variance = ").append(FormatUtil.NF4.format(variance)); return msg.toString(); } diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/PolynomialRegression.java b/src/de/lmu/ifi/dbs/elki/math/statistics/PolynomialRegression.java index c478142a..6c68ffeb 100644 --- a/src/de/lmu/ifi/dbs/elki/math/statistics/PolynomialRegression.java +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/PolynomialRegression.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -51,7 +51,7 @@ public class PolynomialRegression extends MultipleLinearRegression { public final int p; /** - * Provides a new polynomial regression model with the specified parameters. + * Constructor. * * @param y the (n x 1) - vector holding the response values (y1, ..., yn)^T. * @param x the (n x 1)-vector holding the x-values (x1, ..., xn)^T. diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/ProbabilityWeightedMoments.java b/src/de/lmu/ifi/dbs/elki/math/statistics/ProbabilityWeightedMoments.java index b74ba06a..6eb72322 100644 --- a/src/de/lmu/ifi/dbs/elki/math/statistics/ProbabilityWeightedMoments.java +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/ProbabilityWeightedMoments.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/dependence/AbstractDependenceMeasure.java b/src/de/lmu/ifi/dbs/elki/math/statistics/dependence/AbstractDependenceMeasure.java new file mode 100644 index 00000000..ba23588e --- /dev/null +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/dependence/AbstractDependenceMeasure.java @@ -0,0 +1,262 @@ +package de.lmu.ifi.dbs.elki.math.statistics.dependence; + +/* + This file is part of ELKI: + Environment for Developing KDD-Applications Supported by Index-Structures + + Copyright (C) 2014 + Ludwig-Maximilians-Universität München + Lehr- und Forschungseinheit für Datenbanksysteme + ELKI Development Team + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero 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 Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +import java.util.Collection; +import java.util.Iterator; +import java.util.List; + +import de.lmu.ifi.dbs.elki.math.MathUtil; +import de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike.ArrayLikeUtil; +import de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike.NumberArrayAdapter; +import de.lmu.ifi.dbs.elki.utilities.datastructures.arrays.IntegerArrayQuickSort; +import de.lmu.ifi.dbs.elki.utilities.datastructures.arrays.IntegerComparator; +import de.lmu.ifi.dbs.elki.utilities.exceptions.AbortException; + +/** + * Abstract base class for dependence measures. + * + * @author Erich Schubert + */ +public abstract class AbstractDependenceMeasure implements DependenceMeasure { + // In your subclass, you will need to implement at least this method: + // Sorry for the complex use of generics, but this way we can use it with any + // type of array, including vectors in rows or columns etc. + @Override + abstract public <A, B> double dependence(NumberArrayAdapter<?, A> adapter1, A data1, NumberArrayAdapter<?, B> adapter2, B data2); + + @Override + public double dependence(double[] data1, double[] data2) { + return dependence(ArrayLikeUtil.DOUBLEARRAYADAPTER, data1, ArrayLikeUtil.DOUBLEARRAYADAPTER, data2); + } + + @Override + public <A> double dependence(NumberArrayAdapter<?, A> adapter, A data1, A data2) { + return dependence(adapter, data1, adapter, data2); + } + + @Override + public <A> double[] dependence(NumberArrayAdapter<?, A> adapter, List<? extends A> data) { + final int dims = data.size(); + double[] out = new double[(dims * (dims - 1)) >> 1]; + int o = 0; + for(int y = 1; y < dims; y++) { + A dy = data.get(y); + for(int x = 0; x < y; x++) { + out[o++] = dependence(adapter, data.get(x), adapter, dy); + } + } + return out; + } + + /** + * Clamp values to a given minimum and maximum. + * + * @param value True value + * @param min Minimum + * @param max Maximum + * @return {@code value}, unless smaller than {@code min} or larger than + * {@code max}. + */ + protected static double clamp(double value, double min, double max) { + return value < min ? min : value > max ? max : value; + } + + /** + * Compute ranks of all objects, normalized to [0;1] (where 0 is the smallest + * value, 1 is the largest). + * + * @param adapter Data adapter + * @param data Data array + * @param len Length of data + * @return Array of scores + */ + protected static <A> double[] computeNormalizedRanks(final NumberArrayAdapter<?, A> adapter, final A data, int len) { + // Sort the objects: + int[] s1 = sortedIndex(adapter, data, len); + final double norm = .5 / (len - 1); + double[] ret = new double[len]; + for(int i = 0; i < len;) { + final int start = i++; + final double val = adapter.getDouble(data, s1[start]); + while(i < len && adapter.getDouble(data, s1[i]) <= val) { + i++; + } + final double score = (start + i - 1) * norm; + for(int j = start; j < i; j++) { + ret[s1[j]] = score; + } + } + return ret; + } + + /** + * Compute ranks of all objects, ranging from 1 to len. + * + * Ties are given the average rank. + * + * @param adapter Data adapter + * @param data Data array + * @param len Length of data + * @return Array of scores + */ + protected static <A> double[] ranks(final NumberArrayAdapter<?, A> adapter, final A data, int len) { + // Sort the objects: + int[] s1 = sortedIndex(adapter, data, len); + return ranks(adapter, data, s1); + } + + /** + * Compute ranks of all objects, ranging from 1 to len. + * + * Ties are given the average rank. + * + * @param adapter Data adapter + * @param data Data array + * @param idx Data index + * @return Array of scores + */ + protected static <A> double[] ranks(final NumberArrayAdapter<?, A> adapter, final A data, int[] idx) { + final int len = idx.length; + double[] ret = new double[len]; + for(int i = 0; i < len;) { + final int start = i++; + final double val = adapter.getDouble(data, idx[start]); + // Include ties: + while(i < len && adapter.getDouble(data, idx[i]) <= val) { + i++; + } + final double score = (start + i - 1) * .5 + 1; + for(int j = start; j < i; j++) { + ret[idx[j]] = score; + } + } + return ret; + } + + /** + * Build a sorted index of objects. + * + * @param adapter Data adapter + * @param data Data array + * @param len Length of data + * @return Sorted index + */ + protected static <A> int[] sortedIndex(final NumberArrayAdapter<?, A> adapter, final A data, int len) { + int[] s1 = MathUtil.sequence(0, len); + IntegerArrayQuickSort.sort(s1, new IntegerComparator() { + @Override + public int compare(int x, int y) { + return Double.compare(adapter.getDouble(data, x), adapter.getDouble(data, y)); + } + }); + return s1; + } + + /** + * Discretize a data set into equi-width bin numbers. + * + * @param adapter Data adapter + * @param data Data array + * @param len Length of data + * @param bins Number of bins + * @return Array of bin numbers [0;bin[ + */ + protected static <A> int[] discretize(NumberArrayAdapter<?, A> adapter, A data, final int len, final int bins) { + double min = adapter.getDouble(data, 0), max = min; + for(int i = 1; i < len; i++) { + double v = adapter.getDouble(data, i); + if(v < min) { + min = v; + } + else if(v > max) { + max = v; + } + } + final double scale = (max > min) ? bins / (max - min) : 1; + int[] discData = new int[len]; + for(int i = 0; i < len; i++) { + int bin = (int) Math.floor((adapter.getDouble(data, i) - min) * scale); + discData[i] = bin < 0 ? 0 : bin >= bins ? bins - 1 : bin; + } + return discData; + } + + /** + * Index into the serialized array. + * + * @param x Column + * @param y Row + * @return Index in serialized array + */ + protected static int index(int x, int y) { + assert (x < y) : "Only lower triangle is allowed."; + return ((y * (y - 1)) >> 1) + x; + } + + /** + * Validate the length of the two data sets (must be the same, and non-zero) + * + * @param adapter1 First data adapter + * @param data1 First data set + * @param adapter2 Second data adapter + * @param data2 Second data set + * @param <A> First array type + * @param <B> Second array type + */ + public static <A, B> int size(NumberArrayAdapter<?, A> adapter1, A data1, NumberArrayAdapter<?, B> adapter2, B data2) { + final int len = adapter1.size(data1); + if(len != adapter2.size(data2)) { + throw new AbortException("Array sizes do not match!"); + } + if(len == 0) { + throw new AbortException("Empty array!"); + } + return len; + } + + /** + * Validate the length of the two data sets (must be the same, and non-zero) + * + * @param adapter Data adapter + * @param data Data sets + * @param <A> First array type + */ + public static <A> int size(NumberArrayAdapter<?, A> adapter, Collection<? extends A> data) { + if(data.size() < 2) { + throw new AbortException("Need at least two axes to compute dependence measures."); + } + Iterator<? extends A> iter = data.iterator(); + final int len = adapter.size(iter.next()); + while(iter.hasNext()) { + if(len != adapter.size(iter.next())) { + throw new AbortException("Array sizes do not match!"); + } + } + if(len == 0) { + throw new AbortException("Empty array!"); + } + return len; + } +} diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/dependence/CorrelationDependenceMeasure.java b/src/de/lmu/ifi/dbs/elki/math/statistics/dependence/CorrelationDependenceMeasure.java new file mode 100644 index 00000000..e03601f7 --- /dev/null +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/dependence/CorrelationDependenceMeasure.java @@ -0,0 +1,141 @@ +package de.lmu.ifi.dbs.elki.math.statistics.dependence; + +/* + This file is part of ELKI: + Environment for Developing KDD-Applications Supported by Index-Structures + + Copyright (C) 2014 + Ludwig-Maximilians-Universität München + Lehr- und Forschungseinheit für Datenbanksysteme + ELKI Development Team + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero 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 Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +import java.util.List; + +import de.lmu.ifi.dbs.elki.logging.Logging; +import de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike.NumberArrayAdapter; +import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer; + +/** + * Pearson product-moment correlation coefficient. + * + * @author Erich Schubert + */ +public class CorrelationDependenceMeasure extends AbstractDependenceMeasure { + /** + * Class logger. + */ + private static final Logging LOG = Logging.getLogger(CorrelationDependenceMeasure.class); + + /** + * Static instance. + */ + public static final CorrelationDependenceMeasure STATIC = new CorrelationDependenceMeasure(); + + /** + * Constructor - use {@link #STATIC} instance. + */ + protected CorrelationDependenceMeasure() { + super(); + } + + @Override + public <A, B> double dependence(NumberArrayAdapter<?, A> adapter1, A data1, NumberArrayAdapter<?, B> adapter2, B data2) { + final int len = size(adapter1, data1, adapter2, data2); + // Perform two-pass estimation, which is numerically stable and often faster + // than the Knuth-Welford approach (see PearsonCorrelation class) + double m1 = 0., m2 = 0; + for(int i = 0; i < len; i++) { + m1 += adapter1.getDouble(data1, i); + m2 += adapter2.getDouble(data2, i); + } + m1 /= len; + m2 /= len; + // Second pass: variances and covariance + double v1 = 0., v2 = 0., cov = 0.; + for(int i = 0; i < len; i++) { + double d1 = adapter1.getDouble(data1, i) - m1; + double d2 = adapter2.getDouble(data2, i) - m2; + v1 += d1 * d1; + v2 += d2 * d2; + cov += d1 * d2; + } + // Note: we did not normalize by len, as this cancels out. + return cov / Math.sqrt(v1 * v2); + } + + @Override + public <A> double[] dependence(NumberArrayAdapter<?, A> adapter, List<? extends A> data) { + final int dims = data.size(); + final int len = size(adapter, data); + double[] means = new double[dims]; + // Two passes - often faster due to the lower numerical cost + // And accurate, don't use sum-of-squares. + for(int j = 0; j < dims; j++) { + double m = 0.; + A da = data.get(j); + for(int i = 0; i < len; i++) { + m += adapter.getDouble(da, i); + } + means[j] = m / len; + } + // Build the covariance matrix, lower triangular half + double[] vst = new double[dims]; + double[] cov = new double[(dims * (dims - 1)) >> 1]; + double[] buf = new double[dims]; + for(int i = 0; i < len; i++) { + for(int j = 0; j < dims; j++) { + buf[j] = adapter.getDouble(data.get(j), i) - means[j]; + } + for(int y = 0, c = 0; y < dims; y++) { + for(int x = 0; x < y; x++) { + cov[c++] += buf[x] * buf[y]; + } + vst[y] += buf[y] * buf[y]; + } + } + // Compute standard deviations (times sqrt(len)!): + for(int y = 0; y < dims; y++) { + if(vst[y] == 0.) { + LOG.warning("Correlation is not well defined for constant attributes."); + } + vst[y] = Math.sqrt(vst[y]); + } + for(int y = 1, c = 0; y < dims; y++) { + for(int x = 0; x < y; x++) { + // We don't need to divide by sqrt(len), because it will cancel out with + // the division we skipped just above. + cov[c] = cov[c] / (vst[x] * vst[y]); + c++; + } + } + return cov; + } + + /** + * Parameterization class + * + * @author Erich Schubert + * + * @apiviz.exclude + */ + public static class Parameterizer extends AbstractParameterizer { + @Override + protected CorrelationDependenceMeasure makeInstance() { + return STATIC; + } + } +} diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/dependence/DependenceMeasure.java b/src/de/lmu/ifi/dbs/elki/math/statistics/dependence/DependenceMeasure.java new file mode 100644 index 00000000..0e9e02c0 --- /dev/null +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/dependence/DependenceMeasure.java @@ -0,0 +1,98 @@ +package de.lmu.ifi.dbs.elki.math.statistics.dependence; + +/* + This file is part of ELKI: + Environment for Developing KDD-Applications Supported by Index-Structures + + Copyright (C) 2014 + Ludwig-Maximilians-Universität München + Lehr- und Forschungseinheit für Datenbanksysteme + ELKI Development Team + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero 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 Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +import java.util.List; + +import de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike.NumberArrayAdapter; + +/** + * Measure the dependence of two variables. + * + * @author Erich Schubert + */ +public interface DependenceMeasure { + /** + * Measure the dependence of two variables. + * + * This is the more flexible API, which allows using different internal data + * representations. + * + * @param adapter1 First data adapter + * @param data1 First data set + * @param adapter2 Second data adapter + * @param data2 Second data set + * @param <A> First array type + * @param <B> Second array type + * @return Dependence measure + */ + <A, B> double dependence(NumberArrayAdapter<?, A> adapter1, A data1, NumberArrayAdapter<?, B> adapter2, B data2); + + /** + * Measure the dependence of two variables. + * + * This is the more flexible API, which allows using different internal data + * representations. + * + * @param adapter Array type adapter + * @param data1 First data set + * @param data2 Second data set + * @param <A> Array type + * @return Dependence measure + */ + <A> double dependence(NumberArrayAdapter<?, A> adapter, A data1, A data2); + + /** + * Measure the dependence of two variables. + * + * This is the more flexible API, which allows using different internal data + * representations. + * + * The resulting data is a serialized lower triangular matrix: + * + * <pre> + * X S S S S S + * 0 X S S S S + * 1 2 X S S S + * 3 4 5 X S S + * 6 7 8 9 X S + * 10 11 12 13 14 X + * </pre> + * + * @param adapter Data adapter + * @param data Data sets. Must have fast random access! + * @param <A> Array type + * @return Lower triangular serialized matrix + */ + <A> double[] dependence(NumberArrayAdapter<?, A> adapter, List<? extends A> data); + + /** + * Measure the dependence of two variables. + * + * @param data1 First data set + * @param data2 Second data set + * @return Dependence measure + */ + double dependence(double[] data1, double[] data2); +} diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/dependence/DistanceCorrelationDependenceMeasure.java b/src/de/lmu/ifi/dbs/elki/math/statistics/dependence/DistanceCorrelationDependenceMeasure.java new file mode 100644 index 00000000..1ae8d6b5 --- /dev/null +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/dependence/DistanceCorrelationDependenceMeasure.java @@ -0,0 +1,206 @@ +package de.lmu.ifi.dbs.elki.math.statistics.dependence;
+
+/*
+ This file is part of ELKI:
+ Environment for Developing KDD-Applications Supported by Index-Structures
+
+ Copyright (C) 2014
+ Ludwig-Maximilians-Universität München
+ Lehr- und Forschungseinheit für Datenbanksysteme
+ ELKI Development Team
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+import java.util.List;
+
+import de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike.NumberArrayAdapter;
+import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
+
+/**
+ * Distance correlation.
+ *
+ * The value returned is the square root of the dCor² value. This matches the R
+ * implementation by the original authors.
+ *
+ * Reference:
+ * <p>
+ * Székely, G. J., Rizzo, M. L., & Bakirov, N. K.<br />
+ * Measuring and testing dependence by correlation of distances<br />
+ * The Annals of Statistics, 35(6), 2769-2794
+ * </p>
+ *
+ * Implementation notice: we exploit symmetry, and thus use diagonal matrixes.
+ * While initially the diagonal is zero, after double-centering the matrix these
+ * values can become non-zero!
+ *
+ * @author Marie Kiermeier
+ * @author Erich Schubert
+ */
+@Reference(authors = "Székely, G. J., Rizzo, M. L., & Bakirov, N. K.", //
+title = "Measuring and testing dependence by correlation of distances", //
+booktitle = "The Annals of Statistics, 35(6), 2769-2794", //
+url = "http://dx.doi.org/10.1214/009053607000000505")
+public class DistanceCorrelationDependenceMeasure extends AbstractDependenceMeasure {
+ /**
+ * Static instance.
+ */
+ public static final DistanceCorrelationDependenceMeasure STATIC = new DistanceCorrelationDependenceMeasure();
+
+ /**
+ * Constructor - use {@link #STATIC} instance instead!
+ */
+ protected DistanceCorrelationDependenceMeasure() {
+ super();
+ }
+
+ @Override
+ public <A, B> double dependence(NumberArrayAdapter<?, A> adapter1, A data1, NumberArrayAdapter<?, B> adapter2, B data2) {
+ final int len = size(adapter1, data1, adapter2, data2);
+ double[] dMatrixA = computeDistances(adapter1, data1);
+ double[] dMatrixB = computeDistances(adapter2, data2);
+
+ // distance variance
+ double dVarA = computeDCovar(dMatrixA, dMatrixA, len);
+ if(!(dVarA > 0.)) {
+ return 0.;
+ }
+ double dVarB = computeDCovar(dMatrixB, dMatrixB, len);
+ if(!(dVarB > 0.)) {
+ return 0.;
+ }
+ double dCovar = computeDCovar(dMatrixA, dMatrixB, len);
+ // distance correlation
+ return Math.sqrt(dCovar / Math.sqrt(dVarA * dVarB));
+ }
+
+ @Override
+ public <A> double[] dependence(NumberArrayAdapter<?, A> adapter, List<? extends A> data) {
+ final int dims = data.size();
+ final int len = size(adapter, data);
+ double[][] dMatrix = new double[dims][];
+ for(int i = 0; i < dims; i++) {
+ dMatrix[i] = computeDistances(adapter, data.get(i));
+ }
+ double[] dVar = new double[dims];
+ for(int i = 0; i < dims; i++) {
+ dVar[i] = computeDCovar(dMatrix[i], dMatrix[i], len);
+ }
+ double[] dCor = new double[(dims * (dims - 1)) >> 1];
+ for(int y = 1, c = 0; y < dims; y++) {
+ for(int x = 0; x < y; x++) {
+ if(!(dVar[x] * dVar[y] > 0.)) {
+ dCor[c++] = 0.;
+ continue;
+ }
+ double dCovar = computeDCovar(dMatrix[x], dMatrix[y], len);
+ dCor[c++] = Math.sqrt(dCovar / Math.sqrt(dVar[x] * dVar[y]));
+ }
+ }
+ return dCor;
+ }
+
+ /**
+ * Compute the double-centered delta matrix.
+ *
+ * @param adapter Data adapter
+ * @param data Input data
+ * @return Double-centered delta matrix.
+ */
+ protected static <A> double[] computeDistances(NumberArrayAdapter<?, A> adapter, A data) {
+ final int size = adapter.size(data);
+ double[] dMatrix = new double[(size * (size + 1)) >> 1];
+ for(int i = 0, c = 0; i < size; i++) {
+ for(int j = 0; j < i; j++) {
+ double dx = adapter.getDouble(data, i) - adapter.getDouble(data, j);
+ dMatrix[c++] = (dx < 0) ? -dx : dx; // Absolute difference.
+ }
+ c++; // Diagonal entry: zero
+ }
+ doubleCenterMatrix(dMatrix, size);
+ return dMatrix;
+ }
+
+ /**
+ * Computes the distance variance matrix of one axis.
+ *
+ * @param dMatrix distance matrix of the axis
+ * @param size Dimensionality
+ */
+ public static void doubleCenterMatrix(double[] dMatrix, int size) {
+ double[] rowMean = new double[size];
+ // row sum
+ for(int i = 0, c = 0; i < size; i++) {
+ for(int j = 0; j < i; j++) {
+ double v = dMatrix[c++];
+ rowMean[i] += v;
+ rowMean[j] += v;
+ }
+ assert (dMatrix[c] == 0.);
+ c++; // Diagonal entry. Must be zero!
+ }
+ // Normalize averages:
+ double matrixMean = 0.;
+ for(int i = 0; i < size; i++) {
+ matrixMean += rowMean[i];
+ rowMean[i] /= size;
+ }
+ matrixMean /= size * size;
+
+ for(int o = 0, c = 0; o < size; o++) {
+ // Including row mean!
+ for(int p = 0; p <= o; p++) {
+ dMatrix[c++] -= rowMean[o] + rowMean[p] - matrixMean;
+ }
+ }
+ }
+
+ /**
+ * Computes the distance covariance for two axis. Can also be used to compute
+ * the distance variance of one axis (dVarMatrixA = dVarMatrixB).
+ *
+ * @param dVarMatrixA distance variance matrix of the first axis
+ * @param dVarMatrixB distance variance matrix of the second axis
+ * @param n number of points
+ * @return distance covariance
+ */
+ protected double computeDCovar(double[] dVarMatrixA, double[] dVarMatrixB, int n) {
+ double result = 0.;
+ for(int i = 0, c = 0; i < n; i++) {
+ for(int j = 0; j < i; j++) {
+ result += 2. * dVarMatrixA[c] * dVarMatrixB[c];
+ c++;
+ }
+ // Diagonal entry.
+ result += dVarMatrixA[c] * dVarMatrixB[c];
+ c++;
+ }
+ return result / (n * n);
+ }
+
+ /**
+ * Parameterization class
+ *
+ * @author Marie Kiermeier
+ *
+ * @apiviz.exclude
+ */
+ public static class Parameterizer extends AbstractParameterizer {
+ @Override
+ protected DistanceCorrelationDependenceMeasure makeInstance() {
+ return STATIC;
+ }
+ }
+}
diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/dependence/HSMDependenceMeasure.java b/src/de/lmu/ifi/dbs/elki/math/statistics/dependence/HSMDependenceMeasure.java new file mode 100644 index 00000000..aaacb888 --- /dev/null +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/dependence/HSMDependenceMeasure.java @@ -0,0 +1,245 @@ +package de.lmu.ifi.dbs.elki.math.statistics.dependence; + +/* + This file is part of ELKI: + Environment for Developing KDD-Applications Supported by Index-Structures + + Copyright (C) 2014 + Ludwig-Maximilians-Universität München + Lehr- und Forschungseinheit für Datenbanksysteme + ELKI Development Team + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero 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 Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +import de.lmu.ifi.dbs.elki.math.SinCosTable; +import de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike.NumberArrayAdapter; +import de.lmu.ifi.dbs.elki.utilities.documentation.Reference; +import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer; + +/** + * Compute the similarity of dimensions by using a hough transformation. + * + * Reference: <br> + * <p> + * A. Tatu, G. Albuquerque, M. Eisemann, P. Bak, H. Theisel, M. A. Magnor, and + * D. A. Keim.<br /> + * Automated Analytical Methods to Support Visual Exploration of High- + * Dimensional Data. <br/> + * IEEEVisualization and Computer Graphics, 2011. + * </p> + * + * FIXME: This needs serious TESTING before release. Large parts have been + * rewritten, but could not be tested at the time of rewriting. + * + * @author Erich Schubert + * @author Robert Rödler + */ +@Reference(authors = "A. Tatu, G. Albuquerque, M. Eisemann, P. Bak, H. Theisel, M. A. Magnor, and D. A. Keim", // +title = "Automated Analytical Methods to Support Visual Exploration of High-Dimensional Data", // +booktitle = "IEEE Trans. Visualization and Computer Graphics, 2011", // +url = "http://dx.doi.org/10.1109/TVCG.2010.242") +public class HSMDependenceMeasure extends AbstractDependenceMeasure { + /** + * Static instance. + */ + public static final HSMDependenceMeasure STATIC = new HSMDependenceMeasure(); + + /** + * Angular resolution. Best if divisible by 4: smaller tables. + * + * The original publication used 50. + */ + private final static int STEPS = 48; // 64; + + /** + * Resolution of image. + */ + private final int resolution = 512; + + /** + * Precompute sinus and cosinus + */ + private final static SinCosTable table = SinCosTable.make(STEPS); + + @Override + public <A, B> double dependence(NumberArrayAdapter<?, A> adapter1, A data1, NumberArrayAdapter<?, B> adapter2, B data2) { + final int len = size(adapter1, data1, adapter2, data2); + boolean[][] pic = new boolean[resolution][resolution]; + + // Get attribute value range: + final double off1, scale1, off2, scale2; + { + double mi = adapter1.getDouble(data1, 0), ma = mi; + for(int i = 1; i < len; ++i) { + double v = adapter1.getDouble(data1, i); + if(v < mi) { + mi = v; + } + else if(v > ma) { + ma = v; + } + } + off1 = mi; + scale1 = (ma > mi) ? (1. / (ma - mi)) : 1.; + // Second data + mi = adapter2.getDouble(data2, 0); + ma = mi; + for(int i = 1; i < len; ++i) { + double v = adapter2.getDouble(data2, i); + if(v < mi) { + mi = v; + } + else if(v > ma) { + ma = v; + } + } + off2 = mi; + scale2 = (ma > mi) ? (1. / (ma - mi)) : 1.; + } + // Iterate dataset + for(int i = 0; i < len; ++i) { + double xi = (adapter1.getDouble(data1, i) - off1) * scale1; + double xj = (adapter2.getDouble(data2, i) - off2) * scale2; + drawLine(0, (int) (resolution * xi), resolution - 1, (int) (resolution * xj), pic); + } + + final double stepsq = (double) STEPS * (double) STEPS; + int[][] hough = houghTransformation(pic); + // The original publication said "median", but judging from the text, + // meant "mean". Otherwise, always half of the cells are above the + // threshold, which doesn't match the explanation there. + double mean = sumMatrix(hough) / stepsq; + int abovemean = countAboveThreshold(hough, mean); + + return 1. - (abovemean / stepsq); + } + + /** + * Compute the sum of a matrix. + * + * @param mat Matrix + * @return Sum of all elements + */ + private long sumMatrix(int[][] mat) { + long ret = 0; + for(int i = 0; i < mat.length; i++) { + final int[] row = mat[i]; + for(int j = 0; j < row.length; j++) { + ret += row[j]; + } + } + return ret; + } + + /** + * Count the number of cells above the threshold. + * + * @param mat Matrix + * @param threshold Threshold + * @return Number of elements above the threshold. + */ + private int countAboveThreshold(int[][] mat, double threshold) { + int ret = 0; + for(int i = 0; i < mat.length; i++) { + int[] row = mat[i]; + for(int j = 0; j < row.length; j++) { + if(row[j] >= threshold) { + ret++; + } + } + } + return ret; + } + + /** + * Perform a hough transformation on the binary image in "mat". + * + * @param mat Binary image + * @return Hough transformation of image. + */ + private int[][] houghTransformation(boolean[][] mat) { + final int xres = mat.length, yres = mat[0].length; + final double tscale = STEPS * .5 / (xres + yres); + final int[][] ret = new int[STEPS][STEPS]; + + for(int x = 0; x < mat.length; x++) { + for(int y = 0; y < mat[0].length; y++) { + if(mat[x][y]) { + for(int i = 0; i < STEPS; i++) { + final int d = (STEPS >> 1) + (int) (tscale * (x * table.cos(i) + y * table.sin(i))); + if(d > 0 && d < STEPS) { + ret[d][i]++; + } + } + } + } + } + + return ret; + } + + /** + * Draw a line onto the array, using the classic Bresenham algorithm. + * + * @param x0 Start X + * @param y0 Start Y + * @param x1 End X + * @param y1 End Y + * @param pic Picture array + */ + private static void drawLine(int x0, int y0, int x1, int y1, boolean[][] pic) { + final int xres = pic.length, yres = pic[0].length; + // Ensure bounds + y0 = (y0 < 0) ? 0 : (y0 >= yres) ? (yres - 1) : y0; + y1 = (y1 < 0) ? 0 : (y1 >= yres) ? (yres - 1) : y1; + x0 = (x0 < 0) ? 0 : (x0 >= xres) ? (xres - 1) : x0; + x1 = (x1 < 0) ? 0 : (x1 >= xres) ? (xres - 1) : x1; + // Default slope + final int dx = +Math.abs(x1 - x0), sx = x0 < x1 ? 1 : -1; + final int dy = -Math.abs(y1 - y0), sy = y0 < y1 ? 1 : -1; + // Error counter + int err = dx + dy; + + for(;;) { + pic[x0][y0] = true; + if(x0 == x1 && y0 == y1) { + break; + } + + final int e2 = err << 1; + if(e2 > dy) { + err += dy; + x0 += sx; + } + if(e2 < dx) { + err += dx; + y0 += sy; + } + } + } + + /** + * Parameterization class. + * + * @author Erich Schubert + * + * @apiviz.exclude + */ + public static class Parameterizer extends AbstractParameterizer { + @Override + protected HSMDependenceMeasure makeInstance() { + return STATIC; + } + } +} diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/dependence/HiCSDependenceMeasure.java b/src/de/lmu/ifi/dbs/elki/math/statistics/dependence/HiCSDependenceMeasure.java new file mode 100644 index 00000000..e760ef83 --- /dev/null +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/dependence/HiCSDependenceMeasure.java @@ -0,0 +1,243 @@ +package de.lmu.ifi.dbs.elki.math.statistics.dependence; + +/* + This file is part of ELKI: + Environment for Developing KDD-Applications Supported by Index-Structures + + Copyright (C) 2014 + Ludwig-Maximilians-Universität München + Lehr- und Forschungseinheit für Datenbanksysteme + ELKI Development Team + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero 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 Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +import java.util.Random; + +import de.lmu.ifi.dbs.elki.algorithm.outlier.meta.HiCS; +import de.lmu.ifi.dbs.elki.math.MathUtil; +import de.lmu.ifi.dbs.elki.math.random.RandomFactory; +import de.lmu.ifi.dbs.elki.math.statistics.tests.GoodnessOfFitTest; +import de.lmu.ifi.dbs.elki.math.statistics.tests.KolmogorovSmirnovTest; +import de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike.NumberArrayAdapter; +import de.lmu.ifi.dbs.elki.utilities.datastructures.arrays.IntegerArrayQuickSort; +import de.lmu.ifi.dbs.elki.utilities.datastructures.arrays.IntegerComparator; +import de.lmu.ifi.dbs.elki.utilities.documentation.Reference; +import de.lmu.ifi.dbs.elki.utilities.exceptions.AbortException; +import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer; +import de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints.CommonConstraints; +import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization; +import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.DoubleParameter; +import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.IntParameter; +import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter; +import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.RandomParameter; + +/** + * Use the statistical tests as used by HiCS to measure dependence of variables. + * + * Reference: + * <p> + * Elke Achtert, Hans-Peter Kriegel, Erich Schubert, Arthur Zimek:<br /> + * Interactive Data Mining with 3D-Parallel-Coordinate-Trees.<br /> + * Proceedings of the 2013 ACM International Conference on Management of Data + * (SIGMOD), New York City, NY, 2013. + * </p> + * + * Based on: + * <p> + * F. Keller, E. Müller, and K. Böhm.<br /> + * HiCS: High Contrast Subspaces for Density-Based Outlier Ranking. <br /> + * In ICDE, pages 1037–1048, 2012. + * </p> + * + * @author Erich Schubert + * @author Robert Rödler + */ +@Reference(authors = "Elke Achtert, Hans-Peter Kriegel, Erich Schubert, Arthur Zimek", // +title = "Interactive Data Mining with 3D-Parallel-Coordinate-Trees", // +booktitle = "Proc. of the 2013 ACM International Conference on Management of Data (SIGMOD)", // +url = "http://dx.doi.org/10.1145/2463676.2463696") +public class HiCSDependenceMeasure extends AbstractDependenceMeasure { + /** + * Monte-Carlo iterations + */ + private int m = 50; + + /** + * Alpha threshold + */ + private double alphasqrt = Math.sqrt(0.1); + + /** + * Statistical test to use + */ + private GoodnessOfFitTest statTest; + + /** + * Random generator + */ + private RandomFactory rnd; + + /** + * Constructor. + * + * @param statTest Test function + * @param m Number of monte-carlo iterations + * @param alpha Alpha threshold + * @param rnd Random source + */ + public HiCSDependenceMeasure(GoodnessOfFitTest statTest, int m, double alpha, RandomFactory rnd) { + super(); + this.statTest = statTest; + this.m = m; + this.alphasqrt = Math.sqrt(alpha); + this.rnd = rnd; + } + + @Override + public <A, B> double dependence(final NumberArrayAdapter<?, A> adapter1, final A data1, final NumberArrayAdapter<?, B> adapter2, final B data2) { + final int len = size(adapter1, data1, adapter2, data2); + final int windowsize = (int) (len * alphasqrt); + final Random random = rnd.getSingleThreadedRandom(); + + // Sorted copies for slicing. + int[] s1 = MathUtil.sequence(0, len), s2 = MathUtil.sequence(0, len); + IntegerArrayQuickSort.sort(s1, new IntegerComparator() { + @Override + public int compare(int x, int y) { + return Double.compare(adapter1.getDouble(data1, x), adapter1.getDouble(data1, y)); + } + }); + IntegerArrayQuickSort.sort(s2, new IntegerComparator() { + @Override + public int compare(int x, int y) { + return Double.compare(adapter2.getDouble(data2, x), adapter2.getDouble(data2, y)); + } + }); + + // Distributions for testing + double[] fullValues = new double[len]; + double[] sampleValues = new double[windowsize]; + double deviationSum = 0.; + + // For the first half, we use the first dimension as reference + for(int i = 0; i < len; i++) { + fullValues[i] = adapter1.getDouble(data1, i); + if(fullValues[i] != fullValues[i]) { + throw new AbortException("NaN values are not allowed by this implementation!"); + } + } + + int half = m >> 1; // TODO: remove bias? + for(int i = 0; i < half; ++i) { + // Build the sample + for(int j = random.nextInt(len - windowsize), k = 0; k < windowsize; ++k, ++j) { + sampleValues[k] = adapter2.getDouble(data2, j); + } + double contrast = statTest.deviation(fullValues, sampleValues); + if(Double.isNaN(contrast)) { + --i; // Retry. + continue; + } + deviationSum += contrast; + } + + // For the second half, we use the second dimension as reference + for(int i = 0; i < len; i++) { + fullValues[i] = adapter2.getDouble(data2, i); + if(fullValues[i] != fullValues[i]) { + throw new AbortException("NaN values are not allowed by this implementation!"); + } + } + + for(int i = half; i < m; ++i) { + // Build the sample + for(int j = random.nextInt(len - windowsize), k = 0; k < windowsize; ++k, ++j) { + sampleValues[k] = adapter1.getDouble(data1, j); + } + double contrast = statTest.deviation(fullValues, sampleValues); + if(Double.isNaN(contrast)) { + --i; // Retry. + continue; + } + deviationSum += contrast; + } + + return deviationSum / m; + } + + /** + * Parameterization class. + * + * @author Erich Schubert + * + * @apiviz.exclude + */ + public static class Parameterizer extends AbstractParameterizer { + /** + * Statistical test to use + */ + private GoodnessOfFitTest statTest; + + /** + * Holds the value of + * {@link de.lmu.ifi.dbs.elki.algorithm.outlier.meta.HiCS.Parameterizer#M_ID} + * . + */ + private int m = 50; + + /** + * Holds the value of + * {@link de.lmu.ifi.dbs.elki.algorithm.outlier.meta.HiCS.Parameterizer#ALPHA_ID} + * . + */ + private double alpha = 0.1; + + /** + * Random generator. + */ + private RandomFactory rnd; + + @Override + protected void makeOptions(Parameterization config) { + super.makeOptions(config); + final IntParameter mP = new IntParameter(HiCS.Parameterizer.M_ID, 50); + mP.addConstraint(CommonConstraints.GREATER_THAN_ONE_INT); + if(config.grab(mP)) { + m = mP.intValue(); + } + + final DoubleParameter alphaP = new DoubleParameter(HiCS.Parameterizer.ALPHA_ID, 0.1); + alphaP.addConstraint(CommonConstraints.GREATER_THAN_ZERO_DOUBLE); + if(config.grab(alphaP)) { + alpha = alphaP.doubleValue(); + } + + final ObjectParameter<GoodnessOfFitTest> testP = new ObjectParameter<>(HiCS.Parameterizer.TEST_ID, GoodnessOfFitTest.class, KolmogorovSmirnovTest.class); + if(config.grab(testP)) { + statTest = testP.instantiateClass(config); + } + + final RandomParameter rndP = new RandomParameter(HiCS.Parameterizer.SEED_ID); + if(config.grab(rndP)) { + rnd = rndP.getValue(); + } + } + + @Override + protected HiCSDependenceMeasure makeInstance() { + return new HiCSDependenceMeasure(statTest, m, alpha, rnd); + } + } +} diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/dependence/HoeffdingsDDependenceMeasure.java b/src/de/lmu/ifi/dbs/elki/math/statistics/dependence/HoeffdingsDDependenceMeasure.java new file mode 100644 index 00000000..7f1f9fc4 --- /dev/null +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/dependence/HoeffdingsDDependenceMeasure.java @@ -0,0 +1,207 @@ +package de.lmu.ifi.dbs.elki.math.statistics.dependence; + +/* + This file is part of ELKI: + Environment for Developing KDD-Applications Supported by Index-Structures + + Copyright (C) 2014 + Ludwig-Maximilians-Universität München + Lehr- und Forschungseinheit für Datenbanksysteme + ELKI Development Team + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero 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 Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +import de.lmu.ifi.dbs.elki.math.MathUtil; +import de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike.NumberArrayAdapter; +import de.lmu.ifi.dbs.elki.utilities.documentation.Reference; +import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer; + +/** + * Calculate Hoeffding's D as a measure of dependence. + * + * References: + * <p> + * W. Hoeffding:<br /> + * A non-parametric test of independence<br /> + * The Annals of Mathematical Statistics 19:546–57 + * </p> + * + * The resulting value is scaled by 30, so it is in the range {@code [-.5;1]}. + * + * @author Yinchong Yang + * @author Erich Schubert + */ +@Reference(authors = "W. Hoeffding", // +title = "A non-parametric test of independence", // +booktitle = "The Annals of Mathematical Statistics 19", // +url = "http://www.jstor.org/stable/2236021") +public class HoeffdingsDDependenceMeasure extends AbstractDependenceMeasure { + /** + * Static instance. + */ + public static final HoeffdingsDDependenceMeasure STATIC = new HoeffdingsDDependenceMeasure(); + + /** + * Constructor - use {@link #STATIC} instance. + */ + protected HoeffdingsDDependenceMeasure() { + super(); + } + + @Override + public <A, B> double dependence(NumberArrayAdapter<?, A> adapter1, A data1, NumberArrayAdapter<?, B> adapter2, B data2) { + final int n = size(adapter1, data1, adapter2, data2); + assert (n > 4) : "Hoeffdings D needs at least 5 elements!"; + if(n <= 4) { + return Double.NaN; + } + double[] r = ranks(adapter1, data1, n); + double[] s = ranks(adapter2, data2, n); + // TODO: is it possible to exploit sorting to accelerate computing q? + double[] q = computeBivariateRanks(adapter1, data1, adapter2, data2, n); + + double d1 = 0, d2 = 0, d3 = 0; + for(int i = 0; i < n; i++) { + d1 += q[i] * (q[i] - 1); // Note: our q is 0-indexed. + d2 += (r[i] - 1) * (r[i] - 2) * (s[i] - 1) * (s[i] - 2); + d3 += (r[i] - 2) * (s[i] - 2) * q[i]; + } + + // Factor n-2 was moved for better numerical behavior. + double nom = (n - 3.) * d1 + d2 / (n - 2) - 2. * d3; + double div = n * (n - 1.) * (n - 3.) * (n - 4.); + double d = 30 * nom / div; + return d < 1. ? d : 1.; + } + + /** + * Compute bivariate ranks. + * + * q[i] is the number of objects such that x[j] < x[i] and y[j] < y[i] + * + * @param adapter1 First adapter + * @param data1 First data set + * @param adapter2 Second adapter + * @param data2 Second data set + * @param len Length + * @return Bivariate rank statistics. + */ + protected static <A, B> double[] computeBivariateRanks(NumberArrayAdapter<?, A> adapter1, A data1, NumberArrayAdapter<?, B> adapter2, B data2, int len) { + double[] ret = new double[len]; + for(int i = 0; i < len; i++) { + for(int j = i + 1; j < len; j++) { + double xi = adapter1.getDouble(data1, i), xj = adapter1.getDouble(data1, j); + double yi = adapter2.getDouble(data2, i), yj = adapter2.getDouble(data2, j); + if(xi < xj) { + ret[j] += (yi < yj) ? 1 : (yi == yj) ? .5 : 0; + } + else if(xj < xi) { + ret[i] += (yj < yi) ? 1 : (yj == yi) ? .5 : 0; + } + else { // tied on x + if(yi < yj) { + ret[j] += .5; + } + else if(yj < yi) { + ret[i] += .5; + } + else { // Double tied + ret[i] += .25; + ret[j] += .25; + } + } + } + } + return ret; + } + + // Tabular approximation + private final static double[] TABVAL = { // + 0.5297, 0.4918, 0.4565, 0.4236, 0.393, // + 0.3648, 0.3387, 0.3146, 0.2924, 0.2719, // 10 + 0.253, 0.2355, 0.2194, 0.2045, 0.1908, // + 0.1781, 0.1663, 0.1554, 0.1453, 0.1359, // 20 + 0.1273, 0.1192, 0.1117, 0.1047, 0.0982, // + 0.0921, 0.0864, 0.0812, 0.0762, 0.0716, // 30 + 0.0673, 0.0633, 0.0595, 0.056, 0.0527, // + 0.0496, 0.0467, 0.044, 0.0414, 0.039, // 40 + 0.0368, 0.0347, 0.0327, 0.0308, 0.0291, // + 0.0274, 0.0259, 0.0244, 0.023, 0.0217, // 50 + 0.0205, 0.0194, 0.0183, 0.0173, 0.0163, // + 0.0154, 0.0145, 0.0137, 0.013, 0.0123, // 60 + 0.0116, 0.011, 0.0104, 0.0098, 0.0093, // + 0.0087, 0.0083, 0.0078, 0.0074, 0.007, // 70 + 0.0066, 0.0063, 0.0059, 0.0056, 0.0053, // + 0.005, 0.0047, 0.0045, 0.0042, 0.0025, // 80 + 0.0014, 0.0008, 0.0005, 0.0003, 0.0002, 0.0001 }; + + // Table positions + private final static double[] TABPOS = new double[] { // + 1.10, 1.15, 1.20, 1.25, 1.30, 1.35, 1.40, 1.45, 1.50, 1.55, // + 1.60, 1.65, 1.70, 1.75, 1.80, 1.85, 1.90, 1.95, 2.00, 2.05, // + 2.10, 2.15, 2.20, 2.25, 2.30, 2.35, 2.40, 2.45, 2.50, 2.55, // + 2.60, 2.65, 2.70, 2.75, 2.80, 2.85, 2.90, 2.95, 3.00, 3.05, // + 3.10, 3.15, 3.20, 3.25, 3.30, 3.35, 3.40, 3.45, 3.50, 3.55, // + 3.60, 3.65, 3.70, 3.75, 3.80, 3.85, 3.90, 3.95, 4.00, 4.05, // + 4.10, 4.15, 4.20, 4.25, 4.30, 4.35, 4.40, 4.45, 4.50, 4.55, // + 4.60, 4.65, 4.70, 4.75, 4.80, 4.85, 4.90, 4.95, 5.00, // + 5.50, 6.00, 6.50, 7.00, 7.50, 8.00, 8.50 }; + + /** + * Convert Hoeffding D value to a p-value. + * + * @param d D value + * @param n Data set size + * @return p-value + */ + public double toPValue(double d, int n) { + double b = d / 30 + 1. / (36 * n); + double z = .5 * MathUtil.PISQUARE * MathUtil.PISQUARE * n * b; + + // Exponential approximation + if(z < 1.1 || z > 8.5) { + double e = Math.exp(0.3885037 - 1.164879 * z); + return (e > 1) ? 1 : (e < 0) ? 0 : e; + } + // Tabular approximation + for(int i = 0; i < 86; i++) { + if(TABPOS[i] >= z) { + // Exact table value + if(TABPOS[i] == z) { + return TABVAL[i]; + } + // Linear interpolation + double x1 = TABPOS[i], x0 = TABPOS[i - 1]; + double y1 = TABVAL[i], y0 = TABVAL[i - 1]; + return y0 + (y1 - y0) * (z - x0) / (x1 - x0); + } + } + return -1; + } + + /** + * Parameterization class. + * + * @author Erich Schubert + * + * @apiviz.exclude + */ + public static class Parameterizer extends AbstractParameterizer { + @Override + protected HoeffdingsDDependenceMeasure makeInstance() { + return STATIC; + } + } +} diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/dependence/JensenShannonEquiwidthDependenceMeasure.java b/src/de/lmu/ifi/dbs/elki/math/statistics/dependence/JensenShannonEquiwidthDependenceMeasure.java new file mode 100644 index 00000000..7b0000a3 --- /dev/null +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/dependence/JensenShannonEquiwidthDependenceMeasure.java @@ -0,0 +1,143 @@ +package de.lmu.ifi.dbs.elki.math.statistics.dependence; + +/* + This file is part of ELKI: + Environment for Developing KDD-Applications Supported by Index-Structures + + Copyright (C) 2014 + Ludwig-Maximilians-Universität München + Lehr- und Forschungseinheit für Datenbanksysteme + ELKI Development Team + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero 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 Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +import de.lmu.ifi.dbs.elki.math.MathUtil; +import de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike.NumberArrayAdapter; +import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer; + +/** + * Jensen-Shannon Divergence is closely related to mutual information. + * + * The output value is normalized, such that an evenly distributed and identical + * distribution will yield a value of 1. Independent distributions may still + * yield values close to .25, though. + * + * TODO: Offer normalized and non-normalized variants? + * + * @author Erich Schubert + */ +public class JensenShannonEquiwidthDependenceMeasure extends AbstractDependenceMeasure { + /** + * Static instance. + */ + public static final JensenShannonEquiwidthDependenceMeasure STATIC = new JensenShannonEquiwidthDependenceMeasure(); + + /** + * Constructor - use {@link #STATIC} instance. + */ + protected JensenShannonEquiwidthDependenceMeasure() { + super(); + } + + @Override + public <A, B> double dependence(NumberArrayAdapter<?, A> adapter1, A data1, NumberArrayAdapter<?, B> adapter2, B data2) { + final int len = size(adapter1, data1, adapter2, data2); + final int bins = (int) Math.round(Math.sqrt(len)); + final int maxbin = bins - 1; + + double min1 = adapter1.getDouble(data1, 0), max1 = min1; + double min2 = adapter2.getDouble(data2, 0), max2 = min2; + for(int i = 1; i < len; i++) { + final double vx = adapter1.getDouble(data1, i); + final double vy = adapter2.getDouble(data2, i); + if(vx < min1) { + min1 = vx; + } + else if(vx > max1) { + max1 = vx; + } + if(vy < min2) { + min2 = vy; + } + else if(vy > max2) { + max2 = vy; + } + } + final double scale1 = (max1 > min1) ? bins / (max1 - min1) : 1; + final double scale2 = (max2 > min2) ? bins / (max2 - min2) : 1; + + int[] margin1 = new int[bins], margin2 = new int[bins]; + int[][] counts = new int[bins][bins]; + for(int i = 0; i < len; i++) { + int bin1 = (int) Math.floor((adapter1.getDouble(data1, i) - min1) * scale1); + int bin2 = (int) Math.floor((adapter2.getDouble(data2, i) - min2) * scale2); + bin1 = bin1 < bins ? bin1 : maxbin; + bin2 = bin2 < bins ? bin2 : maxbin; + margin1[bin1]++; + margin2[bin2]++; + counts[bin1][bin2]++; + } + + // calculating relative frequencies + double e = 0; + for(int bin1 = 0; bin1 < counts.length; bin1++) { + // Margin value for row i. + final int sum1 = margin1[bin1]; + // Skip empty rows early. + if(sum1 == 0) { + continue; + } + // Inverse pX + final double pX = sum1 / (double) len; + final int[] row = counts[bin1]; + for(int bin2 = 0; bin2 < row.length; bin2++) { + final int sum2 = margin2[bin2]; + if(sum2 > 0) { + final int cell = row[bin2]; + // JS divergence of pXY and (pX * pY) + double pXY = cell / (double) len; + final double pXpY = pX * sum2 / len; + final double iavg = 2. / (pXY + pXpY); + e += pXY > 0. ? pXY * Math.log(pXY * iavg) : 0.; + e += pXpY * Math.log(pXpY * iavg); + } + } + } + // Expected value for evenly distributed and identical: + // pX = pY = 1/b and thus pXpY = 1/b^2. + // for i==j, pXY=1/b and thus iavg = 2*b*b/(b+1) + // otherwise, pXY=0 and thus iavg = 2*b*b + // pXY: e += log(b*2/(b+1)) = log(b) + log(2/(b+1)) + // pXpY1: e += 1/b*log(2/(b+1)) = 1/b*log(2/(b+1)) + // pXpY2: e += (b-1)/b*log(2) = (b-1)/b*log(2) + final double exp = Math.log(bins) + (1. + 1. / bins) * Math.log(2. / (bins + 1)) + (bins - 1.) / bins * MathUtil.LOG2; + // e *= .5; // Average, but we need to adjust exp then, too! + return e / exp; + } + + /** + * Parameterization class. + * + * @author Erich Schubert + * + * @apiviz.exclude + */ + public static class Parameterizer extends AbstractParameterizer { + @Override + protected JensenShannonEquiwidthDependenceMeasure makeInstance() { + return STATIC; + } + } +} diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/dependence/MCEDependenceMeasure.java b/src/de/lmu/ifi/dbs/elki/math/statistics/dependence/MCEDependenceMeasure.java new file mode 100644 index 00000000..899aff9a --- /dev/null +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/dependence/MCEDependenceMeasure.java @@ -0,0 +1,274 @@ +package de.lmu.ifi.dbs.elki.math.statistics.dependence; + +/* + This file is part of ELKI: + Environment for Developing KDD-Applications Supported by Index-Structures + + Copyright (C) 2014 + Ludwig-Maximilians-Universität München + Lehr- und Forschungseinheit für Datenbanksysteme + ELKI Development Team + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero 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 Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +import java.util.ArrayList; +import java.util.Arrays; + +import de.lmu.ifi.dbs.elki.math.MathUtil; +import de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike.NumberArrayAdapter; +import de.lmu.ifi.dbs.elki.utilities.datastructures.arrays.IntegerArrayQuickSort; +import de.lmu.ifi.dbs.elki.utilities.datastructures.arrays.IntegerComparator; +import de.lmu.ifi.dbs.elki.utilities.documentation.Reference; +import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer; + +/** + * Compute a mutual information based dependence measure using a nested means + * discretization, originally proposed for ordering axes in parallel coordinate + * plots. + * + * Reference: + * <p> + * D. Guo<br /> + * Coordinating computational and visual approaches for interactive feature + * selection and multivariate clustering<br /> + * Information Visualization, 2(4), 2003. + * </p> + * + * @author Erich Schubert + */ +@Reference(authors = "D. Guo", // +title = "Coordinating computational and visual approaches for interactive feature selection and multivariate clustering", // +booktitle = "Information Visualization, 2(4)", // +url = "http://dx.doi.org/10.1057/palgrave.ivs.9500053") +public class MCEDependenceMeasure extends AbstractDependenceMeasure { + /** + * Static instance. + */ + public static final MCEDependenceMeasure STATIC = new MCEDependenceMeasure(); + + /** + * Desired size: 35 observations. + * + * While this could trivially be made parameterizable, it is a reasonable rule + * of thumb and not expected to have a major effect. + */ + public static final int TARGET = 35; + + @Override + public <A, B> double dependence(NumberArrayAdapter<?, A> adapter1, A data1, NumberArrayAdapter<?, B> adapter2, B data2) { + final int len = size(adapter1, data1, adapter2, data2); + // Find a number of bins as recommended by Cheng et al. + double p = MathUtil.log2(len / (double) TARGET); + // As we are in 2d, take the root (*.5) But let's use at least 1, too. + // Check: for 10000 this should give 4, for 150 it gives 1. + int power = Math.max(1, (int) Math.floor(p * .5)); + int gridsize = 1 << power; + double loggrid = Math.log((double) gridsize); + + ArrayList<int[]> parts1 = buildPartitions(adapter1, data1, len, power); + ArrayList<int[]> parts2 = buildPartitions(adapter2, data2, len, power); + + int[][] res = new int[gridsize][gridsize]; + intersectionMatrix(res, parts1, parts2, gridsize); + return 1. - getMCEntropy(res, parts1, parts2, len, gridsize, loggrid); + } + + /** + * Partitions an attribute. + * + * @param adapter1 Data adapter + * @param data1 Data set + * @param len Length of data + * @param depth Splitting depth + * @return List of sorted objects + */ + private <A> ArrayList<int[]> buildPartitions(NumberArrayAdapter<?, A> adapter1, A data1, int len, int depth) { + final int[] idx = new int[len]; + final double[] tmp = new double[len]; + for(int i = 0; i < len; ++i) { + idx[i] = i; + tmp[i] = adapter1.getDouble(data1, i); + } + // Sort indexes: + IntegerArrayQuickSort.sort(idx, new IntegerComparator() { + @Override + public int compare(int x, int y) { + return Double.compare(tmp[x], tmp[y]); + } + }); + Arrays.sort(tmp); // Should yield the same ordering + + ArrayList<int[]> ret = new ArrayList<>(1 << depth); + divide(idx, tmp, ret, 0, tmp.length, depth); + return ret; + } + + /** + * Recursive call to further subdivide the array. + * + * @param idx Object indexes. + * @param data 1D data, sorted + * @param ret Output index + * @param start Interval start + * @param end Interval end + * @param depth Depth + */ + private void divide(int[] idx, double[] data, ArrayList<int[]> ret, int start, int end, int depth) { + if(depth == 0) { + int[] a = Arrays.copyOfRange(idx, start, end); + Arrays.sort(a); + ret.add(a); + return; + } + final int count = end - start; + if(count == 0) { + // Corner case, that should barely happen. But for ties, we currently + // Do not yet assure that it doesn't happen! + for(int j = 1 << depth; j > 0; --j) { + ret.add(new int[0]); + } + return; + } + double m = 0.; + for(int i = start; i < end; i++) { + m += data[i]; + } + m /= count; + int pos = Arrays.binarySearch(data, start, end, m); + if(pos >= 0) { + // Ties: try to choose the most central element. + final int opt = (start + end) >> 1; + while(data[pos] == m) { + if(pos < opt) { + pos++; + } + else if(pos > opt) { + pos--; + } + else { + break; + } + } + } + else { + pos = (-pos - 1); + } + divide(idx, data, ret, start, pos, depth - 1); + divide(idx, data, ret, pos, end, depth - 1); + } + + /** + * Intersect the two 1d grid decompositions, to obtain a 2d matrix. + * + * @param res Output matrix to fill + * @param partsx Partitions in first component + * @param partsy Partitions in second component. + * @param gridsize Size of partition decomposition + */ + private void intersectionMatrix(int[][] res, ArrayList<int[]> partsx, ArrayList<int[]> partsy, int gridsize) { + for(int x = 0; x < gridsize; x++) { + final int[] px = partsx.get(x); + final int[] rowx = res[x]; + for(int y = 0; y < gridsize; y++) { + int[] py = partsy.get(y); + rowx[y] = intersectionSize(px, py); + } + } + } + + /** + * Compute the intersection of two sorted integer lists. + * + * @param px First list + * @param py Second list + * @return Intersection size. + */ + private int intersectionSize(int[] px, int[] py) { + int i = 0, j = 0, c = 0; + while(i < px.length && j < py.length) { + final int vx = px[i], vy = py[i]; + if(vx < vy) { + ++i; + } + else if(vx > vy) { + ++j; + } + else { + ++c; + ++i; + ++j; + } + } + return c; + } + + /** + * Compute the MCE entropy value. + * + * @param mat Partition size matrix + * @param partsx Partitions on X + * @param partsy Partitions on Y + * @param size Data set size + * @param gridsize Size of grids + * @param loggrid Logarithm of grid sizes, for normalization + * @return MCE score. + */ + private double getMCEntropy(int[][] mat, ArrayList<int[]> partsx, ArrayList<int[]> partsy, int size, int gridsize, double loggrid) { + // Margin entropies: + double[] mx = new double[gridsize]; + double[] my = new double[gridsize]; + + for(int i = 0; i < gridsize; i++) { + // Note: indexes are a bit tricky here, because we compute both margin + // entropies at the same time! + final double sumx = (double) partsx.get(i).length; + final double sumy = (double) partsy.get(i).length; + for(int j = 0; j < gridsize; j++) { + double px = mat[i][j] / sumx; + double py = mat[j][i] / sumy; + + if(px > 0.) { + mx[i] -= px * Math.log(px); + } + if(py > 0.) { + my[i] -= py * Math.log(py); + } + } + } + + // Weighted sums of margin entropies. + double sumx = 0., sumy = 0.; + for(int i = 0; i < gridsize; i++) { + sumx += mx[i] * partsx.get(i).length; + sumy += my[i] * partsy.get(i).length; + } + + double max = ((sumx > sumy) ? sumx : sumy); + return max / (size * loggrid); + } + + /** + * Parameterization class. + * + * @author Erich Schubert + * + * @apiviz.exclude + */ + public static class Parameterizer extends AbstractParameterizer { + @Override + protected MCEDependenceMeasure makeInstance() { + return STATIC; + } + } +} diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/dependence/MutualInformationEquiwidthDependenceMeasure.java b/src/de/lmu/ifi/dbs/elki/math/statistics/dependence/MutualInformationEquiwidthDependenceMeasure.java new file mode 100644 index 00000000..26a1759a --- /dev/null +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/dependence/MutualInformationEquiwidthDependenceMeasure.java @@ -0,0 +1,137 @@ +package de.lmu.ifi.dbs.elki.math.statistics.dependence; + +/* + This file is part of ELKI: + Environment for Developing KDD-Applications Supported by Index-Structures + + Copyright (C) 2014 + Ludwig-Maximilians-Universität München + Lehr- und Forschungseinheit für Datenbanksysteme + ELKI Development Team + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero 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 Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +import de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike.NumberArrayAdapter; +import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer; + +/** + * Mutual Information (MI) dependence measure by dividing each attribute into + * equal-width bins. MI can be seen as Kullback–Leibler divergence of the joint + * distribution and the product of the marginal distributions. + * + * For normalization, the resulting values are scaled by {@code mi/log(nbins)}. + * This both cancels out the logarithm base, and normalizes for the number of + * bins (a uniform distribution will yield a MI with itself of 1). + * + * TODO: Offer normalized and non-normalized variants? + * + * For a median-based discretization, see {@link MCEDependenceMeasure}. + * + * @author Erich Schubert + */ +public class MutualInformationEquiwidthDependenceMeasure extends AbstractDependenceMeasure { + /** + * Static instance. + */ + public static final MutualInformationEquiwidthDependenceMeasure STATIC = new MutualInformationEquiwidthDependenceMeasure(); + + /** + * Constructor - use {@link #STATIC} instance. + */ + protected MutualInformationEquiwidthDependenceMeasure() { + super(); + } + + @Override + public <A, B> double dependence(NumberArrayAdapter<?, A> adapter1, A data1, NumberArrayAdapter<?, B> adapter2, B data2) { + final int len = size(adapter1, data1, adapter2, data2); + final int bins = (int) Math.round(Math.sqrt(len)); + final int maxbin = bins - 1; + + double min1 = adapter1.getDouble(data1, 0), max1 = min1; + double min2 = adapter2.getDouble(data2, 0), max2 = min2; + for(int i = 1; i < len; i++) { + final double vx = adapter1.getDouble(data1, i); + final double vy = adapter2.getDouble(data2, i); + if(vx < min1) { + min1 = vx; + } + else if(vx > max1) { + max1 = vx; + } + if(vy < min2) { + min2 = vy; + } + else if(vy > max2) { + max2 = vy; + } + } + final double scale1 = (max1 > min1) ? bins / (max1 - min1) : 1; + final double scale2 = (max2 > min2) ? bins / (max2 - min2) : 1; + + int[] margin1 = new int[bins], margin2 = new int[bins]; + int[][] counts = new int[bins][bins]; + for(int i = 0; i < len; i++) { + int bin1 = (int) Math.floor((adapter1.getDouble(data1, i) - min1) * scale1); + int bin2 = (int) Math.floor((adapter2.getDouble(data2, i) - min2) * scale2); + bin1 = bin1 < bins ? bin1 : maxbin; + bin2 = bin2 < bins ? bin2 : maxbin; + margin1[bin1]++; + margin2[bin2]++; + counts[bin1][bin2]++; + } + + // calculating relative frequencies + double e = 0; + for(int bin1 = 0; bin1 < counts.length; bin1++) { + // Margin value for row i. + final int sum1 = margin1[bin1]; + // Skip empty rows early. + if(sum1 == 0) { + continue; + } + // Inverse pX + final double ipX = len / (double) sum1; + final int[] row = counts[bin1]; + for(int bin2 = 0; bin2 < row.length; bin2++) { + final int cell = row[bin2]; + // Skip empty cells. + if(cell != 0) { + // Mutual information pXY / (pX * pY) + double pXY = cell / (double) len; + // Inverse pXpY: 1 / (pX*pY) + final double ipXpY = ipX * len / margin2[bin2]; + e += pXY * Math.log(pXY * ipXpY); + } + } + } + // Expected value for uniform identical: log(bins)! + return e / Math.log(bins); + } + + /** + * Parameterization class. + * + * @author Erich Schubert + * + * @apiviz.exclude + */ + public static class Parameterizer extends AbstractParameterizer { + @Override + protected MutualInformationEquiwidthDependenceMeasure makeInstance() { + return STATIC; + } + } +} diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/dependence/SURFINGDependenceMeasure.java b/src/de/lmu/ifi/dbs/elki/math/statistics/dependence/SURFINGDependenceMeasure.java new file mode 100644 index 00000000..ce866c16 --- /dev/null +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/dependence/SURFINGDependenceMeasure.java @@ -0,0 +1,133 @@ +package de.lmu.ifi.dbs.elki.math.statistics.dependence;
+
+/*
+ This file is part of ELKI:
+ Environment for Developing KDD-Applications Supported by Index-Structures
+
+ Copyright (C) 2014
+ Ludwig-Maximilians-Universität München
+ Lehr- und Forschungseinheit für Datenbanksysteme
+ ELKI Development Team
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+import de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike.NumberArrayAdapter;
+import de.lmu.ifi.dbs.elki.utilities.datastructures.heap.DoubleMinHeap;
+import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
+
+/**
+ * Compute the similarity of dimensions using the SURFING score. The parameter k
+ * for the k nearest neighbors is currently hard-coded to 10% of the set size.
+ *
+ * Note that the complexity is roughly O(n n k), so this is a rather slow
+ * method, and with k at 10% of n, is actually cubic: O(0.1 * n^3).
+ *
+ * This version cannot use index support, as the API operates without database
+ * attachment. However, it should be possible to implement some trivial
+ * sorted-list indexes to get a reasonable speedup!
+ *
+ * Reference:
+ * <p>
+ * Elke Achtert, Hans-Peter Kriegel, Erich Schubert, Arthur Zimek:<br />
+ * Interactive Data Mining with 3D-Parallel-Coordinate-Trees.<br />
+ * Proceedings of the 2013 ACM International Conference on Management of Data
+ * (SIGMOD), New York City, NY, 2013.
+ * </p>
+ *
+ * Based on:
+ * <p>
+ * Christian Baumgartner, Claudia Plant, Karin Kailing, Hans-Peter Kriegel, and
+ * Peer Kröger<br />
+ * Subspace Selection for Clustering High-Dimensional Data<br />
+ * In IEEE International Conference on Data Mining, 2004.
+ * </p>
+ *
+ * TODO: make the subspace distance function and k parameterizable.
+ *
+ * @author Robert Rödler
+ * @author Erich Schubert
+ *
+ * @apiviz.uses SubspaceEuclideanDistanceFunction
+ */
+@Reference(authors = "Elke Achtert, Hans-Peter Kriegel, Erich Schubert, Arthur Zimek", //
+title = "Interactive Data Mining with 3D-Parallel-Coordinate-Trees", //
+booktitle = "Proc. of the 2013 ACM International Conference on Management of Data (SIGMOD)", //
+url = "http://dx.doi.org/10.1145/2463676.2463696")
+public class SURFINGDependenceMeasure extends AbstractDependenceMeasure {
+ /**
+ * Static instance.
+ */
+ public static final SURFINGDependenceMeasure STATIC = new SURFINGDependenceMeasure();
+
+ /**
+ * Constructor. Use static instance instead!
+ */
+ protected SURFINGDependenceMeasure() {
+ super();
+ }
+
+ @Reference(authors = "Christian Baumgartner, Claudia Plant, Karin Kailing, Hans-Peter Kriegel, and Peer Kröger", //
+ title = "Subspace Selection for Clustering High-Dimensional Data", //
+ booktitle = "IEEE International Conference on Data Mining, 2004", //
+ url = "http://dx.doi.org/10.1109/ICDM.2004.10112")
+ @Override
+ public <A, B> double dependence(NumberArrayAdapter<?, A> adapter1, A data1, NumberArrayAdapter<?, B> adapter2, B data2) {
+ final int len = size(adapter1, data1, adapter2, data2);
+ final int k = Math.max(1, len / 10);
+
+ double[] knns = new double[len];
+
+ DoubleMinHeap heap = new DoubleMinHeap(k);
+ double kdistmean = 0.;
+ for(int i = 0; i < len; ++i) {
+ double ix = adapter1.getDouble(data1, i), iy = adapter2.getDouble(data2, i);
+ heap.clear();
+ for(int j = 0; j < len; ++j) {
+ double jx = adapter1.getDouble(data1, j), jy = adapter2.getDouble(data2, j);
+ double dx = ix - jx, dy = iy - jy;
+ heap.add(dx * dx + dy * dy); // Squared Euclidean.
+ }
+ double kdist = Math.sqrt(heap.peek()); // Euclidean
+ knns[i] = kdist;
+ kdistmean += kdist;
+ }
+ kdistmean /= len;
+ // Deviation from mean:
+ double diff = 0.;
+ int below = 0;
+ for(int l = 0; l < knns.length; l++) {
+ diff += Math.abs(kdistmean - knns[l]);
+ if(knns[l] < kdistmean) {
+ below++;
+ }
+ }
+ return (below > 0) ? diff / (2. * kdistmean * below) : 0;
+ }
+
+ /**
+ * Parameterization class.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class Parameterizer extends AbstractParameterizer {
+ @Override
+ protected SURFINGDependenceMeasure makeInstance() {
+ return STATIC;
+ }
+ }
+}
diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/dependence/SlopeDependenceMeasure.java b/src/de/lmu/ifi/dbs/elki/math/statistics/dependence/SlopeDependenceMeasure.java new file mode 100644 index 00000000..3dd4fcaa --- /dev/null +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/dependence/SlopeDependenceMeasure.java @@ -0,0 +1,153 @@ +package de.lmu.ifi.dbs.elki.math.statistics.dependence;
+
+/*
+ This file is part of ELKI:
+ Environment for Developing KDD-Applications Supported by Index-Structures
+
+ Copyright (C) 2014
+ Ludwig-Maximilians-Universität München
+ Lehr- und Forschungseinheit für Datenbanksysteme
+ ELKI Development Team
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+import de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike.NumberArrayAdapter;
+import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
+
+/**
+ * Arrange dimensions based on the entropy of the slope spectrum.
+ *
+ * Reference:
+ * <p>
+ * Elke Achtert, Hans-Peter Kriegel, Erich Schubert, Arthur Zimek:<br />
+ * Interactive Data Mining with 3D-Parallel-Coordinate-Trees.<br />
+ * Proceedings of the 2013 ACM International Conference on Management of Data
+ * (SIGMOD), New York City, NY, 2013.
+ * </p>
+ *
+ * TODO: shouldn't this be normalized by the single-dimension entropies or so?
+ *
+ * @author Erich Schubert
+ * @author Robert Rödler
+ */
+@Reference(authors = "Elke Achtert, Hans-Peter Kriegel, Erich Schubert, Arthur Zimek", //
+title = "Interactive Data Mining with 3D-Parallel-Coordinate-Trees", //
+booktitle = "Proc. of the 2013 ACM International Conference on Management of Data (SIGMOD)", //
+url = "http://dx.doi.org/10.1145/2463676.2463696")
+public class SlopeDependenceMeasure extends AbstractDependenceMeasure {
+ /**
+ * Static instance.
+ */
+ public static final SlopeDependenceMeasure STATIC = new SlopeDependenceMeasure();
+
+ /**
+ * Full precision.
+ */
+ protected final static int PRECISION = 40;
+
+ /**
+ * Precision for entropy normalization.
+ */
+ protected final static double LOG_PRECISION = Math.log(PRECISION);
+
+ /**
+ * Scaling factor.
+ */
+ protected final static double RESCALE = PRECISION * .5;
+
+ /**
+ * Constructor. Use static instance instead!
+ */
+ protected SlopeDependenceMeasure() {
+ super();
+ }
+
+ @Override
+ public <A, B> double dependence(NumberArrayAdapter<?, A> adapter1, A data1, NumberArrayAdapter<?, B> adapter2, B data2) {
+ final int len = size(adapter1, data1, adapter2, data2);
+
+ // Get attribute value range:
+ final double off1, scale1, off2, scale2;
+ {
+ double mi = adapter1.getDouble(data1, 0), ma = mi;
+ for(int i = 1; i < len; ++i) {
+ double v = adapter1.getDouble(data1, i);
+ if(v < mi) {
+ mi = v;
+ }
+ else if(v > ma) {
+ ma = v;
+ }
+ }
+ off1 = mi;
+ scale1 = (ma > mi) ? (1. / (ma - mi)) : 1.;
+ // Second data
+ mi = adapter2.getDouble(data2, 0);
+ ma = mi;
+ for(int i = 1; i < len; ++i) {
+ double v = adapter2.getDouble(data2, i);
+ if(v < mi) {
+ mi = v;
+ }
+ else if(v > ma) {
+ ma = v;
+ }
+ }
+ off2 = mi;
+ scale2 = (ma > mi) ? (1. / (ma - mi)) : 1.;
+ }
+
+ // Collect angular histograms.
+ // Note, we only fill half of the matrix
+ int[] angles = new int[PRECISION];
+
+ // Scratch buffer
+ for(int i = 0; i < len; i++) {
+ double x = adapter1.getDouble(data1, i), y = adapter2.getDouble(data2, i);
+ x = (x - off1) * scale1;
+ y = (y - off2) * scale2;
+ final double delta = x - y + 1;
+ int div = (int) Math.round(delta * RESCALE);
+ // TODO: do we really need this check?
+ div = (div < 0) ? 0 : (div >= PRECISION) ? PRECISION - 1 : div;
+ angles[div] += 1;
+ }
+
+ // Compute entropy:
+ double entropy = 0.;
+ for(int l = 0; l < PRECISION; l++) {
+ if(angles[l] > 0) {
+ final double p = angles[l] / (double) len;
+ entropy += p * Math.log(p);
+ }
+ }
+ return 1 + entropy / LOG_PRECISION;
+ }
+
+ /**
+ * Parameterization class.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class Parameterizer extends AbstractParameterizer {
+ @Override
+ protected SlopeDependenceMeasure makeInstance() {
+ return STATIC;
+ }
+ }
+}
diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/dependence/SlopeInversionDependenceMeasure.java b/src/de/lmu/ifi/dbs/elki/math/statistics/dependence/SlopeInversionDependenceMeasure.java new file mode 100644 index 00000000..01ad78bc --- /dev/null +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/dependence/SlopeInversionDependenceMeasure.java @@ -0,0 +1,157 @@ +package de.lmu.ifi.dbs.elki.math.statistics.dependence;
+
+/*
+ This file is part of ELKI:
+ Environment for Developing KDD-Applications Supported by Index-Structures
+
+ Copyright (C) 2014
+ Ludwig-Maximilians-Universität München
+ Lehr- und Forschungseinheit für Datenbanksysteme
+ ELKI Development Team
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+import de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike.NumberArrayAdapter;
+import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
+
+/**
+ * Arrange dimensions based on the entropy of the slope spectrum.
+ *
+ * Reference:
+ * <p>
+ * Elke Achtert, Hans-Peter Kriegel, Erich Schubert, Arthur Zimek:<br />
+ * Interactive Data Mining with 3D-Parallel-Coordinate-Trees.<br />
+ * Proceedings of the 2013 ACM International Conference on Management of Data
+ * (SIGMOD), New York City, NY, 2013.
+ * </p>
+ *
+ * TODO: shouldn't this be normalized by the single-dimension entropies or so?
+ *
+ * @author Erich Schubert
+ * @author Robert Rödler
+ */
+@Reference(authors = "Elke Achtert, Hans-Peter Kriegel, Erich Schubert, Arthur Zimek", //
+title = "Interactive Data Mining with 3D-Parallel-Coordinate-Trees", //
+booktitle = "Proc. of the 2013 ACM International Conference on Management of Data (SIGMOD)", //
+url = "http://dx.doi.org/10.1145/2463676.2463696")
+public class SlopeInversionDependenceMeasure extends SlopeDependenceMeasure {
+ /**
+ * Static instance.
+ */
+ public static final SlopeInversionDependenceMeasure STATIC = new SlopeInversionDependenceMeasure();
+
+ /**
+ * Constructor. Use static instance instead!
+ */
+ protected SlopeInversionDependenceMeasure() {
+ super();
+ }
+
+ @Override
+ public <A, B> double dependence(NumberArrayAdapter<?, A> adapter1, A data1, NumberArrayAdapter<?, B> adapter2, B data2) {
+ final int len = size(adapter1, data1, adapter2, data2);
+
+ // Get attribute value range:
+ final double off1, scale1, off2, scale2;
+ {
+ double mi = adapter1.getDouble(data1, 0), ma = mi;
+ for(int i = 1; i < len; ++i) {
+ double v = adapter1.getDouble(data1, i);
+ if(v < mi) {
+ mi = v;
+ }
+ else if(v > ma) {
+ ma = v;
+ }
+ }
+ off1 = mi;
+ scale1 = (ma > mi) ? (1. / (ma - mi)) : 1.;
+ // Second data
+ mi = adapter2.getDouble(data2, 0);
+ ma = mi;
+ for(int i = 1; i < len; ++i) {
+ double v = adapter2.getDouble(data2, i);
+ if(v < mi) {
+ mi = v;
+ }
+ else if(v > ma) {
+ ma = v;
+ }
+ }
+ off2 = mi;
+ scale2 = (ma > mi) ? (1. / (ma - mi)) : 1.;
+ }
+
+ // Collect angular histograms.
+ // Note, we only fill half of the matrix
+ int[] angles = new int[PRECISION];
+ int[] angleI = new int[PRECISION];
+
+ // Scratch buffer
+ for(int i = 0; i < len; i++) {
+ double x = adapter1.getDouble(data1, i), y = adapter2.getDouble(data2, i);
+ x = (x - off1) * scale1;
+ y = (y - off2) * scale2;
+ {
+ final double delta = x - y + 1;
+ int div = (int) Math.round(delta * RESCALE);
+ // TODO: do we really need this check?
+ div = (div < 0) ? 0 : (div >= PRECISION) ? PRECISION - 1 : div;
+ angles[div] += 1;
+ }
+ {
+ final double delta = x + y;
+ int div = (int) Math.round(delta * RESCALE);
+ // TODO: do we really need this check?
+ div = (div < 0) ? 0 : (div >= PRECISION) ? PRECISION - 1 : div;
+ angleI[div] += 1;
+ }
+ }
+
+ // Compute entropy:
+ double entropy = 0., entropyI = 0.;
+ for(int l = 0; l < PRECISION; l++) {
+ if(angles[l] > 0) {
+ final double p = angles[l] / (double) len;
+ entropy += p * Math.log(p);
+ }
+ if(angleI[l] > 0) {
+ final double p = angleI[l] / (double) len;
+ entropyI += p * Math.log(p);
+ }
+ }
+ if(entropy >= entropyI) {
+ return 1 + entropy / LOG_PRECISION;
+ }
+ else {
+ return 1 + entropyI / LOG_PRECISION;
+ }
+ }
+
+ /**
+ * Parameterization class.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class Parameterizer extends AbstractParameterizer {
+ @Override
+ protected SlopeInversionDependenceMeasure makeInstance() {
+ return STATIC;
+ }
+ }
+}
diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/dependence/SpearmanCorrelationDependenceMeasure.java b/src/de/lmu/ifi/dbs/elki/math/statistics/dependence/SpearmanCorrelationDependenceMeasure.java new file mode 100644 index 00000000..24202dce --- /dev/null +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/dependence/SpearmanCorrelationDependenceMeasure.java @@ -0,0 +1,78 @@ +package de.lmu.ifi.dbs.elki.math.statistics.dependence; + +/* + This file is part of ELKI: + Environment for Developing KDD-Applications Supported by Index-Structures + + Copyright (C) 2014 + Ludwig-Maximilians-Universität München + Lehr- und Forschungseinheit für Datenbanksysteme + ELKI Development Team + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero 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 Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +import de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike.NumberArrayAdapter; +import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer; + +/** + * Spearman rank-correlation coefficient, also known as Spearmans Rho. + * + * @author Erich Schubert + */ +public class SpearmanCorrelationDependenceMeasure extends AbstractDependenceMeasure { + /** + * Static instance. + */ + public static final SpearmanCorrelationDependenceMeasure STATIC = new SpearmanCorrelationDependenceMeasure(); + + /** + * Constructor - use {@link #STATIC} instance. + */ + protected SpearmanCorrelationDependenceMeasure() { + super(); + } + + @Override + public <A, B> double dependence(NumberArrayAdapter<?, A> adapter1, A data1, NumberArrayAdapter<?, B> adapter2, B data2) { + final int len = size(adapter1, data1, adapter2, data2); + double[] ranks1 = computeNormalizedRanks(adapter1, data1, len); + double[] ranks2 = computeNormalizedRanks(adapter2, data2, len); + + // Second pass: variances and covariance + double v1 = 0., v2 = 0., cov = 0.; + for(int i = 0; i < len; i++) { + double d1 = ranks1[i] - .5, d2 = ranks2[i] - .5; + v1 += d1 * d1; + v2 += d2 * d2; + cov += d1 * d2; + } + // Note: we did not normalize by len, as this cancels out. + return cov / Math.sqrt(v1 * v2); + } + + /** + * Parameterization class + * + * @author Erich Schubert + * + * @apiviz.exclude + */ + public static class Parameterizer extends AbstractParameterizer { + @Override + protected SpearmanCorrelationDependenceMeasure makeInstance() { + return STATIC; + } + } +} diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/dependence/package-info.java b/src/de/lmu/ifi/dbs/elki/math/statistics/dependence/package-info.java new file mode 100644 index 00000000..a1f0bd55 --- /dev/null +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/dependence/package-info.java @@ -0,0 +1,26 @@ +/** + * <p>Statistical measures of dependence, such as correlation.</p> + */ +/* + This file is part of ELKI: + Environment for Developing KDD-Applications Supported by Index-Structures + + Copyright (C) 2014 + Ludwig-Maximilians-Universität München + Lehr- und Forschungseinheit für Datenbanksysteme + ELKI Development Team + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero 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 Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package de.lmu.ifi.dbs.elki.math.statistics.dependence;
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/AbstractDistribution.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/AbstractDistribution.java index 30481d00..1a05daed 100644 --- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/AbstractDistribution.java +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/AbstractDistribution.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -25,7 +25,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution; import java.util.Random; -import de.lmu.ifi.dbs.elki.utilities.RandomFactory; +import de.lmu.ifi.dbs.elki.math.random.RandomFactory; import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer; import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID; import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization; diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/BetaDistribution.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/BetaDistribution.java index 04d55262..f01ac528 100644 --- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/BetaDistribution.java +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/BetaDistribution.java @@ -2,7 +2,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution; import java.util.Random;
-import de.lmu.ifi.dbs.elki.utilities.RandomFactory;
+import de.lmu.ifi.dbs.elki.math.random.RandomFactory;
import de.lmu.ifi.dbs.elki.utilities.exceptions.AbortException;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
@@ -12,7 +12,7 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.DoubleParameter; This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2012
+ Copyright (C) 2014
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/CauchyDistribution.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/CauchyDistribution.java index 2b5d4949..dddfdcc0 100644 --- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/CauchyDistribution.java +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/CauchyDistribution.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -25,7 +25,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution; import java.util.Random; -import de.lmu.ifi.dbs.elki.utilities.RandomFactory; +import de.lmu.ifi.dbs.elki.math.random.RandomFactory; import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID; import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization; import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.DoubleParameter; diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/ChiDistribution.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/ChiDistribution.java index 5f144946..b7de1606 100644 --- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/ChiDistribution.java +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/ChiDistribution.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -25,7 +25,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution; import java.util.Random; -import de.lmu.ifi.dbs.elki.utilities.RandomFactory; +import de.lmu.ifi.dbs.elki.math.random.RandomFactory; import de.lmu.ifi.dbs.elki.utilities.exceptions.ExceptionMessages; import de.lmu.ifi.dbs.elki.utilities.exceptions.NotImplementedException; import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization; diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/ChiSquaredDistribution.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/ChiSquaredDistribution.java index 6fd432b2..5bea555d 100644 --- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/ChiSquaredDistribution.java +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/ChiSquaredDistribution.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -24,7 +24,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution; */ import java.util.Random; -import de.lmu.ifi.dbs.elki.utilities.RandomFactory; +import de.lmu.ifi.dbs.elki.math.random.RandomFactory; import de.lmu.ifi.dbs.elki.utilities.documentation.Reference; import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID; import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization; diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/ConstantDistribution.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/ConstantDistribution.java index b31eaa3d..3d70d0d3 100644 --- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/ConstantDistribution.java +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/ConstantDistribution.java @@ -9,7 +9,7 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.DoubleParameter; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/Distribution.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/Distribution.java index 0c60e02f..68ac1b60 100644 --- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/Distribution.java +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/Distribution.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -23,14 +23,13 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution; along with this program. If not, see <http://www.gnu.org/licenses/>. */ -import de.lmu.ifi.dbs.elki.utilities.optionhandling.Parameterizable; /** * Statistical distributions, with their common functions. * * @author Erich Schubert */ -public interface Distribution extends Parameterizable { +public interface Distribution { /** * Return the density of an existing value * diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/ExponentialDistribution.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/ExponentialDistribution.java index 33d8e853..db6ea61d 100644 --- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/ExponentialDistribution.java +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/ExponentialDistribution.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -25,7 +25,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution; import java.util.Random; -import de.lmu.ifi.dbs.elki.utilities.RandomFactory; +import de.lmu.ifi.dbs.elki.math.random.RandomFactory; import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID; import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization; import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.DoubleParameter; diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/ExponentiallyModifiedGaussianDistribution.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/ExponentiallyModifiedGaussianDistribution.java index 22e75e3d..4905309f 100644 --- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/ExponentiallyModifiedGaussianDistribution.java +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/ExponentiallyModifiedGaussianDistribution.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -26,8 +26,8 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution; import java.util.Random; import de.lmu.ifi.dbs.elki.math.MathUtil; +import de.lmu.ifi.dbs.elki.math.random.RandomFactory; import de.lmu.ifi.dbs.elki.utilities.Alias; -import de.lmu.ifi.dbs.elki.utilities.RandomFactory; import de.lmu.ifi.dbs.elki.utilities.exceptions.ExceptionMessages; import de.lmu.ifi.dbs.elki.utilities.exceptions.NotImplementedException; import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization; diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/GammaDistribution.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/GammaDistribution.java index 850b0e3a..b2a79d81 100644 --- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/GammaDistribution.java +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/GammaDistribution.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -27,7 +27,7 @@ import java.util.Random; import de.lmu.ifi.dbs.elki.logging.LoggingUtil; import de.lmu.ifi.dbs.elki.math.MathUtil; -import de.lmu.ifi.dbs.elki.utilities.RandomFactory; +import de.lmu.ifi.dbs.elki.math.random.RandomFactory; import de.lmu.ifi.dbs.elki.utilities.documentation.Reference; import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID; import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization; diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/GeneralizedExtremeValueDistribution.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/GeneralizedExtremeValueDistribution.java index 0d3fd4f8..4c0e267a 100644 --- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/GeneralizedExtremeValueDistribution.java +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/GeneralizedExtremeValueDistribution.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -25,7 +25,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution; import java.util.Random; -import de.lmu.ifi.dbs.elki.utilities.RandomFactory; +import de.lmu.ifi.dbs.elki.math.random.RandomFactory; import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization; import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.DoubleParameter; diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/GeneralizedLogisticAlternateDistribution.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/GeneralizedLogisticAlternateDistribution.java index eb5e1b1a..6e41be51 100644 --- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/GeneralizedLogisticAlternateDistribution.java +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/GeneralizedLogisticAlternateDistribution.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -24,7 +24,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution; */ import java.util.Random; -import de.lmu.ifi.dbs.elki.utilities.RandomFactory; +import de.lmu.ifi.dbs.elki.math.random.RandomFactory; import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization; import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.DoubleParameter; diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/GeneralizedLogisticDistribution.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/GeneralizedLogisticDistribution.java index 467ad4f9..f86b3b04 100644 --- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/GeneralizedLogisticDistribution.java +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/GeneralizedLogisticDistribution.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -24,7 +24,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution; */ import java.util.Random; -import de.lmu.ifi.dbs.elki.utilities.RandomFactory; +import de.lmu.ifi.dbs.elki.math.random.RandomFactory; import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization; import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.DoubleParameter; diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/GumbelDistribution.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/GumbelDistribution.java index 9f42b7e2..34683b97 100644 --- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/GumbelDistribution.java +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/GumbelDistribution.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -25,7 +25,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution; import java.util.Random; -import de.lmu.ifi.dbs.elki.utilities.RandomFactory; +import de.lmu.ifi.dbs.elki.math.random.RandomFactory; import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization; import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.DoubleParameter; diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/HaltonUniformDistribution.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/HaltonUniformDistribution.java index c16bb498..7724f237 100644 --- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/HaltonUniformDistribution.java +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/HaltonUniformDistribution.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -27,7 +27,7 @@ import java.util.Random; import de.lmu.ifi.dbs.elki.math.MathUtil; import de.lmu.ifi.dbs.elki.math.Primes; -import de.lmu.ifi.dbs.elki.utilities.RandomFactory; +import de.lmu.ifi.dbs.elki.math.random.RandomFactory; import de.lmu.ifi.dbs.elki.utilities.documentation.Reference; import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization; import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.DoubleParameter; diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/KappaDistribution.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/KappaDistribution.java index 156bf325..02940907 100644 --- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/KappaDistribution.java +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/KappaDistribution.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -24,7 +24,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution; */ import java.util.Random; -import de.lmu.ifi.dbs.elki.utilities.RandomFactory; +import de.lmu.ifi.dbs.elki.math.random.RandomFactory; import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID; import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization; import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.DoubleParameter; diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/LaplaceDistribution.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/LaplaceDistribution.java index 18a6ffbe..ad14c001 100644 --- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/LaplaceDistribution.java +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/LaplaceDistribution.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -25,8 +25,8 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution; import java.util.Random; +import de.lmu.ifi.dbs.elki.math.random.RandomFactory; import de.lmu.ifi.dbs.elki.utilities.Alias; -import de.lmu.ifi.dbs.elki.utilities.RandomFactory; import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID; import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization; import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.DoubleParameter; diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/LogGammaAlternateDistribution.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/LogGammaAlternateDistribution.java index 90902ae0..afe12db1 100644 --- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/LogGammaAlternateDistribution.java +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/LogGammaAlternateDistribution.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -25,7 +25,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution; import java.util.Random; -import de.lmu.ifi.dbs.elki.utilities.RandomFactory; +import de.lmu.ifi.dbs.elki.math.random.RandomFactory; import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID; import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization; import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.DoubleParameter; diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/LogGammaDistribution.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/LogGammaDistribution.java index 76b10dde..252794b7 100644 --- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/LogGammaDistribution.java +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/LogGammaDistribution.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -25,7 +25,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution; import java.util.Random; -import de.lmu.ifi.dbs.elki.utilities.RandomFactory; +import de.lmu.ifi.dbs.elki.math.random.RandomFactory; import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID; import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization; import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.DoubleParameter; diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/LogLogisticDistribution.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/LogLogisticDistribution.java index fe8557b3..50b4f762 100644 --- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/LogLogisticDistribution.java +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/LogLogisticDistribution.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -24,8 +24,8 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution; */ import java.util.Random; +import de.lmu.ifi.dbs.elki.math.random.RandomFactory; import de.lmu.ifi.dbs.elki.utilities.Alias; -import de.lmu.ifi.dbs.elki.utilities.RandomFactory; import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization; import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.DoubleParameter; diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/LogNormalDistribution.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/LogNormalDistribution.java index ca2fbbab..cba41e9f 100644 --- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/LogNormalDistribution.java +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/LogNormalDistribution.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -25,8 +25,8 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution; import java.util.Random; import de.lmu.ifi.dbs.elki.math.MathUtil; +import de.lmu.ifi.dbs.elki.math.random.RandomFactory; import de.lmu.ifi.dbs.elki.utilities.Alias; -import de.lmu.ifi.dbs.elki.utilities.RandomFactory; import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID; import de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints.CommonConstraints; import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization; diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/LogisticDistribution.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/LogisticDistribution.java index 12307a36..868d92bd 100644 --- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/LogisticDistribution.java +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/LogisticDistribution.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -25,8 +25,8 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution; import java.util.Random; import de.lmu.ifi.dbs.elki.math.MathUtil; +import de.lmu.ifi.dbs.elki.math.random.RandomFactory; import de.lmu.ifi.dbs.elki.utilities.Alias; -import de.lmu.ifi.dbs.elki.utilities.RandomFactory; import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization; import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.DoubleParameter; diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/NormalDistribution.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/NormalDistribution.java index 0a0d3d4e..4ce0e912 100644 --- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/NormalDistribution.java +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/NormalDistribution.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -26,8 +26,8 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution; import java.util.Random; import de.lmu.ifi.dbs.elki.math.MathUtil; +import de.lmu.ifi.dbs.elki.math.random.RandomFactory; import de.lmu.ifi.dbs.elki.utilities.Alias; -import de.lmu.ifi.dbs.elki.utilities.RandomFactory; import de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints.CommonConstraints; import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization; import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.DoubleParameter; @@ -112,6 +112,11 @@ public class NormalDistribution extends AbstractDistribution { static final double ERFINV_D[] = { 7.784695709041462e-03, 3.224671290700398e-01, 2.445134137142996e+00, 3.754408661907416e+00 }; /** + * CDFINV(0.75) + */ + public static final double PHIINV075 = 0.67448975019608171; + + /** * 1 / CDFINV(0.75) */ public static final double ONEBYPHIINV075 = 1.48260221850560186054; @@ -212,28 +217,28 @@ public class NormalDistribution extends AbstractDistribution { * @return erfc(x) */ public static double erfc(double x) { - if (Double.isNaN(x)) { + if(Double.isNaN(x)) { return Double.NaN; } - if (Double.isInfinite(x)) { + if(Double.isInfinite(x)) { return (x < 0.0) ? 2 : 0; } double result = Double.NaN; double absx = Math.abs(x); // First approximation interval - if (absx < 0.46875) { + if(absx < 0.46875) { double z = x * x; result = 1 - x * ((((ERFAPP_A[0] * z + ERFAPP_A[1]) * z + ERFAPP_A[2]) * z + ERFAPP_A[3]) * z + ERFAPP_A[4]) / ((((ERFAPP_B[0] * z + ERFAPP_B[1]) * z + ERFAPP_B[2]) * z + ERFAPP_B[3]) * z + ERFAPP_B[4]); } // Second approximation interval - else if (absx < 4.0) { + else if(absx < 4.0) { double z = absx; result = ((((((((ERFAPP_C[0] * z + ERFAPP_C[1]) * z + ERFAPP_C[2]) * z + ERFAPP_C[3]) * z + ERFAPP_C[4]) * z + ERFAPP_C[5]) * z + ERFAPP_C[6]) * z + ERFAPP_C[7]) * z + ERFAPP_C[8]) / ((((((((ERFAPP_D[0] * z + ERFAPP_D[1]) * z + ERFAPP_D[2]) * z + ERFAPP_D[3]) * z + ERFAPP_D[4]) * z + ERFAPP_D[5]) * z + ERFAPP_D[6]) * z + ERFAPP_D[7]) * z + ERFAPP_D[8]); double rounded = Math.round(result * 16.0) / 16.0; double del = (absx - rounded) * (absx + rounded); result = Math.exp(-rounded * rounded) * Math.exp(-del) * result; - if (x < 0.0) { + if(x < 0.0) { result = 2.0 - result; } } @@ -245,7 +250,7 @@ public class NormalDistribution extends AbstractDistribution { double rounded = Math.round(result * 16.0) / 16.0; double del = (absx - rounded) * (absx + rounded); result = Math.exp(-rounded * rounded) * Math.exp(-del) * result; - if (x < 0.0) { + if(x < 0.0) { result = 2.0 - result; } } @@ -303,7 +308,7 @@ public class NormalDistribution extends AbstractDistribution { * @return PDF of the given normal distribution at x. */ public static double standardNormalPDF(double x) { - return Math.exp(-.5 * x * x) * MathUtil.SQRTHALF; + return Math.exp(-.5 * x * x) * MathUtil.ONE_BY_SQRTTWOPI; } /** @@ -358,21 +363,26 @@ public class NormalDistribution extends AbstractDistribution { * @return Inverse erf. */ public static double standardNormalQuantile(double d) { - if (d == 0) { + if(d == 0) { return Double.NEGATIVE_INFINITY; - } else if (d == 1) { + } + else if(d == 1) { return Double.POSITIVE_INFINITY; - } else if (Double.isNaN(d) || d < 0 || d > 1) { + } + else if(Double.isNaN(d) || d < 0 || d > 1) { return Double.NaN; - } else if (d < P_LOW) { + } + else if(d < P_LOW) { // Rational approximation for lower region: double q = Math.sqrt(-2 * Math.log(d)); return (((((ERFINV_C[0] * q + ERFINV_C[1]) * q + ERFINV_C[2]) * q + ERFINV_C[3]) * q + ERFINV_C[4]) * q + ERFINV_C[5]) / ((((ERFINV_D[0] * q + ERFINV_D[1]) * q + ERFINV_D[2]) * q + ERFINV_D[3]) * q + 1); - } else if (P_HIGH < d) { + } + else if(P_HIGH < d) { // Rational approximation for upper region: double q = Math.sqrt(-2 * Math.log(1 - d)); return -(((((ERFINV_C[0] * q + ERFINV_C[1]) * q + ERFINV_C[2]) * q + ERFINV_C[3]) * q + ERFINV_C[4]) * q + ERFINV_C[5]) / ((((ERFINV_D[0] * q + ERFINV_D[1]) * q + ERFINV_D[2]) * q + ERFINV_D[3]) * q + 1); - } else { + } + else { // Rational approximation for central region: double q = d - 0.5D; double r = q * q; @@ -396,13 +406,13 @@ public class NormalDistribution extends AbstractDistribution { super.makeOptions(config); DoubleParameter muP = new DoubleParameter(LOCATION_ID); - if (config.grab(muP)) { + if(config.grab(muP)) { mu = muP.doubleValue(); } DoubleParameter sigmaP = new DoubleParameter(SCALE_ID); sigmaP.addConstraint(CommonConstraints.GREATER_THAN_ZERO_DOUBLE); - if (config.grab(sigmaP)) { + if(config.grab(sigmaP)) { sigma = sigmaP.doubleValue(); } } diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/PoissonDistribution.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/PoissonDistribution.java index b6b70b34..3321ee69 100644 --- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/PoissonDistribution.java +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/PoissonDistribution.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -25,7 +25,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution; import java.util.Random; import de.lmu.ifi.dbs.elki.math.MathUtil; -import de.lmu.ifi.dbs.elki.utilities.RandomFactory; +import de.lmu.ifi.dbs.elki.math.random.RandomFactory; import de.lmu.ifi.dbs.elki.utilities.documentation.Reference; import de.lmu.ifi.dbs.elki.utilities.exceptions.ExceptionMessages; import de.lmu.ifi.dbs.elki.utilities.exceptions.NotImplementedException; diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/RayleighDistribution.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/RayleighDistribution.java index 68870f1a..9f3b718f 100644 --- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/RayleighDistribution.java +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/RayleighDistribution.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -25,7 +25,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution; import java.util.Random; -import de.lmu.ifi.dbs.elki.utilities.RandomFactory; +import de.lmu.ifi.dbs.elki.math.random.RandomFactory; import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization; import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.DoubleParameter; diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/SkewGeneralizedNormalDistribution.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/SkewGeneralizedNormalDistribution.java index 76931029..ed3eda95 100644 --- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/SkewGeneralizedNormalDistribution.java +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/SkewGeneralizedNormalDistribution.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -26,7 +26,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution; import java.util.Random; import de.lmu.ifi.dbs.elki.math.MathUtil; -import de.lmu.ifi.dbs.elki.utilities.RandomFactory; +import de.lmu.ifi.dbs.elki.math.random.RandomFactory; import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID; import de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints.CommonConstraints; import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization; diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/StudentsTDistribution.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/StudentsTDistribution.java index ef9f06d4..56cf855f 100644 --- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/StudentsTDistribution.java +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/StudentsTDistribution.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution; This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2012
+ Copyright (C) 2014
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
@@ -25,7 +25,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution; import java.util.Random;
-import de.lmu.ifi.dbs.elki.utilities.RandomFactory;
+import de.lmu.ifi.dbs.elki.math.random.RandomFactory;
import de.lmu.ifi.dbs.elki.utilities.exceptions.ExceptionMessages;
import de.lmu.ifi.dbs.elki.utilities.exceptions.NotImplementedException;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID;
diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/UniformDistribution.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/UniformDistribution.java index db2e2fb2..5dc33e5a 100644 --- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/UniformDistribution.java +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/UniformDistribution.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -25,7 +25,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution; import java.util.Random; -import de.lmu.ifi.dbs.elki.utilities.RandomFactory; +import de.lmu.ifi.dbs.elki.math.random.RandomFactory; import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID; import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization; import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.DoubleParameter; diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/WaldDistribution.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/WaldDistribution.java index 123ece95..332c5ed0 100644 --- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/WaldDistribution.java +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/WaldDistribution.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -26,8 +26,8 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution; import java.util.Random; import de.lmu.ifi.dbs.elki.math.MathUtil; +import de.lmu.ifi.dbs.elki.math.random.RandomFactory; import de.lmu.ifi.dbs.elki.utilities.Alias; -import de.lmu.ifi.dbs.elki.utilities.RandomFactory; import de.lmu.ifi.dbs.elki.utilities.exceptions.ExceptionMessages; import de.lmu.ifi.dbs.elki.utilities.exceptions.NotImplementedException; import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization; diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/WeibullDistribution.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/WeibullDistribution.java index 9b7af6d8..4f261840 100644 --- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/WeibullDistribution.java +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/WeibullDistribution.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -25,7 +25,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution; import java.util.Random; -import de.lmu.ifi.dbs.elki.utilities.RandomFactory; +import de.lmu.ifi.dbs.elki.math.random.RandomFactory; import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization; import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.DoubleParameter; diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/AbstractExpMADEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/AbstractExpMADEstimator.java index 6f9dc541..68ea51e6 100644 --- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/AbstractExpMADEstimator.java +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/AbstractExpMADEstimator.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/AbstractLMMEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/AbstractLMMEstimator.java index 3d77a1e6..969f1c2e 100644 --- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/AbstractLMMEstimator.java +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/AbstractLMMEstimator.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/AbstractLogMADEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/AbstractLogMADEstimator.java index b4e4e095..d1b96526 100644 --- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/AbstractLogMADEstimator.java +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/AbstractLogMADEstimator.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/AbstractLogMOMEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/AbstractLogMOMEstimator.java index 8ae86d4a..f19f0f4f 100644 --- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/AbstractLogMOMEstimator.java +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/AbstractLogMOMEstimator.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/AbstractLogMeanVarianceEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/AbstractLogMeanVarianceEstimator.java index a21186db..b149fedc 100644 --- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/AbstractLogMeanVarianceEstimator.java +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/AbstractLogMeanVarianceEstimator.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/AbstractMADEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/AbstractMADEstimator.java index 54009592..a451d088 100644 --- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/AbstractMADEstimator.java +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/AbstractMADEstimator.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/AbstractMOMEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/AbstractMOMEstimator.java index 30bd0802..cc3c7460 100644 --- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/AbstractMOMEstimator.java +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/AbstractMOMEstimator.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/AbstractMeanVarianceEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/AbstractMeanVarianceEstimator.java index 73a2e6d2..ccf522a0 100644 --- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/AbstractMeanVarianceEstimator.java +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/AbstractMeanVarianceEstimator.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/CauchyMADEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/CauchyMADEstimator.java index e1cfb20c..77a21b11 100644 --- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/CauchyMADEstimator.java +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/CauchyMADEstimator.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/DistributionEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/DistributionEstimator.java index 953fcff8..74ce583b 100644 --- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/DistributionEstimator.java +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/DistributionEstimator.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/EMGOlivierNorbergEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/EMGOlivierNorbergEstimator.java index 65c89c83..0319504a 100644 --- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/EMGOlivierNorbergEstimator.java +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/EMGOlivierNorbergEstimator.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/ExpMADDistributionEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/ExpMADDistributionEstimator.java index 70a16f3e..d185c36e 100644 --- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/ExpMADDistributionEstimator.java +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/ExpMADDistributionEstimator.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/ExponentialLMMEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/ExponentialLMMEstimator.java index 66176545..b9367d11 100644 --- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/ExponentialLMMEstimator.java +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/ExponentialLMMEstimator.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/ExponentialMADEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/ExponentialMADEstimator.java index 208fc72b..fa654738 100644 --- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/ExponentialMADEstimator.java +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/ExponentialMADEstimator.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/ExponentialMOMEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/ExponentialMOMEstimator.java index 4c3f93aa..cd05baad 100644 --- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/ExponentialMOMEstimator.java +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/ExponentialMOMEstimator.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/ExponentialMedianEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/ExponentialMedianEstimator.java index 19ce63c7..6480f6bb 100644 --- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/ExponentialMedianEstimator.java +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/ExponentialMedianEstimator.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/GammaChoiWetteEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/GammaChoiWetteEstimator.java index 9e47e81d..db4a6fb9 100644 --- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/GammaChoiWetteEstimator.java +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/GammaChoiWetteEstimator.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/GammaLMMEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/GammaLMMEstimator.java index edfc3f51..1f30b58b 100644 --- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/GammaLMMEstimator.java +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/GammaLMMEstimator.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/GammaMADEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/GammaMADEstimator.java index 54b0d38b..0007c225 100644 --- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/GammaMADEstimator.java +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/GammaMADEstimator.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/GammaMOMEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/GammaMOMEstimator.java index 0ff0cf47..5f381447 100644 --- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/GammaMOMEstimator.java +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/GammaMOMEstimator.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/GeneralizedExtremeValueLMMEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/GeneralizedExtremeValueLMMEstimator.java index cdadf47d..a2802c24 100644 --- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/GeneralizedExtremeValueLMMEstimator.java +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/GeneralizedExtremeValueLMMEstimator.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -103,7 +103,7 @@ public class GeneralizedExtremeValueLMMEstimator extends AbstractLMMEstimator<Ge // g: Almost zero? if (Math.abs(g) < 1e-50) { double k = 0; - double sigma = xmom[1] / MathUtil.LOG2; + double sigma = xmom[1] * MathUtil.ONE_BY_LOG2; double mu = xmom[0] - Math.E * sigma; return new GeneralizedExtremeValueDistribution(mu, sigma, k); } @@ -113,7 +113,7 @@ public class GeneralizedExtremeValueLMMEstimator extends AbstractLMMEstimator<Ge if (t3 < -.8) { // Newton-Raphson iteration for t3 < -.8 if (t3 <= -.97) { - g = 1. - Math.log(1. + t3) / MathUtil.LOG2; + g = 1. - Math.log1p(t3) * MathUtil.ONE_BY_LOG2; } double t0 = .5 * (t3 + 3.); for (int it = 1;; it++) { diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/GeneralizedLogisticAlternateLMMEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/GeneralizedLogisticAlternateLMMEstimator.java index dfcbcd52..3807c700 100644 --- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/GeneralizedLogisticAlternateLMMEstimator.java +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/GeneralizedLogisticAlternateLMMEstimator.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/GumbelLMMEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/GumbelLMMEstimator.java index c0f64006..539d9a88 100644 --- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/GumbelLMMEstimator.java +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/GumbelLMMEstimator.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -65,7 +65,7 @@ public class GumbelLMMEstimator extends AbstractLMMEstimator<GumbelDistribution> @Override public GumbelDistribution estimateFromLMoments(double[] xmom) { - double scale = xmom[1] / MathUtil.LOG2; + double scale = xmom[1] * MathUtil.ONE_BY_LOG2; return new GumbelDistribution(xmom[0] - Math.E * scale, scale); } diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/GumbelMADEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/GumbelMADEstimator.java index ebf6354a..2f74b36a 100644 --- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/GumbelMADEstimator.java +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/GumbelMADEstimator.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LMMDistributionEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LMMDistributionEstimator.java index f3d8d1b2..56339504 100644 --- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LMMDistributionEstimator.java +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LMMDistributionEstimator.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LaplaceLMMEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LaplaceLMMEstimator.java index 4026fdc5..7ac2ae25 100644 --- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LaplaceLMMEstimator.java +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LaplaceLMMEstimator.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LaplaceMADEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LaplaceMADEstimator.java index 6fe6da0f..10e2f9de 100644 --- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LaplaceMADEstimator.java +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LaplaceMADEstimator.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LaplaceMLEEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LaplaceMLEEstimator.java index 8d2c5707..acd755a6 100644 --- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LaplaceMLEEstimator.java +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LaplaceMLEEstimator.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -44,7 +44,9 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer; * * @apiviz.has LaplaceDistribution */ -@Reference(title = "The Double Exponential Distribution: Using Calculus to Find a Maximum Likelihood Estimator", authors = "R. M. Norton", booktitle = "The American Statistician 38 (2)", url = "http://dx.doi.org/10.2307%2F2683252") +@Reference(title = "The Double Exponential Distribution: Using Calculus to Find a Maximum Likelihood Estimator", // +authors = "R. M. Norton", booktitle = "The American Statistician 38 (2)", // +url = "http://dx.doi.org/10.2307/2683252") public class LaplaceMLEEstimator implements DistributionEstimator<LaplaceDistribution> { /** * Static instance. diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LogGammaAlternateExpMADEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LogGammaAlternateExpMADEstimator.java index 7ea0a6be..a4a3aa87 100644 --- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LogGammaAlternateExpMADEstimator.java +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LogGammaAlternateExpMADEstimator.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LogGammaChoiWetteEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LogGammaChoiWetteEstimator.java index ba3a899d..996132dc 100644 --- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LogGammaChoiWetteEstimator.java +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LogGammaChoiWetteEstimator.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LogGammaLogMADEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LogGammaLogMADEstimator.java index ed34870c..44d8abf6 100644 --- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LogGammaLogMADEstimator.java +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LogGammaLogMADEstimator.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LogGammaLogMOMEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LogGammaLogMOMEstimator.java index ddc6cbb9..e5552714 100644 --- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LogGammaLogMOMEstimator.java +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LogGammaLogMOMEstimator.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LogLogisticMADEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LogLogisticMADEstimator.java index 61b111c9..a9ea3efd 100644 --- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LogLogisticMADEstimator.java +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LogLogisticMADEstimator.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LogMADDistributionEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LogMADDistributionEstimator.java index 9c281952..8b29ad46 100644 --- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LogMADDistributionEstimator.java +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LogMADDistributionEstimator.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LogMOMDistributionEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LogMOMDistributionEstimator.java index 5a589faa..bc482378 100644 --- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LogMOMDistributionEstimator.java +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LogMOMDistributionEstimator.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LogNormalBilkovaLMMEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LogNormalBilkovaLMMEstimator.java index e8fab89f..8ec1560b 100644 --- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LogNormalBilkovaLMMEstimator.java +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LogNormalBilkovaLMMEstimator.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LogNormalLMMEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LogNormalLMMEstimator.java index 48865d3f..40afd20c 100644 --- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LogNormalLMMEstimator.java +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LogNormalLMMEstimator.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LogNormalLevenbergMarquardtKDEEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LogNormalLevenbergMarquardtKDEEstimator.java index b4b8ff0d..22afe9e6 100644 --- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LogNormalLevenbergMarquardtKDEEstimator.java +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LogNormalLevenbergMarquardtKDEEstimator.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LogNormalLogMADEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LogNormalLogMADEstimator.java index 6ad1dc33..ef197776 100644 --- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LogNormalLogMADEstimator.java +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LogNormalLogMADEstimator.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LogNormalLogMOMEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LogNormalLogMOMEstimator.java index 5b753c54..a44441fa 100644 --- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LogNormalLogMOMEstimator.java +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LogNormalLogMOMEstimator.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LogisticLMMEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LogisticLMMEstimator.java index 973a91de..543e7043 100644 --- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LogisticLMMEstimator.java +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LogisticLMMEstimator.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LogisticMADEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LogisticMADEstimator.java index 45181486..fff6830e 100644 --- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LogisticMADEstimator.java +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LogisticMADEstimator.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/MADDistributionEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/MADDistributionEstimator.java index 6bf2b3ae..3ea05e53 100644 --- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/MADDistributionEstimator.java +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/MADDistributionEstimator.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/MOMDistributionEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/MOMDistributionEstimator.java index 383f68cc..8257994c 100644 --- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/MOMDistributionEstimator.java +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/MOMDistributionEstimator.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/MeanVarianceDistributionEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/MeanVarianceDistributionEstimator.java index 4d84465f..6605acdb 100644 --- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/MeanVarianceDistributionEstimator.java +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/MeanVarianceDistributionEstimator.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/NormalLMMEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/NormalLMMEstimator.java index 67880950..df0bcb74 100644 --- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/NormalLMMEstimator.java +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/NormalLMMEstimator.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/NormalLevenbergMarquardtKDEEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/NormalLevenbergMarquardtKDEEstimator.java index bbbcda76..75ffccae 100644 --- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/NormalLevenbergMarquardtKDEEstimator.java +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/NormalLevenbergMarquardtKDEEstimator.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/NormalMADEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/NormalMADEstimator.java index 2221ad4b..e716432f 100644 --- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/NormalMADEstimator.java +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/NormalMADEstimator.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/NormalMOMEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/NormalMOMEstimator.java index dae05eb0..6cc48f4a 100644 --- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/NormalMOMEstimator.java +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/NormalMOMEstimator.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/RayleighLMMEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/RayleighLMMEstimator.java index a827e1e8..42372102 100644 --- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/RayleighLMMEstimator.java +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/RayleighLMMEstimator.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/RayleighMADEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/RayleighMADEstimator.java index 7382ada2..3e1d6e47 100644 --- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/RayleighMADEstimator.java +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/RayleighMADEstimator.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/RayleighMLEEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/RayleighMLEEstimator.java index aa5dc300..f4e1ba82 100644 --- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/RayleighMLEEstimator.java +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/RayleighMLEEstimator.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/SkewGNormalLMMEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/SkewGNormalLMMEstimator.java index df05eef9..a66ac5ee 100644 --- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/SkewGNormalLMMEstimator.java +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/SkewGNormalLMMEstimator.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/UniformEnhancedMinMaxEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/UniformEnhancedMinMaxEstimator.java index 834b0d94..c4401c87 100644 --- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/UniformEnhancedMinMaxEstimator.java +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/UniformEnhancedMinMaxEstimator.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/UniformLMMEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/UniformLMMEstimator.java index 5b3e868f..7ad57dbf 100644 --- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/UniformLMMEstimator.java +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/UniformLMMEstimator.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/UniformMADEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/UniformMADEstimator.java index 47dad134..ec52ed2a 100644 --- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/UniformMADEstimator.java +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/UniformMADEstimator.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/UniformMinMaxEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/UniformMinMaxEstimator.java index 11bb8231..a1409839 100644 --- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/UniformMinMaxEstimator.java +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/UniformMinMaxEstimator.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/WaldMLEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/WaldMLEstimator.java index 16a33f89..b2d4836c 100644 --- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/WaldMLEstimator.java +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/WaldMLEstimator.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/WaldMOMEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/WaldMOMEstimator.java index 82b70936..c8476794 100644 --- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/WaldMOMEstimator.java +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/WaldMOMEstimator.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/WeibullLMMEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/WeibullLMMEstimator.java index 9d7d8e8e..6d68e643 100644 --- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/WeibullLMMEstimator.java +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/WeibullLMMEstimator.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/WeibullLogMADEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/WeibullLogMADEstimator.java index aacceae7..469fb93f 100644 --- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/WeibullLogMADEstimator.java +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/WeibullLogMADEstimator.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/WeibullLogMOMEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/WeibullLogMOMEstimator.java index 9182a7ce..f189fc45 100644 --- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/WeibullLogMOMEstimator.java +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/WeibullLogMOMEstimator.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/meta/BestFitEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/meta/BestFitEstimator.java index 8d57e0b7..54fdf035 100644 --- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/meta/BestFitEstimator.java +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/meta/BestFitEstimator.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator.meta; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -199,7 +199,7 @@ public class BestFitEstimator implements DistributionEstimator<Distribution> { } if (mom.getMax() <= mom.getMin()) { LOG.warning("Constant distribution detected. Cannot fit."); - return new UniformDistribution(mom.getMin() - .1, mom.getMax() + .1); + return new UniformDistribution(mom.getMin() - 1., mom.getMax() + 1.); } // Sort: for L-Moments, but getting the median is now also cheap. Arrays.sort(x); @@ -253,9 +253,7 @@ public class BestFitEstimator implements DistributionEstimator<Distribution> { LOG.debugFine("Fitting distribution " + est.getClass().getSimpleName() + " failed: " + e.getMessage()); } } - if (prog != null) { - prog.incrementProcessed(LOG); - } + LOG.incrementProcessed(prog); } for (MADDistributionEstimator<?> est : madests) { try { @@ -274,9 +272,7 @@ public class BestFitEstimator implements DistributionEstimator<Distribution> { LOG.debugFine("Fitting distribution " + est.getClass().getSimpleName() + " failed: " + e.getMessage()); } } - if (prog != null) { - prog.incrementProcessed(LOG); - } + LOG.incrementProcessed(prog); } for (LMMDistributionEstimator<?> est : lmmests) { if (lmm != null) { @@ -297,9 +293,7 @@ public class BestFitEstimator implements DistributionEstimator<Distribution> { } } } - if (prog != null) { - prog.incrementProcessed(LOG); - } + LOG.incrementProcessed(prog); } for (LogMOMDistributionEstimator<?> est : logmomests) { try { @@ -318,9 +312,7 @@ public class BestFitEstimator implements DistributionEstimator<Distribution> { LOG.debugFine("Fitting distribution " + est.getClass().getSimpleName() + " failed: " + e.getMessage()); } } - if (prog != null) { - prog.incrementProcessed(LOG); - } + LOG.incrementProcessed(prog); } for (LogMADDistributionEstimator<?> est : logmadests) { try { @@ -339,9 +331,7 @@ public class BestFitEstimator implements DistributionEstimator<Distribution> { LOG.debugFine("Fitting distribution " + est.getClass().getSimpleName() + " failed: " + e.getMessage()); } } - if (prog != null) { - prog.incrementProcessed(LOG); - } + LOG.incrementProcessed(prog); } { // Uniform estimators. final UniformMinMaxEstimator est = UniformMinMaxEstimator.STATIC; @@ -361,9 +351,7 @@ public class BestFitEstimator implements DistributionEstimator<Distribution> { LOG.debugFine("Fitting distribution " + est.getClass().getSimpleName() + " failed: " + e.getMessage()); } } - if (prog != null) { - prog.incrementProcessed(LOG); - } + LOG.incrementProcessed(prog); } { // Uniform estimators. final UniformEnhancedMinMaxEstimator est = UniformEnhancedMinMaxEstimator.STATIC; @@ -383,13 +371,9 @@ public class BestFitEstimator implements DistributionEstimator<Distribution> { LOG.debugFine("Fitting distribution " + est.getClass().getSimpleName() + " failed: " + e.getMessage()); } } - if (prog != null) { - prog.incrementProcessed(LOG); - } - } - if (prog != null) { - prog.ensureCompleted(LOG); + LOG.incrementProcessed(prog); } + LOG.ensureCompleted(prog); if (LOG.isVeryVerbose()) { LOG.veryverbose("Best distribution fit: " + bestscore + " " + best.toString() + " via " + bestest); diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/meta/TrimmedEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/meta/TrimmedEstimator.java index a78d9760..d2d81a41 100644 --- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/meta/TrimmedEstimator.java +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/meta/TrimmedEstimator.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator.meta; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/meta/WinsorisingEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/meta/WinsorisingEstimator.java index 47fe427e..7726adaa 100644 --- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/meta/WinsorisingEstimator.java +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/meta/WinsorisingEstimator.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator.meta; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/meta/package-info.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/meta/package-info.java index c06be5d7..fc1812a1 100644 --- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/meta/package-info.java +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/meta/package-info.java @@ -8,7 +8,7 @@ This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/package-info.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/package-info.java index 9a9f0993..6fa3a6ed 100644 --- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/package-info.java +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/package-info.java @@ -11,7 +11,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/package-info.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/package-info.java index 49357049..707e1b7d 100644 --- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/package-info.java +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/package-info.java @@ -5,7 +5,7 @@ This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/kernelfunctions/BiweightKernelDensityFunction.java b/src/de/lmu/ifi/dbs/elki/math/statistics/kernelfunctions/BiweightKernelDensityFunction.java index 4b6ec7b7..7a508dd1 100644 --- a/src/de/lmu/ifi/dbs/elki/math/statistics/kernelfunctions/BiweightKernelDensityFunction.java +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/kernelfunctions/BiweightKernelDensityFunction.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.kernelfunctions; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/kernelfunctions/CosineKernelDensityFunction.java b/src/de/lmu/ifi/dbs/elki/math/statistics/kernelfunctions/CosineKernelDensityFunction.java index 230cb404..e6935da5 100644 --- a/src/de/lmu/ifi/dbs/elki/math/statistics/kernelfunctions/CosineKernelDensityFunction.java +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/kernelfunctions/CosineKernelDensityFunction.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.kernelfunctions; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/kernelfunctions/EpanechnikovKernelDensityFunction.java b/src/de/lmu/ifi/dbs/elki/math/statistics/kernelfunctions/EpanechnikovKernelDensityFunction.java index bf91e227..ab8c885c 100644 --- a/src/de/lmu/ifi/dbs/elki/math/statistics/kernelfunctions/EpanechnikovKernelDensityFunction.java +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/kernelfunctions/EpanechnikovKernelDensityFunction.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.kernelfunctions; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/kernelfunctions/GaussianKernelDensityFunction.java b/src/de/lmu/ifi/dbs/elki/math/statistics/kernelfunctions/GaussianKernelDensityFunction.java index 2e666871..4c4fca33 100644 --- a/src/de/lmu/ifi/dbs/elki/math/statistics/kernelfunctions/GaussianKernelDensityFunction.java +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/kernelfunctions/GaussianKernelDensityFunction.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.kernelfunctions; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/kernelfunctions/KernelDensityFunction.java b/src/de/lmu/ifi/dbs/elki/math/statistics/kernelfunctions/KernelDensityFunction.java index ce6d5a0d..ffd0a39e 100644 --- a/src/de/lmu/ifi/dbs/elki/math/statistics/kernelfunctions/KernelDensityFunction.java +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/kernelfunctions/KernelDensityFunction.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.kernelfunctions; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/kernelfunctions/TriangularKernelDensityFunction.java b/src/de/lmu/ifi/dbs/elki/math/statistics/kernelfunctions/TriangularKernelDensityFunction.java index c6acf031..fa8237df 100644 --- a/src/de/lmu/ifi/dbs/elki/math/statistics/kernelfunctions/TriangularKernelDensityFunction.java +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/kernelfunctions/TriangularKernelDensityFunction.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.kernelfunctions; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/kernelfunctions/TricubeKernelDensityFunction.java b/src/de/lmu/ifi/dbs/elki/math/statistics/kernelfunctions/TricubeKernelDensityFunction.java index 933207ed..dc8c76fc 100644 --- a/src/de/lmu/ifi/dbs/elki/math/statistics/kernelfunctions/TricubeKernelDensityFunction.java +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/kernelfunctions/TricubeKernelDensityFunction.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.kernelfunctions; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/kernelfunctions/TriweightKernelDensityFunction.java b/src/de/lmu/ifi/dbs/elki/math/statistics/kernelfunctions/TriweightKernelDensityFunction.java index 993ab8bf..e2b7b4c5 100644 --- a/src/de/lmu/ifi/dbs/elki/math/statistics/kernelfunctions/TriweightKernelDensityFunction.java +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/kernelfunctions/TriweightKernelDensityFunction.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.kernelfunctions; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/kernelfunctions/UniformKernelDensityFunction.java b/src/de/lmu/ifi/dbs/elki/math/statistics/kernelfunctions/UniformKernelDensityFunction.java index 2a820355..6ff8c91c 100644 --- a/src/de/lmu/ifi/dbs/elki/math/statistics/kernelfunctions/UniformKernelDensityFunction.java +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/kernelfunctions/UniformKernelDensityFunction.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.kernelfunctions; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/kernelfunctions/package-info.java b/src/de/lmu/ifi/dbs/elki/math/statistics/kernelfunctions/package-info.java index 219509a5..9ebe8d46 100644 --- a/src/de/lmu/ifi/dbs/elki/math/statistics/kernelfunctions/package-info.java +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/kernelfunctions/package-info.java @@ -6,7 +6,7 @@ This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/package-info.java b/src/de/lmu/ifi/dbs/elki/math/statistics/package-info.java index cc39a615..34d63a91 100644 --- a/src/de/lmu/ifi/dbs/elki/math/statistics/package-info.java +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/package-info.java @@ -5,7 +5,7 @@ This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures -Copyright (C) 2013 +Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/tests/GoodnessOfFitTest.java b/src/de/lmu/ifi/dbs/elki/math/statistics/tests/GoodnessOfFitTest.java index 363dbfea..668e74ca 100644 --- a/src/de/lmu/ifi/dbs/elki/math/statistics/tests/GoodnessOfFitTest.java +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/tests/GoodnessOfFitTest.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.tests; This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2012
+ Copyright (C) 2014
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
@@ -23,18 +23,16 @@ package de.lmu.ifi.dbs.elki.math.statistics.tests; along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.Parameterizable;
-
/**
* Interface for the statistical test used by HiCS.
*
- * Provides a single method that calculates the deviation between two data
+ * Constists of a single method that calculates the deviation between two data
* samples, given as arrays of double values
*
* @author Jan Brusis
* @author Erich Schubert
*/
-public interface GoodnessOfFitTest extends Parameterizable {
+public interface GoodnessOfFitTest {
/**
* Measure the deviation of a full sample from a conditional sample.
*
diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/tests/KolmogorovSmirnovTest.java b/src/de/lmu/ifi/dbs/elki/math/statistics/tests/KolmogorovSmirnovTest.java index a134ab09..db9c985c 100644 --- a/src/de/lmu/ifi/dbs/elki/math/statistics/tests/KolmogorovSmirnovTest.java +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/tests/KolmogorovSmirnovTest.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.tests; This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2012
+ Copyright (C) 2014
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/tests/WelchTTest.java b/src/de/lmu/ifi/dbs/elki/math/statistics/tests/WelchTTest.java index 554a22db..9ae416d1 100644 --- a/src/de/lmu/ifi/dbs/elki/math/statistics/tests/WelchTTest.java +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/tests/WelchTTest.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.tests; This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2012
+ Copyright (C) 2014
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/tests/package-info.java b/src/de/lmu/ifi/dbs/elki/math/statistics/tests/package-info.java index 6698f462..a89e1031 100644 --- a/src/de/lmu/ifi/dbs/elki/math/statistics/tests/package-info.java +++ b/src/de/lmu/ifi/dbs/elki/math/statistics/tests/package-info.java @@ -5,7 +5,7 @@ This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures -Copyright (C) 2013 +Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team |