WordAlignedLatticeTester Class Reference
Collaboration diagram for WordAlignedLatticeTester:

Public Member Functions

 WordAlignedLatticeTester (const CompactLattice &lat, const TransitionModel &tmodel, const WordBoundaryInfo &info, const CompactLattice &aligned_lat)
 
void Test ()
 

Private Member Functions

void TestArc (const CompactLatticeArc &arc)
 
bool TestArcEmpty (const CompactLatticeArc &arc)
 
bool TestArcSilence (const CompactLatticeArc &arc)
 
bool TestArcOnePhoneWord (const CompactLatticeArc &arc)
 
bool TestArcNormalWord (const CompactLatticeArc &arc)
 
bool TestArcPartialWord (const CompactLatticeArc &arc)
 
void TestFinal (const CompactLatticeWeight &w)
 
void TestEquivalent ()
 

Private Attributes

const CompactLatticelat_
 
const TransitionModeltmodel_
 
const WordBoundaryInfoinfo_
 
const CompactLatticealigned_lat_
 

Detailed Description

Definition at line 734 of file word-align-lattice.cc.

Constructor & Destructor Documentation

◆ WordAlignedLatticeTester()

WordAlignedLatticeTester ( const CompactLattice lat,
const TransitionModel tmodel,
const WordBoundaryInfo info,
const CompactLattice aligned_lat 
)
inline

Definition at line 736 of file word-align-lattice.cc.

739  :
740  lat_(lat), tmodel_(tmodel), info_(info), aligned_lat_(aligned_lat) { }
const WordBoundaryInfo & info_
const CompactLattice & aligned_lat_

Member Function Documentation

◆ Test()

void Test ( )
inline

Definition at line 742 of file word-align-lattice.cc.

References CompactLatticeWeightTpl< WeightType, IntType >::Zero().

Referenced by kaldi::TestWordAlignedLattice().

742  {
743  // First test that each aligned arc is valid.
745  for (StateId s = 0; s < aligned_lat_.NumStates(); s++) {
746  for (fst::ArcIterator<CompactLattice> iter(aligned_lat_, s);
747  !iter.Done();
748  iter.Next()) {
749  TestArc(iter.Value());
750  }
751  if (aligned_lat_.Final(s) != CompactLatticeWeight::Zero()) {
752  TestFinal(aligned_lat_.Final(s));
753  }
754  }
755  TestEquivalent();
756  }
fst::StdArc::StateId StateId
Lattice::StateId StateId
void TestArc(const CompactLatticeArc &arc)
void TestFinal(const CompactLatticeWeight &w)
const CompactLattice & aligned_lat_
static const CompactLatticeWeightTpl< WeightType, IntType > Zero()

◆ TestArc()

void TestArc ( const CompactLatticeArc arc)
inlineprivate

Definition at line 758 of file word-align-lattice.cc.

References KALDI_ERR.

758  {
759  if (! (TestArcSilence(arc) || TestArcNormalWord(arc) || TestArcOnePhoneWord(arc)
760  || TestArcEmpty(arc)))
761  KALDI_ERR << "Invalid arc in aligned CompactLattice: "
762  << arc.ilabel << " " << arc.olabel << " " << arc.nextstate
763  << " " << arc.weight;
764  }
bool TestArcNormalWord(const CompactLatticeArc &arc)
bool TestArcOnePhoneWord(const CompactLatticeArc &arc)
bool TestArcEmpty(const CompactLatticeArc &arc)
bool TestArcSilence(const CompactLatticeArc &arc)
#define KALDI_ERR
Definition: kaldi-error.h:147

◆ TestArcEmpty()

bool TestArcEmpty ( const CompactLatticeArc arc)
inlineprivate

Definition at line 765 of file word-align-lattice.cc.

765  {
766  if (arc.ilabel != 0) return false; // Check there is no label. Note, ilabel==olabel.
767  const std::vector<int32> &tids = arc.weight.String();
768  return tids.empty();
769  }

◆ TestArcNormalWord()

bool TestArcNormalWord ( const CompactLatticeArc arc)
inlineprivate

Definition at line 828 of file word-align-lattice.cc.

References rnnlm::i, LatticeWordAligner::info_, TransitionModel::IsFinal(), TransitionModel::IsSelfLoop(), rnnlm::j, WordBoundaryInfo::kWordBeginPhone, WordBoundaryInfo::kWordEndPhone, WordBoundaryInfo::kWordInternalPhone, WordBoundaryInfo::reorder, LatticeWordAligner::tmodel_, TransitionModel::TransitionIdToPhone(), TransitionModel::TransitionIdToTransitionState(), and WordBoundaryInfo::TypeOfPhone().

828  {
829  if (arc.ilabel == 0) return false; // Check there's a label. Note, ilabel==olabel.
830  const std::vector<int32> &tids = arc.weight.String();
831  if (tids.empty()) return false;
832  int32 first_phone = tmodel_.TransitionIdToPhone(tids.front());
834  return false;
835  size_t i;
836  { // first phone.
837  int num_final = 0;
838  for (i = 0; i < tids.size(); i++) {
839  if (tmodel_.TransitionIdToPhone(tids[i]) != first_phone) break;
840  if (tmodel_.IsFinal(tids[i])) num_final++;
841  }
842  if (num_final != 1)
843  return false; // Something went wrong-- perhaps we
844  // got two beginning phones in a row.
845  }
846  { // middle phones. Skip over them.
847  while (i < tids.size() &&
850  i++;
851  }
852  if (i == tids.size()) return false;
853  int32 final_phone = tmodel_.TransitionIdToPhone(tids[i]);
855  return false; // not word-ending.
856  for (size_t j = i; j < tids.size(); j++) // make sure only this final phone till end.
857  if (tmodel_.TransitionIdToPhone(tids[j]) != final_phone)
858  return false; // Other phones after final phone.
859 
860  for (size_t j = i; j < tids.size(); j++) {
861  if (tmodel_.IsFinal(tids[j])) { // Found "final transition".. Note:
862  // may be "reordered" with its self loops.
863  if (!info_.reorder) return (j+1 == tids.size());
864  else {
865  // Make sure the only thing that follows this is self-loops
866  // of the final transition-state.
867  for (size_t k = j + 1; k < tids.size(); k++)
870  || !tmodel_.IsSelfLoop(tids[k]))
871  return false;
872  return true;
873  }
874  }
875  }
876  return false; // Found no final state.
877  }
const WordBoundaryInfo & info_
kaldi::int32 int32
PhoneType TypeOfPhone(int32 p) const
bool IsSelfLoop(int32 trans_id) const
int32 TransitionIdToTransitionState(int32 trans_id) const
bool IsFinal(int32 trans_id) const
int32 TransitionIdToPhone(int32 trans_id) const

◆ TestArcOnePhoneWord()

bool TestArcOnePhoneWord ( const CompactLatticeArc arc)
inlineprivate

Definition at line 800 of file word-align-lattice.cc.

References rnnlm::i, LatticeWordAligner::info_, TransitionModel::IsFinal(), rnnlm::j, WordBoundaryInfo::kWordBeginAndEndPhone, WordBoundaryInfo::reorder, LatticeWordAligner::tmodel_, TransitionModel::TransitionIdToPhone(), TransitionModel::TransitionIdToTransitionState(), and WordBoundaryInfo::TypeOfPhone().

800  {
801  if (arc.ilabel == 0) return false; // Check there's a label. Note, ilabel==olabel.
802  const std::vector<int32> &tids = arc.weight.String();
803  if (tids.empty()) return false;
804  int32 first_phone = tmodel_.TransitionIdToPhone(tids.front());
805  if (info_.TypeOfPhone(first_phone) !=
807  for (size_t i = 0; i < tids.size(); i++)
808  if (tmodel_.TransitionIdToPhone(tids[i]) != first_phone) return false;
809 
810  if (!info_.reorder) return tmodel_.IsFinal(tids.back());
811  else {
812  for (size_t i = 0; i < tids.size(); i++) {
813  if (tmodel_.IsFinal(tids[i])) { // got the "final" transition, which is
814  // reordered to actually not be final. Make sure that all the
815  // rest of the transition ids are the self-loop of that same
816  // transition-state.
817  for (size_t j = i+1; j < tids.size(); j++) {
819  != tmodel_.TransitionIdToTransitionState(tids[i])) return false;
820  }
821  return true;
822  }
823  }
824  return false; // fell off loop. No final-state present.
825  }
826  }
const WordBoundaryInfo & info_
kaldi::int32 int32
PhoneType TypeOfPhone(int32 p) const
int32 TransitionIdToTransitionState(int32 trans_id) const
bool IsFinal(int32 trans_id) const
int32 TransitionIdToPhone(int32 trans_id) const

◆ TestArcPartialWord()

bool TestArcPartialWord ( const CompactLatticeArc arc)
inlineprivate

Definition at line 879 of file word-align-lattice.cc.

References LatticeWordAligner::info_, and WordBoundaryInfo::partial_word_label.

879  {
880  if (arc.ilabel != info_.partial_word_label) return false; // label should
881  // be the partial-word label.
882  const std::vector<int32> &tids = arc.weight.String();
883  if (tids.empty()) return false;
884  return true; // We're pretty liberal when it comes to partial words here.
885  }
const WordBoundaryInfo & info_

◆ TestArcSilence()

bool TestArcSilence ( const CompactLatticeArc arc)
inlineprivate

Definition at line 770 of file word-align-lattice.cc.

References rnnlm::i, LatticeWordAligner::info_, TransitionModel::IsFinal(), rnnlm::j, WordBoundaryInfo::kNonWordPhone, WordBoundaryInfo::reorder, WordBoundaryInfo::silence_label, LatticeWordAligner::tmodel_, TransitionModel::TransitionIdToPhone(), TransitionModel::TransitionIdToTransitionState(), and WordBoundaryInfo::TypeOfPhone().

770  {
771  // This only applies when silence doesn't have word labels.
772  if (arc.ilabel != info_.silence_label) return false; // Check the label is
773  // the silence label. Note, ilabel==olabel.
774  const std::vector<int32> &tids = arc.weight.String();
775  if (tids.empty()) return false;
776  int32 first_phone = tmodel_.TransitionIdToPhone(tids.front());
778  return false;
779  for (size_t i = 0; i < tids.size(); i++)
780  if (tmodel_.TransitionIdToPhone(tids[i]) != first_phone) return false;
781 
782  if (!info_.reorder) return tmodel_.IsFinal(tids.back());
783  else {
784  for (size_t i = 0; i < tids.size(); i++) {
785  if (tmodel_.IsFinal(tids[i])) { // got the "final" transition, which is
786  // reordered to actually not be final. Make sure that all the
787  // rest of the transition ids are the self-loop of that same
788  // transition-state.
789  for (size_t j = i+1; j < tids.size(); j++) {
791  == tmodel_.TransitionIdToTransitionState(tids[i]))) return false;
792  }
793  return true;
794  }
795  }
796  return false; // fell off loop. No final-state present.
797  }
798  }
const WordBoundaryInfo & info_
kaldi::int32 int32
PhoneType TypeOfPhone(int32 p) const
int32 TransitionIdToTransitionState(int32 trans_id) const
bool IsFinal(int32 trans_id) const
int32 TransitionIdToPhone(int32 trans_id) const

◆ TestEquivalent()

void TestEquivalent ( )
inlineprivate

Definition at line 891 of file word-align-lattice.cc.

References LatticeWordAligner::info_, KALDI_ERR, LatticeWordAligner::lat_, kaldi::Rand(), fst::RemoveSomeInputSymbols(), and WordBoundaryInfo::silence_label.

891  {
892  CompactLattice aligned_lat(aligned_lat_);
893  if (info_.silence_label != 0) { // remove silence labels.
894  std::vector<int32> to_remove;
895  to_remove.push_back(info_.silence_label);
896  RemoveSomeInputSymbols(to_remove, &aligned_lat);
897  Project(&aligned_lat, fst::PROJECT_INPUT);
898  }
899 
900  if (!RandEquivalent(lat_, aligned_lat, 5/*paths*/, 1.0e+10/*delta*/, Rand()/*seed*/,
901  200/*path length (max?)*/))
902  KALDI_ERR << "Equivalence test failed (testing word-alignment of lattices.) "
903  << "Make sure your model and lattices match!";
904  }
const WordBoundaryInfo & info_
const CompactLattice & aligned_lat_
#define KALDI_ERR
Definition: kaldi-error.h:147
int Rand(struct RandomState *state)
Definition: kaldi-math.cc:45
fst::VectorFst< CompactLatticeArc > CompactLattice
Definition: kaldi-lattice.h:46
void RemoveSomeInputSymbols(const std::vector< I > &to_remove, MutableFst< Arc > *fst)
RemoveSomeInputSymbols removes any symbol that appears in "to_remove", from the input side of the FST...

◆ TestFinal()

void TestFinal ( const CompactLatticeWeight w)
inlineprivate

Definition at line 887 of file word-align-lattice.cc.

References KALDI_ERR, and CompactLatticeWeightTpl< WeightType, IntType >::String().

887  {
888  if (!w.String().empty())
889  KALDI_ERR << "Expect to have no strings on final-weights of lattices.";
890  }
#define KALDI_ERR
Definition: kaldi-error.h:147

Member Data Documentation

◆ aligned_lat_

const CompactLattice& aligned_lat_
private

Definition at line 909 of file word-align-lattice.cc.

◆ info_

const WordBoundaryInfo& info_
private

Definition at line 908 of file word-align-lattice.cc.

◆ lat_

const CompactLattice& lat_
private

Definition at line 906 of file word-align-lattice.cc.

◆ tmodel_

const TransitionModel& tmodel_
private

Definition at line 907 of file word-align-lattice.cc.


The documentation for this class was generated from the following file: