package joshua.discriminative.semiring_parsing; /** This class implements an element in a ConvolutionSemiring * This class does not depend on the 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 VarianceSemiring implements CompositeSemiring { // TODO: assuming the following are always in *log* semiring private double logProb; //TODO: assuming the following are always in *real* semiring private SignedValue factor1; private SignedValue factor2; private SignedValue combinedfactor; public VarianceSemiring(){ factor1 = new SignedValue(); factor2 = new SignedValue(); combinedfactor = new SignedValue(); } public VarianceSemiring(double logProb_, SignedValue factor1_, SignedValue factor2_, SignedValue combinedfactor_){ logProb = logProb_; factor1 = factor1_; factor2 = factor2_; combinedfactor = combinedfactor_; } public void setToZero(AtomicSemiring atomic){ logProb = atomic.ATOMIC_ZERO_IN_SEMIRING; factor1.setZero(); factor2.setZero(); combinedfactor.setZero(); } public void setToOne(AtomicSemiring atomic){ logProb = 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 * */ factor1.setZero(); factor2.setZero(); combinedfactor.setZero(); } public void add(CompositeSemiring b, AtomicSemiring atomic){ VarianceSemiring b2 = (VarianceSemiring)b; this.logProb = atomic.add_in_atomic_semiring(this.logProb, b2.logProb); //this.factor1 = this.factor1 + b2.factor1;//real semiring this.factor1 = SignedValue.add(this.factor1, b2.factor1); //this.factor2 = this.factor2 + b2.factor2;//real semiring this.factor2 = SignedValue.add(this.factor2, b2.factor2); //this.combinedfactor = this.combinedfactor + b2.combinedfactor;//real semiring this.combinedfactor = SignedValue.add(this.combinedfactor, b2.combinedfactor); } public void multi(CompositeSemiring b, AtomicSemiring atomic){ VarianceSemiring b2 = (VarianceSemiring)b; // combinedfacotr = a.prob * b.combinedfacotr + a.combinedfacotr * b.prob + a.factor1 * b.factor2 + a.factor2 * b.factor1 //this.combinedfactor = Math.exp(oldLogProb)* b2.combinedfactor + Math.exp(b2.logProb) * oldCombineFactor + oldFactor1*b2.factor2 + oldFactor2* b2.factor1; SignedValue part1 = SignedValue.add( SignedValue.multi(this.logProb, b2.combinedfactor), SignedValue.multi(b2.logProb, this.combinedfactor) ); SignedValue part2 = SignedValue.add( SignedValue.multi(this.factor1, b2.factor2), SignedValue.multi(this.factor2, b2.factor1) ); this.combinedfactor = SignedValue.add( part1, part2 ); //this.factor1 = Math.exp(oldLogProb)* b2.factor1 + Math.exp(b2.logProb) * oldFactor1; this.factor1 = SignedValue.add( SignedValue.multi(this.logProb, b2.factor1), SignedValue.multi(b2.logProb, this.factor1) ); //this.factor2 = Math.exp(oldLogProb)* b2.factor2 + Math.exp(b2.logProb) * oldFactor2; this.factor2 = SignedValue.add( SignedValue.multi(this.logProb, b2.factor2), SignedValue.multi(b2.logProb, this.factor2) ); //we should update logProb at the end as the update of factors requres the 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); //this.factor2 = factor2/Math.exp(logProb); this.factor2 = SignedValue.multi(-logProb, this.factor2); //this.combinedfactor = combinedfactor/Math.exp(logProb); this.combinedfactor = SignedValue.multi(-logProb, this.combinedfactor); } public void printInfor(){ System.out.println("prob: " + logProb + "; factor1: " + factor1.convertRealValue() + "; factor2: " + factor2.convertRealValue() +"; combined:" + combinedfactor.convertRealValue()); } public void printInfor2(){ SignedValue true_factor1 = SignedValue.multi(-logProb, this.factor1); SignedValue true_factor2 = SignedValue.multi(-logProb, this.factor2); SignedValue true_combinedfactor = SignedValue.multi(-logProb, this.combinedfactor); System.out.println("prob: " + logProb + "; factor1: " + factor1 + "; factor2: " + factor2 +"; combined:" + combinedfactor); System.out.println("true factor1: " + true_factor1 + "; true factor2: " + true_factor2 +"; true combined:" + true_combinedfactor); } }