package joshua.discriminative.semiring_parsing; /** This class implements an element in a ConvolutionSemiring * This class does not depend on the compact structure, e.g., hypergraph, lattice, or nbest * */ /**we should not normalize the probability at each intermediate node * because our model is a global model??? * */ /**@todo: right now, the atomic semiring must be log-sum semiring * */ public class ExpectationSemiring implements CompositeSemiring { private double logProb;//maybe un-normalized (this is fine for factor1, as we will divide do factor1/norm in normalizeFactors()) private SignedValue factor1;//p.v public ExpectationSemiring(){ factor1 = new SignedValue(); } public ExpectationSemiring(double logProb_, SignedValue factor1_){ logProb = logProb_; factor1 = factor1_; } public void setToZero(AtomicSemiring atomic){ this.logProb = atomic.ATOMIC_ZERO_IN_SEMIRING; this.factor1.setZero(); } public void setToOne(AtomicSemiring atomic){ this.logProb = atomic.ATOMIC_ONE_IN_SEMIRING; //this.factor1 = atomic.ATOMIC_ONE_IN_SEMIRING; /**Note that factor should always set as zero. * For example, when the factor is expected length, it should start from zero * */ this.factor1.setZero(); } public void add(CompositeSemiring b, AtomicSemiring atomic){ this.logProb = atomic.add_in_atomic_semiring(this.logProb, ((ExpectationSemiring)b).logProb); //this.factor1 = atomic.add_in_atomic_semiring(this.factor1, ((ConvolutionSemiring2)b).factor1); this.factor1 = SignedValue.add(this.factor1,((ExpectationSemiring)b).factor1); } public void multi(CompositeSemiring b, AtomicSemiring atomic){ ExpectationSemiring b2 = (ExpectationSemiring)b; /**this already assumes the prob is in log domain*/ //this.factor1 = Math.exp(oldLogProb)*b2.factor1 + Math.exp(b2.logProb)*oldFactor1;//real semiring this.factor1 = SignedValue.add( SignedValue.multi(this.logProb, b2.factor1), SignedValue.multi(b2.logProb, this.factor1) ); //first update factor, then logProb as factor update depends on old logProb this.logProb = atomic.multi_in_atomic_semiring(this.logProb, b2.logProb); } public void normalizeFactors(){ /**we should not normalize the probability at each intermediate node * because our model is a global model??? */ /**originallly, the factor value is \sum_x p(x).v(x), where p(x) is not normalized, meaning \sum_x p(x)!=1; *we need to normalize p(x) by divide out Math.exp(prob) * */ //this.factor1 = factor1/Math.exp(logProb); this.factor1 = SignedValue.multi(-logProb, this.factor1); } public void printInfor(){ System.out.println("prob: " + logProb + "; factor1: " + factor1.convertRealValue()); } public void printInfor2(){ SignedValue true_factor = SignedValue.multi(-logProb, this.factor1); System.out.println("unnormalize logProb: " + logProb + "; factor1: " + factor1 + "; true_factor: " + true_factor.convertRealValue()); } public double getLogProb(){ return logProb; } public SignedValue getFactor1(){ return factor1; } }