name: HierarchicalSearch
synopsis:

>     g++ [flags ...] file ... -l /isip/tools/lib/$ISIP_BINARY/lib_search.a

>     #include <HierarchicalSearch.h>

>     HierarchicalSearch();
>     HierarchicalSearch(const HierarchicalSearch& copy_search);
>     boolean setNumLevels(long num_levels);
>     SearchLevel& getSearchLevel(long level)
>     boolean decode(FrontEnd& fe, long num_frames = DEF_NUM_FRAMES);
>     boolean getHypotheses(String& output_hyp, float& total_score,
>                           long& num_frames, long level = 0,
>                           boolean detailed = false,
>                           boolean cumulative = false);

quick start:

>     // configure FrontEnd
>     //
>     FrontEnd fe;

>     Sof front_end_sof;
>     front_end_sof.open(L"front_end.sof");
>     fe.read(front_end_sof, front_end_sof.first(fe.name()));
>     front_end_sof.close();

>     // configure HierarchicalSearch
>     //
>     HierarchicalSearch search_engine;
>     long num_levels = 3;
>     search_engine.setNumLevels(num_levels);

>     // read models
>     //
>     Sof model_sof;
>     model_sof.open(L"models.sof");

>     for (long curr_level = 0; curr_level < num_levels; curr_level++) {
>       SearchLevel& level = search_engine.getSearchLevel(curr_level);
>       level.load(model_sof);
>     }
>     model_sof.close();

>     // process the sentence
>     //
>     Filename speech_file(L"speech_file.raw");
>     fe.open(speech_file);
>     search_engine.decode(fe);
>     fe.close();

>     // get the best hypothesis
>     //
>     String best_hypothesis;
>     float score = 0;
>     long num_frames = 0;
>     search_engine.getHypotheses(best_hypothesis, score, num_frames);

description:
HierarchicalSearch class implements a hierarchical, synchronous, Viterbi search engine.
The basic premise behind this is as follows:

- The search space is hierarchical in that each level has nodes and each node is either:
  - composed of a sub-graph + probability evaluation
  - composed of probability evaluation.
- At each level you will be able to do the following:
  - beam prune
  - instance prune
  - generate context-dependent scoring models on the fly including cross-symbol models
  - specify whether search information is to be maintained - otherwise we can prune away redundant information. For instance, once a word is completed, it is no longer necessary to maintain the sub-word units that correspond to that word.
  - turn on/off sub-level evaluation
- Each graph position will be capable of the following:
  - generate a probability of being in that graph position given the input stream. For acoustic models, this will involve direct evaluation of the data stream. For levels like language models, this will not involve manipulation of the data stream at all. Any level can access the data stream as it will be passed from the highest level all the way down to the lowest via pointer reference.
  - store the overlapping paths in the sub-graph as a "lexical" tree.
  - use N-symbol models related to the possible entries on that level
- We will revolve around the concept of a "trace" where the trace moves through the graph and keeps track of the paths/scores through the search space

dependencies:

- FrontEnd
- VectorFloat
- Instance
- Trace
- SearchLevel
- SearchNode

public constants:

- define the class name:

      static const String CLASS_NAME = L"HierarchicalSearch";

- define i/o related constants:

      static const String HierarchicalSearch::DEF_PARAM = L"search";

- define the search mode choices:

      enum SMODE { DECODE = 0, TRAIN, DEF_SMODE = DECODE};

- default values and arguments:

      static const llong DEF_START_FRAME = -1;

      static const long DEF_CONTEXT_LEVEL = 0;

      static const boolean DEF_CONTEXT_MODE = false;

      static const long DEF_NUM_LEVELS = 1;

      static const long DEF_CAPACITY = 12000;

      static const long DEF_NUM_FRAMES = -1;

      static const long DEF_INITIAL_LEVEL = 0;

      static const long ALL_LEVELS = -1;

error codes:

- error code indicating a general error:

      static const long ERR = 90700;

      static const long ERR = 90701;

protected data:

- define a search mode flag:

      SEARCH_MODE search_mode_d;

- current frame's feature vector:

      VectorFloat features_d;

- Hierarchicaldigraph, sub-graphs are maintained at each SearchLevel:

      HierarchicalDigraph* h_digraph_d;

- initial search level:

      Long initial_level_d;

- current frame in the search:

      Long current_frame_d;

- the lexical tree list:

      SingleLinkedList<LexicalTree> lex_tree_list_d;

- current maximal trace scores:

      Vector<Float> max_trace_scores_d;

- current maximal instance scores:

      Vector<Float> max_instance_scores_d;

- symbol graph generation structure

      SymbolGraph symbol_graph_d;

- n-symbol probability lookup variables

      NGramCache nsymbol_cache_d;

      Vector<Long> nsymbol_indices_d;

- lists to keep track of instances during the search:

      Vector<DoubleLinkedList<Instance> > instance_lists_d;

      DoubleLinkedList<Instance> instance_valid_hyps_d;

- lists to keep track of traces during the search:

      Vector<DoubleLinkedList<Trace> > trace_lists_d;

      DoubleLinkedList<Trace> trace_valid_hyps_d;

- define a bi-graph structure that stores the entire search path:

      BiGraph<TrainNode> trellis_d;

- define a mapping from the hypothesis path to the vertices:

      HashTable<HashKey<Trace>, BiGraphVertex<TrainNode> > trace_mapping_d;

      HashTable<HashKey<Instance>, BiGraphVertex<TrainNode> > instance_mapping_d;

- context generation level:

      Long context_level_d;

      boolean context_generation_mode_d;

- context generation list:

      Vector<String> context_list_d;

      HashTable<String, Ulong> context_hash_d;

- declare the debugging parameters:

      static Integral::DEBUG debug_level_d;

- declare the memory manager:

      static MemoryManager mgr_d;

required public methods:

- static methods:

      static const String& name();

      static boolean diagnose(Integral::DEBUG debug_level);

- debug methods:

      boolean debug(const unichar* message) const;

      static boolean setDebug(Integral::DEBUG debug_level;

- destructor/constructor(s):

      ~HierarchicalSearch();

      HierarchicalSearch();

      HierarchicalSearch(const HierarchicalSearch& arg);

- assign methods:

      boolean assign(const HierarchicalSearch& arg);

- i/o methods:

      long sofSize() const;

      boolean read(Sof& sof, long tag, const String& name = CLASS_NAME);

      boolean write(Sof& sof, long tag, const String& name = CLASS_NAME) const;

      boolean readData(Sof& sof, const String& pname = DEF_PARAM, long size = SofParser::FULL_OBJECT, boolean param = true, boolean nested = false);

      boolean writeData(Sof& sof, const String& pname = DEF_PARAM) const;

- equality methods:

      boolean eq(const HierarchicalSearch& arg) const;

- memory management methods:

      static void* operator new(size_t size);

      static void* operator new[](size_t size);

      static void operator delete(void* ptr);

      static void operator delete[](void* ptr);

      static boolean setGrowSize(long grow_size);

      boolean clear(Integral::CMODE ctype = Integral::DEF_CMODE);

class-specific public methods:

- declare search node methods:

      boolean setSearchMode(SEARCH_MODE arg);

      SEARCH_MODE getSearchMode();

- declare initial level methods:

      boolean setInitialLevel(long init_level);

      long getInitialLevel() const;

- declare number of levels methods:

      boolean setNumLevels(long num_levels);

      long getNumLevels() const;

- declare context methods:

      long getContextLevel();

      boolean setContextLevel(long arg);

      Vector<String>& getContextList();

      boolean setContextList(Vector<String>& arg);

      boolean setFeatures(Vector<VectorFloat>& features);

- declare search level methods:

      SearchLevel& getSearchLevel(long level);

      HierarchicalDigraph& getHDigraph();

      boolean setHDigraph(HierarchicalDigraph& h_digraph);

      ContextPool& getContextPool();

      boolean setContextPool(ContextPool& arg);

      HistoryPool& getHistoryPool();

      boolean setHistoryPool(HistoryPool& arg);

- declare decoding methods:

      boolean initializeLinearDecoder();

      boolean initializeLinearPartial();

      boolean initializeGrammarDecoder();

      boolean initializeGrammarPartial();

      boolean initializeNetworkDecoder();

      boolean linearDecoder(FrontEnd& fe, long num_frames = DEF_NUM_FRAMES);

      boolean linearDecoder(Vector<VectorFloat>& fe, long num_frames = DEF_NUM_FRAMES);

      boolean grammarDecoder(FrontEnd& fe, long num_frames = DEF_NUM_FRAMES);

      boolean grammarDecoder(Vector<VectorFloat>& fe, long num_frames = DEF_NUM_FRAMES);

      boolean networkDecoder(FrontEnd& fe, long num_frames = DEF_NUM_FRAMES);

      boolean networkDecoder(Vector<VectorFloat>& fe, long num_frames = DEF_NUM_FRAMES);

- declare hypothesis methods:

      boolean getHypotheses(String& output_hyp, long level_a, double& total_score, long& num_frames, DoubleLinkedList<Trace>& trace_path);

      boolean getHypotheses(String& output_hyp, long level_a, double& total_score, long& num_frames, DoubleLinkedList<Instance>& trace_path);

      boolean getLexHypotheses(String& output_hyp, long level_a, float& total_score, long& num_frames, DoubleLinkedList<Instance>& trace_path);

      boolean connectValidHypothesis();

- declare training methods:

      BiGraphVertex<TrainNode>* insertTrace(Trace* arg);

      BiGraphVertex<TrainNode>* insertInstance(Instance* arg);

- trellis state occupancy computation rules:

      BiGraph<TrainNode>* computeForwardBackward(Vector<VectorFloat>& data, float beta_threshold);

- symbol graph routines:

      SymbolGraph& getSymbolGraph();

      boolean generateSymbolGraph();

      boolean initializeSymbolGraphTrace(double& score, long& num_frames);

      boolean initializeSymbolGraphInstance(double& score, long& num_frames);

- declare context generation methods:

      boolean initializeContextGeneration();

- declare forced-alignment methods:

      boolean forcedAlignment(String& alignment, Long level, DoubleLinkedList<Trace>& trace_path, boolean cumulative = false);

private methods:

- symbol graph generation method

      boolean generateSymbolGraph(SymbolGraphNode* prev_node, SymbolGraphNode* curr_node, float score, float lm_score);

- declare search clean-up methods:

      boolean clearTraceStorage();

      boolean clearSearchNodesTraceLists();

      boolean clearValidHypsTrace();

      boolean clearInstanceStorage();

      boolean clearSearchNodesInstanceLists();

      boolean clearValidHypsInstance();

      boolean clearValidHypsLexInstance();

- declare search evaluation methods:

      boolean evaluateTraceModels();

      boolean evaluateInstanceModels();

      boolean evaluateLexInstanceModels();

- declare search activity methods:

      long getActiveTraces(long search_level = ALL_LEVELS);

      long getActiveInstances(long search_level = ALL_LEVELS);

- declare search display methods:

      boolean printNewPath(Trace* new_trace, Trace* old_trace);

      boolean printDeletedPath(Trace* new_trace, Trace* old_trace);

      boolean printNewPath(Instance* new_instance, Instance* old_instance);

      boolean printDeletedPath(Instance* new_instance, Instance* old_instance);

      boolean printHistory(const History* history);

- declare training methods:

      boolean insertNewPath(Trace* parent, Trace* child, float weight);

      boolean insertOldPath(Trace* parent, Trace* child, float weight);

      boolean insertNewPath(Instance* parent, Instance* child, float weight);

      boolean insertOldPath(Instance* parent, Instance* child, float weight);

      boolean initializeForwardBackward();

      boolean computeBackward(Vector<VectorFloat>& data, float beta_threshold);

      boolean computeBeta(Vector<VectorFloat>& data, BiGraphVertex<TrainNode>* vertex);

      boolean computeForward(Vector<VectorFloat>& data);

      boolean computeAlpha(Vector<VectorFloat>& data, BiGraphVertex<TrainNode>* vertex);

- declare search n-symbol methods:

      float getPosteriorScore(Trace* curr_trace);

      float getPosteriorScore(Context** context, long level);

- declare search beam pruning methods:

      boolean beamPruneTrace(long level_num);

      boolean beamPruneInstance(long level_num);

      boolean beamPruneLexInstance(long level_num);

- declare search initialization methods:

      boolean generateRightContexts(DoubleLinkedList<Context>& context_list, const Context& initial_context, long depth);

      boolean initializeRightContexts(Instance* curr_instance, Context& init_context, long level_num, float curr_weight_a, long depth_a);

      boolean extendRightContexts(Instance* curr_instance, long level_num, boolean descend = false);

- declare search traversal methods:

      boolean traverseTraceLevels();

      boolean pathsRemainTrace();

      boolean traverseInstanceLevels();

      boolean pathsRemainInstance();

      boolean propagateTraces();

      boolean propagateTracesDown(long level_num_a);

      boolean propagateTracesUp(long level_num_a);

      boolean propagateInstances();

      boolean propagateInstancesDown(long level_num_a);

      boolean propagateInstancesUp(long level_num_a);

      boolean isTerminal(Instance* curr_instance, long level_num);

      boolean propagateUp(long curr_level, long level, long curr_depth, long depth, DoubleLinkedList<Instance>& inst_list, DoubleLinkedList<History>& curr_hist, DoubleLinkedList<History>& prev_hist, DoubleLinkedList<Float>& score_list);

      boolean propagateDown(Context& initial_context, Context& initial1_context, GraphVertex<SearchNode>* curr_vertex, long curr_level, long level, long curr_depth, long depth, DoubleLinkedList<Instance>& inst_list, DoubleLinkedList<History>& curr_hist, DoubleLinkedList<History>& prev_hist, DoubleLinkedList<Float>& score_list);

      boolean lookAhead(long level, long depth, DoubleLinkedList<Instance>& inst_list, DoubleLinkedList<Float>& score_list);

      boolean lookAheadHelper(GraphVertex<SearchNode>* curr_vertex, long curr_level, long level, long curr_depth, long depth, DoubleLinkedList<Instance>& inst_list, DoubleLinkedList<History>& curr_hist, DoubleLinkedList<History>& prev_hist, DoubleLinkedList<Float>& score_list);

      boolean printInstance(Instance* new_instance_a, long level_num_a = -1, boolean recursive = false);

      boolean changeHistory(Instance*& curr_instance_a, boolean ascend_a, long level_num_a = 0, GraphVertex<SearchNode>* start_vert = (GraphVertex<SearchNode>*)NULL);

      boolean addHypothesisPath(Trace*& new_instance, Trace*& old_instance, GraphArc<SearchNode>*& arc, long level_num);

      boolean addHypothesisPath(Instance*& new_instance, Instance*& old_instance, long level_num, float weight);

      boolean addInstance(long level_num_a, Instance*& curr_instance_a, Instance*& next_instance_a, boolean pruning_a);

      boolean ascendInstance(long level_num_a, Instance*& curr_instance_a);

      boolean descendInstance(long level_num_a, Instance*& curr_instance_a);

      boolean traverseLexInstanceLevels();

      boolean propagateLexInstances();

      boolean propagateLexInstancesUp(long level_num_a);

      boolean propagateLexInstancesDown(long level_num_a);

      boolean networkLexStart();

      boolean expandLexicalTree(long level_num_a);

      boolean applyNSymbolScore(Instance*& curr_instance_a, long level_num_a);

      boolean addInstanceScore(Instance* curr_instance_a, float score_a, long level_num_a, boolean weight_score_a);

      boolean initializeNsymbolInstance(Instance*& curr_instance_a);

examples:

- none.

notes:

- none.