Search in sources :

Example 1 with SingularValueDecomposition

use of de.lmu.ifi.dbs.elki.math.linearalgebra.SingularValueDecomposition in project elki by elki-project.

the class ClassicMultidimensionalScalingTransformTest method parameters.

/**
 * Test with parameters.
 */
@Test
public void parameters() {
    int pdim = 2;
    String filename = UNITTEST + "transformation-test-1.csv";
    ClassicMultidimensionalScalingTransform<DoubleVector, DoubleVector> filter = // 
    new ELKIBuilder<ClassicMultidimensionalScalingTransform<DoubleVector, DoubleVector>>(ClassicMultidimensionalScalingTransform.class).with(ClassicMultidimensionalScalingTransform.Parameterizer.DIM_ID, // 
    pdim).with(ClassicMultidimensionalScalingTransform.Parameterizer.DISTANCE_ID, // 
    EuclideanDistanceFunction.class).build();
    MultipleObjectsBundle filteredBundle = readBundle(filename, filter);
    // Load the test data again without a filter.
    MultipleObjectsBundle unfilteredBundle = readBundle(filename);
    int dimu = getFieldDimensionality(unfilteredBundle, 0, TypeUtil.NUMBER_VECTOR_FIELD);
    int dimf = getFieldDimensionality(filteredBundle, 0, TypeUtil.NUMBER_VECTOR_FIELD);
    assertEquals("Dimensionality not as requested", pdim, dimf);
    // Verify that the Euclidean distance between any two points is identical
    // before and after the MDS transform is performed - O(n^2)!
    // Calculate the covariance matricies of the filtered and unfiltered
    // bundles.
    CovarianceMatrix cmUnfil = new CovarianceMatrix(dimu);
    CovarianceMatrix cmFil = new CovarianceMatrix(dimf);
    for (int outer = 0; outer < filteredBundle.dataLength(); outer++) {
        DoubleVector dFil_1 = get(filteredBundle, outer, 0, DoubleVector.class);
        DoubleVector dUnfil_1 = get(unfilteredBundle, outer, 0, DoubleVector.class);
        cmUnfil.put(dUnfil_1);
        cmFil.put(dFil_1);
        for (int row = outer + 1; row < filteredBundle.dataLength(); row++) {
            DoubleVector dFil_2 = get(filteredBundle, row, 0, DoubleVector.class);
            DoubleVector dUnfil_2 = get(unfilteredBundle, row, 0, DoubleVector.class);
            final double distF = EuclideanDistanceFunction.STATIC.distance(dFil_1, dFil_2);
            final double distU = EuclideanDistanceFunction.STATIC.distance(dUnfil_1, dUnfil_2);
            assertEquals("Expected same distance", distU, distF, 1e-11);
        }
    }
    // Calculate the SVD of the covariance matrix of the unfiltered data.
    // Verify that this SVD represents the diagonals of the covariance matrix of
    // the filtered data.
    double[][] ncmUnfil = cmUnfil.destroyToPopulationMatrix();
    double[][] ncmFil = cmFil.destroyToPopulationMatrix();
    SingularValueDecomposition svd = new SingularValueDecomposition(ncmUnfil);
    double[] dia = svd.getSingularValues();
    for (int ii = 0; ii < dia.length; ii++) {
        assertEquals("Unexpected covariance", dia[ii], ncmFil[ii][ii], 1e-11);
    }
}
Also used : EuclideanDistanceFunction(de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.EuclideanDistanceFunction) MultipleObjectsBundle(de.lmu.ifi.dbs.elki.datasource.bundle.MultipleObjectsBundle) CovarianceMatrix(de.lmu.ifi.dbs.elki.math.linearalgebra.CovarianceMatrix) DoubleVector(de.lmu.ifi.dbs.elki.data.DoubleVector) SingularValueDecomposition(de.lmu.ifi.dbs.elki.math.linearalgebra.SingularValueDecomposition) AbstractDataSourceTest(de.lmu.ifi.dbs.elki.datasource.AbstractDataSourceTest) Test(org.junit.Test)

Example 2 with SingularValueDecomposition

use of de.lmu.ifi.dbs.elki.math.linearalgebra.SingularValueDecomposition in project elki by elki-project.

the class FastMultidimensionalScalingTransformTest method parameters.

/**
 * Test with parameters.
 */
@Test
public void parameters() {
    int pdim = 2;
    String filename = UNITTEST + "transformation-test-1.csv";
    FastMultidimensionalScalingTransform<DoubleVector, DoubleVector> filter = // 
    new ELKIBuilder<FastMultidimensionalScalingTransform<DoubleVector, DoubleVector>>(FastMultidimensionalScalingTransform.class).with(ClassicMultidimensionalScalingTransform.Parameterizer.DIM_ID, // 
    pdim).with(FastMultidimensionalScalingTransform.Parameterizer.RANDOM_ID, // 
    0L).with(ClassicMultidimensionalScalingTransform.Parameterizer.DISTANCE_ID, // 
    EuclideanDistanceFunction.class).build();
    MultipleObjectsBundle filteredBundle = readBundle(filename, filter);
    // Load the test data again without a filter.
    MultipleObjectsBundle unfilteredBundle = readBundle(filename);
    int dimu = getFieldDimensionality(unfilteredBundle, 0, TypeUtil.NUMBER_VECTOR_FIELD);
    int dimf = getFieldDimensionality(filteredBundle, 0, TypeUtil.NUMBER_VECTOR_FIELD);
    assertEquals("Dimensionality not as requested", pdim, dimf);
    // Verify that the Euclidean distance between any two points is identical
    // before and after the MDS transform is performed - O(n^2)!
    // Calculate the covariance matricies of the filtered and unfiltered
    // bundles.
    CovarianceMatrix cmUnfil = new CovarianceMatrix(dimu);
    CovarianceMatrix cmFil = new CovarianceMatrix(dimf);
    for (int outer = 0; outer < filteredBundle.dataLength(); outer++) {
        DoubleVector dFil_1 = get(filteredBundle, outer, 0, DoubleVector.class);
        DoubleVector dUnfil_1 = get(unfilteredBundle, outer, 0, DoubleVector.class);
        cmUnfil.put(dUnfil_1);
        cmFil.put(dFil_1);
        for (int row = outer + 1; row < filteredBundle.dataLength(); row++) {
            DoubleVector dFil_2 = get(filteredBundle, row, 0, DoubleVector.class);
            DoubleVector dUnfil_2 = get(unfilteredBundle, row, 0, DoubleVector.class);
            final double distF = EuclideanDistanceFunction.STATIC.distance(dFil_1, dFil_2);
            final double distU = EuclideanDistanceFunction.STATIC.distance(dUnfil_1, dUnfil_2);
            assertEquals("Expected same distance", distU, distF, 1e-10);
        }
    }
    // Calculate the SVD of the covariance matrix of the unfiltered data.
    // Verify that this SVD represents the diagonals of the covariance matrix of
    // the filtered data.
    double[][] ncmUnfil = cmUnfil.destroyToPopulationMatrix();
    double[][] ncmFil = cmFil.destroyToPopulationMatrix();
    SingularValueDecomposition svd = new SingularValueDecomposition(ncmUnfil);
    double[] dia = svd.getSingularValues();
    for (int ii = 0; ii < dia.length; ii++) {
        assertEquals("Unexpected covariance", dia[ii], ncmFil[ii][ii], 1e-8);
    }
}
Also used : EuclideanDistanceFunction(de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.EuclideanDistanceFunction) ELKIBuilder(de.lmu.ifi.dbs.elki.utilities.ELKIBuilder) MultipleObjectsBundle(de.lmu.ifi.dbs.elki.datasource.bundle.MultipleObjectsBundle) DoubleVector(de.lmu.ifi.dbs.elki.data.DoubleVector) SingularValueDecomposition(de.lmu.ifi.dbs.elki.math.linearalgebra.SingularValueDecomposition) CovarianceMatrix(de.lmu.ifi.dbs.elki.math.linearalgebra.CovarianceMatrix) AbstractDataSourceTest(de.lmu.ifi.dbs.elki.datasource.AbstractDataSourceTest) Test(org.junit.Test)

Example 3 with SingularValueDecomposition

use of de.lmu.ifi.dbs.elki.math.linearalgebra.SingularValueDecomposition in project elki by elki-project.

the class MultidimensionalScalingMSTLayout3DPC method layout.

@Override
public Layout layout(int dim, double[] mat) {
    // Find maximum of |cij|
    double max = 0;
    for (double v : mat) {
        v = (v > 0) ? v : -v;
        max = (v > max) ? v : max;
    }
    // Assume that "max - |cij|" is now a distance.
    // We use sqrt(v) instead of v*v, since this makes the method
    // less aggressive overall, and we are not using euclidean anyway.
    double[] means = new double[dim];
    double mean = 0.0;
    for (int y = 1, o = 0; y < dim; y++) {
        for (int x = 0; x < y; x++, o++) {
            double v = max - Math.abs(mat[o]);
            v = -.5 * FastMath.sqrt(v);
            means[x] += v;
            means[y] += v;
            mean += 2 * v;
        }
    }
    for (int i = 0; i < dim; i++) {
        means[i] /= dim;
    }
    mean /= (dim * dim);
    // Build double centered matrix:
    double[][] d = new double[dim][dim];
    for (int y = 1, o = 0; y < dim; y++) {
        d[y][y] = -2 * means[y] + mean;
        for (int x = 0; x < y; x++, o++) {
            double v = max - Math.abs(mat[o]);
            v = -.5 * FastMath.sqrt(v) - means[x] - means[y] + mean;
            d[x][y] = d[y][x] = v;
        }
    }
    SingularValueDecomposition svd = new SingularValueDecomposition(d);
    double[][] u = svd.getU();
    double[] lambda = svd.getSingularValues();
    lambda[0] = FastMath.sqrt(Math.abs(lambda[0]));
    lambda[1] = FastMath.sqrt(Math.abs(lambda[1]));
    Layout l = new Layout();
    buildSpanningTree(dim, mat, l);
    double maxabs = 0;
    for (int i = 0; i < dim; i++) {
        Node n = (Node) l.getNode(i);
        n.x = u[i][0] * lambda[0];
        n.y = u[i][1] * lambda[1];
        double v = n.x * n.x + n.y * n.y;
        if (v > maxabs) {
            maxabs = v;
        }
    }
    maxabs = 1. / FastMath.sqrt(maxabs);
    for (int i = 0; i < dim; i++) {
        Node n = (Node) l.getNode(i);
        n.x *= maxabs;
        n.y *= maxabs;
    }
    return l;
}
Also used : SingularValueDecomposition(de.lmu.ifi.dbs.elki.math.linearalgebra.SingularValueDecomposition)

Example 4 with SingularValueDecomposition

use of de.lmu.ifi.dbs.elki.math.linearalgebra.SingularValueDecomposition in project elki by elki-project.

the class ClassicMultidimensionalScalingTransform method filter.

@Override
public MultipleObjectsBundle filter(MultipleObjectsBundle objects) {
    final int size = objects.dataLength();
    if (size == 0) {
        return objects;
    }
    MultipleObjectsBundle bundle = new MultipleObjectsBundle();
    for (int r = 0; r < objects.metaLength(); r++) {
        @SuppressWarnings("unchecked") SimpleTypeInformation<Object> type = (SimpleTypeInformation<Object>) objects.meta(r);
        @SuppressWarnings("unchecked") final List<Object> column = (List<Object>) objects.getColumn(r);
        if (!dist.getInputTypeRestriction().isAssignableFromType(type)) {
            bundle.appendColumn(type, column);
            continue;
        }
        // Get the replacement type information
        @SuppressWarnings("unchecked") final List<I> castColumn = (List<I>) column;
        bundle.appendColumn(new VectorFieldTypeInformation<>(factory, tdim), castColumn);
        StepProgress prog = LOG.isVerbose() ? new StepProgress("Classic MDS", 2) : null;
        // Compute distance matrix.
        LOG.beginStep(prog, 1, "Computing distance matrix");
        double[][] mat = computeSquaredDistanceMatrix(castColumn, dist);
        doubleCenterSymmetric(mat);
        // Find eigenvectors.
        {
            LOG.beginStep(prog, 2, "Computing singular value decomposition");
            SingularValueDecomposition svd = new SingularValueDecomposition(mat);
            double[][] u = svd.getU();
            double[] lambda = svd.getSingularValues();
            // Undo squared, unless we were given a squared distance function:
            if (!dist.isSquared()) {
                for (int i = 0; i < tdim; i++) {
                    lambda[i] = FastMath.sqrt(Math.abs(lambda[i]));
                }
            }
            double[] buf = new double[tdim];
            for (int i = 0; i < size; i++) {
                double[] row = u[i];
                for (int x = 0; x < buf.length; x++) {
                    buf[x] = lambda[x] * row[x];
                }
                column.set(i, factory.newNumberVector(buf));
            }
        }
        LOG.setCompleted(prog);
    }
    return bundle;
}
Also used : MultipleObjectsBundle(de.lmu.ifi.dbs.elki.datasource.bundle.MultipleObjectsBundle) SimpleTypeInformation(de.lmu.ifi.dbs.elki.data.type.SimpleTypeInformation) StepProgress(de.lmu.ifi.dbs.elki.logging.progress.StepProgress) List(java.util.List) SingularValueDecomposition(de.lmu.ifi.dbs.elki.math.linearalgebra.SingularValueDecomposition)

Aggregations

SingularValueDecomposition (de.lmu.ifi.dbs.elki.math.linearalgebra.SingularValueDecomposition)4 MultipleObjectsBundle (de.lmu.ifi.dbs.elki.datasource.bundle.MultipleObjectsBundle)3 DoubleVector (de.lmu.ifi.dbs.elki.data.DoubleVector)2 AbstractDataSourceTest (de.lmu.ifi.dbs.elki.datasource.AbstractDataSourceTest)2 EuclideanDistanceFunction (de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.EuclideanDistanceFunction)2 CovarianceMatrix (de.lmu.ifi.dbs.elki.math.linearalgebra.CovarianceMatrix)2 Test (org.junit.Test)2 SimpleTypeInformation (de.lmu.ifi.dbs.elki.data.type.SimpleTypeInformation)1 StepProgress (de.lmu.ifi.dbs.elki.logging.progress.StepProgress)1 ELKIBuilder (de.lmu.ifi.dbs.elki.utilities.ELKIBuilder)1 List (java.util.List)1