package cc.mallet.types; public class LogNumber { public double logVal; public boolean sign; public LogNumber(double logVal, boolean sign) { this.logVal = logVal; this.sign = sign; } public void timesEquals(LogNumber other) { this.logVal += other.logVal; this.sign = (this.sign && other.sign) || (!this.sign && !other.sign); } public double exp() { double exp = Math.exp(logVal); if (!sign) { exp *= -1; } return exp; } public void set(double logVal, boolean sign) { this.logVal = logVal; this.sign = sign; } public void plusEquals(LogNumber other) { if (this.logVal == Double.NEGATIVE_INFINITY) { // this.logVal may become negative infinity // without having the sign flipped to true. // if so, flip the sign now. if (!this.sign) { this.sign = true; } if (other.logVal == Double.NEGATIVE_INFINITY) { // this.logVal is already negative infinity, // so we do nothing return; } this.logVal = other.logVal; this.sign = other.sign; } else if (other.logVal == Double.NEGATIVE_INFINITY) { // no change return; } else if (this.logVal > other.logVal) { if (this.sign && other.sign) { this.logVal = this.logVal + Math.log (1 + Math.exp(other.logVal-this.logVal)); // sign was already positive, no need to change //this.sign = true; } else if (this.sign && !other.sign) { this.logVal = this.logVal + Math.log (1 - Math.exp(other.logVal-this.logVal)); // sign was already positive, no need to change //this.sign = true; } else if (!this.sign && other.sign) { this.logVal = this.logVal + Math.log (1 - Math.exp(other.logVal-this.logVal)); // sign was already negative, no need to change //this.sign = false; } else if (!this.sign && !other.sign) { this.logVal = this.logVal + Math.log (1 + Math.exp(other.logVal-this.logVal)); // sign was already negative, no need to change //this.sign = false; } } else { if (this.sign && other.sign) { this.logVal = other.logVal + Math.log (1 + Math.exp(this.logVal - other.logVal)); // alpha sign was already positive, no need to change //signs[si] = true; } else if (this.sign && !other.sign) { this.logVal = other.logVal + Math.log (1 - Math.exp(this.logVal - other.logVal)); // alpha was already negative, no need to change this.sign = false; } else if (!this.sign && other.sign) { this.logVal = other.logVal + Math.log (1 - Math.exp(this.logVal - other.logVal)); // alpha sign was already positive, no need to change this.sign = true; } else if (!this.sign && !other.sign) { this.logVal = other.logVal + Math.log (1 + Math.exp(this.logVal - other.logVal)); // alpha was already negative, no need to change //this.sign = false; } } } @Override public String toString() { return "log value = " + this.logVal + ", positive = " + this.sign; } }