Java tutorial
/* * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package models; import java.util.Arrays; import java.util.BitSet; import java.util.Map; import com.google.common.hash.Hashing; import com.google.common.hash.HashFunction; /** * Created with IntelliJ IDEA. * User: oyiptong * Date: 2012-09-07 * Time: 2:12 PM */ public class RandomProjection { final static int HASH_BYTES = 4; final static double MAX_HASH_VALUE = Math.pow(2, 8 * HASH_BYTES); public static double[] project(Map<Integer, Double> input, int dimensions) { double[] projection = new double[dimensions]; Arrays.fill(projection, 0.0); for (Map.Entry<Integer, Double> pair : input.entrySet()) { int key = pair.getKey().intValue(); double value = pair.getValue(); double[] randomRow = randomRow(key, dimensions, 0); // multiply by scalar for (int i = 0; i < randomRow.length; i++) { randomRow[i] = randomRow[i] * value; } // add to projection for (int i = 0; i < projection.length; i++) { projection[i] += randomRow[i]; } } return projection; } public static double[] project(double[] input, int dimensions) { double[] projection = new double[dimensions]; Arrays.fill(projection, 0.0); for (int index = 0; index < input.length; index++) { double value = input[index]; double[] randomRow = randomRow(index, dimensions, 0); // multiply by scalar for (int i = 0; i < randomRow.length; i++) { randomRow[i] = randomRow[i] * value; } // add to projection for (int i = 0; i < projection.length; i++) { projection[i] += randomRow[i]; } } return projection; } public static BitSet projectBinaryBytes(double[] input, int dimensions) { double[] projection = project(input, dimensions); BitSet bs = new BitSet(dimensions); for (int i = 0; i < projection.length; i++) { if (projection[i] > 0) { bs.set(i, true); } } return bs; } public static String projectString(double[] input, int dimensions) { double[] projection = project(input, dimensions); StringBuilder sb = new StringBuilder(); for (int i = 0; i < projection.length; i++) { if (projection[i] > 0) { sb.append("1"); } else { sb.append("0"); } } return sb.toString(); } public static double[] randomRow(int key, int dimensions, int randomSeed) { double[] values = new double[dimensions]; for (int i = 0; i < dimensions; i++) { String matrixEntryName = String.format("%d-%d-%d", key, i, randomSeed); double randomValue = deterministicRandom(matrixEntryName); double gaussianValue = gaussianFromProbability(randomValue); values[i] = gaussianValue; } return values; } public static double deterministicRandom(String value) { // obtain a hash function that will generate a 32-bit long hash code HashFunction hf = Hashing.goodFastHash(32); long i = Hashing.padToLong(hf.hashString(value)); return 1.0 * i / MAX_HASH_VALUE; } public static double gaussianFromProbability(double value) { double value2 = deterministicRandom(String.format("%1.10f-x2", value)); return gaussianFromTwoProbabilities(value, value2); } public static double gaussianFromTwoProbabilities(double value1, double value2) { double theta = value1 * 2 * Math.PI; double rsq = (-1.0 / 0.5) * Math.log(value2); double y = Math.sqrt(rsq) * Math.cos(theta); return y; } }