package edu.vt.marian.common; import java.io.*; import java.net.*; import java.util.*; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.DataInputStream; import java.io.DataOutputStream; import edu.vt.marian.common.Sortable; /** * The weight of an object in some approximate context (e.g., match to * a query). * @author Jianxin Zhao * @author Robert France * @author Paul Mather * @version $Id: Weight.java,v 1.3 2000/09/21 18:40:07 france Exp $ */ public class Weight implements Sortable { /** the underlying value of this object. */ private int value = -1; // Always created INVALID. /** the bounds of reasonable weight values. */ private final static int upper_limit = 65536; // 2**16 private final static int lower_limit = 0; /** Public versions of the bounds for reasonable values. */ public final static Weight topWt = new Weight(upper_limit, null); public final static Weight bottomWt = new Weight(lower_limit, null); /** the methods' return values. */ public final static int EQUAL = Sortable.EQUAL; public final static int HIGHER = Sortable.GREATER; public final static int LOWER = Sortable.LESS; public final static int NOT_APPLY = 6; public final static int NULL_STREAM = 7; /** this is just used for debugging */ Debug debug; /** * Create an invalid Weight object. * @param debug used for debugging */ public Weight(Debug debug) { this.debug = debug; } /** * Create a Weight object based on a specified value. * @param i the underlying value for this Weight object * @param debug used for debugging */ public Weight(int i, Debug debug) { this.debug = debug; value = i; } /** * Create a Weight object based on a specified value. * @param f the value of this Weight object; * @param debug used for debugging */ public Weight(double f, Debug debug) { this.debug = debug; value = (int) (f * upper_limit); } /** * Create a Weight object based on another Weight object. * @param w the Weight object to copy. */ public Weight(Weight w) { this.debug = w.debug; this.value = w.value; } /** * Create a Weight object from an input stream. * @param br the stream to read out this object * @param debug used for debugging */ public Weight(BufferedReader br, Debug debug) { this.debug = debug; if (br == null) { debug.dumpTrace("Weight.[constructor 2]: stream is null"); } // br is not null, read out value try { value = Integer.parseInt(br.readLine()); } catch (Exception e) { debug.dumpTrace("Weight:[constructor 2]: error (" + e.getMessage() + ") while reading value from stream."); return; } } /** * Tell whether or not this Weight object is valid. * @return true if this weight has a valid value set; false otherwise. */ public boolean isValid() { return( (value <= upper_limit) && (value >= lower_limit) ); } /** * Return the result of the comparision between this Weight object * and the parameter Weight object. * @param w the Weight object used to compared with this object * @return EQUAL -- their values are equal; * HIGHER -- the value of this object is higher than the parameter object; * LOWER -- the value of this object is lower than the parameter object. */ public int compare(Weight w) { if (w == null) { debug.dumpTrace("Weight.compare(): parameter w is null"); return NOT_APPLY; } // w is not null if (value > w.getValue()) { return HIGHER; } if (value < w.getValue()) { return LOWER; } // they are equal return EQUAL; } /* * Sortable interface comparison method. * @param obj Object being compared to this weight * @return integer indicating how we compare to given value * @see edu.vt.marian.common.Sortable */ public int compare(Object obj) { if (obj instanceof Weight) return this.compare((Weight) obj); else return Sortable.INCOMPARABLE; } /** * Scale one Weight by another. * @param w the Weight object used to scale this object. *

NOTE: We are using the integer values lower_limit..upper_limit * to mimic the real number interval 0..1. As long as * lower_limit == 0) we need only adjust to keep values * proportionally under upper_limit, which we treat both * as the top value and as multiplicative identity. We * achieve this by multiplying the two "value" fields, * then shifting the result right by 16 bits (effectively * dividing by 2**16). */ public void scale(Weight w) { value = (value * w.value) >> 16; } /** * Scale one Weight by a real constant. * @param f the double precision value used to scale this object. */ public void scale(double f) { value = (int) (f * value); } /** * "Add" one Weight to another. * @param w the Weight object to be accumulated into this object. */ public void accum(Weight w) { value = value + w.value; } /** * "Add" a float between 0..1 to this object. * @param f the double precision value to be accumulated into * this object. */ public void accum(double f) { value = value + (int) (f * upper_limit); } /** * Return the value of this Weight object. * @return the value of this Weight object as a double. */ public double getValue() { return (double) value / (double) upper_limit; } public int getUnderlyingValue() { return value; } public void set(Weight w) { if (w == null) { debug.dumpTrace("Weight.set(): parameter w is null"); value = -1; } value = w.getUnderlyingValue(); } /** * Pack this into a byte array for compact storage. * @param bos a ByteArrayOutputStream into which to pack this. * @return OK -- all jake; NULL_STREAM -- could not write. */ public int writePacked(ByteArrayOutputStream bos) { DataOutputStream dos = new DataOutputStream(bos); try { dos.writeShort(value); } catch (Exception e) { debug.dumpTrace("Weight.writePacked(): cannot write: " + e.getMessage()); return ReturnCodes.NULL_STREAM; } return(ReturnCodes.OK); } /** * Read this out of compact storage in a byte array. * @param bis a ByteArrayInputStream from which to unpack this. * @return OK -- all jake; NULL_STREAM -- could not read. */ public int readPacked(ByteArrayInputStream bis) { DataInputStream dis = new DataInputStream(bis); try { value = dis.readUnsignedShort(); } catch (Exception e) { debug.dumpTrace("Weight.readPacked(): cannot read: " + e.getMessage()); return ReturnCodes.NULL_STREAM; } return(ReturnCodes.OK); } /** * Print the content of this object to a specified stream. * @param pw the stream to write this object * @return OK -- the object has been written to the stream correctly; * NULL_STREAM -- the parameter stream is null */ public int toStream(PrintWriter pw) { if (pw == null) { debug.dumpTrace("Weight.toStream(): stream is null"); return ReturnCodes.NULL_STREAM; } // pw is not null pw.println(value); pw.flush(); return ReturnCodes.OK; } }