package joshua.discriminative.semiring_parsing; public class AtomicSemiring { /*Two operations: add and multi * add: different hyperedges lead to a specific item * multi: prob of a derivation is a multi of all constituents **/ int ATOMIC_ADD_MODE=0; //0: sum; 1: viterbi-min, 2: viterbi-max public static int LOG_SEMIRING=1; public int ATOMIC_SEMIRING=LOG_SEMIRING; //default is in log; or real, or logic double ATOMIC_ZERO_IN_SEMIRING = Double.NEGATIVE_INFINITY;//log-domain double ATOMIC_ONE_IN_SEMIRING = 0;//log-domain // ############ common ########################## public AtomicSemiring(int semiring, int add_mode){ ATOMIC_ADD_MODE=add_mode; ATOMIC_SEMIRING = semiring; if(ATOMIC_SEMIRING==LOG_SEMIRING){ if(ATOMIC_ADD_MODE==0){//sum ATOMIC_ZERO_IN_SEMIRING = Double.NEGATIVE_INFINITY; ATOMIC_ONE_IN_SEMIRING = 0; }else if (ATOMIC_ADD_MODE==1){//viter-min System.out.println("unsupported add mode"); System.exit(0); ATOMIC_ZERO_IN_SEMIRING = Double.POSITIVE_INFINITY; ATOMIC_ONE_IN_SEMIRING = 0; }else if (ATOMIC_ADD_MODE==2){//viter-max System.out.println("unsupported add mode"); System.exit(0); ATOMIC_ZERO_IN_SEMIRING = Double.NEGATIVE_INFINITY; ATOMIC_ONE_IN_SEMIRING = 0; }else{ System.out.println("invalid add mode"); System.exit(0); } }else{ System.out.println("un-supported semiring"); System.exit(0); } } public double multi_in_atomic_semiring(double x, double y){ if(ATOMIC_SEMIRING==LOG_SEMIRING){ return multiInAtomicLogSemiring(x,y); }else{ System.out.println("un-supported semiring"); System.exit(0); return -1; } } public double divide_in_atomic_semiring(double x, double y){// x/y if(ATOMIC_SEMIRING==LOG_SEMIRING){ return x-y; }else{ System.out.println("un-supported semiring"); System.exit(0); return -1; } } public double add_in_atomic_semiring(double x, double y){ if(ATOMIC_SEMIRING==LOG_SEMIRING){ return addInAtomicLogSemiring(x,y); }else{ System.out.println("un-supported semiring"); System.exit(0); return -1; } } //AND static private double multiInAtomicLogSemiring(double x, double y){//value is Log prob return x + y; } //OR: return Math.log(Math.exp(x) + Math.exp(y)); private double addInAtomicLogSemiring(double x, double y){//prevent over-flow if(ATOMIC_ADD_MODE==0){//sum if(x==Double.NEGATIVE_INFINITY)//if y is also n-infinity, then return n-infinity return y; if(y==Double.NEGATIVE_INFINITY) return x; if(y<=x) return x + Log(1+Math.exp(y-x)); else//x<y return y + Log(1+Math.exp(x-y)); }else if (ATOMIC_ADD_MODE==1){//viter-min return (x<=y)?x:y; }else if (ATOMIC_ADD_MODE==2){//viter-max return (x>=y)?x:y; }else{ System.out.println("invalid add mode"); System.exit(0); return 0; } } static public double Log(double x){ /*if(x==0) return 0;//it is not clear whether it should be Double.NEGATIVE_INFINITY or zero else*/ return Math.log(x); } // ############ end common ##################### }