float-weight.h revision dfd8b8327b93660601d016cdc6f29f433b45a8d8
1f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// float-weight.h 2f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 3f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Licensed under the Apache License, Version 2.0 (the "License"); 4f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// you may not use this file except in compliance with the License. 5f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// You may obtain a copy of the License at 6f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// 7f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// http://www.apache.org/licenses/LICENSE-2.0 8f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// 9f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Unless required by applicable law or agreed to in writing, software 10f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// distributed under the License is distributed on an "AS IS" BASIS, 11f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// See the License for the specific language governing permissions and 13f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// limitations under the License. 14f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// 15f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Copyright 2005-2010 Google, Inc. 16f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Author: riley@google.com (Michael Riley) 17f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// 18f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// \file 19f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Float weight set and associated semiring operation definitions. 20f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// 21f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 22f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#ifndef FST_LIB_FLOAT_WEIGHT_H__ 23f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#define FST_LIB_FLOAT_WEIGHT_H__ 24f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 25f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#include <limits> 26f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#include <climits> 27f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#include <sstream> 28f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#include <string> 29f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 30f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#include <fst/util.h> 31f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#include <fst/weight.h> 32f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 33f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 34f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonnamespace fst { 35f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 36f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// numeric limits class 37f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class T> 38f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonclass FloatLimits { 39f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson public: 40dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin static const T PosInfinity() { 41dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin static const T pos_infinity = numeric_limits<T>::infinity(); 42dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin return pos_infinity; 43dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin } 44f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 45dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin static const T NegInfinity() { 46dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin static const T neg_infinity = -PosInfinity(); 47dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin return neg_infinity; 48dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin } 49f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 50dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin static const T NumberBad() { 51dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin static const T number_bad = numeric_limits<T>::quiet_NaN(); 52dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin return number_bad; 53dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin } 54f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 55dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin}; 56f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 57f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// weight class to be templated on floating-points types 58f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class T = float> 59f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonclass FloatWeightTpl { 60f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson public: 61f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson FloatWeightTpl() {} 62f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 63f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson FloatWeightTpl(T f) : value_(f) {} 64f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 65f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson FloatWeightTpl(const FloatWeightTpl<T> &w) : value_(w.value_) {} 66f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 67f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson FloatWeightTpl<T> &operator=(const FloatWeightTpl<T> &w) { 68f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson value_ = w.value_; 69f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return *this; 70f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 71f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 72f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson istream &Read(istream &strm) { 73f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return ReadType(strm, &value_); 74f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 75f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 76f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson ostream &Write(ostream &strm) const { 77f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return WriteType(strm, value_); 78f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 79f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 80f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson size_t Hash() const { 81f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson union { 82f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson T f; 83f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson size_t s; 84f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } u; 85f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson u.s = 0; 86f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson u.f = value_; 87f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return u.s; 88f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 89f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 90f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson const T &Value() const { return value_; } 91f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 92f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson protected: 93f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson void SetValue(const T &f) { value_ = f; } 94f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 95f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson inline static string GetPrecisionString() { 96f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson int64 size = sizeof(T); 97f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (size == sizeof(float)) return ""; 98f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson size *= CHAR_BIT; 99f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 100f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson string result; 101f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson Int64ToStr(size, &result); 102f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return result; 103f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 104f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 105f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson private: 106f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson T value_; 107f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson}; 108f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 109f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Single-precision float weight 110f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontypedef FloatWeightTpl<float> FloatWeight; 111f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 112f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class T> 113f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsoninline bool operator==(const FloatWeightTpl<T> &w1, 114f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson const FloatWeightTpl<T> &w2) { 115f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson // Volatile qualifier thwarts over-aggressive compiler optimizations 116f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson // that lead to problems esp. with NaturalLess(). 117f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson volatile T v1 = w1.Value(); 118f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson volatile T v2 = w2.Value(); 119f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return v1 == v2; 120f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson} 121f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 122f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsoninline bool operator==(const FloatWeightTpl<double> &w1, 123f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson const FloatWeightTpl<double> &w2) { 124f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return operator==<double>(w1, w2); 125f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson} 126f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 127f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsoninline bool operator==(const FloatWeightTpl<float> &w1, 128f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson const FloatWeightTpl<float> &w2) { 129f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return operator==<float>(w1, w2); 130f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson} 131f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 132f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class T> 133f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsoninline bool operator!=(const FloatWeightTpl<T> &w1, 134f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson const FloatWeightTpl<T> &w2) { 135f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return !(w1 == w2); 136f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson} 137f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 138f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsoninline bool operator!=(const FloatWeightTpl<double> &w1, 139f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson const FloatWeightTpl<double> &w2) { 140f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return operator!=<double>(w1, w2); 141f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson} 142f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 143f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsoninline bool operator!=(const FloatWeightTpl<float> &w1, 144f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson const FloatWeightTpl<float> &w2) { 145f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return operator!=<float>(w1, w2); 146f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson} 147f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 148f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class T> 149f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsoninline bool ApproxEqual(const FloatWeightTpl<T> &w1, 150f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson const FloatWeightTpl<T> &w2, 151f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson float delta = kDelta) { 152f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return w1.Value() <= w2.Value() + delta && w2.Value() <= w1.Value() + delta; 153f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson} 154f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 155f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class T> 156f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsoninline ostream &operator<<(ostream &strm, const FloatWeightTpl<T> &w) { 157dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin if (w.Value() == FloatLimits<T>::PosInfinity()) 158f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return strm << "Infinity"; 159dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin else if (w.Value() == FloatLimits<T>::NegInfinity()) 160f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return strm << "-Infinity"; 161f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson else if (w.Value() != w.Value()) // Fails for NaN 162f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return strm << "BadNumber"; 163f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson else 164f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return strm << w.Value(); 165f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson} 166f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 167f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class T> 168f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsoninline istream &operator>>(istream &strm, FloatWeightTpl<T> &w) { 169f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson string s; 170f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson strm >> s; 171f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (s == "Infinity") { 172dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin w = FloatWeightTpl<T>(FloatLimits<T>::PosInfinity()); 173f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } else if (s == "-Infinity") { 174dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin w = FloatWeightTpl<T>(FloatLimits<T>::NegInfinity()); 175f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } else { 176f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson char *p; 177f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson T f = strtod(s.c_str(), &p); 178f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (p < s.c_str() + s.size()) 179f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson strm.clear(std::ios::badbit); 180f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson else 181f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson w = FloatWeightTpl<T>(f); 182f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 183f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return strm; 184f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson} 185f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 186f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 187f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Tropical semiring: (min, +, inf, 0) 188f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class T> 189f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonclass TropicalWeightTpl : public FloatWeightTpl<T> { 190f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson public: 191f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson using FloatWeightTpl<T>::Value; 192f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 193f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson typedef TropicalWeightTpl<T> ReverseWeight; 194f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 195f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson TropicalWeightTpl() : FloatWeightTpl<T>() {} 196f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 197f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson TropicalWeightTpl(T f) : FloatWeightTpl<T>(f) {} 198f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 199f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson TropicalWeightTpl(const TropicalWeightTpl<T> &w) : FloatWeightTpl<T>(w) {} 200f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 201f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson static const TropicalWeightTpl<T> Zero() { 202dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin return TropicalWeightTpl<T>(FloatLimits<T>::PosInfinity()); } 203f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 204f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson static const TropicalWeightTpl<T> One() { 205f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return TropicalWeightTpl<T>(0.0F); } 206f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 207f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson static const TropicalWeightTpl<T> NoWeight() { 208dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin return TropicalWeightTpl<T>(FloatLimits<T>::NumberBad()); } 209f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 210f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson static const string &Type() { 211f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson static const string type = "tropical" + 212f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson FloatWeightTpl<T>::GetPrecisionString(); 213f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return type; 214f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 215f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 216f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson bool Member() const { 217f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson // First part fails for IEEE NaN 218dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin return Value() == Value() && Value() != FloatLimits<T>::NegInfinity(); 219f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 220f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 221f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson TropicalWeightTpl<T> Quantize(float delta = kDelta) const { 222dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin if (Value() == FloatLimits<T>::NegInfinity() || 223dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin Value() == FloatLimits<T>::PosInfinity() || 224f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson Value() != Value()) 225f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return *this; 226f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson else 227f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return TropicalWeightTpl<T>(floor(Value()/delta + 0.5F) * delta); 228f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 229f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 230f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson TropicalWeightTpl<T> Reverse() const { return *this; } 231f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 232f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson static uint64 Properties() { 233f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return kLeftSemiring | kRightSemiring | kCommutative | 234f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson kPath | kIdempotent; 235f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 236f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson}; 237f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 238f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Single precision tropical weight 239f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontypedef TropicalWeightTpl<float> TropicalWeight; 240f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 241f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class T> 242f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsoninline TropicalWeightTpl<T> Plus(const TropicalWeightTpl<T> &w1, 243f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson const TropicalWeightTpl<T> &w2) { 244f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (!w1.Member() || !w2.Member()) 245f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return TropicalWeightTpl<T>::NoWeight(); 246f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return w1.Value() < w2.Value() ? w1 : w2; 247f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson} 248f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 249f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsoninline TropicalWeightTpl<float> Plus(const TropicalWeightTpl<float> &w1, 250f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson const TropicalWeightTpl<float> &w2) { 251f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return Plus<float>(w1, w2); 252f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson} 253f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 254f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsoninline TropicalWeightTpl<double> Plus(const TropicalWeightTpl<double> &w1, 255f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson const TropicalWeightTpl<double> &w2) { 256f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return Plus<double>(w1, w2); 257f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson} 258f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 259f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class T> 260f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsoninline TropicalWeightTpl<T> Times(const TropicalWeightTpl<T> &w1, 261f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson const TropicalWeightTpl<T> &w2) { 262f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (!w1.Member() || !w2.Member()) 263f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return TropicalWeightTpl<T>::NoWeight(); 264f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson T f1 = w1.Value(), f2 = w2.Value(); 265dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin if (f1 == FloatLimits<T>::PosInfinity()) 266f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return w1; 267dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin else if (f2 == FloatLimits<T>::PosInfinity()) 268f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return w2; 269f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson else 270f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return TropicalWeightTpl<T>(f1 + f2); 271f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson} 272f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 273f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsoninline TropicalWeightTpl<float> Times(const TropicalWeightTpl<float> &w1, 274f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson const TropicalWeightTpl<float> &w2) { 275f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return Times<float>(w1, w2); 276f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson} 277f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 278f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsoninline TropicalWeightTpl<double> Times(const TropicalWeightTpl<double> &w1, 279f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson const TropicalWeightTpl<double> &w2) { 280f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return Times<double>(w1, w2); 281f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson} 282f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 283f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class T> 284f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsoninline TropicalWeightTpl<T> Divide(const TropicalWeightTpl<T> &w1, 285f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson const TropicalWeightTpl<T> &w2, 286f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson DivideType typ = DIVIDE_ANY) { 287f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (!w1.Member() || !w2.Member()) 288f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return TropicalWeightTpl<T>::NoWeight(); 289f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson T f1 = w1.Value(), f2 = w2.Value(); 290dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin if (f2 == FloatLimits<T>::PosInfinity()) 291dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin return FloatLimits<T>::NumberBad(); 292dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin else if (f1 == FloatLimits<T>::PosInfinity()) 293dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin return FloatLimits<T>::PosInfinity(); 294f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson else 295f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return TropicalWeightTpl<T>(f1 - f2); 296f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson} 297f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 298f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsoninline TropicalWeightTpl<float> Divide(const TropicalWeightTpl<float> &w1, 299f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson const TropicalWeightTpl<float> &w2, 300f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson DivideType typ = DIVIDE_ANY) { 301f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return Divide<float>(w1, w2, typ); 302f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson} 303f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 304f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsoninline TropicalWeightTpl<double> Divide(const TropicalWeightTpl<double> &w1, 305f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson const TropicalWeightTpl<double> &w2, 306f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson DivideType typ = DIVIDE_ANY) { 307f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return Divide<double>(w1, w2, typ); 308f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson} 309f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 310f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 311f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Log semiring: (log(e^-x + e^y), +, inf, 0) 312f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class T> 313f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonclass LogWeightTpl : public FloatWeightTpl<T> { 314f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson public: 315f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson using FloatWeightTpl<T>::Value; 316f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 317f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson typedef LogWeightTpl ReverseWeight; 318f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 319f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson LogWeightTpl() : FloatWeightTpl<T>() {} 320f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 321f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson LogWeightTpl(T f) : FloatWeightTpl<T>(f) {} 322f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 323f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson LogWeightTpl(const LogWeightTpl<T> &w) : FloatWeightTpl<T>(w) {} 324f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 325f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson static const LogWeightTpl<T> Zero() { 326dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin return LogWeightTpl<T>(FloatLimits<T>::PosInfinity()); 327f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 328f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 329f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson static const LogWeightTpl<T> One() { 330f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return LogWeightTpl<T>(0.0F); 331f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 332f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 333f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson static const LogWeightTpl<T> NoWeight() { 334dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin return LogWeightTpl<T>(FloatLimits<T>::NumberBad()); } 335f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 336f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson static const string &Type() { 337f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson static const string type = "log" + FloatWeightTpl<T>::GetPrecisionString(); 338f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return type; 339f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 340f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 341f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson bool Member() const { 342f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson // First part fails for IEEE NaN 343dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin return Value() == Value() && Value() != FloatLimits<T>::NegInfinity(); 344f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 345f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 346f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson LogWeightTpl<T> Quantize(float delta = kDelta) const { 347dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin if (Value() == FloatLimits<T>::NegInfinity() || 348dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin Value() == FloatLimits<T>::PosInfinity() || 349f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson Value() != Value()) 350f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return *this; 351f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson else 352f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return LogWeightTpl<T>(floor(Value()/delta + 0.5F) * delta); 353f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 354f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 355f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson LogWeightTpl<T> Reverse() const { return *this; } 356f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 357f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson static uint64 Properties() { 358f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return kLeftSemiring | kRightSemiring | kCommutative; 359f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 360f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson}; 361f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 362f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Single-precision log weight 363f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontypedef LogWeightTpl<float> LogWeight; 364f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Double-precision log weight 365f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontypedef LogWeightTpl<double> Log64Weight; 366f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 367f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class T> 368f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsoninline T LogExp(T x) { return log(1.0F + exp(-x)); } 369f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 370f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class T> 371f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsoninline LogWeightTpl<T> Plus(const LogWeightTpl<T> &w1, 372f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson const LogWeightTpl<T> &w2) { 373f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson T f1 = w1.Value(), f2 = w2.Value(); 374dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin if (f1 == FloatLimits<T>::PosInfinity()) 375f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return w2; 376dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin else if (f2 == FloatLimits<T>::PosInfinity()) 377f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return w1; 378f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson else if (f1 > f2) 379f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return LogWeightTpl<T>(f2 - LogExp(f1 - f2)); 380f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson else 381f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return LogWeightTpl<T>(f1 - LogExp(f2 - f1)); 382f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson} 383f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 384f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsoninline LogWeightTpl<float> Plus(const LogWeightTpl<float> &w1, 385f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson const LogWeightTpl<float> &w2) { 386f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return Plus<float>(w1, w2); 387f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson} 388f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 389f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsoninline LogWeightTpl<double> Plus(const LogWeightTpl<double> &w1, 390f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson const LogWeightTpl<double> &w2) { 391f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return Plus<double>(w1, w2); 392f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson} 393f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 394f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class T> 395f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsoninline LogWeightTpl<T> Times(const LogWeightTpl<T> &w1, 396f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson const LogWeightTpl<T> &w2) { 397f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (!w1.Member() || !w2.Member()) 398f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return LogWeightTpl<T>::NoWeight(); 399f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson T f1 = w1.Value(), f2 = w2.Value(); 400dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin if (f1 == FloatLimits<T>::PosInfinity()) 401f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return w1; 402dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin else if (f2 == FloatLimits<T>::PosInfinity()) 403f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return w2; 404f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson else 405f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return LogWeightTpl<T>(f1 + f2); 406f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson} 407f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 408f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsoninline LogWeightTpl<float> Times(const LogWeightTpl<float> &w1, 409f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson const LogWeightTpl<float> &w2) { 410f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return Times<float>(w1, w2); 411f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson} 412f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 413f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsoninline LogWeightTpl<double> Times(const LogWeightTpl<double> &w1, 414f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson const LogWeightTpl<double> &w2) { 415f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return Times<double>(w1, w2); 416f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson} 417f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 418f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class T> 419f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsoninline LogWeightTpl<T> Divide(const LogWeightTpl<T> &w1, 420f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson const LogWeightTpl<T> &w2, 421f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson DivideType typ = DIVIDE_ANY) { 422f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (!w1.Member() || !w2.Member()) 423f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return LogWeightTpl<T>::NoWeight(); 424f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson T f1 = w1.Value(), f2 = w2.Value(); 425dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin if (f2 == FloatLimits<T>::PosInfinity()) 426dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin return FloatLimits<T>::NumberBad(); 427dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin else if (f1 == FloatLimits<T>::PosInfinity()) 428dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin return FloatLimits<T>::PosInfinity(); 429f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson else 430f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return LogWeightTpl<T>(f1 - f2); 431f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson} 432f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 433f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsoninline LogWeightTpl<float> Divide(const LogWeightTpl<float> &w1, 434f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson const LogWeightTpl<float> &w2, 435f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson DivideType typ = DIVIDE_ANY) { 436f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return Divide<float>(w1, w2, typ); 437f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson} 438f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 439f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsoninline LogWeightTpl<double> Divide(const LogWeightTpl<double> &w1, 440f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson const LogWeightTpl<double> &w2, 441f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson DivideType typ = DIVIDE_ANY) { 442f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return Divide<double>(w1, w2, typ); 443f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson} 444f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 445f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// MinMax semiring: (min, max, inf, -inf) 446f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class T> 447f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonclass MinMaxWeightTpl : public FloatWeightTpl<T> { 448f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson public: 449f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson using FloatWeightTpl<T>::Value; 450f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 451f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson typedef MinMaxWeightTpl<T> ReverseWeight; 452f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 453f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson MinMaxWeightTpl() : FloatWeightTpl<T>() {} 454f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 455f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson MinMaxWeightTpl(T f) : FloatWeightTpl<T>(f) {} 456f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 457f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson MinMaxWeightTpl(const MinMaxWeightTpl<T> &w) : FloatWeightTpl<T>(w) {} 458f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 459f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson static const MinMaxWeightTpl<T> Zero() { 460dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin return MinMaxWeightTpl<T>(FloatLimits<T>::PosInfinity()); 461f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 462f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 463f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson static const MinMaxWeightTpl<T> One() { 464dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin return MinMaxWeightTpl<T>(FloatLimits<T>::NegInfinity()); 465f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 466f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 467f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson static const MinMaxWeightTpl<T> NoWeight() { 468dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin return MinMaxWeightTpl<T>(FloatLimits<T>::NumberBad()); } 469f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 470f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson static const string &Type() { 471f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson static const string type = "minmax" + 472f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson FloatWeightTpl<T>::GetPrecisionString(); 473f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return type; 474f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 475f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 476f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson bool Member() const { 477f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson // Fails for IEEE NaN 478f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return Value() == Value(); 479f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 480f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 481f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson MinMaxWeightTpl<T> Quantize(float delta = kDelta) const { 482f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson // If one of infinities, or a NaN 483dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin if (Value() == FloatLimits<T>::NegInfinity() || 484dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin Value() == FloatLimits<T>::PosInfinity() || 485f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson Value() != Value()) 486f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return *this; 487f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson else 488f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return MinMaxWeightTpl<T>(floor(Value()/delta + 0.5F) * delta); 489f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 490f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 491f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson MinMaxWeightTpl<T> Reverse() const { return *this; } 492f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 493f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson static uint64 Properties() { 494f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return kLeftSemiring | kRightSemiring | kCommutative | kIdempotent | kPath; 495f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 496f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson}; 497f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 498f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Single-precision min-max weight 499f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontypedef MinMaxWeightTpl<float> MinMaxWeight; 500f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 501f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Min 502f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class T> 503f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsoninline MinMaxWeightTpl<T> Plus( 504f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson const MinMaxWeightTpl<T> &w1, const MinMaxWeightTpl<T> &w2) { 505f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (!w1.Member() || !w2.Member()) 506f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return MinMaxWeightTpl<T>::NoWeight(); 507f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return w1.Value() < w2.Value() ? w1 : w2; 508f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson} 509f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 510f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsoninline MinMaxWeightTpl<float> Plus( 511f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson const MinMaxWeightTpl<float> &w1, const MinMaxWeightTpl<float> &w2) { 512f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return Plus<float>(w1, w2); 513f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson} 514f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 515f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsoninline MinMaxWeightTpl<double> Plus( 516f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson const MinMaxWeightTpl<double> &w1, const MinMaxWeightTpl<double> &w2) { 517f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return Plus<double>(w1, w2); 518f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson} 519f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 520f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Max 521f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class T> 522f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsoninline MinMaxWeightTpl<T> Times( 523f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson const MinMaxWeightTpl<T> &w1, const MinMaxWeightTpl<T> &w2) { 524f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (!w1.Member() || !w2.Member()) 525f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return MinMaxWeightTpl<T>::NoWeight(); 526f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return w1.Value() >= w2.Value() ? w1 : w2; 527f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson} 528f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 529f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsoninline MinMaxWeightTpl<float> Times( 530f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson const MinMaxWeightTpl<float> &w1, const MinMaxWeightTpl<float> &w2) { 531f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return Times<float>(w1, w2); 532f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson} 533f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 534f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsoninline MinMaxWeightTpl<double> Times( 535f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson const MinMaxWeightTpl<double> &w1, const MinMaxWeightTpl<double> &w2) { 536f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return Times<double>(w1, w2); 537f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson} 538f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 539f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Defined only for special cases 540f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class T> 541f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsoninline MinMaxWeightTpl<T> Divide(const MinMaxWeightTpl<T> &w1, 542f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson const MinMaxWeightTpl<T> &w2, 543f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson DivideType typ = DIVIDE_ANY) { 544f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (!w1.Member() || !w2.Member()) 545f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return MinMaxWeightTpl<T>::NoWeight(); 546f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson // min(w1, x) = w2, w1 >= w2 => min(w1, x) = w2, x = w2 547dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin return w1.Value() >= w2.Value() ? w1 : FloatLimits<T>::NumberBad(); 548f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson} 549f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 550f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsoninline MinMaxWeightTpl<float> Divide(const MinMaxWeightTpl<float> &w1, 551f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson const MinMaxWeightTpl<float> &w2, 552f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson DivideType typ = DIVIDE_ANY) { 553f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return Divide<float>(w1, w2, typ); 554f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson} 555f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 556f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsoninline MinMaxWeightTpl<double> Divide(const MinMaxWeightTpl<double> &w1, 557f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson const MinMaxWeightTpl<double> &w2, 558f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson DivideType typ = DIVIDE_ANY) { 559f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return Divide<double>(w1, w2, typ); 560f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson} 561f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 562f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// 563f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// WEIGHT CONVERTER SPECIALIZATIONS. 564f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// 565f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 566f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Convert to tropical 567f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <> 568f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonstruct WeightConvert<LogWeight, TropicalWeight> { 569f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson TropicalWeight operator()(LogWeight w) const { return w.Value(); } 570f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson}; 571f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 572f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <> 573f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonstruct WeightConvert<Log64Weight, TropicalWeight> { 574f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson TropicalWeight operator()(Log64Weight w) const { return w.Value(); } 575f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson}; 576f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 577f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Convert to log 578f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <> 579f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonstruct WeightConvert<TropicalWeight, LogWeight> { 580f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson LogWeight operator()(TropicalWeight w) const { return w.Value(); } 581f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson}; 582f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 583f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <> 584f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonstruct WeightConvert<Log64Weight, LogWeight> { 585f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson LogWeight operator()(Log64Weight w) const { return w.Value(); } 586f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson}; 587f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 588f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Convert to log64 589f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <> 590f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonstruct WeightConvert<TropicalWeight, Log64Weight> { 591f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson Log64Weight operator()(TropicalWeight w) const { return w.Value(); } 592f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson}; 593f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 594f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <> 595f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonstruct WeightConvert<LogWeight, Log64Weight> { 596f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson Log64Weight operator()(LogWeight w) const { return w.Value(); } 597f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson}; 598f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 599f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson} // namespace fst 600f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 601f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#endif // FST_LIB_FLOAT_WEIGHT_H__ 602