#ifndef _CONDITIONAL_PSEG_H_ #define _CONDITIONAL_PSEG_H_ #include #include #include #include #include "m.h" #include "prob.h" #include "ccrp_nt.h" #include "mfcr.h" #include "trule.h" #include "base_distributions.h" #include "tdict.h" template struct MConditionalTranslationModel { explicit MConditionalTranslationModel(ConditionalBaseMeasure& rcp0) : rp0(rcp0), d(0.5), strength(1.0), lambdas(1, prob_t::One()), p0s(1) {} void Summary() const { std::cerr << "Number of conditioning contexts: " << r.size() << std::endl; for (RuleModelHash::const_iterator it = r.begin(); it != r.end(); ++it) { std::cerr << TD::GetString(it->first) << " \t(d=" << it->second.discount() << ",s=" << it->second.strength() << ") --------------------------" << std::endl; for (MFCR<1,TRule>::const_iterator i2 = it->second.begin(); i2 != it->second.end(); ++i2) std::cerr << " " << i2->second.total_dish_count_ << '\t' << i2->first << std::endl; } } double log_likelihood(const double& dd, const double& aa) const { if (aa <= -dd) return -std::numeric_limits::infinity(); //double llh = Md::log_beta_density(dd, 10, 3) + Md::log_gamma_density(aa, 1, 1); double llh = Md::log_beta_density(dd, 1, 1) + Md::log_gamma_density(dd + aa, 1, 1); typename std::tr1::unordered_map, MFCR<1,TRule>, boost::hash > >::const_iterator it; for (it = r.begin(); it != r.end(); ++it) llh += it->second.log_crp_prob(dd, aa); return llh; } struct DiscountResampler { DiscountResampler(const MConditionalTranslationModel& m) : m_(m) {} const MConditionalTranslationModel& m_; double operator()(const double& proposed_discount) const { return m_.log_likelihood(proposed_discount, m_.strength); } }; struct AlphaResampler { AlphaResampler(const MConditionalTranslationModel& m) : m_(m) {} const MConditionalTranslationModel& m_; double operator()(const double& proposed_strength) const { return m_.log_likelihood(m_.d, proposed_strength); } }; void ResampleHyperparameters(MT19937* rng) { typename std::tr1::unordered_map, MFCR<1,TRule>, boost::hash > >::iterator it; #if 1 for (it = r.begin(); it != r.end(); ++it) { it->second.resample_hyperparameters(rng); } #else const unsigned nloop = 5; const unsigned niterations = 10; DiscountResampler dr(*this); AlphaResampler ar(*this); for (int iter = 0; iter < nloop; ++iter) { strength = slice_sampler1d(ar, strength, *rng, -d + std::numeric_limits::min(), std::numeric_limits::infinity(), 0.0, niterations, 100*niterations); double min_discount = std::numeric_limits::min(); if (strength < 0.0) min_discount -= strength; d = slice_sampler1d(dr, d, *rng, min_discount, 1.0, 0.0, niterations, 100*niterations); } strength = slice_sampler1d(ar, strength, *rng, -d, std::numeric_limits::infinity(), 0.0, niterations, 100*niterations); std::cerr << "MConditionalTranslationModel(d=" << d << ",s=" << strength << ") = " << log_likelihood(d, strength) << std::endl; for (it = r.begin(); it != r.end(); ++it) { it->second.set_discount(d); it->second.set_strength(strength); } #endif } int DecrementRule(const TRule& rule, MT19937* rng) { RuleModelHash::iterator it = r.find(rule.f_); assert(it != r.end()); const TableCount delta = it->second.decrement(rule, rng); if (delta.count) { if (it->second.num_customers() == 0) r.erase(it); } return delta.count; } int IncrementRule(const TRule& rule, MT19937* rng) { RuleModelHash::iterator it = r.find(rule.f_); if (it == r.end()) { //it = r.insert(make_pair(rule.f_, MFCR<1,TRule>(d, strength))).first; it = r.insert(make_pair(rule.f_, MFCR<1,TRule>(1,1,1,1,0.6, -0.12))).first; } p0s[0] = rp0(rule); TableCount delta = it->second.increment(rule, p0s.begin(), lambdas.begin(), rng); return delta.count; } prob_t RuleProbability(const TRule& rule) const { prob_t p; RuleModelHash::const_iterator it = r.find(rule.f_); if (it == r.end()) { p = rp0(rule); } else { p0s[0] = rp0(rule); p = it->second.prob(rule, p0s.begin(), lambdas.begin()); } return p; } prob_t Likelihood() const { prob_t p; p.logeq(log_likelihood(d, strength)); return p; } const ConditionalBaseMeasure& rp0; typedef std::tr1::unordered_map, MFCR<1, TRule>, boost::hash > > RuleModelHash; RuleModelHash r; double d, strength; std::vector lambdas; mutable std::vector p0s; }; template struct ConditionalTranslationModel { explicit ConditionalTranslationModel(ConditionalBaseMeasure& rcp0) : rp0(rcp0) {} void Summary() const { std::cerr << "Number of conditioning contexts: " << r.size() << std::endl; for (RuleModelHash::const_iterator it = r.begin(); it != r.end(); ++it) { std::cerr << TD::GetString(it->first) << " \t(\\alpha = " << it->second.alpha() << ") --------------------------" << std::endl; for (CCRP_NoTable::const_iterator i2 = it->second.begin(); i2 != it->second.end(); ++i2) std::cerr << " " << i2->second << '\t' << i2->first << std::endl; } } void ResampleHyperparameters(MT19937* rng) { for (RuleModelHash::iterator it = r.begin(); it != r.end(); ++it) it->second.resample_hyperparameters(rng); } int DecrementRule(const TRule& rule) { RuleModelHash::iterator it = r.find(rule.f_); assert(it != r.end()); int count = it->second.decrement(rule); if (count) { if (it->second.num_customers() == 0) r.erase(it); } return count; } int IncrementRule(const TRule& rule) { RuleModelHash::iterator it = r.find(rule.f_); if (it == r.end()) { it = r.insert(make_pair(rule.f_, CCRP_NoTable(1.0, 1.0, 8.0))).first; } int count = it->second.increment(rule); return count; } void IncrementRules(const std::vector& rules) { for (int i = 0; i < rules.size(); ++i) IncrementRule(*rules[i]); } void DecrementRules(const std::vector& rules) { for (int i = 0; i < rules.size(); ++i) DecrementRule(*rules[i]); } prob_t RuleProbability(const TRule& rule) const { prob_t p; RuleModelHash::const_iterator it = r.find(rule.f_); if (it == r.end()) { p.logeq(log(rp0(rule))); } else { p.logeq(it->second.logprob(rule, log(rp0(rule)))); } return p; } prob_t Likelihood() const { prob_t p = prob_t::One(); for (RuleModelHash::const_iterator it = r.begin(); it != r.end(); ++it) { prob_t q; q.logeq(it->second.log_crp_prob()); p *= q; for (CCRP_NoTable::const_iterator i2 = it->second.begin(); i2 != it->second.end(); ++i2) p *= rp0(i2->first); } return p; } const ConditionalBaseMeasure& rp0; typedef std::tr1::unordered_map, CCRP_NoTable, boost::hash > > RuleModelHash; RuleModelHash r; }; template struct ConditionalParallelSegementationModel { explicit ConditionalParallelSegementationModel(ConditionalBaseMeasure& rcp0) : tmodel(rcp0), base(prob_t::One()), aligns(1,1) {} ConditionalTranslationModel tmodel; void DecrementRule(const TRule& rule) { tmodel.DecrementRule(rule); } void IncrementRule(const TRule& rule) { tmodel.IncrementRule(rule); } void IncrementRulesAndAlignments(const std::vector& rules) { tmodel.IncrementRules(rules); for (int i = 0; i < rules.size(); ++i) { IncrementAlign(rules[i]->f_.size()); } } void DecrementRulesAndAlignments(const std::vector& rules) { tmodel.DecrementRules(rules); for (int i = 0; i < rules.size(); ++i) { DecrementAlign(rules[i]->f_.size()); } } prob_t RuleProbability(const TRule& rule) const { return tmodel.RuleProbability(rule); } void IncrementAlign(unsigned span) { if (aligns.increment(span)) { // TODO } } void DecrementAlign(unsigned span) { if (aligns.decrement(span)) { // TODO } } prob_t AlignProbability(unsigned span) const { prob_t p; p.logeq(aligns.logprob(span, Md::log_poisson(span, 1.0))); return p; } prob_t Likelihood() const { prob_t p; p.logeq(aligns.log_crp_prob()); p *= base; p *= tmodel.Likelihood(); return p; } prob_t base; CCRP_NoTable aligns; }; #endif