Beispiel #1
0
        private void InitializeManaged(IList <Target> targets, DistanceFunc distance, Func <Target, Extraction> targetToExtraction, Func <Extraction, Pronounceable> extractionToPronounceable)
        {
            this.targets                   = targets;
            this.distance                  = distance;
            this.targetToExtraction        = targetToExtraction;
            this.extractionToPronounceable = extractionToPronounceable;
            this.nativeDistanceDelegate    = this.Distance;

            if (targetToExtraction == null)
            {
                try
                {
                    this.extractions = (IList <Extraction>)targets;
                }
                catch
                {
                    throw new InvalidCastException(string.Format("Can't cast Target type [{0}] to Extraction type [{1}]. You must provide a conversion function 'targetToExtraction'.", typeof(Target), typeof(Extraction)));
                }
            }
            else
            {
                this.extractions = new Extraction[targets.Count];
            }

            if (extractionToPronounceable == null)
            {
                this.pronounceables = (IList <Pronounceable>) this.extractions;
            }
            else
            {
                this.pronounceables = new Pronounceable[targets.Count];
            }
        }
Beispiel #2
0
        private static void AgnesClusteringPrint(IrisData[] irisData, DistanceDelegate calculateDistanceFunction, ClusterDistanceStrategy strategy)
        {
            var irisDataHier = irisData.Select(d => new double[] { d.PetalLength, d.PetalWidth, d.SepalLength, d.SepalWidth }).ToHashSet();
            var hc           = new AgnesClustering(calculateDistanceFunction, irisDataHier);
            var clusters     = hc.Cluster(strategy, 3);

            var i = 0;

            Console.ForegroundColor = ConsoleColor.DarkYellow;
            Console.WriteLine($"Agnes {calculateDistanceFunction.Method.Name} {strategy.ToString()} Predicted:");
            Console.ForegroundColor = ConsoleColor.Gray;
            var res = new IrisData[clusters.Count()][];

            foreach (Cluster cl in clusters)
            {
                var pp            = cl.GetAllPatterns();
                var clusterResult = pp.Select(p => p.GetAttributes()).Select(p => _irisData.First(x =>
                                                                                                  x.PetalLength == p[0] &&
                                                                                                  x.PetalWidth == p[1] &&
                                                                                                  x.SepalLength == p[2] &&
                                                                                                  x.SepalWidth == p[3])).ToArray();

                res[i++] = clusterResult;
            }

            PrintResult(res, irisData.Length);
            Console.WriteLine();
        }
Beispiel #3
0
        private static double CalculateClusteringInformation(
            double[][] data,
            int[] clustering,
            ref int[] centroidIdx,
            int clusterCount,
            ref int[] clusterItemCount,
            DistanceDelegate calculateDistanceFunction)
        {
            var means = CreateMatrix(clusterCount, data[0].Length);

            // Calculate the means for each cluster
            // Do this in two phases, first sum them all up and then divide by the count in each cluster
            for (var i = 0; i < data.Length; i++)
            {
                // Sum up the means
                var row        = data[i];
                var clusterIdx = clustering[i]; // What cluster is data i assigned to
                ++clusterItemCount[clusterIdx]; // Increment the count of the cluster that row i is assigned to
                for (var j = 0; j < row.Length; j++)
                {
                    means[clusterIdx][j] += row[j];
                }
            }

            // Now divide to get the average
            for (var k = 0; k < means.Length; k++)
            {
                for (var a = 0; a < means[k].Length; a++)
                {
                    var itemCount = clusterItemCount[k];
                    means[k][a] /= itemCount > 0 ? itemCount : 1;
                }
            }

            double totalDistance = 0;
            var    minDistances  = new double[clusterCount].Select(x => double.MaxValue).ToArray();

            for (var i = 0; i < data.Length; i++)
            {
                var clusterIdx = clustering[i]; // What cluster is data i assigned to
                var distance   = calculateDistanceFunction(data[i], means[clusterIdx]);
                totalDistance += distance;
                if (distance < minDistances[clusterIdx])
                {
                    minDistances[clusterIdx] = distance;
                    centroidIdx[clusterIdx]  = i;
                }
            }

            return(totalDistance);
        }
Beispiel #4
0
        public void Searcher(ActorRoot _curActor, ActorRoot _inActor, DistanceDelegate _delegate)
        {
            ulong num = _delegate(_curActor.location, _inActor.location);

            if (num < this.maxValue)
            {
                this.targetList.Clear();
                this.maxValue = num;
                this.targetList.Add(_inActor);
            }
            else if (num == this.maxValue)
            {
                this.targetList.Add(_inActor);
            }
        }
        public AgnesClustering(DistanceDelegate distanceFunction, HashSet <double[]> dataSet)
        {
            _clusters      = new Clusters();
            _patternMatrix = new HashSet <Pattern>();

            foreach (var item in dataSet)
            {
                _pattern    = new Pattern();
                _pattern.Id = _patternIndex;
                _pattern.AddAttributes(item);
                _patternMatrix.Add(_pattern);
                _patternIndex++;
            }

            this._distanceFunction = distanceFunction;
        }
Beispiel #6
0
        private static void KMeansWithDistanceFunc(IrisData[] irisData, DistanceDelegate calculateDistanceFunction)
        {
            Console.WriteLine();
            var results = new List <KMeans.Result <IrisData> >(25);

            for (int i = 0; i < results.Capacity; i++)
            {
                var result = KMeans.Cluster(calculateDistanceFunction, irisData, 3);
                results.Add(result);
            }

            var bestResult = results.Aggregate((minItem, nextItem) => minItem.TotalDistance < nextItem.TotalDistance ? minItem : nextItem);

            Console.ForegroundColor = ConsoleColor.DarkYellow;
            Console.WriteLine($"KMeans {calculateDistanceFunction.Method.Name} Predicted:");
            Console.ForegroundColor = ConsoleColor.Gray;
            PrintResult(bestResult.Clusters, irisData.Length, bestResult.Iteration);
        }
Beispiel #7
0
        public static Result <T> Cluster <T>(DistanceDelegate calculateDistanceFunction, T[] items, int clusterCount, int maxIterations = 10)
        {
            var data = ConvertToVectors(items);

            var    hasChanges    = true;
            var    iteration     = 0;
            double totalDistance = 0;
            var    numData       = data.Length;

            // Create a random initial clustering assignment
            var clustering = InitializeClustering(numData, clusterCount);

            var centroidIdx      = new int[clusterCount];
            var clusterItemCount = new int[clusterCount];

            // Perform the clustering
            while (hasChanges && iteration < maxIterations)
            {
                clusterItemCount = new int[clusterCount];
                totalDistance    = CalculateClusteringInformation(data, clustering, ref centroidIdx, clusterCount, ref clusterItemCount, calculateDistanceFunction);
                hasChanges       = AssignClustering(data, clustering, centroidIdx, clusterCount, calculateDistanceFunction);
                ++iteration;
            }

            var clusters = new T[clusterCount][];

            for (var k = 0; k < clusters.Length; k++)
            {
                clusters[k] = new T[clusterItemCount[k]];
            }

            var clustersCurIdx = new int[clusterCount];

            for (var i = 0; i < clustering.Length; i++)
            {
                var c = clustering[i];
                clusters[c][clustersCurIdx[c]] = items[i];
                ++clustersCurIdx[c];
            }

            return(new Result <T>(clusters, totalDistance, iteration));
        }
Beispiel #8
0
        public int Spawn(LabeledVector <L> lvector, DistanceDelegate measure, ParallelStrategy parallelStrategy, bool spawnUsingLDA)
        {
            int nSpawnCount = 0;

            if (this.DoesEncloseVector(lvector, measure))
            {
                if (parallelStrategy == ParallelStrategy.Multithreaded)
                {
                    List <Task> lstSpawnThreads = new List <Task>();
                    foreach (SphereEx <L> child in this.Children)
                    {
                        lstSpawnThreads.Add(Task.Factory.StartNew(c =>
                        {
                            nSpawnCount += ((SphereEx <L>)c).Spawn(lvector, measure, ParallelStrategy.SingleThreaded, spawnUsingLDA);
                        }, child, TaskCreationOptions.LongRunning));
                    }

                    Task.WaitAll(lstSpawnThreads.ToArray());
                }
                else
                {
                    foreach (SphereEx <L> child in this.Children)
                    {
                        nSpawnCount += child.Spawn(lvector, measure, ParallelStrategy.SingleThreaded, spawnUsingLDA);
                    }
                }

                if (!spawnUsingLDA)
                {
                    #region Regular Spawn

                    if (!this.Label.Equals(lvector.Label) && !Vector.EqualsEx(this, lvector) && !this.DoesAtLeastOneChildEncloseVector(lvector, measure))
                    {
                        this.AddChild(new SphereEx <L>(this.Radius - measure(this, lvector), lvector));
                        nSpawnCount++;
                    }

                    #endregion
                }
                else
                {
                    #region LDA Spawn

                    if (!this.DoesAtLeastOneChildEncloseVector(lvector, measure))   // Don't care about label as well as location of lvector
                    {
                        bool bContains = false;

                        List <LabeledVector <L> > lst;
                        if (!this.LDAVectors.TryGetValue(lvector.Label, out lst))
                        {
                            this.LDAVectors.Add(lvector.Label, (lst = new List <LabeledVector <L> >()));
                        }
                        else
                        {
                            bContains = lst.Any(v => Vector.EqualsEx(v, lvector));
                        }

                        if (!bContains)
                        {
                            lst.Add(lvector);

                            if (this.LDAVectors.Keys.Count == 2 && !this.Children.Any())
                            {
                                #region If the sphere contains exactly 2 classes, do the following...
                                // 1.  Create another discriminant
                                // 2.  If the discrimant CANNOT separate the classes, do the following...
                                // 2a.    Remove the lvector from the list it was just added to
                                // 2b.    Create new children from the classes
                                // 2c.    Try to spawn the presented LVector in the NEW children
                                // 2d.    Clear the dictionary, LDAVectors
                                // 2e.    If you can't spawn WITHIN the NEW children, add the vector to the this.LDAVectors
                                // 3.  Else (If the discrimant CAN separate the classes), do nothing but assign the property.

                                bool bIsSeparable = false;
                                DiscriminantEx <L> discriminant = null;
                                try
                                {
                                    //bIsSeparable = LDA.IsCompletelySeparatedWithDiscriminant(this.LDAVectors.ElementAt(0).Value, this.LDAVectors.ElementAt(1).Value, this, out discriminant);

                                    bIsSeparable = LDAEx.IsCompletelySeparatedWithDiscriminant(this.LDAVectors.ElementAt(0).Value, this.LDAVectors.ElementAt(1).Value, out discriminant);
                                }
                                catch
                                {
                                    // Just consume, leaving bIsSeparable = false
                                }

                                if (!bIsSeparable)
                                {
                                    lst.RemoveAt(lst.Count - 1);    // Faster than .Remove() as I am not linearly searching

                                    List <SphereEx <L> > lstNewChildren = new List <SphereEx <L> >();
                                    foreach (KeyValuePair <L, List <LabeledVector <L> > > kvp in this.LDAVectors)
                                    {
                                        if (kvp.Value.Any() && !kvp.Key.Equals(this.Label))
                                        {
                                            //Vector vectorCentroid = Vector.Centroid(kvp.Value);

                                            //if (!Vector.EqualsEx(this, vectorCentroid))
                                            //{
                                            //    SphereEx<L> child = new SphereEx<L>(this.Radius - measure(this, vectorCentroid), kvp.Key, (IVector)vectorCentroid);

                                            //    this.AddChild(child);
                                            //    lstNewChildren.Add(child);
                                            //    nSpawnCount++;
                                            //}
                                        }
                                    }

                                    //bool hasSpawned = false;
                                    //foreach (SphereEx<L> child in lstNewChildren)
                                    //{
                                    //    if (child.DoesEncloseVector(lvector, measure))
                                    //    {
                                    //        nSpawnCount += child.Spawn(lvector, measure, ParallelStrategy.SingleThreaded, spawnUsingLDA);
                                    //        hasSpawned = true;
                                    //    }
                                    //}

                                    this.LDAVectors.Clear();

                                    //if (!hasSpawned)
                                    //{
                                    //    this.LDAVectors.Add(lvector.Label, new List<LabeledVector<L>>() { lvector });
                                    //}
                                }
                                else
                                {
                                    this.DiscriminantEx = discriminant;
                                }

                                #endregion
                            }
                            else if (this.LDAVectors.Keys.Count > 2)
                            {
                                #region If the sphere contains 3 or more classes, do the following...
                                // 1.  Create children from the OLDER label-sets
                                // 2.  Try to spawn the presented LVector IN the NEW children just created
                                // 3.  Clear the dictionary, LDAVectors
                                // 4.  If you can't spawn WITHIN the NEW children, add the vector to this.LDAVectors

                                List <SphereEx <L> > lstNewChildren = new List <SphereEx <L> >();

                                foreach (KeyValuePair <L, List <LabeledVector <L> > > kvp in this.LDAVectors)
                                {
                                    if (!kvp.Key.Equals(lvector.Label))
                                    {
                                        Vector vectorCentroid = Vector.Centroid(kvp.Value);

                                        if (!Vector.EqualsEx(this, vectorCentroid))
                                        {
                                            SphereEx <L> child = new SphereEx <L>(this.Radius - measure(this, vectorCentroid), kvp.Key, (IVector)vectorCentroid);

                                            this.AddChild(child);
                                            lstNewChildren.Add(child);
                                            nSpawnCount++;
                                        }
                                    }
                                }

                                //bool hasSpawned = false;
                                //foreach (SphereEx<L> child in lstNewChildren)
                                //{
                                //    if (child.DoesEncloseVector(lvector, measure))
                                //    {
                                //        nSpawnCount += child.Spawn(lvector, measure, ParallelStrategy.SingleThreaded, spawnUsingLDA);
                                //        hasSpawned = true;
                                //    }
                                //}

                                this.LDAVectors.Clear();

                                //if (!hasSpawned)
                                //{
                                //    this.LDAVectors.Add(lvector.Label, new List<LabeledVector<L>>() { lvector });
                                //}

                                #endregion
                            }
                            // Note: If this.LDAVectors.Keys.Count == 1, don't do anything additional.
                        }
                    }

                    #endregion
                }
            }

            return(nSpawnCount);
        }
        public Composite    CreateBehavior_MoveNearTarget(WoWObjectDelegate     target,
                                                          DistanceDelegate      minRange,
                                                          DistanceDelegate      maxRange)
        {
            return (
            new PrioritySelector(context => target(),

                // If we're too far from target, move closer...
                new Decorator(wowObject => (((WoWObject)wowObject).Distance > maxRange()),
                    new Sequence(
                        new DecoratorThrottled(Delay_StatusUpdateThrottle, ret => true,
                            new Action(wowObject =>
                            {
                                TreeRoot.StatusText = string.Format("Moving to {0} (distance: {1:0.0}) ",
                                                                    ((WoWObject)wowObject).Name,
                                                                    ((WoWObject)wowObject).Distance);
                            })),

                        CreateBehavior_InternalMoveTo(() => target().Location)
                    )),

                // If we're too close to target, back up...
                new Decorator(wowObject => (((WoWObject)wowObject).Distance < minRange()),
                    new PrioritySelector(

                        // If backing up, make sure we're facing the target...
                        new Decorator(ret => Me.MovementInfo.MovingBackward,
                            new Action(wowObject => WoWMovement.Face(((WoWObject)wowObject).Guid))),

                        // Start backing up...
                        new Action(wowObject =>
                        {
                            TreeRoot.StatusText = "Too close to \"" + ((WoWObject)wowObject).Name + "\"--backing up";
                            WoWMovement.MoveStop();
                            WoWMovement.Face(((WoWObject)wowObject).Guid);
                            WoWMovement.Move(WoWMovement.MovementDirection.Backwards);
                        })
                        )),

                // We're between MinRange and MaxRange, stop movement and face the target...
                new Decorator(ret => Me.IsMoving,
                    new Sequence(
                        new Action(delegate { WoWMovement.MoveStop(); }),
                        new Action(wowObject => WoWMovement.Face(((WoWObject)wowObject).Guid)),
                        new WaitContinue(Delay_WowClientLagTime, ret => false, new ActionAlwaysSucceed()),
                        new ActionAlwaysFail()      // fall through to next element
                        ))
            ));
        }
Beispiel #10
0
        private static bool AssignClustering(double[][] data, int[] clustering, int[] centroidIdx, int clusterCount, DistanceDelegate calculateDistanceFunction)
        {
            var changed = false;

            for (var i = 0; i < data.Length; i++)
            {
                var minDistance     = double.MaxValue;
                var minClusterIndex = -1;

                for (var k = 0; k < clusterCount; k++)
                {
                    var distance = calculateDistanceFunction(data[i], data[centroidIdx[k]]);
                    if (distance < minDistance)
                    {
                        minDistance     = distance;
                        minClusterIndex = k;
                    }
                }

                // Re-arrange the clustering for datapoint if needed
                if (minClusterIndex != -1 && clustering[i] != minClusterIndex)
                {
                    changed       = true;
                    clustering[i] = minClusterIndex;
                }
            }

            return(changed);
        }
Beispiel #11
0
        public override Sphere <L> Recognize(IVector vector, DistanceDelegate measure, ParallelStrategy parallelStrategy)
        {
            if (this is SphereEx <L> && ((SphereEx <L>) this).DiscriminantEx != null)
            {
                Sphere <L> sphereMinRadius = this.Parent == null ? this : null;

                if (this.DoesEncloseVector(vector, measure))
                {
                    double proj = Accord.Math.Matrix.Dot(this.DiscriminantEx.ProjectionVector, vector.Features);
                    if (proj <= this.DiscriminantEx.ProjectedSetMean)
                    {
                        // Should be the ClassLabelLeft label

                        // Graphical Example:
                        //
                        //      |-------X--------+----------------|       X => Decision point calculated by LDA,     + => Centroid of Sphere
                        //      |-------|                                 <-- If a point falls left of the decision point, I need the segment between | and X.  Remember to divide by 2.0 because it should be a radius.
                        //          ^
                        //          |
                        //      Remember to divide by two as it's a radius

                        double farLeft = Accord.Math.Matrix.Dot(this.DiscriminantEx.ProjectionVector, this.Features) - (this.Radius * this.Radius);
                        if (farLeft > this.DiscriminantEx.ProjectedLeftMean)
                        {
                            // Squared Euclidean may have a problem because the ProjectLeftMean may be left of the hypersphere
                            // As such, add a small buffer (distance between farLeft and ProjectedLeftMean)
                            // This is, perhaps, not the best method, but it works.  Maybe explore other solutions when using Squared Euclidean Distance with LDA.

                            sphereMinRadius = new Sphere <L>((this.DiscriminantEx.ProjectedSetMean - this.DiscriminantEx.ProjectedLeftMean) / 2.0, this.DiscriminantEx.ClassLeft, vector);
                        }
                        else
                        {
                            sphereMinRadius = new Sphere <L>((this.DiscriminantEx.ProjectedSetMean - farLeft) / 2.0, this.DiscriminantEx.ClassLeft, vector);
                        }
                    }
                    else
                    {
                        // Should be the ClassLabelRight label

                        double farRight = Accord.Math.Matrix.Dot(this.DiscriminantEx.ProjectionVector, this.Features) + (this.Radius * this.Radius);

                        if (farRight < this.DiscriminantEx.ProjectedRightMean)
                        {
                            // Squared Euclidean may have a problem because the ProjectRightMean may be right of the hypersphere
                            // As such, add a small buffer (distance between farRight and ProjectedRightMean)
                            // This is, perhaps, not the best method, but it works.  Maybe explore other solutions when using Squared Euclidean Distance with LDA.

                            sphereMinRadius = new Sphere <L>((this.DiscriminantEx.ProjectedRightMean - this.DiscriminantEx.ProjectedSetMean) / 2.0, this.DiscriminantEx.ClassRight, vector);
                        }
                        else
                        {
                            sphereMinRadius = new Sphere <L>((farRight - this.DiscriminantEx.ProjectedSetMean) / 2.0, this.DiscriminantEx.ClassRight, vector);
                        }
                    }
                }

                return(sphereMinRadius);
            }
            else
            {
                return(base.Recognize(vector, measure, parallelStrategy));
            }
        }
Beispiel #12
0
        public int Spawn(LabeledVector <L> lvector, DistanceDelegate measure, ParallelStrategy parallelStrategy, bool spawnUsingLDA)
        {
            int nSpawnCount = 0;

            if (this.DoesEncloseVector(lvector, measure))
            {
                if (parallelStrategy == ParallelStrategy.Multithreaded)
                {
                    List <Task> lstSpawnThreads = new List <Task>();
                    foreach (SphereEx <L> child in this.Children)
                    {
                        lstSpawnThreads.Add(Task.Factory.StartNew(c =>
                        {
                            nSpawnCount += ((SphereEx <L>)c).Spawn(lvector, measure, ParallelStrategy.SingleThreaded, spawnUsingLDA);
                        }, child, TaskCreationOptions.LongRunning));
                    }

                    Task.WaitAll(lstSpawnThreads.ToArray());
                }
                else
                {
                    foreach (SphereEx <L> child in this.Children)
                    {
                        nSpawnCount += child.Spawn(lvector, measure, ParallelStrategy.SingleThreaded, spawnUsingLDA);
                    }
                }

                if (!spawnUsingLDA)
                {
                    #region Regular Spawn

                    if (!this.Label.Equals(lvector.Label) && !Vector.EqualsEx(this, lvector) && !this.DoesAtLeastOneChildEncloseVector(lvector, measure))
                    {
                        SphereEx <L> child = new SphereEx <L>(this.Radius - measure(this, lvector), lvector);
                        child.LDAVectors.Add(child.Label, new List <KeyValuePair <int, LabeledVector <L> > >()
                        {
                            new KeyValuePair <int, LabeledVector <L> >(0, lvector)
                        });
                        this.AddChild(child);
                        nSpawnCount++;
                    }

                    #endregion
                }
                else
                {
                    #region LDA Spawn

                    // Note that LDA Spawn doesn't work with SquaredEuclideanDistance.  I may -- in the future -- do an additional check to see if the vector is contained by the hypersphere with SquaredEuclideanDistance and EuclideanDistance.  If so, this will work.  Until then, I'll leave it as is.
                    if (this.Children.Any())
                    {
                        // Next if-statement a duplicate of the region "Regular Spawn"
                        // Remember, LDA is only applied at nodes with no children (leaf)
                        if (!this.Label.Equals(lvector.Label) && !Vector.EqualsEx(this, lvector) && !this.DoesAtLeastOneChildEncloseVector(lvector, measure))
                        {
                            SphereEx <L> child = new SphereEx <L>(this.Radius - measure(this, lvector), lvector);
                            child.LDAVectors.Add(child.Label, new List <KeyValuePair <int, LabeledVector <L> > >()
                            {
                                new KeyValuePair <int, LabeledVector <L> >(0, lvector)
                            });
                            this.AddChild(child);
                            nSpawnCount++;
                        }
                    }
                    else
                    {
                        bool bContains = false;

                        List <KeyValuePair <int, LabeledVector <L> > > lst;
                        if (!this.LDAVectors.TryGetValue(lvector.Label, out lst))
                        {
                            this.LDAVectors.Add(lvector.Label, (lst = new List <KeyValuePair <int, LabeledVector <L> > >()));
                        }
                        else
                        {
                            bContains = lst.Any(kvp => Vector.EqualsEx(kvp.Value, lvector));
                        }

                        if (!bContains)
                        {
                            lst.Add(new KeyValuePair <int, LabeledVector <L> >(this.LDAVectors.Sum(kvp => kvp.Value.Count), lvector));

                            if (this.LDAVectors.Keys.Count == 2)
                            {
                                #region If the sphere contains exactly 2 classes, do the following...

                                bool bIsSeparable = false;
                                DiscriminantEx <L> discriminant = null;
                                try
                                {
                                    bIsSeparable = LDAEx.IsCompletelySeparatedWithDiscriminant(this.LDAVectors.ElementAt(0).Value.Select(kvp => kvp.Value).ToList(), this.LDAVectors.ElementAt(1).Value.Select(kvp => kvp.Value).ToList(), out discriminant);
                                }
                                catch
                                {
                                    // Just consume, leaving bIsSeparable = false
                                }

                                if (!bIsSeparable)
                                {
                                    bool spawnedAtLeastOnce            = false;
                                    List <LabeledVector <L> > lstCache = this.LDAVectors.SelectMany(kvp => kvp.Value).OrderBy(kvp => kvp.Key).Select(kvp => kvp.Value).ToList();

                                    this.LDAVectors.Clear();
                                    this.DiscriminantEx = null;

                                    foreach (LabeledVector <L> v in lstCache)
                                    {
                                        if (!spawnedAtLeastOnce)
                                        {
                                            int count = this.Spawn(v, measure, ParallelStrategy.SingleThreaded, false);
                                            nSpawnCount       += count;
                                            spawnedAtLeastOnce = count > 0;
                                        }
                                        else
                                        {
                                            nSpawnCount += this.Spawn(v, measure, ParallelStrategy.SingleThreaded, true);
                                        }
                                    }
                                }
                                else
                                {
                                    if (discriminant != null)
                                    {
                                        this.DiscriminantEx = discriminant;
                                    }
                                }

                                #endregion
                            }
                            else if (this.LDAVectors.Keys.Count > 2)
                            {
                                #region If the sphere contains 3 or more classes, do the following...

                                bool spawnedAtLeastOnce            = false;
                                List <LabeledVector <L> > lstCache = this.LDAVectors.SelectMany(kvp => kvp.Value).OrderBy(kvp => kvp.Key).Select(kvp => kvp.Value).ToList();

                                this.LDAVectors.Clear();
                                this.DiscriminantEx = null;

                                foreach (LabeledVector <L> v in lstCache)
                                {
                                    if (!spawnedAtLeastOnce)
                                    {
                                        int count = this.Spawn(v, measure, ParallelStrategy.SingleThreaded, false);
                                        nSpawnCount       += count;
                                        spawnedAtLeastOnce = count > 0;
                                    }
                                    else
                                    {
                                        nSpawnCount += this.Spawn(v, measure, ParallelStrategy.SingleThreaded, true);
                                    }
                                }

                                #endregion
                            }
                            // Note: If this.LDAVectors.Keys.Count == 1, don't do anything additional.
                        }
                    }

                    #endregion
                }
            }

            return(nSpawnCount);
        }
Beispiel #13
0
        public override L RecognizeAsLabel(IVector vector, DistanceDelegate measure, ParallelStrategy parallelStrategy)
        {
            Sphere <L> winner = this.Recognize(vector, measure, parallelStrategy);

            return(winner != null ? winner.Label : default(L));
        }
Beispiel #14
0
 protected static extern NativeResult FuzzyMatcher_Create(int count, DistanceDelegate distance, bool isAccelerated, out IntPtr fuzzyMatcher, StringBuilder errorMsg, ref int bufferSize);