/// <summary> /// Gets the selective tri-phone for each leaf nodes in the tree. /// </summary> /// <param name="nodeToTriphone">The selective tri-phone for first node in decision tree. The key is the leaf node, and the tri-phone pair set is the value.</param> /// <param name="questions">The related questions.</param> private static void GetSelectiveTriphone(Dictionary<DecisionTreeNode, TriphoneSet> nodeToTriphone, IDictionary<string, Question> questions) { while (true) { // Check whether there are some non-leaf nodes? IEnumerable<DecisionTreeNode> list = nodeToTriphone.Keys.Where(o => o.NodeType == DecisionTreeNodeType.NonLeaf); if (list.Count() == 0) { // All the data are leaf nodes, just break to return them. break; } // Process the first non-leaf node. DecisionTreeNode node = list.First(); TriphoneSet parentSet = nodeToTriphone[node]; nodeToTriphone.Remove(node); Question question = questions[node.QuestionName]; // Check the question of this node. // Copy from parent. TriphoneSet leftChildSet = parentSet; TriphoneSet rightChildSet = new TriphoneSet(parentSet); switch (question.FeatureName) { case LabelFeatureNameSet.CentralPhonemeFeatureName: // It is central phone question. // Right child (YES child) will only contains the ones which occur simultaneously in the question set and parent set. // Left child (NO child) will contains the ones which in parent set but not in question set. rightChildSet.CentralPhones.IntersectWith(question.ValueSet); leftChildSet.CentralPhones.ExceptWith(question.ValueSet); break; case LabelFeatureNameSet.LeftPhonemeFeatureName: // Left phone question. // Right child (YES child) will only contains the ones which occur simultaneously in the question set and parent set. // Left child (NO child) will contains the ones which in parent set but not in question set. rightChildSet.LeftPhones.IntersectWith(question.ValueSet); leftChildSet.LeftPhones.ExceptWith(question.ValueSet); break; case LabelFeatureNameSet.RightPhonemeFeatureName: // Right phone question. // Right child (YES child) will only contains the ones which occur simultaneously in the question set and parent set. // Left child (NO child) will contains the ones which in parent set but not in question set. rightChildSet.RightPhones.IntersectWith(question.ValueSet); leftChildSet.RightPhones.ExceptWith(question.ValueSet); break; default: // This question have nothing about phone. Just copy the set from parent. break; } // Add the two children. nodeToTriphone.Add(node.LeftChild, leftChildSet); nodeToTriphone.Add(node.RightChild, rightChildSet); } }
/// <summary> /// Initializes a new instance of the TriphoneSet class as a copy of the given instance. /// </summary> /// <param name="set">The set to copied.</param> public TriphoneSet(TriphoneSet set) { LeftPhones = new HashSet<string>(set.LeftPhones.OrderBy(p => p)); CentralPhones = new HashSet<string>(set.CentralPhones.OrderBy(p => p)); RightPhones = new HashSet<string>(set.RightPhones.OrderBy(p => p)); }
/// <summary> /// Gets the selective tri-phone for each leaf nodes in the tree. /// </summary> /// <param name="tree">The given tree.</param> /// <param name="questions">The related questions.</param> /// <param name="phonemes">The whole set of phoneme, which is used to initialize the tri-phone pairs.</param> /// <returns>The selective tri-phone for each leaf node in decision tree. /// The key is the leaf node, and the tri-phone pair set is the value.</returns> private static Dictionary<DecisionTreeNode, TriphoneSet> GetSelectiveTriphone(DecisionTree tree, IDictionary<string, Question> questions, HashSet<string> phonemes) { Dictionary<DecisionTreeNode, TriphoneSet> nodeToTriphone = new Dictionary<DecisionTreeNode, TriphoneSet>(); // Firstly, generate a whole tri-phone set. TriphoneSet set = new TriphoneSet(phonemes); // Phone-dependent tree should resize the central phone set. string phone = tree.Phone; if (!Phoneme.IsAnyPhone(phone)) { set.CentralPhones.Clear(); set.CentralPhones.Add(phone); } // Assign the tri-phone set to the root of the tree. nodeToTriphone.Add(tree.NodeList[0], set); GetSelectiveTriphone(nodeToTriphone, questions); return nodeToTriphone; }