summaryrefslogtreecommitdiff
path: root/kaldi_io/src/tools/openfst/include/fst/pair-weight.h
diff options
context:
space:
mode:
Diffstat (limited to 'kaldi_io/src/tools/openfst/include/fst/pair-weight.h')
-rw-r--r--kaldi_io/src/tools/openfst/include/fst/pair-weight.h280
1 files changed, 280 insertions, 0 deletions
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 <climits>
+#include <stack>
+#include <string>
+
+#include <fst/weight.h>
+
+
+DECLARE_string(fst_weight_parentheses);
+DECLARE_string(fst_weight_separator);
+
+namespace fst {
+
+template<class W1, class W2> class PairWeight;
+template <class W1, class W2>
+istream &operator>>(istream &strm, PairWeight<W1, W2> &w);
+
+template<class W1, class W2>
+class PairWeight {
+ public:
+ friend istream &operator>><W1, W2>(istream&, PairWeight<W1, W2>&);
+
+ typedef PairWeight<typename W1::ReverseWeight,
+ typename W2::ReverseWeight>
+ ReverseWeight;
+
+ PairWeight() {}
+
+ PairWeight(const PairWeight& w) : value1_(w.value1_), value2_(w.value2_) {}
+
+ PairWeight(W1 w1, W2 w2) : value1_(w1), value2_(w2) {}
+
+ static const PairWeight<W1, W2> &Zero() {
+ static const PairWeight<W1, W2> zero(W1::Zero(), W2::Zero());
+ return zero;
+ }
+
+ static const PairWeight<W1, W2> &One() {
+ static const PairWeight<W1, W2> one(W1::One(), W2::One());
+ return one;
+ }
+
+ static const PairWeight<W1, W2> &NoWeight() {
+ static const PairWeight<W1, W2> 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<W1, W2> &operator=(const PairWeight<W1, W2> &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<W1, W2> Quantize(float delta = kDelta) const {
+ return PairWeight<W1, W2>(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<W1, W2>& 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>(w1, w2);
+ return strm;
+ }
+
+ // Reads PairWeight when there are parentheses around pair terms
+ inline static istream &ReadWithParen(
+ istream &strm, PairWeight<W1, W2>& 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<int> 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>(w1, w2);
+ return strm;
+ }
+
+ private:
+ W1 value1_;
+ W2 value2_;
+
+};
+
+template <class W1, class W2>
+inline bool operator==(const PairWeight<W1, W2> &w,
+ const PairWeight<W1, W2> &v) {
+ return w.Value1() == v.Value1() && w.Value2() == v.Value2();
+}
+
+template <class W1, class W2>
+inline bool operator!=(const PairWeight<W1, W2> &w1,
+ const PairWeight<W1, W2> &w2) {
+ return w1.Value1() != w2.Value1() || w1.Value2() != w2.Value2();
+}
+
+
+template <class W1, class W2>
+inline bool ApproxEqual(const PairWeight<W1, W2> &w1,
+ const PairWeight<W1, W2> &w2,
+ float delta = kDelta) {
+ return ApproxEqual(w1.Value1(), w2.Value1(), delta) &&
+ ApproxEqual(w1.Value2(), w2.Value2(), delta);
+}
+
+template <class W1, class W2>
+inline ostream &operator<<(ostream &strm, const PairWeight<W1, W2> &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 <class W1, class W2>
+inline istream &operator>>(istream &strm, PairWeight<W1, W2> &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<W1, W2>::ReadWithParen(
+ strm, w, separator, FLAGS_fst_weight_parentheses[0],
+ FLAGS_fst_weight_parentheses[1]);
+ } else {
+ return PairWeight<W1, W2>::ReadNoParen(strm, w, separator);
+ }
+}
+
+} // namespace fst
+
+#endif // FST_LIB_PAIR_WEIGHT_H_