21 #ifndef KALDI_FSTEXT_LATTICE_WEIGHT_H_ 22 #define KALDI_FSTEXT_LATTICE_WEIGHT_H_ 24 #include "fst/fstlib.h" 36 template<
class FloatType>
39 template <
class FloatType>
40 inline std::ostream &operator <<(std::ostream &strm, const LatticeWeightTpl<FloatType> &w);
42 template <
class FloatType>
46 template<
class FloatType>
78 std::numeric_limits<T>::infinity());
85 static const std::string &
Type() {
86 static const std::string type = (
sizeof(
T) == 4 ?
"lattice4" :
"lattice8") ;
92 std::numeric_limits<FloatType>::quiet_NaN());
100 if (
value1_ == -std::numeric_limits<T>::infinity() ||
101 value2_ == -std::numeric_limits<T>::infinity())
return false;
102 if (
value1_ == std::numeric_limits<T>::infinity() ||
103 value2_ == std::numeric_limits<T>::infinity()) {
104 if (
value1_ != std::numeric_limits<T>::infinity() ||
105 value2_ != std::numeric_limits<T>::infinity())
return false;
113 return LatticeWeightTpl(-std::numeric_limits<T>::infinity(), -std::numeric_limits<T>::infinity());
114 }
else if (
value1_ +
value2_ == std::numeric_limits<T>::infinity()) {
115 return LatticeWeightTpl(std::numeric_limits<T>::infinity(), std::numeric_limits<T>::infinity());
123 return kLeftSemiring | kRightSemiring | kCommutative |
129 std::istream &
Read(std::istream &strm) {
141 std::ostream &
Write(std::ostream &strm)
const {
163 if (f == std::numeric_limits<T>::infinity())
165 else if (f == -std::numeric_limits<T>::infinity())
177 if (s ==
"Infinity") {
178 f = std::numeric_limits<T>::infinity();
179 }
else if (s ==
"-Infinity") {
180 f = -std::numeric_limits<T>::infinity();
181 }
else if (s ==
"BadNumber") {
182 f = std::numeric_limits<T>::quiet_NaN();
185 f = strtod(s.c_str(), &p);
186 if (p < s.c_str() + s.size())
187 strm.clear(std::ios::badbit);
194 std::istream &strm,
char separator) {
198 }
while (isspace(c));
201 while (c != separator) {
203 strm.clear(std::ios::badbit);
209 std::istringstream strm1(s1);
231 template<
class FloatType,
class ScaleFloatType>
234 const std::vector<std::vector<ScaleFloatType> > &scale) {
236 if (w.
Value1() == std::numeric_limits<FloatType>::infinity())
247 template<
class FloatType,
class ScaleFloatType>
248 inline PairWeight<TropicalWeightTpl<FloatType>,
250 const PairWeight<TropicalWeightTpl<FloatType>,
251 TropicalWeightTpl<FloatType> > &w,
252 const std::vector<std::vector<ScaleFloatType> > &scale) {
253 typedef TropicalWeightTpl<FloatType> BaseType;
254 typedef PairWeight<BaseType, BaseType> PairType;
255 const BaseType zero = BaseType::Zero();
257 if (w.Value1() == zero || w.Value2() == zero)
258 return PairType(zero, zero);
259 FloatType f1 = w.Value1().Value(), f2 = w.Value2().Value();
260 return PairType(BaseType(scale[0][0] * f1 + scale[0][1] * f2),
261 BaseType(scale[1][0] * f1 + scale[1][1] * f2));
266 template<
class FloatType>
271 volatile FloatType va1 = wa.
Value1(), va2 = wa.
Value2(),
273 return (va1 == vb1 && va2 == vb2);
276 template<
class FloatType>
281 volatile FloatType va1 = wa.
Value1(), va2 = wa.
Value2(),
283 return (va1 != vb1 || va2 != vb2);
293 template<
class FloatType>
298 if (f1 < f2) {
return 1; }
300 else if (f1 > f2) {
return -1; }
310 template<
class FloatType>
313 return (
Compare(w1, w2) >= 0 ? w1 : w2);
318 template<
class FloatType>
361 template<
class FloatType>
369 template<
class FloatType>
372 DivideType typ = DIVIDE_ANY) {
375 if (a != a || b != b || a == -std::numeric_limits<T>::infinity()
376 || b == -std::numeric_limits<T>::infinity()) {
377 KALDI_WARN <<
"LatticeWeightTpl::Divide, NaN or invalid number produced. " 378 <<
"[dividing by zero?] Returning zero";
381 if (a == std::numeric_limits<T>::infinity() ||
382 b == std::numeric_limits<T>::infinity())
388 template<
class FloatType>
391 float delta = kDelta) {
396 template <
class FloatType>
397 inline std::ostream &operator <<(std::ostream &strm, const LatticeWeightTpl<FloatType> &w) {
399 CHECK(FLAGS_fst_weight_separator.size() == 1);
400 strm << FLAGS_fst_weight_separator[0];
406 template <
class FloatType>
408 CHECK(FLAGS_fst_weight_separator.size() == 1);
410 return w1.
ReadNoParen(strm, FLAGS_fst_weight_separator[0]);
422 template<
class WeightType,
class IntType>
425 typedef WeightType
W;
439 weight_(w), string_(s) { }
447 const W &
Weight()
const {
return weight_; }
449 const std::vector<IntType> &
String()
const {
return string_; }
453 void SetString(
const std::vector<IntType> &s) { string_ = s; }
457 WeightType::Zero(), std::vector<IntType>());
462 WeightType::One(), std::vector<IntType>());
467 buf[0] =
'0' +
sizeof(IntType);
471 static const std::string &
Type() {
472 static const std::string type =
"compact" + WeightType::Type()
473 + GetIntSizeString();
479 WeightType::NoWeight(), std::vector<IntType>());
484 size_t s = string_.size();
485 std::vector<IntType> v(s);
486 for(
size_t i = 0;
i < s;
i++)
487 v[
i] = string_[s-
i-1];
495 if (!weight_.Member())
return false;
496 if (weight_ == WeightType::Zero())
497 return string_.empty();
507 return kLeftSemiring | kRightSemiring | kPath | kIdempotent;
512 std::istream &
Read(std::istream &strm) {
514 if (strm.fail()){
return strm; }
517 if (strm.fail()){
return strm; }
519 KALDI_WARN <<
"Negative string size! Read failure";
520 strm.clear(std::ios::badbit);
525 ReadType(strm, &(string_[
i]));
532 std::ostream &
Write(std::ostream &strm)
const {
534 if (strm.fail()){
return strm; }
535 int32 sz =
static_cast<int32>(string_.size());
538 WriteType(strm, string_[
i]);
542 size_t ans = weight_.Hash();
544 size_t sz = string_.size(), mult = 6967;
545 for(
size_t i = 0;
i < sz;
i++) {
546 ans += string_[
i] * mult;
557 template<
class WeightType,
class IntType>
563 template<
class WeightType,
class IntType>
569 template<
class WeightType,
class IntType>
572 float delta = kDelta) {
590 template<
class WeightType,
class IntType>
594 if (c1 != 0)
return c1;
598 if (l1 > l2)
return -1;
599 else if (l1 < l2)
return 1;
600 for(
int i = 0;
i < l1;
i++) {
608 template<
class FloatType,
class IntType>
654 const TropicalWeight &w2) {
655 float f1 = w1.Value(), f2 = w2.Value();
656 if (f1 == f2)
return 0;
657 else if (f1 > f2)
return -1;
663 template<
class WeightType,
class IntType>
667 return (
Compare(w1, w2) >= 0 ? w1 : w2);
670 template<
class WeightType,
class IntType>
675 if (w == WeightType::Zero()) {
679 std::vector<IntType> v;
681 typename std::vector<IntType>::iterator iter = v.begin();
682 iter = std::copy(w1.
String().begin(), w1.
String().end(), iter);
683 std::copy(w2.
String().begin(), w2.
String().end(), iter);
688 template<
class WeightType,
class IntType>
691 DivideType div = DIVIDE_ANY) {
692 if (w1.
Weight() == WeightType::Zero()) {
693 if (w2.
Weight() != WeightType::Zero()) {
698 }
else if (w2.
Weight() == WeightType::Zero()) {
703 const std::vector<IntType> v1 = w1.
String(), v2 = w2.
String();
704 if (v2.size() > v1.size()) {
705 KALDI_ERR <<
"Cannot divide, length mismatch";
707 typename std::vector<IntType>::const_iterator v1b = v1.begin(),
708 v1e = v1.end(), v2b = v2.begin(), v2e = v2.end();
709 if (div == DIVIDE_LEFT) {
710 if (!std::equal(v2b, v2e, v1b)) {
711 KALDI_ERR <<
"Cannot divide, data mismatch";
714 w, std::vector<IntType>(v1b+(v2e-v2b), v1e));
715 }
else if (div == DIVIDE_RIGHT) {
716 if (!std::equal(v2b, v2e, v1e-(v2e-v2b))) {
717 KALDI_ERR <<
"Cannot divide, data mismatch";
720 w, std::vector<IntType>(v1b, v1e-(v2e-v2b)));
723 KALDI_ERR <<
"Cannot divide CompactLatticeWeightTpl with DIVIDE_ANY";
728 template <
class WeightType,
class IntType>
729 inline std::ostream &operator <<(std::ostream &strm, const CompactLatticeWeightTpl<WeightType, IntType> &w) {
731 CHECK(FLAGS_fst_weight_separator.size() == 1);
732 strm << FLAGS_fst_weight_separator[0];
733 for(
size_t i = 0;
i < w.String().size();
i++) {
734 strm << w.String()[
i];
735 if (
i+1 < w.String().size())
736 strm << kStringSeparator;
741 template <
class WeightType,
class IntType>
748 CHECK(FLAGS_fst_weight_separator.size() == 1);
749 size_t pos = s.find_last_of(FLAGS_fst_weight_separator);
750 if (pos == std::string::npos) {
751 strm.clear(std::ios::badbit);
755 std::string s1(s, 0, pos), s2(s, pos+1);
756 std::istringstream strm1(s1);
760 if (strm1.fail() || !strm1.eof()) {
761 strm.clear(std::ios::badbit);
765 std::vector<IntType> string;
766 const char *c = s2.c_str();
768 if (*c == kStringSeparator)
771 long int i = strtol(c, &c2, 10);
772 if (c2 == c || static_cast<long int>(static_cast<IntType>(i)) != i) {
773 strm.clear(std::ios::badbit);
777 string.push_back(static_cast<IntType>(i));
783 template<
class BaseWeightType,
class IntType>
788 Weight
operator()(
const Weight &w1,
const Weight &w2)
const {
790 typename std::vector<IntType>::const_iterator s1b = w1.
String().begin(),
792 while (s1b < s1e && s2b < s2e && *s1b == *s2b) {
807 template<
class Weight,
class IntType,
class ScaleFloatType>
810 const std::vector<std::vector<ScaleFloatType> > &scale) {
818 template<
class Float1,
class Float2>
826 template<
class Float1,
class Float2,
class Int>
831 w_in.Weight().Value2());
832 w_out->SetWeight(weight2);
833 w_out->SetString(w_in.String());
837 template<
class Float1,
class Float2>
840 TropicalWeightTpl<Float2> *w_out) {
841 TropicalWeightTpl<Float2> w1(w_in.
Value1());
842 TropicalWeightTpl<Float2> w2(w_in.
Value2());
843 *w_out =
Times(w1, w2);
846 template<
class Float>
848 return static_cast<double>(w.
Value1()) + static_cast<double>(w.
Value2());
851 template<
class Float,
class Int>
853 return static_cast<double>(w.Weight().Value1()) + static_cast<double>(w.Weight().Value2());
856 template<
class Float>
864 #endif // KALDI_FSTEXT_LATTICE_WEIGHT_H_ LatticeWeightTpl Quantize(float delta=kDelta) const
LatticeWeightTpl< FloatType > Divide(const LatticeWeightTpl< FloatType > &w1, const LatticeWeightTpl< FloatType > &w2, DivideType typ=DIVIDE_ANY)
bool operator()(const Weight &w1, const Weight &w2) const
static constexpr uint64 Properties()
static const LatticeWeightTpl NoWeight()
LatticeWeightTpl< FloatType > ScaleTupleWeight(const LatticeWeightTpl< FloatType > &w, const std::vector< std::vector< ScaleFloatType > > &scale)
bool operator!=(const LatticeWeightTpl< FloatType > &wa, const LatticeWeightTpl< FloatType > &wb)
LatticeWeightTpl< FloatType > Reverse() const
static const std::string & Type()
static const LatticeWeightTpl One()
static void WriteFloatType(std::ostream &strm, const T &f)
CompactLatticeWeightTpl< LatticeWeightTpl< double >, int32 > Weight
For an extended explanation of the framework of which grammar-fsts are a part, please see Support for...
std::istream & Read(std::istream &strm)
CompactLatticeWeightTpl(const WeightType &w, const std::vector< IntType > &s)
LatticeWeightTpl & operator=(const LatticeWeightTpl &w)
bool operator()(const Weight &w1, const Weight &w2) const
bool operator()(const Weight &w1, const Weight &w2) const
CompactLatticeWeightTpl< WeightType, IntType > ReverseWeight
LatticeWeightTpl< FloatType > Plus(const LatticeWeightTpl< FloatType > &w1, const LatticeWeightTpl< FloatType > &w2)
CompactLatticeWeightTpl< WeightType, IntType > Reverse() const
LatticeWeightTpl(const LatticeWeightTpl &other)
static std::string GetIntSizeString()
bool ApproxEqual(const LatticeWeightTpl< FloatType > &w1, const LatticeWeightTpl< FloatType > &w2, float delta=kDelta)
bool operator()(const Weight &w1, const Weight &w2) const
CompactLatticeWeightTpl< LatticeWeightTpl< float >, int32 > Weight
static void ReadFloatType(std::istream &strm, T &f)
Weight operator()(const Weight &w1, const Weight &w2) const
std::istream & Read(std::istream &strm)
LatticeWeightTpl ReverseWeight
std::ostream & Write(std::ostream &strm) const
LatticeWeightTpl< FloatType > Times(const LatticeWeightTpl< FloatType > &w1, const LatticeWeightTpl< FloatType > &w2)
CompactLatticeWeightTpl< LatticeWeightTpl< FloatType >, IntType > Weight
LatticeWeightTpl(T a, T b)
CompactLatticeWeightTpl< BaseWeightType, IntType > Weight
void ConvertLatticeWeight(const LatticeWeightTpl< Float1 > &w_in, LatticeWeightTpl< Float2 > *w_out)
Define some ConvertLatticeWeight functions that are used in various lattice conversions...
static const CompactLatticeWeightTpl< WeightType, IntType > One()
std::istream & operator>>(std::istream &strm, LatticeWeightTpl< FloatType > &w)
std::ostream & Write(std::ostream &strm) const
double ConvertToCost(const LatticeWeightTpl< Float > &w)
static const LatticeWeightTpl Zero()
LatticeWeightTpl< FloatType > Weight
std::vector< IntType > string_
bool operator()(const Weight &w1, const Weight &w2) const
fst::StdArc::Weight Weight
int Compare(const LatticeWeightTpl< FloatType > &w1, const LatticeWeightTpl< FloatType > &w2)
Compare returns -1 if w1 < w2, +1 if w1 > w2, and 0 if w1 == w2.
LatticeWeightTpl< float > Weight
static const CompactLatticeWeightTpl< WeightType, IntType > Zero()
static constexpr uint64 Properties()
bool operator==(const LatticeWeightTpl< FloatType > &wa, const LatticeWeightTpl< FloatType > &wb)
CompactLatticeWeightTpl Quantize(float delta=kDelta) const
static const std::string & Type()
std::istream & ReadNoParen(std::istream &strm, char separator)
static const CompactLatticeWeightTpl< WeightType, IntType > NoWeight()
CompactLatticeWeightTpl & operator=(const CompactLatticeWeightTpl< WeightType, IntType > &w)
LatticeWeightTpl< double > Weight
bool operator()(const Weight &w1, const Weight &w2) const
const std::vector< IntType > & String() const
void SetString(const std::vector< IntType > &s)
CompactLatticeWeightTpl()
void SetWeight(const W &w)
friend std::istream & operator>>(std::istream &, LatticeWeightTpl< FloatType > &)