예제 #1
0
            /**
             * /// Determines if the context pair needs an empty version. A context pair needs an empty version if the left
             * /// context has a max size of zero.
             *
             * /// @param cp the contex pair to check
             * /// @return <code>true</code> if the pair needs an empt version
             */
            private Boolean NeedsEmptyVersion(ContextPair cp)
            {
                UnitContext left = cp.LeftContext;

                Unit[] units = left.Units;
                return(units.Length > 0 && (GetRightContextSize(units[0]) < GetRightContextSize()));
            }
예제 #2
0
            /// <summary>
            /// Gets the context-free entry point to this state
            /// </summary>
            /// <returns>the entry point to the state</returns>
            /// TODO: ideally we'll look for entry points with no left
            // context, but those don't exist yet so we just take
            // the first entry point with an SILENCE left context
            // note that this assumes that the first node in a grammar has a
            // word and that word is a SIL. Not always a valid assumption.
            public SentenceHMMState GetEntryPoint()
            {
                ContextPair         cp   = ContextPair.Get(UnitContext.Silence, UnitContext.Silence);
                List <ISearchState> list = GetEntryPoints(cp);

                return(list == null || list.Count == 0 ? null : (SentenceHMMState)list[0]);
            }
예제 #3
0
        /**
         * /// Gets the ContextPair for the given set of contexts. This is a factory method. If the ContextPair already exists,
         * /// return that one, otherwise, create it and store it so it can be reused.
         *
         * /// @param left  the left context
         * /// @param right the right context
         * /// @return the unit context.
         */
        public static ContextPair Get(UnitContext left, UnitContext right)
        {
            var newCp    = new ContextPair(left, right);
            var cachedCp = ContextPairCache.cache(newCp);

            return(cachedCp ?? newCp);
        }
예제 #4
0
            /**
             * /// Attaches the given unit to the given tail, expanding the unit if necessary. If an identical unit is already
             * /// attached, then this path is folded into the existing path.
             *
             * /// @param parent       the parent state
             * /// @param tail         the place to attach the unit to
             * /// @param units        the set of units
             * /// @param which        the index into the set of units
             * /// @param leftContext  the left context for the unit
             * /// @param rightContext the right context for the unit
             * /// @return the tail of the added unit (or null if the path was folded onto an already expanded path.
             */
            private SentenceHMMState AttachUnit(PronunciationState parent,
                                                SentenceHMMState tail, Unit[] units, int which,
                                                UnitContext leftContext, UnitContext rightContext)
            {
                Unit[]           lc = GetLC(leftContext, units, which);
                Unit[]           rc = GetRC(units, which, rightContext);
                UnitContext      actualRightContext = UnitContext.Get(rc);
                LeftRightContext context            = LeftRightContext.Get(lc, rc);
                Unit             cdUnit             = _parent.UnitManager.GetUnit(units[which].Name, units[which].IsFiller, context);
                UnitState        unitState          = new ExtendedUnitState(parent, which, cdUnit);
                float            logInsertionProbability;

                if (unitState.Unit.IsSilence)
                {
                    logInsertionProbability = _parent.LogSilenceInsertionProbability;
                }
                else if (unitState.Unit.IsFiller)
                {
                    logInsertionProbability = _parent._logFillerInsertionProbability;
                }
                else if (unitState.GetWhich() == 0)
                {
                    logInsertionProbability = _parent._logWordInsertionProbability;
                }
                else
                {
                    logInsertionProbability = _parent._logUnitInsertionProbability;
                }
                // check to see if this state already exists, if so
                // branch to it and we are done, otherwise, branch to
                // the new state and expand it.
                SentenceHMMState existingState = GetExistingState(unitState);

                if (existingState != null)
                {
                    AttachState(tail, existingState, LogOne, logInsertionProbability);
                    // T(" Folding " + existingState);
                    return(null);
                }
                else
                {
                    AttachState(tail, unitState, LogOne, logInsertionProbability);
                    AddStateToCache(unitState);
                    // T(" Attaching " + unitState);
                    tail = ExpandUnit(unitState);
                    // if we are attaching the last state of a word, then
                    // we add it to the exitPoints table. the exit points
                    // table is indexed by a ContextPair, consisting of
                    // the exiting left context and the right context.
                    if (unitState.IsLast())
                    {
                        UnitContext nextLeftContext = GenerateNextLeftContext(leftContext, units[which]);
                        ContextPair cp = ContextPair.Get(nextLeftContext, actualRightContext);
                        // T(" Adding to exitPoints " + cp);
                        AddExitPoint(cp, tail);
                    }
                    return(tail);
                }
            }
예제 #5
0
 public bool Equals(ContextPair o)
 {
     if (this == o)
     {
         return(true);
     }
     return(LeftContext.Equals(o.LeftContext) && RightContext.Equals(o.RightContext));
 }
예제 #6
0
 /// <summary>
 /// Expands each GState into the sentence HMM States
 /// </summary>
 public void Expand()
 {
     //this.LogDebug("Item Context: {0} : {1} : {2}",startingContexts.Count, rightContexts.Count, leftContexts.Count);
     // for each left context/starting context pair create a list
     // of starting states.
     foreach (UnitContext leftContext in _leftContexts)
     {
         foreach (UnitContext startingContext in GetStartingContexts())
         {
             ContextPair contextPair = ContextPair.Get(leftContext, startingContext);
             if (!_entryPoints.ContainsKey(contextPair))
             {
                 _entryPoints.Add(contextPair, new List <ISearchState>());
             }
         }
     }
     this.LogDebug("Item entryPoints Count: {0}", _entryPoints.Count);
     // if this is a final node don't expand it, just create a
     // state and add it to all entry points
     if (_node.IsFinalNode)
     {
         GrammarState gs = new GrammarState(_node);
         foreach (List <ISearchState> epList in _entryPoints.Values)
         {
             epList.Add(gs);
         }
     }
     else if (!_node.IsEmpty)
     {
         // its a full fledged node with a word
         // so expand it. Nodes without words don't need
         // to be expanded.
         foreach (UnitContext leftContext in _leftContexts)
         {
             ExpandWord(leftContext);
         }
     }
     else
     {
         //if the node is empty, populate the set of entry and exit
         //points with a branch state. The branch state
         // branches to the successor entry points for this
         // state
         // the exit point should consist of the set of
         // incoming left contexts and outgoing right contexts
         // the 'entryPoint' table already consists of such
         // pairs so we can use that
         foreach (var entry in _entryPoints)
         {
             ContextPair         cp     = entry.Key;
             List <ISearchState> epList = entry.Value;
             SentenceHMMState    bs     = new BranchState(cp.LeftContext.ToString(), cp.RightContext.ToString(), _node.ID);
             epList.Add(bs);
             AddExitPoint(cp, bs);
         }
     }
     AddEmptyEntryPoints();
 }
예제 #7
0
            /// <summary>
            /// Adds an exit point to this gstate
            /// </summary>
            /// <param name="cp">the context tag for the state</param>
            /// <param name="state">the state associated with the tag</param>
            private void AddExitPoint(ContextPair cp, SentenceHMMState state)
            {
                List <ISearchState> list = _exitPoints.Get(cp);

                if (list == null)
                {
                    list = new List <ISearchState>();
                    _exitPoints.Put(cp, list);
                }
                list.Add(state);
            }
예제 #8
0
 /**
  * /// Determines if the given object is equal to this UnitContext
  *
  * /// @param o the object to compare to
  * /// @return <code>true</code> if the objects are equal return;
  */
 public override bool Equals(Object o)
 {
     if (this == o)
     {
         return(true);
     }
     else if (o is ContextPair)
     {
         ContextPair other = (ContextPair)o;
         return(LeftContext.Equals(other.LeftContext) && RightContext.Equals(other.RightContext));
     }
     return(false);
 }
예제 #9
0
            /**
             * /// Expand the pronunciation given the left context
             *
             * /// @param leftContext   the left context
             * /// @param pronunciation the pronunciation to expand
             * /// @param which         unique ID for this pronunciation
             */
            // Each GState maintains a list of entry points. This list of
            // entry points is used when connecting up the end states of
            // one GState to the beginning states in another GState. The
            // entry points are tagged by a ContextPair which represents
            // the left context upon entering the state (the left context
            // of the initial units of the state), and the right context
            // of the previous states (corresponding to the starting
            // contexts for this state).
            //
            // When expanding a pronunciation, the following steps are
            // taken:
            //      1) Get the starting context for the pronunciation.
            //      This is the set of units that correspond to the start
            //      of the pronunciation.
            //
            //      2) Create a new PronunciationState for the
            //      pronunciation.
            //
            //      3) Add the PronunciationState to the entry point table
            //      (a hash table keyed by the ContextPair(LeftContext,
            //      StartingContext).
            //
            //      4) Generate the set of context dependent units, using
            //      the left and right context of the GState as necessary.
            //      Note that there will be fan out at the end of the
            //      pronunciation to allow for units with all of the
            //      various right contexts. The point where the fan-out
            //      occurs is the (length of the pronunciation - the max
            //      right context size).
            //
            //      5) Attach each cd unit to the tree
            //
            //      6) Expand each cd unit into the set of HMM states
            //
            //      7) Attach the optional and looping back silence cd
            //      unit
            //
            //      8) Collect the leaf states of the tree and add them to
            //      the exitStates list.
            private void ExpandPronunciation(UnitContext leftContext, Pronunciation pronunciation, int which)
            {
                UnitContext startingContext = GetStartingContext(pronunciation);
                // Add the pronunciation state to the entry point list
                // (based upon its left and right context)
                string pname = "P(" + pronunciation.Word + '[' + leftContext
                               + ',' + startingContext + "])-G" + GetNode().ID;
                PronunciationState ps = new PronunciationState(pname, pronunciation, which);

                _parent.T("     Expanding " + ps.Pronunciation + " for lc " + leftContext);
                ContextPair cp = ContextPair.Get(leftContext, startingContext);

                var epList = _entryPoints.Get(cp);

                if (epList == null)
                {
                    throw new Error("No EP list for context pair " + cp);
                }
                else
                {
                    epList.Add(ps);
                }

                Unit[] units       = pronunciation.Units;
                int    fanOutPoint = units.Length - GetRightContextSize();

                if (fanOutPoint < 0)
                {
                    fanOutPoint = 0;
                }
                SentenceHMMState tail = ps;

                for (int i = 0; tail != null && i < fanOutPoint; i++)
                {
                    tail = AttachUnit(ps, tail, units, i, leftContext, UnitContext.Empty);
                }
                SentenceHMMState branchTail = tail;

                foreach (UnitContext finalRightContext in _rightContexts)
                {
                    tail = branchTail;
                    for (int i = fanOutPoint; tail != null && i < units.Length; i++)
                    {
                        tail = AttachUnit(ps, tail, units, i, leftContext, finalRightContext);
                    }
                }
            }
예제 #10
0
            /**
             * /// Adds the set of empty entry points. The list of entry points are tagged with a context pair. The context pair
             * /// represent the left context for the state and the starting context for the state, this allows states to be
             * /// hooked up properly. However, we may be transitioning from states that have no right hand context (CI units
             * /// such as SIL fall into this category). In this case we'd normally have no place to transition to since we add
             * /// entry points for each starting context. To make sure that there are entry points for empty contexts if
             * /// necessary, we go through the list of entry points and find all left contexts that have a right hand context
             * /// size of zero. These entry points will need an entry point with an empty starting context. These entries are
             * /// synthesized and added to the the list of entry points.
             */
            private void AddEmptyEntryPoints()
            {
                var emptyEntryPoints = new HashMap <ContextPair, List <ISearchState> >();

                foreach (var entry in _entryPoints)
                {
                    ContextPair cp = entry.Key;
                    if (NeedsEmptyVersion(cp))
                    {
                        ContextPair         emptyContextPair = ContextPair.Get(cp.LeftContext, UnitContext.Empty);
                        List <ISearchState> epList           = emptyEntryPoints.Get(emptyContextPair);
                        if (epList == null)
                        {
                            epList = new List <ISearchState>();
                            emptyEntryPoints.Put(emptyContextPair, epList);
                        }
                        epList.AddRange(entry.Value);
                    }
                }
                _entryPoints.PutAll(emptyEntryPoints);
            }
예제 #11
0
 /// <summary>
 /// Returns the entry points for a given context pair
 /// </summary>
 /// <param name="contextPair"></param>
 /// <returns></returns>
 private List <ISearchState> GetEntryPoints(ContextPair contextPair)
 {
     return(_entryPoints.Get(contextPair));
 }