14a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// float-weight.h 24a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// 34a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// Licensed under the Apache License, Version 2.0 (the "License"); 44a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// you may not use this file except in compliance with the License. 54a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// You may obtain a copy of the License at 64a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// 74a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// http://www.apache.org/licenses/LICENSE-2.0 84a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// 94a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// Unless required by applicable law or agreed to in writing, software 104a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// distributed under the License is distributed on an "AS IS" BASIS, 114a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 124a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// See the License for the specific language governing permissions and 134a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// limitations under the License. 144a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// 154a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// 164a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// \file 174a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// Float weight set and associated semiring operation definitions. 184a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// 194a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 204a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#ifndef FST_LIB_FLOAT_WEIGHT_H__ 214a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#define FST_LIB_FLOAT_WEIGHT_H__ 224a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 234a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include <limits> 244a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 254a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include "fst/lib/weight.h" 264a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 274a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectnamespace fst { 284a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 294a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectstatic const float kPosInfinity = numeric_limits<float>::infinity(); 304a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectstatic const float kNegInfinity = -kPosInfinity; 314a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 324a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// Single precision floating point weight base class 334a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectclass FloatWeight { 344a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project public: 354a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project FloatWeight() {} 364a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 374a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project FloatWeight(float f) : value_(f) {} 384a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 394a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project FloatWeight(const FloatWeight &w) : value_(w.value_) {} 404a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 414a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project FloatWeight &operator=(const FloatWeight &w) { 424a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project value_ = w.value_; 434a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return *this; 444a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 454a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 464a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project istream &Read(istream &strm) { 474a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return ReadType(strm, &value_); 484a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 494a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 504a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project ostream &Write(ostream &strm) const { 514a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return WriteType(strm, value_); 524a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 534a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 544a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project ssize_t Hash() const { 554a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project union { 564a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project float f; 574a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project ssize_t s; 584a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } u = { value_ }; 594a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return u.s; 604a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 614a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 624a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project const float &Value() const { return value_; } 634a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 644a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project protected: 654a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project float value_; 664a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}; 674a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 684a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectinline bool operator==(const FloatWeight &w1, const FloatWeight &w2) { 694a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project // Volatile qualifier thwarts over-aggressive compiler optimizations 704a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project // that lead to problems esp. with NaturalLess(). 714a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project volatile float v1 = w1.Value(); 724a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project volatile float v2 = w2.Value(); 734a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return v1 == v2; 744a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project} 754a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 764a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectinline bool operator!=(const FloatWeight &w1, const FloatWeight &w2) { 774a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return !(w1 == w2); 784a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project} 794a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 804a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectinline bool ApproxEqual(const FloatWeight &w1, const FloatWeight &w2, 814a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project float delta = kDelta) { 824a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return w1.Value() <= w2.Value() + delta && w2.Value() <= w1.Value() + delta; 834a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project} 844a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 854a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectinline ostream &operator<<(ostream &strm, const FloatWeight &w) { 864a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (w.Value() == kPosInfinity) 874a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return strm << "Infinity"; 884a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project else if (w.Value() == kNegInfinity) 894a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return strm << "-Infinity"; 904a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project else if (w.Value() != w.Value()) // Fails for NaN 914a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return strm << "BadFloat"; 924a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project else 934a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return strm << w.Value(); 944a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project} 954a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 964a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectinline istream &operator>>(istream &strm, FloatWeight &w) { 974a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project string s; 984a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project strm >> s; 994a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (s == "Infinity") { 1004a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project w = FloatWeight(kPosInfinity); 1014a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } else if (s == "-Infinity") { 1024a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project w = FloatWeight(kNegInfinity); 1034a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } else { 1044a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project char *p; 1054a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project float f = strtod(s.c_str(), &p); 1064a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (p < s.c_str() + s.size()) 1074a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project strm.clear(std::ios::badbit); 1084a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project else 1094a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project w = FloatWeight(f); 1104a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 1114a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return strm; 1124a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project} 1134a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 1144a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 1154a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// Tropical semiring: (min, +, inf, 0) 1164a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectclass TropicalWeight : public FloatWeight { 1174a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project public: 1184a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project typedef TropicalWeight ReverseWeight; 1194a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 1204a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project TropicalWeight() : FloatWeight() {} 1214a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 1224a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project TropicalWeight(float f) : FloatWeight(f) {} 1234a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 1244a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project TropicalWeight(const TropicalWeight &w) : FloatWeight(w) {} 1254a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 1264a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project static const TropicalWeight Zero() { return TropicalWeight(kPosInfinity); } 1274a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 1284a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project static const TropicalWeight One() { return TropicalWeight(0.0F); } 1294a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 1304a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project static const string &Type() { 1314a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project static const string type = "tropical"; 1324a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return type; 1334a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 1344a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 1354a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project bool Member() const { 1364a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project // First part fails for IEEE NaN 1374a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return Value() == Value() && Value() != kNegInfinity; 1384a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 1394a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 1404a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project TropicalWeight Quantize(float delta = kDelta) const { 1414a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return TropicalWeight(floor(Value()/delta + 0.5F) * delta); 1424a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 1434a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 1444a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project TropicalWeight Reverse() const { return *this; } 1454a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 1464a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project static uint64 Properties() { 1474a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return kLeftSemiring | kRightSemiring | kCommutative | 1484a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project kPath | kIdempotent; 1494a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 1504a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}; 1514a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 1524a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectinline TropicalWeight Plus(const TropicalWeight &w1, 1534a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project const TropicalWeight &w2) { 1544a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return w1.Value() < w2.Value() ? w1 : w2; 1554a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project} 1564a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 1574a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectinline TropicalWeight Times(const TropicalWeight &w1, 1584a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project const TropicalWeight &w2) { 1594a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project float f1 = w1.Value(), f2 = w2.Value(); 1604a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (f1 == kPosInfinity) 1614a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return w1; 1624a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project else if (f2 == kPosInfinity) 1634a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return w2; 1644a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project else 1654a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return TropicalWeight(f1 + f2); 1664a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project} 1674a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 1684a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectinline TropicalWeight Divide(const TropicalWeight &w1, 1694a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project const TropicalWeight &w2, 1704a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project DivideType typ = DIVIDE_ANY) { 1714a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project float f1 = w1.Value(), f2 = w2.Value(); 1724a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (f2 == kPosInfinity) 1734a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return kNegInfinity; 1744a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project else if (f1 == kPosInfinity) 1754a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return kPosInfinity; 1764a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project else 1774a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return TropicalWeight(f1 - f2); 1784a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project} 1794a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 1804a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 1814a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// Log semiring: (log(e^-x + e^y), +, inf, 0) 1824a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectclass LogWeight : public FloatWeight { 1834a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project public: 1844a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project typedef LogWeight ReverseWeight; 1854a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 1864a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project LogWeight() : FloatWeight() {} 1874a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 1884a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project LogWeight(float f) : FloatWeight(f) {} 1894a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 1904a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project LogWeight(const LogWeight &w) : FloatWeight(w) {} 1914a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 1924a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project static const LogWeight Zero() { return LogWeight(kPosInfinity); } 1934a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 1944a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project static const LogWeight One() { return LogWeight(0.0F); } 1954a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 1964a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project static const string &Type() { 1974a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project static const string type = "log"; 1984a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return type; 1994a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 2004a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 2014a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project bool Member() const { 2024a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project // First part fails for IEEE NaN 2034a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return Value() == Value() && Value() != kNegInfinity; 2044a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 2054a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 2064a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project LogWeight Quantize(float delta = kDelta) const { 2074a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return LogWeight(floor(Value()/delta + 0.5F) * delta); 2084a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 2094a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 2104a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project LogWeight Reverse() const { return *this; } 2114a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 2124a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project static uint64 Properties() { 2134a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return kLeftSemiring | kRightSemiring | kCommutative; 2144a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 2154a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}; 2164a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 2174a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectinline double LogExp(double x) { return log(1.0F + exp(-x)); } 2184a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 2194a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectinline LogWeight Plus(const LogWeight &w1, const LogWeight &w2) { 2204a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project float f1 = w1.Value(), f2 = w2.Value(); 2214a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (f1 == kPosInfinity) 2224a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return w2; 2234a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project else if (f2 == kPosInfinity) 2244a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return w1; 2254a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project else if (f1 > f2) 2264a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return LogWeight(f2 - LogExp(f1 - f2)); 2274a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project else 2284a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return LogWeight(f1 - LogExp(f2 - f1)); 2294a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project} 2304a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 2314a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectinline LogWeight Times(const LogWeight &w1, const LogWeight &w2) { 2324a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project float f1 = w1.Value(), f2 = w2.Value(); 2334a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (f1 == kPosInfinity) 2344a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return w1; 2354a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project else if (f2 == kPosInfinity) 2364a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return w2; 2374a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project else 2384a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return LogWeight(f1 + f2); 2394a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project} 2404a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 2414a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectinline LogWeight Divide(const LogWeight &w1, 2424a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project const LogWeight &w2, 2434a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project DivideType typ = DIVIDE_ANY) { 2444a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project float f1 = w1.Value(), f2 = w2.Value(); 2454a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (f2 == kPosInfinity) 2464a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return kNegInfinity; 2474a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project else if (f1 == kPosInfinity) 2484a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return kPosInfinity; 2494a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project else 2504a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return LogWeight(f1 - f2); 2514a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project} 2524a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 2534a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project} // namespace fst; 2544a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 2554a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#endif // FST_LIB_FLOAT_WEIGHT_H__ 256