signed-log-weight.h revision f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Licensed under the Apache License, Version 2.0 (the "License"); 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// you may not use this file except in compliance with the License. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// You may obtain a copy of the License at 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// http://www.apache.org/licenses/LICENSE-2.0 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Unless required by applicable law or agreed to in writing, software 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// distributed under the License is distributed on an "AS IS" BASIS, 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// See the License for the specific language governing permissions and 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// limitations under the License. 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright 2005-2010 Google, Inc. 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Author: krr@google.com (Kasturi Rangan Raghavan) 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// \file 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// LogWeight along with sign information that represents the value X in the 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// linear domain as <sign(X), -ln(|X|)> 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The sign is a TropicalWeight: 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// positive, TropicalWeight.Value() > 0.0, recommended value 1.0 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// negative, TropicalWeight.Value() <= 0.0, recommended value -1.0 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef FST_LIB_SIGNED_LOG_WEIGHT_H_ 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define FST_LIB_SIGNED_LOG_WEIGHT_H_ 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <fst/float-weight.h> 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <fst/pair-weight.h> 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace fst { 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)template <class T> 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class SignedLogWeightTpl 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : public PairWeight<TropicalWeight, LogWeightTpl<T> > { 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) typedef TropicalWeight X1; 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef LogWeightTpl<T> X2; 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) using PairWeight<X1, X2>::Value1; 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) using PairWeight<X1, X2>::Value2; 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) using PairWeight<X1, X2>::Reverse; 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) using PairWeight<X1, X2>::Quantize; 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) using PairWeight<X1, X2>::Member; 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef SignedLogWeightTpl<T> ReverseWeight; 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SignedLogWeightTpl() : PairWeight<X1, X2>() {} 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SignedLogWeightTpl(const SignedLogWeightTpl<T>& w) 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : PairWeight<X1, X2> (w) { } 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SignedLogWeightTpl(const PairWeight<X1, X2>& w) 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : PairWeight<X1, X2> (w) { } 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SignedLogWeightTpl(const X1& x1, const X2& x2) 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : PairWeight<X1, X2>(x1, x2) { } 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const SignedLogWeightTpl<T> &Zero() { 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const SignedLogWeightTpl<T> zero(X1(1.0), X2::Zero()); 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return zero; 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const SignedLogWeightTpl<T> &One() { 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static const SignedLogWeightTpl<T> one(X1(1.0), X2::One()); 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return one; 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const SignedLogWeightTpl<T> &NoWeight() { 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const SignedLogWeightTpl<T> no_weight(X1(1.0), X2::NoWeight()); 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return no_weight; 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const string &Type() { 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const string type = "signed_log_" + X1::Type() + "_" + X2::Type(); 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return type; 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProductWeight<X1, X2> Quantize(float delta = kDelta) const { 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return PairWeight<X1, X2>::Quantize(); 792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ReverseWeight Reverse() const { 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return PairWeight<X1, X2>::Reverse(); 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool Member() const { 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return PairWeight<X1, X2>::Member(); 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static uint64 Properties() { 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // not idempotent nor path 912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return kLeftSemiring | kRightSemiring | kCommutative; 922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) size_t Hash() const { 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) size_t h1; 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (Value2() == X2::Zero() || Value1().Value() > 0.0) 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) h1 = TropicalWeight(1.0).Hash(); 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) h1 = TropicalWeight(-1.0).Hash(); 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) size_t h2 = Value2().Hash(); 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const int lshift = 5; 1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const int rshift = CHAR_BIT * sizeof(size_t) - 5; 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return h1 << lshift ^ h1 >> rshift ^ h2; 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)template <class T> 1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)inline SignedLogWeightTpl<T> Plus(const SignedLogWeightTpl<T> &w1, 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const SignedLogWeightTpl<T> &w2) { 1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!w1.Member() || !w2.Member()) 1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return SignedLogWeightTpl<T>::NoWeight(); 1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool s1 = w1.Value1().Value() > 0.0; 1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool s2 = w2.Value1().Value() > 0.0; 1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) T f1 = w1.Value2().Value(); 1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) T f2 = w2.Value2().Value(); 1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (f1 == FloatLimits<T>::kPosInfinity) 1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return w2; 1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else if (f2 == FloatLimits<T>::kPosInfinity) 1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return w1; 1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else if (f1 == f2) { 1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (s1 == s2) 1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return SignedLogWeightTpl<T>(w1.Value1(), (f2 - log(2.0F))); 1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else 1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return SignedLogWeightTpl<T>::Zero(); 1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else if (f1 > f2) { 1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (s1 == s2) { 1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return SignedLogWeightTpl<T>( 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) w1.Value1(), (f2 - log(1.0F + exp(f2 - f1)))); 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SignedLogWeightTpl<T>( 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) w2.Value1(), (f2 - log(1.0F - exp(f2 - f1)))); 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (s2 == s1) { 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SignedLogWeightTpl<T>( 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) w2.Value1(), (f1 - log(1.0F + exp(f1 - f2)))); 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SignedLogWeightTpl<T>( 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) w1.Value1(), (f1 - log(1.0F - exp(f1 - f2)))); 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <class T> 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)inline SignedLogWeightTpl<T> Minus(const SignedLogWeightTpl<T> &w1, 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const SignedLogWeightTpl<T> &w2) { 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SignedLogWeightTpl<T> minus_w2(-w2.Value1().Value(), w2.Value2()); 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return Plus(w1, minus_w2); 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <class T> 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)inline SignedLogWeightTpl<T> Times(const SignedLogWeightTpl<T> &w1, 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const SignedLogWeightTpl<T> &w2) { 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!w1.Member() || !w2.Member()) 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SignedLogWeightTpl<T>::NoWeight(); 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool s1 = w1.Value1().Value() > 0.0; 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool s2 = w2.Value1().Value() > 0.0; 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) T f1 = w1.Value2().Value(); 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) T f2 = w2.Value2().Value(); 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (s1 == s2) 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SignedLogWeightTpl<T>(TropicalWeight(1.0), (f1 + f2)); 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SignedLogWeightTpl<T>(TropicalWeight(-1.0), (f1 + f2)); 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <class T> 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)inline SignedLogWeightTpl<T> Divide(const SignedLogWeightTpl<T> &w1, 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const SignedLogWeightTpl<T> &w2, 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DivideType typ = DIVIDE_ANY) { 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!w1.Member() || !w2.Member()) 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SignedLogWeightTpl<T>::NoWeight(); 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool s1 = w1.Value1().Value() > 0.0; 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool s2 = w2.Value1().Value() > 0.0; 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) T f1 = w1.Value2().Value(); 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) T f2 = w2.Value2().Value(); 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (f2 == FloatLimits<T>::kPosInfinity) 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SignedLogWeightTpl<T>(TropicalWeight(1.0), 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FloatLimits<T>::kNumberBad); 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (f1 == FloatLimits<T>::kPosInfinity) 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SignedLogWeightTpl<T>(TropicalWeight(1.0), 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FloatLimits<T>::kPosInfinity); 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (s1 == s2) 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SignedLogWeightTpl<T>(TropicalWeight(1.0), (f1 - f2)); 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SignedLogWeightTpl<T>(TropicalWeight(-1.0), (f1 - f2)); 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <class T> 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)inline bool ApproxEqual(const SignedLogWeightTpl<T> &w1, 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const SignedLogWeightTpl<T> &w2, 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) float delta = kDelta) { 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool s1 = w1.Value1().Value() > 0.0; 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool s2 = w2.Value1().Value() > 0.0; 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (s1 == s2) { 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ApproxEqual(w1.Value2(), w2.Value2(), delta); 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return w1.Value2() == LogWeightTpl<T>::Zero() 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) && w2.Value2() == LogWeightTpl<T>::Zero(); 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <class T> 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)inline bool operator==(const SignedLogWeightTpl<T> &w1, 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const SignedLogWeightTpl<T> &w2) { 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool s1 = w1.Value1().Value() > 0.0; 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool s2 = w2.Value1().Value() > 0.0; 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (s1 == s2) 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return w1.Value2() == w2.Value2(); 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (w1.Value2() == LogWeightTpl<T>::Zero()) && 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (w2.Value2() == LogWeightTpl<T>::Zero()); 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Single-precision signed-log weight 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef SignedLogWeightTpl<float> SignedLogWeight; 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Double-precision signed-log weight 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef SignedLogWeightTpl<double> SignedLog64Weight; 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// WEIGHT CONVERTER SPECIALIZATIONS. 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <class W1, class W2> 2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool SignedLogConvertCheck(W1 w) { 2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (w.Value1().Value() < 0.0) { 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FSTERROR() << "WeightConvert: can't convert weight from \"" 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << W1::Type() << "\" to \"" << W2::Type(); 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Convert to tropical 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <> 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct WeightConvert<SignedLogWeight, TropicalWeight> { 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TropicalWeight operator()(SignedLogWeight w) const { 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!SignedLogConvertCheck<SignedLogWeight, TropicalWeight>(w)) 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TropicalWeight::NoWeight(); 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return w.Value2().Value(); 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <> 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct WeightConvert<SignedLog64Weight, TropicalWeight> { 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TropicalWeight operator()(SignedLog64Weight w) const { 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!SignedLogConvertCheck<SignedLog64Weight, TropicalWeight>(w)) 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TropicalWeight::NoWeight(); 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return w.Value2().Value(); 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Convert to log 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <> 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct WeightConvert<SignedLogWeight, LogWeight> { 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LogWeight operator()(SignedLogWeight w) const { 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!SignedLogConvertCheck<SignedLogWeight, LogWeight>(w)) 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return LogWeight::NoWeight(); 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return w.Value2().Value(); 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <> 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct WeightConvert<SignedLog64Weight, LogWeight> { 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LogWeight operator()(SignedLog64Weight w) const { 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!SignedLogConvertCheck<SignedLog64Weight, LogWeight>(w)) 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return LogWeight::NoWeight(); 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return w.Value2().Value(); 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Convert to log64 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <> 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct WeightConvert<SignedLogWeight, Log64Weight> { 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Log64Weight operator()(SignedLogWeight w) const { 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!SignedLogConvertCheck<SignedLogWeight, Log64Weight>(w)) 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return Log64Weight::NoWeight(); 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return w.Value2().Value(); 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <> 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct WeightConvert<SignedLog64Weight, Log64Weight> { 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Log64Weight operator()(SignedLog64Weight w) const { 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!SignedLogConvertCheck<SignedLog64Weight, Log64Weight>(w)) 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return Log64Weight::NoWeight(); 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return w.Value2().Value(); 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Convert to signed log 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <> 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct WeightConvert<TropicalWeight, SignedLogWeight> { 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SignedLogWeight operator()(TropicalWeight w) const { 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TropicalWeight x1 = 1.0; 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LogWeight x2 = w.Value(); 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SignedLogWeight(x1, x2); 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <> 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct WeightConvert<LogWeight, SignedLogWeight> { 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SignedLogWeight operator()(LogWeight w) const { 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TropicalWeight x1 = 1.0; 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LogWeight x2 = w.Value(); 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SignedLogWeight(x1, x2); 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <> 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct WeightConvert<Log64Weight, SignedLogWeight> { 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SignedLogWeight operator()(Log64Weight w) const { 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TropicalWeight x1 = 1.0; 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LogWeight x2 = w.Value(); 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SignedLogWeight(x1, x2); 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <> 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct WeightConvert<SignedLog64Weight, SignedLogWeight> { 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SignedLogWeight operator()(SignedLog64Weight w) const { 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TropicalWeight x1 = w.Value1(); 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LogWeight x2 = w.Value2().Value(); 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SignedLogWeight(x1, x2); 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Convert to signed log64 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <> 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct WeightConvert<TropicalWeight, SignedLog64Weight> { 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SignedLog64Weight operator()(TropicalWeight w) const { 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TropicalWeight x1 = 1.0; 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Log64Weight x2 = w.Value(); 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SignedLog64Weight(x1, x2); 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <> 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct WeightConvert<LogWeight, SignedLog64Weight> { 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SignedLog64Weight operator()(LogWeight w) const { 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TropicalWeight x1 = 1.0; 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Log64Weight x2 = w.Value(); 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SignedLog64Weight(x1, x2); 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <> 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct WeightConvert<Log64Weight, SignedLog64Weight> { 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SignedLog64Weight operator()(Log64Weight w) const { 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TropicalWeight x1 = 1.0; 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Log64Weight x2 = w.Value(); 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SignedLog64Weight(x1, x2); 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <> 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct WeightConvert<SignedLogWeight, SignedLog64Weight> { 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SignedLog64Weight operator()(SignedLogWeight w) const { 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TropicalWeight x1 = w.Value1(); 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Log64Weight x2 = w.Value2().Value(); 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SignedLog64Weight(x1, x2); 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace fst 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // FST_LIB_SIGNED_LOG_WEIGHT_H_ 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)