diff options
Diffstat (limited to 'src/de/lmu/ifi/dbs/elki/math/linearalgebra')
68 files changed, 974 insertions, 874 deletions
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 |