edu.indiana.d2i.htrc.vecproj.RandomProjection.java Source code

Java tutorial

Introduction

Here is the source code for edu.indiana.d2i.htrc.vecproj.RandomProjection.java

Source

/*
#
# Copyright 2012 The Trustees of Indiana University
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# -----------------------------------------------------------------
#
# Project: knn
# File:  RandomProjection.java
# Description:  
#
# -----------------------------------------------------------------
# 
 */

package edu.indiana.d2i.htrc.vecproj;

import org.apache.mahout.common.distance.DistanceMeasure;
import org.apache.mahout.common.distance.EuclideanDistanceMeasure;
import org.apache.mahout.math.DenseMatrix;
import org.apache.mahout.math.DenseVector;
import org.apache.mahout.math.Matrix;
import org.apache.mahout.math.Vector;
import org.apache.mahout.math.function.DoubleFunction;
import org.apache.mahout.math.function.Functions;

public class RandomProjection implements VectorProjectionIF {

    private int originalDim, reducedDim;
    private Matrix basis = null;
    private final DoubleFunction random; // (0.0, 1.0)

    class DoubleFunctionWrapper implements DoubleFunction {
        @Override
        public double apply(double arg1) {
            return -1 + random.apply(arg1) * 2; // (-1.0, 1.0)
        }
    }

    class RandomProjectionMeasurement extends EuclideanDistanceMeasure {
        private double scale;

        public RandomProjectionMeasurement(double scale) {
            this.scale = scale;
        }

        @Override
        public double distance(Vector v1, Vector v2) {
            return Math.sqrt(super.distance(v1, v2)) * scale;
        }

        @Override
        public double distance(double centroidLengthSquare, Vector centroid, Vector v) {
            return Math.sqrt(super.distance(centroidLengthSquare, centroid, v)) * scale;
        }
    }

    public RandomProjection(int originalDim /* d */, int reducedDim /* k */) {
        this.originalDim = originalDim;
        this.reducedDim = reducedDim;

        // generate random matrix, use a O(kd) algorithm [Achlioptas, 2000]
        random = Functions.random();
        DoubleFunctionWrapper randomWrapper = new DoubleFunctionWrapper();
        basis = new DenseMatrix(reducedDim, originalDim);
        for (int i = 0; i < reducedDim; i++) {
            DenseVector projection = new DenseVector(originalDim);
            projection.assign(randomWrapper);
            basis.assignRow(i, projection);
        }
    }

    @Override
    public DistanceMeasure getDistanceMeasurement() {
        return new RandomProjectionMeasurement(Math.pow((double) originalDim / reducedDim, 0.5));
    }

    @Override
    public Vector project(Vector v) {
        return basis.times(v);
    }
}