#ifndef EXP_SEMIRING_H_ #define EXP_SEMIRING_H_ #include #include "star.h" // this file implements the first-order expectation semiring described // in Li & Eisner (EMNLP 2009) // requirements: // RType * RType ==> RType // PType * PType ==> PType // RType * PType ==> RType // good examples: // PType scalar, RType vector // BAD examples: // PType vector, RType scalar template struct PRPair { PRPair() : p(), r() {} // Inside algorithm requires that T(0) and T(1) // return the 0 and 1 values of the semiring explicit PRPair(double x) : p(x), r() {} PRPair(const PType& p, const RType& r) : p(p), r(r) {} PRPair& operator+=(const PRPair& o) { p += o.p; r += o.r; return *this; } PRPair& operator*=(const PRPair& o) { r = (o.r * p) + (o.p * r); p *= o.p; return *this; } PType p; RType r; }; template std::ostream& operator<<(std::ostream& o, const PRPair& x) { return o << '<' << x.p << ", " << x.r << '>'; } template const PRPair operator+(const PRPair& a, const PRPair& b) { PRPair result = a; result += b; return result; } template const PRPair operator*(const PRPair& a, const PRPair& b) { PRPair result = a; result *= b; return result; } template inline const PRPair star(const PRPair& x) { const P pstar = star(x.p); return PRPair(pstar, pstar * x.r * pstar); } #endif