예제 #1
0
        public void Process(VarietyPair data)
        {
            IWordAligner aligner = _project.WordAligners[_alignerId];

            var correspondenceColls = new Dictionary <FeatureSymbol, SoundCorrespondenceCollection>
            {
                { CogFeatureSystem.Onset, new SoundCorrespondenceCollection() },
                { CogFeatureSystem.Nucleus, new SoundCorrespondenceCollection() },
                { CogFeatureSystem.Coda, new SoundCorrespondenceCollection() }
            };

            foreach (WordPair wordPair in data.WordPairs.Where(wp => wp.Cognacy))
            {
                Alignment <Word, ShapeNode> alignment = aligner.Compute(wordPair).GetAlignments().First();
                for (int i = 0; i < alignment.ColumnCount; i++)
                {
                    AlignmentCell <ShapeNode> cell1 = alignment[0, i];
                    AlignmentCell <ShapeNode> cell2 = alignment[1, i];

                    if (!cell1.IsNull && !cell2.IsNull && cell1.Count == 1 && cell2.Count == 1)
                    {
                        SymbolicFeatureValue pos1, pos2;
                        if (cell1.First.Annotation.FeatureStruct.TryGetValue(CogFeatureSystem.SyllablePosition, out pos1) &&
                            cell2.First.Annotation.FeatureStruct.TryGetValue(CogFeatureSystem.SyllablePosition, out pos2) &&
                            (FeatureSymbol)pos1 == (FeatureSymbol)pos2)
                        {
                            Ngram <Segment> ngram1 = cell1.ToNgram(_segmentPool);
                            Ngram <Segment> ngram2 = cell2.ToNgram(_segmentPool);
                            Segment         seg1   = ngram1.First;
                            Segment         seg2   = ngram2.First;
                            if (!seg1.Equals(seg2))
                            {
                                SoundCorrespondenceCollection correspondences = correspondenceColls[(FeatureSymbol)pos1];
                                SoundCorrespondence           corr;
                                if (!correspondences.TryGet(seg1, seg2, out corr))
                                {
                                    corr = new SoundCorrespondence(seg1, seg2);
                                    correspondences.Add(corr);
                                }
                                corr.Frequency++;
                                corr.WordPairs.Add(wordPair);
                            }
                        }
                    }
                }
            }

            foreach (KeyValuePair <FeatureSymbol, SoundCorrespondenceCollection> kvp in correspondenceColls)
            {
                data.CognateSoundCorrespondencesByPosition[kvp.Key].ReplaceAll(kvp.Value);
            }
        }
예제 #2
0
        public IBidirectionalGraph <GlobalCorrespondencesGraphVertex, GlobalCorrespondencesGraphEdge> GenerateGlobalCorrespondencesGraph(SyllablePosition syllablePosition, IEnumerable <Variety> varieties)
        {
            var        varietiesSet = new HashSet <Variety>(varieties);
            CogProject project      = _projectService.Project;
            var        graph        = new BidirectionalGraph <GlobalCorrespondencesGraphVertex, GlobalCorrespondencesGraphEdge>();
            var        vertices     = new Dictionary <object, GlobalSegmentVertex>();
            var        edges        = new Dictionary <UnorderedTuple <object, object>, GlobalCorrespondencesGraphEdge>();
            int        maxFreq      = 0;

            if (syllablePosition == SyllablePosition.Nucleus)
            {
                graph.AddVertexRange(new GlobalCorrespondencesGraphVertex[]
                {
                    new VowelBacknessVertex(VowelBackness.Front),
                    new VowelBacknessVertex(VowelBackness.Central),
                    new VowelBacknessVertex(VowelBackness.Back),

                    new VowelHeightVertex(VowelHeight.Close),
                    new VowelHeightVertex(VowelHeight.CloseMid),
                    new VowelHeightVertex(VowelHeight.OpenMid),
                    new VowelHeightVertex(VowelHeight.Open)
                });

                foreach (VarietyPair vp in project.VarietyPairs.Where(vp => varietiesSet.Contains(vp.Variety1) && varietiesSet.Contains(vp.Variety2)))
                {
                    foreach (SoundCorrespondence corr in vp.CognateSoundCorrespondencesByPosition[CogFeatureSystem.Nucleus])
                    {
                        VowelHeight   height1, height2;
                        VowelBackness backness1, backness2;
                        bool          round1, round2;
                        if (GetVowelInfo(corr.Segment1, out height1, out backness1, out round1) && GetVowelInfo(corr.Segment2, out height2, out backness2, out round2) &&
                            (height1 != height2 || backness1 != backness2 || round1 != round2))
                        {
                            Tuple <VowelHeight, VowelBackness, bool> key1 = Tuple.Create(height1, backness1, round1);
                            GlobalSegmentVertex vertex1 = vertices.GetValue(key1, () => new GlobalVowelVertex(height1, backness1, round1));
                            vertex1.StrReps.Add(corr.Segment1.StrRep);
                            Tuple <VowelHeight, VowelBackness, bool> key2 = Tuple.Create(height2, backness2, round2);
                            GlobalSegmentVertex vertex2 = vertices.GetValue(key2, () => new GlobalVowelVertex(height2, backness2, round2));
                            vertex2.StrReps.Add(corr.Segment2.StrRep);
                            int freq = AddEdge(edges, corr, key1, vertex1, key2, vertex2);
                            maxFreq = Math.Max(freq, maxFreq);
                        }
                    }
                }
            }
            else
            {
                graph.AddVertexRange(new GlobalCorrespondencesGraphVertex[]
                {
                    new ConsonantPlaceVertex(ConsonantPlace.Bilabial),
                    new ConsonantPlaceVertex(ConsonantPlace.Labiodental),
                    new ConsonantPlaceVertex(ConsonantPlace.Dental),
                    new ConsonantPlaceVertex(ConsonantPlace.Alveolar),
                    new ConsonantPlaceVertex(ConsonantPlace.Postalveolar),
                    new ConsonantPlaceVertex(ConsonantPlace.Retroflex),
                    new ConsonantPlaceVertex(ConsonantPlace.Palatal),
                    new ConsonantPlaceVertex(ConsonantPlace.Velar),
                    new ConsonantPlaceVertex(ConsonantPlace.Uvular),
                    new ConsonantPlaceVertex(ConsonantPlace.Pharyngeal),
                    new ConsonantPlaceVertex(ConsonantPlace.Glottal),

                    new ConsonantMannerVertex(ConsonantManner.Nasal),
                    new ConsonantMannerVertex(ConsonantManner.Stop),
                    new ConsonantMannerVertex(ConsonantManner.Affricate),
                    new ConsonantMannerVertex(ConsonantManner.Fricative),
                    new ConsonantMannerVertex(ConsonantManner.Approximant),
                    new ConsonantMannerVertex(ConsonantManner.FlapOrTap),
                    new ConsonantMannerVertex(ConsonantManner.Trill),
                    new ConsonantMannerVertex(ConsonantManner.LateralFricative),
                    new ConsonantMannerVertex(ConsonantManner.LateralApproximant)
                });

                foreach (VarietyPair vp in project.VarietyPairs.Where(vp => varietiesSet.Contains(vp.Variety1) && varietiesSet.Contains(vp.Variety2)))
                {
                    SoundCorrespondenceCollection corrs = null;
                    switch (syllablePosition)
                    {
                    case SyllablePosition.Onset:
                        corrs = vp.CognateSoundCorrespondencesByPosition[CogFeatureSystem.Onset];
                        break;

                    case SyllablePosition.Coda:
                        corrs = vp.CognateSoundCorrespondencesByPosition[CogFeatureSystem.Coda];
                        break;
                    }
                    Debug.Assert(corrs != null);
                    foreach (SoundCorrespondence corr in corrs)
                    {
                        ConsonantPlace  place1, place2;
                        ConsonantManner manner1, manner2;
                        bool            voiced1, voiced2;
                        if (GetConsonantPosition(corr.Segment1, out place1, out manner1, out voiced1) && GetConsonantPosition(corr.Segment2, out place2, out manner2, out voiced2) &&
                            (place1 != place2 || manner1 != manner2 || voiced1 != voiced2))
                        {
                            Tuple <ConsonantPlace, ConsonantManner, bool> key1 = Tuple.Create(place1, manner1, voiced1);
                            GlobalSegmentVertex vertex1 = vertices.GetValue(key1, () => new GlobalConsonantVertex(place1, manner1, voiced1));
                            vertex1.StrReps.Add(corr.Segment1.StrRep);
                            Tuple <ConsonantPlace, ConsonantManner, bool> key2 = Tuple.Create(place2, manner2, voiced2);
                            GlobalSegmentVertex vertex2 = vertices.GetValue(key2, () => new GlobalConsonantVertex(place2, manner2, voiced2));
                            vertex2.StrReps.Add(corr.Segment2.StrRep);

                            int freq = AddEdge(edges, corr, key1, vertex1, key2, vertex2);
                            maxFreq = Math.Max(freq, maxFreq);
                        }
                    }
                }
            }

            graph.AddVertexRange(vertices.Values);
            foreach (GlobalCorrespondencesGraphEdge edge in edges.Values)
            {
                edge.NormalizedFrequency = (double)edge.Frequency / maxFreq;
                graph.AddEdge(edge);
            }

            return(graph);
        }