Exemplo n.º 1
0
        public void Equals_SameTuples_ReturnsTrue()
        {
            var tuple1 = UnorderedTuple.Create("A", "B", "C");
            var tuple2 = UnorderedTuple.Create("A", "B", "C");

            Assert.That(tuple1.Equals(tuple2), Is.True);
        }
Exemplo n.º 2
0
        private void AddToLookupDictionary(int index, CognacyDecision item)
        {
            Dictionary <Meaning, int> lookup = _lookupDictionary.GetValue(UnorderedTuple.Create(item.Variety1, item.Variety2),
                                                                          () => new Dictionary <Meaning, int>());

            lookup[item.Meaning] = index;
        }
Exemplo n.º 3
0
        public void GetHashCode_DifferentTuples_HashCodesNotEqual()
        {
            var tuple1 = UnorderedTuple.Create("A", "B", "D");
            var tuple2 = UnorderedTuple.Create("A", "B", "C");

            Assert.That(tuple1.GetHashCode(), Is.Not.EqualTo(tuple2.GetHashCode()));
        }
Exemplo n.º 4
0
        public void GetHashCode_SameTuplesDifferentTypesInDifferentOrder_HashCodesEqual()
        {
            var tuple1 = UnorderedTuple.Create("A", "B", 0);
            var tuple2 = UnorderedTuple.Create("B", "A", 0);

            Assert.That(tuple1.GetHashCode(), Is.EqualTo(tuple2.GetHashCode()));
        }
Exemplo n.º 5
0
        public void GetHashCode_SameTuples_HashCodesEqual()
        {
            var tuple1 = UnorderedTuple.Create("A", "B", "C");
            var tuple2 = UnorderedTuple.Create("A", "B", "C");

            Assert.That(tuple1.GetHashCode(), Is.EqualTo(tuple2.GetHashCode()));
        }
Exemplo n.º 6
0
        public void Equals_SameTuplesDifferentTypesInDifferentOrder_ReturnsTrue()
        {
            var tuple1 = UnorderedTuple.Create("A", "B", 0);
            var tuple2 = UnorderedTuple.Create("B", "A", 0);

            Assert.That(tuple1.Equals(tuple2), Is.True);
        }
Exemplo n.º 7
0
        public void Equals_DifferentTuples_ReturnsFalse()
        {
            var tuple1 = UnorderedTuple.Create("A", "B", "D");
            var tuple2 = UnorderedTuple.Create("A", "B", "C");

            Assert.That(tuple1.Equals(tuple2), Is.False);
        }
Exemplo n.º 8
0
 private IEnumerable <UnorderedTuple <string, string> > ParseMappings(XElement elem)
 {
     foreach (XElement mappingElem in elem.Elements(ConfigManager.Cog + "Mapping"))
     {
         yield return(UnorderedTuple.Create((string)mappingElem.Attribute("segment1"), (string)mappingElem.Attribute("segment2")));
     }
 }
Exemplo n.º 9
0
        public void IsMapped_ImplicitComplexSegments()
        {
            var segmentPool = new SegmentPool();

            var mappings = new ListSegmentMappings(_segmenter, new[]
            {
                UnorderedTuple.Create("m", "n"),
                UnorderedTuple.Create("t", "-"),
                UnorderedTuple.Create("h#", "-#"),
                UnorderedTuple.Create("c", "#g"),
                UnorderedTuple.Create("f", "@")
            }, true);

            Shape shape1 = _segmenter.Segment("s͡mat͡h");
            Shape shape2 = _segmenter.Segment("k͡no");

            Assert.That(mappings.IsMapped(shape1.First.Prev, segmentPool.Get(shape1.First), shape1.First.Next, shape2.First.Prev, segmentPool.Get(shape2.First), shape2.First.Next), Is.True);
            Assert.That(mappings.IsMapped(shape1.Last.Prev, segmentPool.Get(shape1.Last), shape1.Last.Next, shape2.Last, new Ngram <Segment>(), shape2.Last.Next), Is.True);
            Assert.That(mappings.IsMapped(shape1.First, segmentPool.Get(shape1.First.Next), shape1.Last, shape2.First, segmentPool.Get(shape2.Last), shape2.Last.Next), Is.False);

            shape1 = _segmenter.Segment("got͡h");
            shape2 = _segmenter.Segment("c͡lo");

            Assert.That(mappings.IsMapped(shape1.First.Prev, segmentPool.Get(shape1.First), shape1.First.Next, shape2.First.Prev, segmentPool.Get(shape2.First), shape2.First.Next), Is.True);
            Assert.That(mappings.IsMapped(shape1.Last.Prev, segmentPool.Get(shape1.Last), shape1.Last.Next, shape2.Last, new Ngram <Segment>(), shape2.Last.Next), Is.True);

            shape1 = _segmenter.Segment("s͡hog");
            shape2 = _segmenter.Segment("oc͡t");

            Assert.That(mappings.IsMapped(shape1.First.Prev, segmentPool.Get(shape1.First), shape1.First.Next, shape2.First.Prev, new Ngram <Segment>(), shape2.First), Is.False);
            Assert.That(mappings.IsMapped(shape1.Last.Prev, segmentPool.Get(shape1.Last), shape1.Last.Next, shape2.Last.Prev, segmentPool.Get(shape2.Last), shape2.Last.Next), Is.False);
        }
Exemplo n.º 10
0
        public static IEnumerable <Cluster <Word> > GenerateCognateSets(this CogProject project, Meaning meaning)
        {
            var words = new HashSet <Word>();
            var noise = new HashSet <Word>();

            foreach (VarietyPair vp in project.VarietyPairs)
            {
                WordPair wp;
                if (vp.WordPairs.TryGetValue(meaning, out wp))
                {
                    if (wp.AreCognatePredicted)
                    {
                        words.Add(wp.Word1);
                        words.Add(wp.Word2);
                        noise.Remove(wp.Word1);
                        noise.Remove(wp.Word2);
                    }
                    else
                    {
                        if (!words.Contains(wp.Word1))
                        {
                            noise.Add(wp.Word1);
                        }
                        if (!words.Contains(wp.Word2))
                        {
                            noise.Add(wp.Word2);
                        }
                    }
                }
            }

            double min = double.MaxValue, max = double.MinValue;
            var    distanceMatrix = new Dictionary <UnorderedTuple <Word, Word>, double>();

            Word[] wordArray = words.ToArray();
            for (int i = 0; i < wordArray.Length; i++)
            {
                for (int j = i + 1; j < wordArray.Length; j++)
                {
                    Word     w1    = wordArray[i];
                    Word     w2    = wordArray[j];
                    double   score = 0;
                    WordPair wp;
                    if (w1.Variety != w2.Variety && w1.Variety.VarietyPairs[w2.Variety].WordPairs.TryGetValue(meaning, out wp) && wp.AreCognatePredicted &&
                        wp.GetWord(w1.Variety) == w1 && wp.GetWord(w2.Variety) == w2)
                    {
                        score = wp.CognicityScore;
                    }
                    double distance = 1.0 - score;
                    min = Math.Min(min, distance);
                    max = Math.Max(max, distance);
                    distanceMatrix[UnorderedTuple.Create(w1, w2)] = distance;
                }
            }

            var clusterer = new FlatUpgmaClusterer <Word>((w1, w2) => distanceMatrix[UnorderedTuple.Create(w1, w2)], (max + min) / 2);

            return(clusterer.GenerateClusters(words).Concat(new Cluster <Word>(noise, true)));
        }
Exemplo n.º 11
0
        protected override void MoveItem(int oldIndex, int newIndex)
        {
            CognacyDecision item = Items[oldIndex];
            UnorderedTuple <Variety, Variety> key = UnorderedTuple.Create(item.Variety1, item.Variety2);

            _lookupDictionary[key][item.Meaning] = newIndex;
            base.MoveItem(oldIndex, newIndex);
        }
Exemplo n.º 12
0
        private static int AddEdge(Dictionary <UnorderedTuple <object, object>, GlobalCorrespondencesGraphEdge> edges, SoundCorrespondence corr,
                                   object key1, GlobalSegmentVertex vertex1, object key2, GlobalSegmentVertex vertex2)
        {
            GlobalCorrespondencesGraphEdge edge = edges.GetValue(UnorderedTuple.Create(key1, key2), () => new GlobalCorrespondencesGraphEdge(vertex1, vertex2));

            edge.Frequency += corr.Frequency;
            edge.DomainWordPairs.AddRange(corr.WordPairs);
            return(edge.Frequency);
        }
Exemplo n.º 13
0
        private void RemoveFromLookupDictionary(int index)
        {
            CognacyDecision item = Items[index];
            UnorderedTuple <Variety, Variety> key       = UnorderedTuple.Create(item.Variety1, item.Variety2);
            Dictionary <Meaning, int>         decisions = _lookupDictionary[key];

            if (decisions.Remove(item.Meaning) && decisions.Count == 0)
            {
                _lookupDictionary.Remove(key);
            }
        }
Exemplo n.º 14
0
        public bool Remove(WordPair wordPair)
        {
            Dictionary <Meaning, CognacyDecision> decisions;
            UnorderedTuple <Variety, Variety>     key = UnorderedTuple.Create(wordPair.VarietyPair.Variety1, wordPair.VarietyPair.Variety2);

            if (_lookupDictionary.TryGetValue(key, out decisions))
            {
                CognacyDecision decision;
                if (decisions.TryGetValue(wordPair.Meaning, out decision))
                {
                    return(Remove(decision));
                }
            }
            return(false);
        }
Exemplo n.º 15
0
        public bool?GetCognacy(VarietyPair varietyPair, Meaning meaning)
        {
            Dictionary <Meaning, CognacyDecision> decisions;

            if (_lookupDictionary.TryGetValue(UnorderedTuple.Create(varietyPair.Variety1, varietyPair.Variety2),
                                              out decisions))
            {
                CognacyDecision decision;
                if (decisions.TryGetValue(meaning, out decision))
                {
                    return(decision.Cognacy);
                }
            }

            return(null);
        }
Exemplo n.º 16
0
        public bool?GetCognacy(VarietyPair varietyPair, Meaning meaning)
        {
            Dictionary <Meaning, int> decisions;

            if (_lookupDictionary.TryGetValue(UnorderedTuple.Create(varietyPair.Variety1, varietyPair.Variety2),
                                              out decisions))
            {
                int index;
                if (decisions.TryGetValue(meaning, out index))
                {
                    return(Items[index].Cognacy);
                }
            }

            return(null);
        }
Exemplo n.º 17
0
        public void IsMapped()
        {
            var segmentPool = new SegmentPool();

            var mappings = new ListSegmentMappings(_segmenter, new[]
            {
                UnorderedTuple.Create("m", "n"),
                UnorderedTuple.Create("t", "-"),
                UnorderedTuple.Create("h#", "-#"),
                UnorderedTuple.Create("c", "#g"),
                UnorderedTuple.Create("f", "@"),
                UnorderedTuple.Create("a", "o"),
                UnorderedTuple.Create("Cw", "-V")
            }, false);

            Shape shape1 = _segmenter.Segment("ma͡et");
            Shape shape2 = _segmenter.Segment("no");

            Assert.That(mappings.IsMapped(shape1.First.Prev, segmentPool.Get(shape1.First), shape1.First.Next, shape2.First.Prev, segmentPool.Get(shape2.First), shape2.First.Next), Is.True);
            Assert.That(mappings.IsMapped(shape1.Last.Prev, segmentPool.Get(shape1.Last), shape1.Last.Next, shape2.Last, new Ngram <Segment>(), shape2.Last.Next), Is.True);
            Assert.That(mappings.IsMapped(shape1.First, segmentPool.Get(shape1.First.Next), shape1.Last, shape2.First, segmentPool.Get(shape2.Last), shape2.Last.Next), Is.False);

            shape1 = _segmenter.Segment("goh");
            shape2 = _segmenter.Segment("co");

            Assert.That(mappings.IsMapped(shape1.First.Prev, segmentPool.Get(shape1.First), shape1.First.Next, shape2.First.Prev, segmentPool.Get(shape2.First), shape2.First.Next), Is.True);
            Assert.That(mappings.IsMapped(shape1.Last.Prev, segmentPool.Get(shape1.Last), shape1.Last.Next, shape2.Last, new Ngram <Segment>(), shape2.Last.Next), Is.True);

            shape1 = _segmenter.Segment("hog");
            shape2 = _segmenter.Segment("oc");

            Assert.That(mappings.IsMapped(shape1.First.Prev, segmentPool.Get(shape1.First), shape1.First.Next, shape2.First.Prev, new Ngram <Segment>(), shape2.First), Is.False);
            Assert.That(mappings.IsMapped(shape1.Last.Prev, segmentPool.Get(shape1.Last), shape1.Last.Next, shape2.Last.Prev, segmentPool.Get(shape2.Last), shape2.Last.Next), Is.False);

            shape1 = _segmenter.Segment("swat");
            shape2 = _segmenter.Segment("sat");

            Assert.That(mappings.IsMapped(shape1.ElementAt(0), segmentPool.Get(shape1.ElementAt(1)), shape1.ElementAt(2), shape2.ElementAt(0), new Ngram <Segment>(), shape2.ElementAt(1)), Is.True);

            shape1 = _segmenter.Segment("sawat");
            shape2 = _segmenter.Segment("saat");
            Assert.That(mappings.IsMapped(shape1.ElementAt(1), segmentPool.Get(shape1.ElementAt(2)), shape1.ElementAt(3), shape2.ElementAt(1), new Ngram <Segment>(), shape2.ElementAt(2)), Is.False);
        }
Exemplo n.º 18
0
        public bool Remove(WordPair wordPair)
        {
            Dictionary <Meaning, int>         decisions;
            UnorderedTuple <Variety, Variety> key = UnorderedTuple.Create(wordPair.VarietyPair.Variety1, wordPair.VarietyPair.Variety2);

            if (_lookupDictionary.TryGetValue(key, out decisions))
            {
                int index;
                if (decisions.TryGetValue(wordPair.Meaning, out index))
                {
                    decisions.Remove(wordPair.Meaning);
                    if (decisions.Count == 0)
                    {
                        _lookupDictionary.Remove(key);
                    }
                    base.RemoveItem(index);
                    return(true);
                }
            }
            return(false);
        }
Exemplo n.º 19
0
        private void AddToLookupDictionary(CognacyDecision item)
        {
            Dictionary <Meaning, CognacyDecision> lookup = _lookupDictionary.GetOrCreate(UnorderedTuple.Create(item.Variety1, item.Variety2),
                                                                                         () => new Dictionary <Meaning, CognacyDecision>());

            lookup[item.Meaning] = item;
        }
Exemplo n.º 20
0
        public SegmentMappingsTableViewModel(IProjectService projectService, SegmentMappingsTableSegmentPairViewModel.Factory segmentPairFactory, SegmentMappingViewModel.Factory mappingFactory,
                                             IEnumerable <SegmentMappingViewModel> mappings, SoundType soundType, int threshold)
        {
            _threshold = threshold;

            _soundType = soundType;
            FeatureSymbol segmentType;

            switch (_soundType)
            {
            case SoundType.Consonant:
                segmentType = CogFeatureSystem.ConsonantType;
                break;

            case SoundType.Vowel:
                segmentType = CogFeatureSystem.VowelType;
                break;

            default:
                throw new InvalidEnumArgumentException();
            }

            var segmentComparer  = new SegmentComparer();
            var categoryComparer = new SegmentCategoryComparer();

            _segments = new ReadOnlyList <SegmentMappingsTableSegmentViewModel>(projectService.Project.Varieties.SelectMany(v => v.SegmentFrequencyDistribution.ObservedSamples)
                                                                                .Where(s => s.Type == segmentType).Distinct().OrderBy(s => s.Category(), categoryComparer).ThenBy(s => s, segmentComparer)
                                                                                .Select(s => new SegmentMappingsTableSegmentViewModel(s, _soundType)).Concat(new SegmentMappingsTableSegmentViewModel(null, _soundType)).ToArray());
            _categories = new ReadOnlyList <SegmentCategoryViewModel>(_segments.GroupBy(s => s.DomainSegment == null ? string.Empty : s.DomainSegment.Category())
                                                                      .OrderBy(g => g.Key, categoryComparer).Select(g => new SegmentCategoryViewModel(g.Key, g)).ToArray());

            var mappingLookup = new Dictionary <UnorderedTuple <string, string>, HashSet <UnorderedTuple <string, string> > >();

            foreach (SegmentMappingViewModel mapping in mappings)
            {
                string        seg1, seg2;
                FeatureSymbol leftEnv1, rightEnv1, leftEnv2, rightEnv2;
                if (ListSegmentMappings.Normalize(projectService.Project.Segmenter, mapping.Segment1, out seg1, out leftEnv1, out rightEnv1) &&
                    ListSegmentMappings.Normalize(projectService.Project.Segmenter, mapping.Segment2, out seg2, out leftEnv2, out rightEnv2))
                {
                    UnorderedTuple <string, string>            key = UnorderedTuple.Create(seg1, seg2);
                    HashSet <UnorderedTuple <string, string> > m   = mappingLookup.GetOrCreate(key, () => new HashSet <UnorderedTuple <string, string> >());
                    m.Add(UnorderedTuple.Create(mapping.Segment1, mapping.Segment2));
                }
            }

            IWordAligner aligner = projectService.Project.WordAligners[ComponentIdentifiers.PrimaryWordAligner];

            foreach (SegmentMappingsTableSegmentViewModel segment1 in _segments)
            {
                bool isEnabled = true;
                foreach (SegmentMappingsTableSegmentViewModel segment2 in _segments)
                {
                    if (EqualityComparer <Segment> .Default.Equals(segment1.DomainSegment, segment2.DomainSegment))
                    {
                        isEnabled = false;
                    }

                    int delta = segment1.DomainSegment == null || segment2.DomainSegment == null ? -1
                                                : aligner.Delta(segment1.DomainSegment.FeatureStruct, segment2.DomainSegment.FeatureStruct);
                    SegmentMappingsTableSegmentPairViewModel segmentPair = segmentPairFactory(segment1, segment2, delta, isEnabled);
                    segmentPair.MeetsThreshold = delta != -1 && delta <= _threshold;
                    HashSet <UnorderedTuple <string, string> > pairMappings;
                    if (mappingLookup.TryGetValue(UnorderedTuple.Create(segment1.StrRep, segment2.StrRep), out pairMappings))
                    {
                        segmentPair.Mappings.Mappings.AddRange(pairMappings.Select(m => mappingFactory(m.Item1, m.Item2)));
                    }
                    segment1.SegmentPairs.Add(segmentPair);
                }
            }
        }
Exemplo n.º 21
0
		protected override UnorderedTuple<Segment, Segment> GetKeyForItem(SoundCorrespondence item)
		{
			return UnorderedTuple.Create(item.Segment1, item.Segment2);
		}
Exemplo n.º 22
0
		public bool Remove(Segment seg1, Segment seg2)
		{
			return Remove(UnorderedTuple.Create(seg1, seg2));
		}
Exemplo n.º 23
0
		public bool Contains(Segment seg1, Segment seg2)
		{
			return Contains(UnorderedTuple.Create(seg1, seg2));
		}
Exemplo n.º 24
0
		public bool TryGet(Segment seg1, Segment seg2, out SoundCorrespondence value)
		{
			return TryGet(UnorderedTuple.Create(seg1, seg2), out value);
		}
Exemplo n.º 25
0
        public void UpdateComponent()
        {
            var thresholdSegmentMappings = new ThresholdSegmentMappings(_projectService.Project, _threshold, ComponentIdentifiers.PrimaryWordAligner);
            var listSegmentMappings      = new ListSegmentMappings(_projectService.Project.Segmenter, _mappings.Mappings.Select(m => UnorderedTuple.Create(m.Segment1, m.Segment2)), _implicitComplexSegments);

            SegmentMappings = new UnionSegmentMappings(new ISegmentMappings[] { thresholdSegmentMappings, listSegmentMappings });
        }
Exemplo n.º 26
0
        public IBidirectionalGraph <Cluster <T>, ClusterEdge <T> > GenerateClusters(IEnumerable <T> dataObjects)
        {
            var tree     = new BidirectionalGraph <Cluster <T>, ClusterEdge <T> >(false);
            var clusters = new List <Cluster <T> >();

            foreach (T dataObject in dataObjects)
            {
                var cluster = new Cluster <T>(dataObject)
                {
                    Description = dataObject.ToString()
                };
                clusters.Add(cluster);
                tree.AddVertex(cluster);
            }
            var distances = new Dictionary <UnorderedTuple <Cluster <T>, Cluster <T> >, double>();
            var heights   = new Dictionary <Cluster <T>, double>();

            for (int i = 0; i < clusters.Count; i++)
            {
                for (int j = i + 1; j < clusters.Count; j++)
                {
                    double distance = _getDistance(clusters[i].DataObjects.First(), clusters[j].DataObjects.First());
                    if (double.IsNaN(distance) || double.IsInfinity(distance) || distance < 0)
                    {
                        throw new ArgumentException("Invalid distance between data objects.", "dataObjects");
                    }
                    distances[UnorderedTuple.Create(clusters[i], clusters[j])] = distance;
                }
                heights[clusters[i]] = 0;
            }

            while (clusters.Count >= 2)
            {
                int    minI = 0, minJ = 0;
                double minDist = double.MaxValue;
                for (int i = 0; i < clusters.Count; i++)
                {
                    for (int j = i + 1; j < clusters.Count; j++)
                    {
                        double dist = distances[UnorderedTuple.Create(clusters[i], clusters[j])];
                        if (dist < minDist)
                        {
                            minDist = dist;
                            minI    = i;
                            minJ    = j;
                        }
                    }
                }

                Cluster <T> iCluster = clusters[minI];
                Cluster <T> jCluster = clusters[minJ];
                distances.Remove(UnorderedTuple.Create(iCluster, jCluster));

                var uCluster = new Cluster <T>();
                tree.AddVertex(uCluster);

                double height = minDist / 2;
                heights[uCluster] = height;

                int    iCount = tree.GetAllDataObjects(iCluster).Count();
                double iLen   = height - heights[iCluster];
                if (iLen <= 0 && !tree.IsOutEdgesEmpty(iCluster))
                {
                    foreach (ClusterEdge <T> edge in tree.OutEdges(iCluster))
                    {
                        tree.AddEdge(new ClusterEdge <T>(uCluster, edge.Target, edge.Length));
                    }
                    tree.RemoveVertex(iCluster);
                }
                else
                {
                    tree.RemoveInEdgeIf(iCluster, edge => true);
                    tree.AddEdge(new ClusterEdge <T>(uCluster, iCluster, Math.Max(iLen, 0)));
                }

                int    jCount = tree.GetAllDataObjects(jCluster).Count();
                double jLen   = height - heights[jCluster];
                if (jLen <= 0 && !tree.IsOutEdgesEmpty(jCluster))
                {
                    foreach (ClusterEdge <T> edge in tree.OutEdges(jCluster))
                    {
                        tree.AddEdge(new ClusterEdge <T>(uCluster, edge.Target, edge.Length));
                    }
                    tree.RemoveVertex(jCluster);
                }
                else
                {
                    tree.RemoveInEdgeIf(jCluster, edge => true);
                    tree.AddEdge(new ClusterEdge <T>(uCluster, jCluster, Math.Max(jLen, 0)));
                }

                double iWeight = (double)iCount / (iCount + jCount);
                double jWeight = (double)jCount / (iCount + jCount);
                foreach (Cluster <T> kCluster in clusters.Where(c => c != iCluster && c != jCluster))
                {
                    UnorderedTuple <Cluster <T>, Cluster <T> > kiKey = UnorderedTuple.Create(kCluster, iCluster);
                    UnorderedTuple <Cluster <T>, Cluster <T> > kjKey = UnorderedTuple.Create(kCluster, jCluster);
                    distances[UnorderedTuple.Create(uCluster, kCluster)] = (iWeight * distances[kiKey]) + (jWeight * distances[kjKey]);
                    distances.Remove(kiKey);
                    distances.Remove(kjKey);
                }
                clusters.RemoveAt(minJ);
                clusters.RemoveAt(minI);
                clusters.Add(uCluster);
            }

            return(tree);
        }
Exemplo n.º 27
0
        public IUndirectedGraph <Cluster <T>, ClusterEdge <T> > GenerateClusters(IEnumerable <T> dataObjects)
        {
            var tree     = new BidirectionalGraph <Cluster <T>, ClusterEdge <T> >(false);
            var clusters = new List <Cluster <T> >();

            foreach (T dataObject in dataObjects)
            {
                var cluster = new Cluster <T>(dataObject)
                {
                    Description = dataObject.ToString()
                };
                clusters.Add(cluster);
                tree.AddVertex(cluster);
            }
            var distances = new Dictionary <UnorderedTuple <Cluster <T>, Cluster <T> >, double>();

            for (int i = 0; i < clusters.Count; i++)
            {
                for (int j = i + 1; j < clusters.Count; j++)
                {
                    double distance = _getDistance(clusters[i].DataObjects.First(), clusters[j].DataObjects.First());
                    if (double.IsNaN(distance) || double.IsInfinity(distance) || distance < 0)
                    {
                        throw new ArgumentException("Invalid distance between data objects.", "dataObjects");
                    }
                    distances[UnorderedTuple.Create(clusters[i], clusters[j])] = distance;
                }
            }

            while (clusters.Count > 2)
            {
                Dictionary <Cluster <T>, double> r = clusters.ToDictionary(c => c, c => clusters.Where(oc => oc != c).Sum(oc => distances[UnorderedTuple.Create(c, oc)] / (clusters.Count - 2)));
                int    minI = 0, minJ = 0;
                double minDist = 0, minQ = double.MaxValue;
                for (int i = 0; i < clusters.Count; i++)
                {
                    for (int j = i + 1; j < clusters.Count; j++)
                    {
                        double dist = distances[UnorderedTuple.Create(clusters[i], clusters[j])];
                        double q    = dist - r[clusters[i]] - r[clusters[j]];
                        if (q < minQ)
                        {
                            minQ    = q;
                            minDist = dist;
                            minI    = i;
                            minJ    = j;
                        }
                    }
                }

                Cluster <T> iCluster = clusters[minI];
                Cluster <T> jCluster = clusters[minJ];
                distances.Remove(UnorderedTuple.Create(iCluster, jCluster));

                var uCluster = new Cluster <T>();
                tree.AddVertex(uCluster);

                double iLen = (minDist / 2) + ((r[iCluster] - r[jCluster]) / 2);
                if (iLen <= 0 && !tree.IsOutEdgesEmpty(iCluster))
                {
                    foreach (ClusterEdge <T> edge in tree.OutEdges(iCluster))
                    {
                        tree.AddEdge(new ClusterEdge <T>(uCluster, edge.Target, edge.Length));
                    }
                    tree.RemoveVertex(iCluster);
                }
                else
                {
                    tree.RemoveInEdgeIf(iCluster, edge => true);
                    tree.AddEdge(new ClusterEdge <T>(uCluster, iCluster, Math.Max(iLen, 0)));
                }
                double jLen = minDist - iLen;
                if (jLen <= 0 && !tree.IsOutEdgesEmpty(jCluster))
                {
                    foreach (ClusterEdge <T> edge in tree.OutEdges(jCluster))
                    {
                        tree.AddEdge(new ClusterEdge <T>(uCluster, edge.Target, edge.Length));
                    }
                    tree.RemoveVertex(jCluster);
                }
                else
                {
                    tree.RemoveInEdgeIf(jCluster, edge => true);
                    tree.AddEdge(new ClusterEdge <T>(uCluster, jCluster, Math.Max(jLen, 0)));
                }

                foreach (Cluster <T> kCluster in clusters.Where(c => c != iCluster && c != jCluster))
                {
                    UnorderedTuple <Cluster <T>, Cluster <T> > kiKey = UnorderedTuple.Create(kCluster, iCluster);
                    UnorderedTuple <Cluster <T>, Cluster <T> > kjKey = UnorderedTuple.Create(kCluster, jCluster);
                    distances[UnorderedTuple.Create(kCluster, uCluster)] = (distances[kiKey] + distances[kjKey] - minDist) / 2;
                    distances.Remove(kiKey);
                    distances.Remove(kjKey);
                }
                clusters.RemoveAt(minJ);
                clusters.RemoveAt(minI);
                clusters.Add(uCluster);
            }

            if (clusters.Count == 2)
            {
                tree.AddEdge(new ClusterEdge <T>(clusters[1], clusters[0], distances[UnorderedTuple.Create(clusters[0], clusters[1])]));
                clusters.RemoveAt(0);
            }

            var unrootedTree = new UndirectedGraph <Cluster <T>, ClusterEdge <T> >(false);

            unrootedTree.AddVertexRange(tree.Vertices);
            unrootedTree.AddEdgeRange(tree.Edges);
            return(unrootedTree);
        }
Exemplo n.º 28
0
        public override object UpdateComponent()
        {
            _similarVowels.UpdateComponent();
            _similarConsonants.UpdateComponent();
            var cognateIdentifier = new BlairCognateIdentifier(_segmentPool, _ignoreRegularInsertionDeletion, _regularConsEqual,
                                                               _automaticRegularCorrespondenceThreshold, _defaultRegularCorrepondenceThreshold,
                                                               new ListSegmentMappings(_projectService.Project.Segmenter, _ignoredMappings.Mappings.Select(m => UnorderedTuple.Create(m.Segment1, m.Segment2)), false),
                                                               new TypeSegmentMappings(_similarVowels.SegmentMappings, _similarConsonants.SegmentMappings));

            _projectService.Project.CognateIdentifiers[ComponentIdentifiers.PrimaryCognateIdentifier] = cognateIdentifier;
            return(cognateIdentifier);
        }