Esempio n. 1
0
        }   // End getEigenvalue(double[,] SecondDerivMatrix)

        public void SetAllEigenvaluesIteratively(ClusteringSolution Solution)
        {
            if (Solution.DistributedExecutionMode)
            {
                Exception e = DAVectorUtility.SALSAError(" Illegal Eigenvalue and Parallelization Combination ");
                throw (e);
            }
            if (Program.SigmaMethod > 0)
            {
                Exception e = DAVectorUtility.SALSAError(" Illegal Eigenvalue and Sigma Method Combination " + Program.SigmaMethod.ToString());
                throw (e);
            }
            this.CurrentSolution        = Solution;
            this.CenterEigenvector      = this.CurrentSolution.Eigenvector_k_i;
            this.CenterEigenvalue       = this.CurrentSolution.Eigenvalue_k;
            this.InitVector             = new double[Program.ParameterVectorDimension];
            this.FirstTerm              = new double[this.CurrentSolution.Ncent_Global];
            this.CenterEigenstatus      = new int[this.CurrentSolution.Ncent_Global];
            this.CenterEigenconvergence = new int[this.CurrentSolution.Ncent_Global];

            Random random   = new Random();
            double InitNorm = 0.0;

            for (int VectorIndex = 0; VectorIndex < Program.ParameterVectorDimension; VectorIndex++)
            {
                InitVector[VectorIndex] = -0.5 + random.NextDouble();
                InitNorm += InitVector[VectorIndex] * InitVector[VectorIndex];
            }
            InitNorm = 1.0 / Math.Sqrt(InitNorm);
            for (int VectorIndex = 0; VectorIndex < Program.ParameterVectorDimension; VectorIndex++)
            {
                InitVector[VectorIndex] *= InitNorm;
            }

            //  Initialization Loop over Clusters
            int somethingtodo = 0;

            for (int ClusterIndex = 0; ClusterIndex < this.CurrentSolution.Ncent_Global; ClusterIndex++)
            {
                this.CenterEigenconvergence[ClusterIndex] = 0;
                this.CenterEigenstatus[ClusterIndex]      = 0;
                this.FirstTerm[ClusterIndex] = 0;
                if (this.CurrentSolution.Splittable_k_[ClusterIndex] != 1)
                {
                    continue;
                }
                ++somethingtodo;
                for (int VectorIndex = 0; VectorIndex < Program.ParameterVectorDimension; VectorIndex++)
                {
                    this.CenterEigenvector[ClusterIndex][VectorIndex] = InitVector[VectorIndex];
                }
            }   // End Loop over Clusters
            if (somethingtodo == 0)
            {
                return;
            }

            GlobalReductions.FindVectorDoubleSum FindClusterFirstTerm     = new GlobalReductions.FindVectorDoubleSum(DAVectorUtility.ThreadCount, this.CurrentSolution.Ncent_Global);
            GlobalReductions.FindDoubleSum       FindNumberScalarProducts = new GlobalReductions.FindDoubleSum(DAVectorUtility.ThreadCount);

            for (int NumPowerIterations = 0; NumPowerIterations < Program.PowerIterationLimit; NumPowerIterations++)
            {
                somethingtodo = 0;
                for (int ClusterIndex = 0; ClusterIndex < this.CurrentSolution.Ncent_Global; ClusterIndex++)
                {
                    if (this.CurrentSolution.LocalStatus[ClusterIndex] != 1)
                    {
                        continue;
                    }
                    if (this.CurrentSolution.Splittable_k_[ClusterIndex] != 1)
                    {
                        continue;
                    }
                    if (this.CenterEigenconvergence[ClusterIndex] == 0)
                    {
                        ++somethingtodo;
                    }
                }
                if (somethingtodo == 0)
                {
                    break;
                }

                GlobalReductions.FindVectorDoubleSum3 FindNewPowerVectors = new GlobalReductions.FindVectorDoubleSum3(DAVectorUtility.ThreadCount,
                                                                                                                      Program.ParameterVectorDimension, this.CurrentSolution.Ncent_Global);

                Parallel.For(0, Program.ParallelOptions.MaxDegreeOfParallelism, Program.ParallelOptions, (ThreadNo) =>
                {
                    FindNewPowerVectors.startthread(ThreadNo);
                    double[] PartVector = new double[Program.ParameterVectorDimension];

                    int indexlen   = DAVectorUtility.PointsperThread[ThreadNo];
                    int beginpoint = DAVectorUtility.StartPointperThread[ThreadNo] - DAVectorUtility.PointStart_Process;
                    for (int alpha = beginpoint; alpha < indexlen + beginpoint; alpha++)
                    {
                        int IndirectSize = this.CurrentSolution.NumClusters_alpha_[alpha];

                        for (int IndirectClusterIndex = 0; IndirectClusterIndex < IndirectSize; IndirectClusterIndex++)
                        {   // Loop over Clusters for this point
                            int RealClusterIndex   = -1;
                            int RemoteIndex        = -1;
                            int ActiveClusterIndex = -1;
                            VectorAnnealIterate.ClusterPointersforaPoint(alpha, IndirectClusterIndex, ref RealClusterIndex, ref ActiveClusterIndex, ref RemoteIndex);
                            if (this.CurrentSolution.Splittable_k_[RealClusterIndex] != 1)
                            {
                                continue;
                            }

                            double Mvalue = this.CurrentSolution.M_alpha_kpointer_[alpha][IndirectClusterIndex];
                            if (NumPowerIterations == 0)
                            {
                                FindClusterFirstTerm.addapoint(ThreadNo, Mvalue, RealClusterIndex);
                            }
                            double multiplier = 0.0;
                            for (int VectorIndex = 0; VectorIndex < Program.ParameterVectorDimension; VectorIndex++)
                            {
                                PartVector[VectorIndex] = this.CurrentSolution.Y_k_i_[RealClusterIndex][VectorIndex] - Program.PointPosition[alpha][VectorIndex];
                                multiplier += PartVector[VectorIndex] * CenterEigenvector[RealClusterIndex][VectorIndex];
                            }
                            FindNumberScalarProducts.addapoint(ThreadNo, 1.0);

                            double wgt = Mvalue * multiplier;
                            for (int VectorIndex = 0; VectorIndex < Program.ParameterVectorDimension; VectorIndex++)
                            {
                                PartVector[VectorIndex] *= wgt;
                            }
                            FindNewPowerVectors.addapoint(ThreadNo, PartVector, RealClusterIndex);
                        }
                    } // End Loop over points
                });   // End loop initialing Point dependent quantities

                FindNewPowerVectors.sumoverthreadsandmpi();
                for (int ClusterIndex = 0; ClusterIndex < this.CurrentSolution.Ncent_Global; ClusterIndex++)
                {
                    if (this.CurrentSolution.LocalStatus[ClusterIndex] != 1)
                    {
                        continue;
                    }
                    if ((this.CurrentSolution.Splittable_k_[ClusterIndex] != 1) || (this.CenterEigenconvergence[ClusterIndex] != 0))
                    {
                        continue;
                    }
                    double[] sums = new double[3];  // Old.New Old.Old New.New
                    for (int loop = 0; loop < 3; loop++)
                    {
                        sums[loop] = 0.0;
                    }
                    for (int VectorIndex = 0; VectorIndex < Program.ParameterVectorDimension; VectorIndex++)
                    {
                        int    TotalIndex = VectorIndex + ClusterIndex * Program.ParameterVectorDimension;
                        double newvalue   = FindNewPowerVectors.TotalVectorSum[TotalIndex];
                        double oldvalue   = CenterEigenvector[ClusterIndex][VectorIndex];
                        sums[0] += oldvalue * newvalue;
                        sums[1] += oldvalue * oldvalue;
                        sums[2] += newvalue * newvalue;
                        CenterEigenvector[ClusterIndex][VectorIndex] = newvalue;
                    }

                    //  Decide if finished and set eigenvalue
                    double CandidateEigenvalue = sums[0] / sums[1];
                    bool   LegalEigenvalue     = (CandidateEigenvalue > 0.0);
                    DAVectorUtility.SynchronizeMPIvariable(ref LegalEigenvalue);

                    //	Check if converged
                    //	Do this in one process ONLY
                    if ((NumPowerIterations > 5) && LegalEigenvalue)
                    { // Arbitrary choice for Number of Power Iterations Cut
                        int EigenvalueDone = 0;
                        if (DAVectorUtility.MPI_Rank == 0)
                        { // Decisions can only be made in one process
                            if (Math.Abs(CandidateEigenvalue - this.CenterEigenvalue[ClusterIndex]) > CandidateEigenvalue * Program.eigenvaluechange)
                            {
                                ++EigenvalueDone;
                            }
                            double delta = sums[2] - 2.0 * sums[0] * CandidateEigenvalue + sums[1] * CandidateEigenvalue * CandidateEigenvalue;   // (Ax- Eigenvalue*Axold)**2
                            if (Math.Abs(delta) > CandidateEigenvalue * CandidateEigenvalue * Program.eigenvectorchange)
                            {
                                ++EigenvalueDone;
                            }
                        }   // End Test on Convergence
                        DAVectorUtility.SynchronizeMPIvariable(ref EigenvalueDone);

                        if (EigenvalueDone == 0)
                        {
                            this.CenterEigenconvergence[ClusterIndex] = 1 + NumPowerIterations;
                        }
                    }
                    this.CenterEigenvalue[ClusterIndex] = CandidateEigenvalue;

                    //  Normalize current Power Vector to 1
                    double wgt = 1.0 / Math.Sqrt(sums[2]);
                    for (int VectorIndex = 0; VectorIndex < Program.ParameterVectorDimension; VectorIndex++)
                    {
                        CenterEigenvector[ClusterIndex][VectorIndex] *= wgt;
                    }
                } // End Loop over Clusters
            }     //  End Loop over NumPowerIterations

            FindClusterFirstTerm.sumoverthreadsandmpi();
            FindNumberScalarProducts.sumoverthreadsandmpi();
            Program.SumEigenSPCalcs += FindNumberScalarProducts.Total;

            for (int ClusterIndex = 0; ClusterIndex < this.CurrentSolution.Ncent_Global; ClusterIndex++)
            {
                this.CenterEigenstatus[ClusterIndex] = 0;
                if (this.CurrentSolution.LocalStatus[ClusterIndex] != 1)
                {
                    continue;
                }
                if ((this.CurrentSolution.Splittable_k_[ClusterIndex] != 1) || (this.CenterEigenconvergence[ClusterIndex] <= 0))
                {
                    continue;
                }
                this.CenterEigenstatus[ClusterIndex] = 1;
                this.FirstTerm[ClusterIndex]         = FindClusterFirstTerm.TotalVectorSum[ClusterIndex];
                double tmp = this.CenterEigenvalue[ClusterIndex] / this.CurrentSolution.Temperature;
                this.CenterEigenvalue[ClusterIndex] = this.FirstTerm[ClusterIndex] - tmp;
            }
        }   // End SetEigenvaluesIteratively(ClusteringSolution Solution)
Esempio n. 2
0
        }   // End GetClusterRadius

        // Use LastClusterCenter if Size 0
        public static void FindClusterCenters(bool begin, int[] NearestCentertoPoint, double[] Distance_NearestCentertoPoint, double[][] LastClusterCenter)
        {   // Calculate Cluster Parameters
            GlobalReductions.FindVectorDoubleSum3 FindCenterVectorSums = new GlobalReductions.FindVectorDoubleSum3(DAVectorUtility.ThreadCount,
                                                                                                                   Kmeans.ParameterVectorDimension, Kmeans.Ncent_Global);
            GlobalReductions.FindVectorIntSum    FindCenterSizeSums = new GlobalReductions.FindVectorIntSum(DAVectorUtility.ThreadCount, Kmeans.Ncent_Global);
            GlobalReductions.FindVectorDoubleMax FindClusterRadius  = new GlobalReductions.FindVectorDoubleMax(DAVectorUtility.ThreadCount, Kmeans.Ncent_Global);
            GlobalReductions.FindVectorDoubleSum FindClusterWidth   = new GlobalReductions.FindVectorDoubleSum(DAVectorUtility.ThreadCount, Kmeans.Ncent_Global);
            ;
            Parallel.For(0, Kmeans._parallelOptions.MaxDegreeOfParallelism, Kmeans._parallelOptions, (ThreadIndex) =>
            {
                FindCenterVectorSums.startthread(ThreadIndex);
                FindCenterSizeSums.startthread(ThreadIndex);
                int indexlen   = DAVectorUtility.PointsperThread[ThreadIndex];
                int beginpoint = DAVectorUtility.StartPointperThread[ThreadIndex] - DAVectorUtility.PointStart_Process;
                for (int alpha = beginpoint; alpha < indexlen + beginpoint; alpha++)
                {
                    int ClusterIndex = NearestCentertoPoint[alpha];
                    if ((ClusterIndex >= Kmeans.Ncent_Global) || (ClusterIndex < 0))
                    {
                        Exception e = DAVectorUtility.SALSAError("Illegal Cluster Index " + ClusterIndex.ToString() + " Number " + Kmeans.Ncent_Global.ToString()
                                                                 + " Point " + (alpha + DAVectorUtility.PointStart_Process).ToString() + " Rank " + DAVectorUtility.MPI_Rank.ToString());
                        throw (e);
                    }
                    FindCenterVectorSums.addapoint(ThreadIndex, PointPosition[alpha], ClusterIndex);
                    FindCenterSizeSums.addapoint(ThreadIndex, 1, ClusterIndex);
                    if (!begin)
                    {
                        FindClusterRadius.addapoint(ThreadIndex, Distance_NearestCentertoPoint[alpha], ClusterIndex);
                        FindClusterWidth.addapoint(ThreadIndex, Distance_NearestCentertoPoint[alpha] * Distance_NearestCentertoPoint[alpha], ClusterIndex);
                    }
                } // End loop over Points
            });   // End Sum over Threads

            FindCenterVectorSums.sumoverthreadsandmpi();
            FindCenterSizeSums.sumoverthreadsandmpi();
            if (!begin)
            {
                FindClusterRadius.sumoverthreadsandmpi();
                FindClusterWidth.sumoverthreadsandmpi();
            }
            Kmeans.AverageRadius       = 0.0;
            Kmeans.AverageWidth        = 0.0;
            Kmeans.AverageCenterChange = 0.0;

            if (Kmeans.UseParallelismoverCenters)
            {   // Centers Parallel over Threads NOT nodes
                double[] AccumulateRadius       = new double[DAVectorUtility.ThreadCount];
                double[] AccumulateWidth        = new double[DAVectorUtility.ThreadCount];
                double[] AccumulateCenterChange = new double[DAVectorUtility.ThreadCount];
                for (int ThreadIndex = 0; ThreadIndex < DAVectorUtility.ThreadCount; ThreadIndex++)
                {
                    AccumulateRadius[ThreadIndex]       = 0.0;
                    AccumulateWidth[ThreadIndex]        = 0.0;
                    AccumulateCenterChange[ThreadIndex] = 0.0;
                }

                Parallel.For(0, Kmeans._parallelOptions.MaxDegreeOfParallelism, Kmeans._parallelOptions, (ThreadIndex) =>
                {
                    int indexlen   = KmeansTriangleInequality.LocalParallel_CentersperThread[ThreadIndex];
                    int beginpoint = KmeansTriangleInequality.LocalParallel_StartCenterperThread[ThreadIndex];
                    for (int CenterIndex = beginpoint; CenterIndex < indexlen + beginpoint; CenterIndex++)
                    {
                        Kmeans.ClusterSize[CenterIndex] = FindCenterSizeSums.TotalVectorSum[CenterIndex];

                        if (Kmeans.ClusterSize[CenterIndex] > 0)
                        {
                            double divisor = 1.0 / (double)Kmeans.ClusterSize[CenterIndex];
                            for (int VectorIndex = 0; VectorIndex < Kmeans.ParameterVectorDimension; VectorIndex++)
                            {
                                int totalindex = VectorIndex + CenterIndex * Kmeans.ParameterVectorDimension;
                                Kmeans.ClusterCenter[CenterIndex][VectorIndex] = FindCenterVectorSums.TotalVectorSum[totalindex] * divisor;
                            }

                            if (!begin)
                            {
                                Kmeans.ClusterRadius[CenterIndex]    = FindClusterRadius.TotalVectorMax[CenterIndex];
                                Kmeans.ClusterWidth[CenterIndex]     = FindClusterWidth.TotalVectorSum[CenterIndex];
                                AccumulateRadius[ThreadIndex]       += Kmeans.ClusterRadius[CenterIndex];
                                AccumulateWidth[ThreadIndex]        += Kmeans.ClusterWidth[CenterIndex];
                                AccumulateCenterChange[ThreadIndex] += DAVectorParallelism.getNOTSquaredUNScaledDistancebetweenVectors(Kmeans.ClusterCenter[CenterIndex], LastClusterCenter[CenterIndex]);
                            }
                        }
                        else
                        {   // Zero Size Cluster
                            if (begin)
                            {
                                Exception e = DAVectorUtility.SALSAError("Empty Input Cluster " + CenterIndex.ToString() + " Number " + Kmeans.Ncent_Global.ToString()
                                                                         + " Rank " + DAVectorUtility.MPI_Rank.ToString());
                                throw (e);
                            }
                            for (int VectorIndex = 0; VectorIndex < Kmeans.ParameterVectorDimension; VectorIndex++)
                            {
                                Kmeans.ClusterCenter[CenterIndex][VectorIndex] = LastClusterCenter[CenterIndex][VectorIndex];
                            }
                            Kmeans.ClusterRadius[CenterIndex] = 0.0;
                            Kmeans.ClusterWidth[CenterIndex]  = 0.0;
                        }
                    }
                }); // End Sum over Threads
                if (!begin)
                {
                    for (int ThreadIndex = 0; ThreadIndex < DAVectorUtility.ThreadCount; ThreadIndex++)
                    {
                        Kmeans.AverageRadius       += AccumulateRadius[ThreadIndex];
                        Kmeans.AverageWidth        += AccumulateWidth[ThreadIndex];
                        Kmeans.AverageCenterChange += AccumulateCenterChange[ThreadIndex];
                    }
                }
            }

            else
            {   // Centers Sequential
                for (int CenterIndex = 0; CenterIndex < Kmeans.Ncent_Global; CenterIndex++)
                {
                    Kmeans.ClusterSize[CenterIndex] = FindCenterSizeSums.TotalVectorSum[CenterIndex];

                    if (Kmeans.ClusterSize[CenterIndex] > 0)
                    {
                        double divisor = 1.0 / (double)Kmeans.ClusterSize[CenterIndex];
                        for (int VectorIndex = 0; VectorIndex < Kmeans.ParameterVectorDimension; VectorIndex++)
                        {
                            int totalindex = VectorIndex + CenterIndex * Kmeans.ParameterVectorDimension;
                            Kmeans.ClusterCenter[CenterIndex][VectorIndex] = FindCenterVectorSums.TotalVectorSum[totalindex] * divisor;
                        }

                        if (!begin)
                        {
                            Kmeans.ClusterRadius[CenterIndex] = FindClusterRadius.TotalVectorMax[CenterIndex];
                            Kmeans.ClusterWidth[CenterIndex]  = FindClusterWidth.TotalVectorSum[CenterIndex];
                            Kmeans.AverageRadius       += Kmeans.ClusterRadius[CenterIndex];
                            Kmeans.AverageWidth        += Kmeans.ClusterWidth[CenterIndex];
                            Kmeans.AverageCenterChange += DAVectorParallelism.getNOTSquaredUNScaledDistancebetweenVectors(Kmeans.ClusterCenter[CenterIndex], LastClusterCenter[CenterIndex]);
                        }
                    }
                    else
                    {
                        if (begin)
                        {
                            Exception e = DAVectorUtility.SALSAError("Empty Input Cluster " + CenterIndex.ToString() + " Number " + Kmeans.Ncent_Global.ToString()
                                                                     + " Rank " + DAVectorUtility.MPI_Rank.ToString());
                            throw (e);
                        }
                        Kmeans.ClusterRadius[CenterIndex] = 0.0;
                        Kmeans.ClusterWidth[CenterIndex]  = 0.0;
                        for (int VectorIndex = 0; VectorIndex < Kmeans.ParameterVectorDimension; VectorIndex++)
                        {
                            Kmeans.ClusterCenter[CenterIndex][VectorIndex] = LastClusterCenter[CenterIndex][VectorIndex];
                        }
                    }
                }   // End Sequential Center Loop
            }

            if (begin)
            {
                return;
            }
            Kmeans.AverageCenterChange = Kmeans.AverageCenterChange / Kmeans.Ncent_Global;
            Kmeans.AverageRadius       = Kmeans.AverageRadius / Kmeans.Ncent_Global;
            Kmeans.AverageWidth        = Kmeans.AverageWidth / DAVectorUtility.PointCount_Global;
            return;
        }   // End FindClusterCenters(int[] NearestCentertoPoint, double[][] LastClusterCenter)