package org.wikibrain.matrix; import java.io.Serializable; /** * Configuration for the values in a sparse matrix row. * This class handles packing and unpacking of values. * Right now it uses a simple scheme, and packs the float * into a short. This will work well if the floats are * uniformly distributed across the range in [minScore, maxScore]. */ public class ValueConf implements Serializable { public static final Float MIN_SCORE = -1.1f; public static final Float MAX_SCORE = 1.1f; public static final int PACKED_RANGE = (Short.MAX_VALUE - Short.MIN_VALUE); public final float minScore; public final float maxScore; public final float range; public final float c1; public final float c2; public ValueConf() { this(MIN_SCORE, MAX_SCORE); } /** * Unpacking constants c1 and c2 are calculated as follows: * * float f = (1.0f * (s - Short.MIN_VALUE) / PACKED_RANGE) * range + minScore; * float f = s * range / PACKED_RANGE - Short.MIN_VALUE / PACKAGED_RANGE * range + minScore; * float f = s * c1 + c2; * * @param minScore * @param maxScore */ public ValueConf(float minScore, float maxScore) { this.minScore = minScore; this.maxScore = maxScore; this.range = maxScore - minScore; this.c1 = range / PACKED_RANGE; this.c2 = - Short.MIN_VALUE * range / PACKED_RANGE + minScore; } public final short pack(float s) { float normalized = (pinchScore(s) - minScore) / range; return (short)(normalized * PACKED_RANGE + Short.MIN_VALUE); } public final float unpack(short s) { float f = (1.0f * (s - Short.MIN_VALUE) / PACKED_RANGE) * range + minScore; assert(minScore <= f && f <= maxScore); return f; } public final float pinchScore(float s) { if (s > maxScore) return maxScore; else if (s < minScore) return minScore; else return s; } public boolean almostEquals(ValueConf vconf) { double delta = 0.001 * Math.min(range, vconf.range); // allowed error return ( (Math.abs(minScore - vconf.minScore) < delta) && (Math.abs(maxScore - vconf.maxScore) < delta) && (Math.abs(range - vconf.range) < delta) ); } }