From 96a32415ab43377cf1575bd3f4f2980f58028209 Mon Sep 17 00:00:00 2001 From: Determinant Date: Fri, 14 Aug 2015 11:51:42 +0800 Subject: add implementation for kaldi io (by ymz) --- .../src/tools/openfst/include/fst/pair-weight.h | 280 +++++++++++++++++++++ 1 file changed, 280 insertions(+) create mode 100644 kaldi_io/src/tools/openfst/include/fst/pair-weight.h (limited to 'kaldi_io/src/tools/openfst/include/fst/pair-weight.h') diff --git a/kaldi_io/src/tools/openfst/include/fst/pair-weight.h b/kaldi_io/src/tools/openfst/include/fst/pair-weight.h new file mode 100644 index 0000000..7d8aa11 --- /dev/null +++ b/kaldi_io/src/tools/openfst/include/fst/pair-weight.h @@ -0,0 +1,280 @@ +// pair-weight.h + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Copyright 2005-2010 Google, Inc. +// Author: shumash@google.com (Masha Maria Shugrina) +// +// \file +// Pair weight templated base class for weight classes that +// contain two weights (e.g. Product, Lexicographic) + +#ifndef FST_LIB_PAIR_WEIGHT_H_ +#define FST_LIB_PAIR_WEIGHT_H_ + +#include +#include +#include + +#include + + +DECLARE_string(fst_weight_parentheses); +DECLARE_string(fst_weight_separator); + +namespace fst { + +template class PairWeight; +template +istream &operator>>(istream &strm, PairWeight &w); + +template +class PairWeight { + public: + friend istream &operator>>(istream&, PairWeight&); + + typedef PairWeight + ReverseWeight; + + PairWeight() {} + + PairWeight(const PairWeight& w) : value1_(w.value1_), value2_(w.value2_) {} + + PairWeight(W1 w1, W2 w2) : value1_(w1), value2_(w2) {} + + static const PairWeight &Zero() { + static const PairWeight zero(W1::Zero(), W2::Zero()); + return zero; + } + + static const PairWeight &One() { + static const PairWeight one(W1::One(), W2::One()); + return one; + } + + static const PairWeight &NoWeight() { + static const PairWeight no_weight(W1::NoWeight(), W2::NoWeight()); + return no_weight; + } + + istream &Read(istream &strm) { + value1_.Read(strm); + return value2_.Read(strm); + } + + ostream &Write(ostream &strm) const { + value1_.Write(strm); + return value2_.Write(strm); + } + + PairWeight &operator=(const PairWeight &w) { + value1_ = w.Value1(); + value2_ = w.Value2(); + return *this; + } + + bool Member() const { return value1_.Member() && value2_.Member(); } + + size_t Hash() const { + size_t h1 = value1_.Hash(); + size_t h2 = value2_.Hash(); + const int lshift = 5; + const int rshift = CHAR_BIT * sizeof(size_t) - 5; + return h1 << lshift ^ h1 >> rshift ^ h2; + } + + PairWeight Quantize(float delta = kDelta) const { + return PairWeight(value1_.Quantize(delta), + value2_.Quantize(delta)); + } + + ReverseWeight Reverse() const { + return ReverseWeight(value1_.Reverse(), value2_.Reverse()); + } + + const W1& Value1() const { return value1_; } + + const W2& Value2() const { return value2_; } + + protected: + void SetValue1(const W1 &w) { value1_ = w; } + void SetValue2(const W2 &w) { value2_ = w; } + + // Reads PairWeight when there are not parentheses around pair terms + inline static istream &ReadNoParen( + istream &strm, PairWeight& w, char separator) { + int c; + do { + c = strm.get(); + } while (isspace(c)); + + string s1; + while (c != separator) { + if (c == EOF) { + strm.clear(std::ios::badbit); + return strm; + } + s1 += c; + c = strm.get(); + } + istringstream strm1(s1); + W1 w1 = W1::Zero(); + strm1 >> w1; + + // read second element + W2 w2 = W2::Zero(); + strm >> w2; + + w = PairWeight(w1, w2); + return strm; + } + + // Reads PairWeight when there are parentheses around pair terms + inline static istream &ReadWithParen( + istream &strm, PairWeight& w, + char separator, char open_paren, char close_paren) { + int c; + do { + c = strm.get(); + } while (isspace(c)); + if (c != open_paren) { + FSTERROR() << " is fst_weight_parentheses flag set correcty? "; + strm.clear(std::ios::failbit); + return strm; + } + c = strm.get(); + + // read first element + stack parens; + string s1; + while (c != separator || !parens.empty()) { + if (c == EOF) { + strm.clear(std::ios::badbit); + return strm; + } + s1 += c; + // if parens encountered before separator, they must be matched + if (c == open_paren) { + parens.push(1); + } else if (c == close_paren) { + // Fail for mismatched parens + if (parens.empty()) { + strm.clear(std::ios::failbit); + return strm; + } + parens.pop(); + } + c = strm.get(); + } + istringstream strm1(s1); + W1 w1 = W1::Zero(); + strm1 >> w1; + + // read second element + string s2; + c = strm.get(); + while (c != EOF) { + s2 += c; + c = strm.get(); + } + if (s2.empty() || (s2[s2.size() - 1] != close_paren)) { + FSTERROR() << " is fst_weight_parentheses flag set correcty? "; + strm.clear(std::ios::failbit); + return strm; + } + + s2.erase(s2.size() - 1, 1); + istringstream strm2(s2); + W2 w2 = W2::Zero(); + strm2 >> w2; + + w = PairWeight(w1, w2); + return strm; + } + + private: + W1 value1_; + W2 value2_; + +}; + +template +inline bool operator==(const PairWeight &w, + const PairWeight &v) { + return w.Value1() == v.Value1() && w.Value2() == v.Value2(); +} + +template +inline bool operator!=(const PairWeight &w1, + const PairWeight &w2) { + return w1.Value1() != w2.Value1() || w1.Value2() != w2.Value2(); +} + + +template +inline bool ApproxEqual(const PairWeight &w1, + const PairWeight &w2, + float delta = kDelta) { + return ApproxEqual(w1.Value1(), w2.Value1(), delta) && + ApproxEqual(w1.Value2(), w2.Value2(), delta); +} + +template +inline ostream &operator<<(ostream &strm, const PairWeight &w) { + if(FLAGS_fst_weight_separator.size() != 1) { + FSTERROR() << "FLAGS_fst_weight_separator.size() is not equal to 1"; + strm.clear(std::ios::badbit); + return strm; + } + char separator = FLAGS_fst_weight_separator[0]; + if (FLAGS_fst_weight_parentheses.empty()) + return strm << w.Value1() << separator << w.Value2(); + + if (FLAGS_fst_weight_parentheses.size() != 2) { + FSTERROR() << "FLAGS_fst_weight_parentheses.size() is not equal to 2"; + strm.clear(std::ios::badbit); + return strm; + } + char open_paren = FLAGS_fst_weight_parentheses[0]; + char close_paren = FLAGS_fst_weight_parentheses[1]; + return strm << open_paren << w.Value1() << separator + << w.Value2() << close_paren ; +} + +template +inline istream &operator>>(istream &strm, PairWeight &w) { + if(FLAGS_fst_weight_separator.size() != 1) { + FSTERROR() << "FLAGS_fst_weight_separator.size() is not equal to 1"; + strm.clear(std::ios::badbit); + return strm; + } + char separator = FLAGS_fst_weight_separator[0]; + bool read_parens = !FLAGS_fst_weight_parentheses.empty(); + if (read_parens) { + if (FLAGS_fst_weight_parentheses.size() != 2) { + FSTERROR() << "FLAGS_fst_weight_parentheses.size() is not equal to 2"; + strm.clear(std::ios::badbit); + return strm; + } + return PairWeight::ReadWithParen( + strm, w, separator, FLAGS_fst_weight_parentheses[0], + FLAGS_fst_weight_parentheses[1]); + } else { + return PairWeight::ReadNoParen(strm, w, separator); + } +} + +} // namespace fst + +#endif // FST_LIB_PAIR_WEIGHT_H_ -- cgit v1.2.3-70-g09d2