Пример #1
0
        }       // End getEigenvalues

        // Compute the crrelation matrix compared to PairwiseThread. Rest is same as PairwiseThread
        // PassIndicator = 0 Find MAXIMUM eigenvalue  LMAX[kk] in EACH Cluster sector kk
        // PassIndicator = 1 Find MINIMUM eigenvalue in each cluster sector by finding Maximum eigenvalue of (LMAX[kk]-Second Derivative Matrix)

        // Methodology = 1 -- Calculate Power Vector for all Clusters (one per Cluster) from Original Second Derivative Matrix
        // Methodology = 2 -- Calculate Power Vector for all Clusters (one per Cluster) from  modification of second derivative matrix to reflect replication
        //                    for cases like ContinuousClustering=true that cluster can be divided into two with M halved for each case
        // Methodology = 3 -- Calculate Power Vector for ONE Clusters "Clustertoprocess" (Specified in ClusterSelected) from proper modification of second derivative matrix to reflect replication
        //                          Assuming that Clustertoprocess has its M value doubled in previous EM Iteration
        //                  2 and 3 are same except 3 assumes explicit facor of 2 weight in Z in calculation; Methodology=2 assumes no factor of 2
        // Methodology = 4 -- Calculate ONE Power Vector for set of Clusters (Could be just one but specified in ClusterSelected and usually at least two) from proper modification of second derivative matrix to reflect replication
        //                          Assuming NO doubled M values
        // Set Dist.ClusterSelected for all cases ( all zeros if Methodology 1,2)
        // Set ClustertoSplitin Methodology 3 CONSISTENT with Dist.ClusterSelected[ClustertoSplit]=1 being only ONE value
        // Set Dist.PlaceforEigsforMultipleCluster in Methodology 4 to indicate where results stored

        void PairwiseThread_SecDrv(int Methodology, int PassIndicator, double[][] localMalpha_k_, double[] localA_k_, double[][] localBalpha_k_, double[] localC_k_, int localNcent)
        {
            double T             = Dist.RunningPWC.Temperature;
            int    cachelinesize = Program.cachelinesize;

            int[]    UsethisCluster = new int[localNcent];
            double[] AxPattern      = new double[localNcent];
            int      REMOVEZEROEigs = 0;

            if (Methodology == 4)
            {
                REMOVEZEROEigs = 1;
            }

            for (int ClusterIndex = 0; ClusterIndex < localNcent; ClusterIndex++)
            {
                AxPattern[ClusterIndex]      = 1.0;
                UsethisCluster[ClusterIndex] = Dist.ClusterSelected[ClusterIndex];
                if ((Methodology == 3) && (UsethisCluster[ClusterIndex] == 1))
                {
                    eigenconverged[ClusterIndex] = -1;
                }
                if (Methodology < 3)
                {
                    eigenconverged[ClusterIndex] = -1;
                    if ((PassIndicator == 1) && (vectorclass.Eigenvalues_Pass0[ClusterIndex] <= 0.0))
                    {
                        UsethisCluster[ClusterIndex] = 0;
                    }
                }
                if ((Methodology == 4) && (UsethisCluster[ClusterIndex] == 0))
                {
                    REMOVEZEROEigs = 0;
                }
            }
            if (Methodology == 4)
            {
                eigenconverged[Dist.PlaceforEigsforMultipleCluster] = -1;
                int usedclusters = 0;
                for (int ClusterIndex = 0; ClusterIndex < localNcent; ClusterIndex++)
                {
                    if (UsethisCluster[ClusterIndex] > 0)
                    {
                        ++usedclusters;
                    }
                }
                double vectormult    = 1.0;
                double oddmultiplier = 1.0;
                if (usedclusters > 1)
                {
                    int halfused = usedclusters / 2;
                    if (halfused * 2 == usedclusters)
                    {
                        vectormult = 1.0 / Math.Sqrt((double)usedclusters);
                    }
                    else
                    {
                        oddmultiplier = 1.0 + 1.0 / halfused;
                        vectormult    = 1.0 / Math.Sqrt(2.0 * halfused + 3.0 + 1.0 / halfused);
                    }
                }
                for (int ClusterIndex = 0; ClusterIndex < localNcent; ClusterIndex++)
                {
                    if (Dist.ClusterSelected[ClusterIndex] == 0)
                    {
                        AxPattern[ClusterIndex] = 0.0;
                    }
                    else
                    {
                        AxPattern[ClusterIndex] = vectormult;
                        vectormult = -vectormult;
                        if (vectormult > 0.0)
                        {
                            AxPattern[ClusterIndex] *= oddmultiplier;
                        }
                    }
                }
            }   // End Methodology = 4

            Parallel.For(0, Program.ParallelOptions.MaxDegreeOfParallelism, Program.ParallelOptions, (threadIndex) =>
            {
                //	Start Code initializing power vectors Ax oldAx
                int indexlen   = PWCUtility.PointsperThread[threadIndex];
                int beginpoint = PWCUtility.StartPointperThread[threadIndex] - PWCUtility.PointStart_Process;
                for (int ProcessPointIndex = beginpoint; ProcessPointIndex < indexlen + beginpoint; ProcessPointIndex++)
                {
                    for (int ClusterIndex = 0; ClusterIndex < localNcent; ClusterIndex++)
                    {
                        if (Dist.ClusterSelected[ClusterIndex] == 0)
                        {
                            continue;
                        }
                        Ax[ProcessPointIndex][ClusterIndex]    = initialvector[ProcessPointIndex] * AxPattern[ClusterIndex];
                        oldAx[ProcessPointIndex][ClusterIndex] = Ax[ProcessPointIndex][ClusterIndex];
                    }
                }
            });



            double Mfudge = 1.0;

            if (Methodology == 2)
            {
                Mfudge = 0.5;
            }
            bool Subtract_twiceDuplicatedCenter = false;

            if ((Methodology != 1) && (Methodology != 4))
            {
                Subtract_twiceDuplicatedCenter = true;
            }

            MPISecPacket fromafarMandB = new MPISecPacket(MaxlengthMandB);
            MPISecPacket toafarMandB   = new MPISecPacket(MaxlengthMandB);
            MPISecPacket myownMandB    = new MPISecPacket(MaxlengthMandB);

            double[] fromafarAxarray = null;
            double[] toafarAxarray   = null;
            double[] myownAxarray    = null;

            int oldMaxLength2 = int.MinValue;

            for (int NumPowerIterations = 0; NumPowerIterations < Program.PowerIterationLimit; NumPowerIterations++)
            {   // Loop over Power Iterations
                //	Check if any centers are still not converged
                int NumberofAVectorsUsed = 0;
                for (int ClusterIndex = 0; ClusterIndex < localNcent; ClusterIndex++)
                {
                    if (UsethisCluster[ClusterIndex] == 1)
                    {
                        ++NumberofAVectorsUsed;
                    }
                }
                if (NumberofAVectorsUsed == 0)
                {
                    break;
                }
                if ((Methodology == 4) && (vectorclass.eigenconverged[Dist.PlaceforEigsforMultipleCluster] > 0))
                {
                    break;
                }

                // Increment Global Count of Iterations
                ++Program.CountTotalPowerIterations;

                // Loop over MPI calls
                MPI.CompletedStatus MPISecStatus;
                int sendtag    = 0;
                int receivetag = 0;

                if (!MandBset)
                {
                    fromafarMandB.Clear();
                }

                toafarMandB.Clear();
                myownMandB.Clear();

                int Maxlength2 = NumberofAVectorsUsed * PWCUtility.PointCount_Largest;

                if (oldMaxLength2 != Maxlength2)
                {
                    fromafarAxarray = new double[Maxlength2];
                    toafarAxarray   = new double[Maxlength2];
                    myownAxarray    = new double[Maxlength2];
                    oldMaxLength2   = Maxlength2;
                }
                else
                {
                    Array.Clear(fromafarAxarray, 0, Maxlength2);
                    Array.Clear(toafarAxarray, 0, Maxlength2);
                    Array.Clear(myownAxarray, 0, Maxlength2);
                }

                myownMandB.FirstPoint     = PWCUtility.PointStart_Process;
                myownMandB.NumberofPoints = PWCUtility.PointCount_Process;
                if (PWCUtility.PointCount_Process < PWCUtility.PointCount_Largest)
                {
                    int Acount = 0;
                    for (int countC = 0; countC < localNcent; countC++)
                    {
                        int settozero = PWCUtility.PointCount_Process * localNcent + countC;
                        myownMandB.Marray[settozero] = 0.0;
                        myownMandB.Barray[settozero] = 0.0;
                        if (UsethisCluster[countC] == 0)
                        {
                            continue;
                        }
                        myownAxarray[PWCUtility.PointCount_Process * NumberofAVectorsUsed + Acount] = 0.0;
                        ++Acount;
                    }
                }
                int fromprocess = PWCUtility.MPI_Rank - 1;
                if (fromprocess < 0)
                {
                    fromprocess = PWCUtility.MPI_Size - 1;
                }
                int toprocess = PWCUtility.MPI_Rank + 1;
                if (toprocess > PWCUtility.MPI_Size - 1)
                {
                    toprocess = 0;
                }

                //	First communicationloop is local; then we have MPI_Size transfers of data in  a ring through processes
                for (int MPICommunicationSteps = 0; MPICommunicationSteps < PWCUtility.MPI_Size; MPICommunicationSteps++)
                {
                    if (MPICommunicationSteps == 1)
                    {
                        toafarMandB.FirstPoint     = PWCUtility.PointStart_Process;
                        toafarMandB.NumberofPoints = PWCUtility.PointCount_Process;
                        if (PWCUtility.PointCount_Process < PWCUtility.PointCount_Largest)
                        {
                            int Acount = 0;
                            for (int ClusterIndex = 0; ClusterIndex < localNcent; ClusterIndex++)
                            {
                                int bigindex = PWCUtility.PointCount_Process * localNcent + ClusterIndex;
                                toafarMandB.Marray[bigindex] = myownMandB.Marray[bigindex];
                                toafarMandB.Barray[bigindex] = myownMandB.Barray[bigindex];
                                if (UsethisCluster[ClusterIndex] == 0)
                                {
                                    continue;
                                }
                                toafarAxarray[PWCUtility.PointCount_Process * NumberofAVectorsUsed + Acount] = myownAxarray[PWCUtility.PointCount_Process * NumberofAVectorsUsed + Acount];
                                ++Acount;
                            }
                        }
                    }
                    if (MPICommunicationSteps > 1)
                    {
                        toafarMandB.FirstPoint     = fromafarMandB.FirstPoint;
                        toafarMandB.NumberofPoints = fromafarMandB.NumberofPoints;
                        if (PWCUtility.PointCount_Process < PWCUtility.PointCount_Largest)
                        {
                            int Acount = 0;
                            for (int ClusterIndex = 0; ClusterIndex < localNcent; ClusterIndex++)
                            {
                                int bigindex = PWCUtility.PointCount_Process * localNcent + ClusterIndex;
                                toafarMandB.Marray[bigindex] = fromafarMandB.Marray[bigindex];
                                toafarMandB.Barray[bigindex] = fromafarMandB.Barray[bigindex];
                                if (UsethisCluster[ClusterIndex] == 0)
                                {
                                    continue;
                                }
                                toafarAxarray[PWCUtility.PointCount_Process * NumberofAVectorsUsed + Acount] = fromafarAxarray[PWCUtility.PointCount_Process * NumberofAVectorsUsed + Acount];
                                ++Acount;
                            }
                        }
                    }
                    if (MPICommunicationSteps > 0)
                    {
                        PWCUtility.StartSubTimer(PWCUtility.MPISENDRECEIVEEigenTiming);
                        if (!MandBset)
                        {
                            PWCUtility.MPI_communicator.SendReceive <MPISecPacket>(toafarMandB, toprocess, sendtag, fromprocess, receivetag, out fromafarMandB, out MPISecStatus);
                            MPISecPacket.Membercopy(ref fromafarMandB, ref MandBRepository[MPICommunicationSteps]);
                        }
                        else
                        {
                            fromafarMandB = MandBRepository[MPICommunicationSteps];
                        }
                        PWCUtility.MPI_communicator.SendReceive <double>(toafarAxarray, toprocess, sendtag, fromprocess, receivetag, ref fromafarAxarray, out MPISecStatus);
                        PWCUtility.StopSubTimer(PWCUtility.MPISENDRECEIVEEigenTiming);
                    }

                    // Communication finished -- now update A vector
                    Parallel.For(0, Program.ParallelOptions.MaxDegreeOfParallelism, Program.ParallelOptions, (ThreadNo) =>
                    {
                        //	Start Code calculating power vectors Ax oldAx
                        double[] DiagonalTerm = new double[localNcent];

                        int indexlen   = PWCUtility.PointsperThread[ThreadNo];
                        int beginpoint = PWCUtility.StartPointperThread[ThreadNo] - PWCUtility.PointStart_Process;

                        for (int ProcessPointIndex = beginpoint; ProcessPointIndex < indexlen + beginpoint; ProcessPointIndex++)
                        {   // Loop over Home Indices
                            int betatotal, betastart;
                            if (MPICommunicationSteps == 0)
                            {
                                betatotal  = PWCUtility.PointCount_Process;
                                betastart  = PWCUtility.PointStart_Process;
                                int Acount = 0;
                                for (int ClusterIndex = 0; ClusterIndex < localNcent; ClusterIndex++)
                                {
                                    int bigindex = ProcessPointIndex * localNcent + ClusterIndex;
                                    myownMandB.Marray[bigindex]  = localMalpha_k_[ProcessPointIndex][ClusterIndex];
                                    myownMandB.Barray[bigindex]  = localBalpha_k_[ProcessPointIndex][ClusterIndex];
                                    toafarMandB.Marray[bigindex] = localMalpha_k_[ProcessPointIndex][ClusterIndex];
                                    toafarMandB.Barray[bigindex] = localBalpha_k_[ProcessPointIndex][ClusterIndex];
                                    if (UsethisCluster[ClusterIndex] == 0)
                                    {
                                        continue;
                                    }
                                    int Aindex = ProcessPointIndex * NumberofAVectorsUsed + Acount;
                                    ++Acount;
                                    toafarAxarray[Aindex] = oldAx[ProcessPointIndex][ClusterIndex];
                                    myownAxarray[Aindex]  = oldAx[ProcessPointIndex][ClusterIndex];
                                    vectorclass.Ax[ProcessPointIndex][ClusterIndex] = 0.0;
                                }
                            }
                            else
                            {
                                betatotal = fromafarMandB.NumberofPoints;
                                betastart = fromafarMandB.FirstPoint;
                                if (MPICommunicationSteps != (PWCUtility.MPI_Size - 1))
                                {
                                    int Acount = 0;
                                    for (int ClusterIndex = 0; ClusterIndex < localNcent; ClusterIndex++)
                                    {
                                        int bigindex = ProcessPointIndex * localNcent + ClusterIndex;
                                        toafarMandB.Marray[bigindex] = fromafarMandB.Marray[bigindex];
                                        toafarMandB.Barray[bigindex] = fromafarMandB.Barray[bigindex];
                                        if (UsethisCluster[ClusterIndex] == 0)
                                        {
                                            continue;
                                        }
                                        int Aindex = ProcessPointIndex * NumberofAVectorsUsed + Acount;
                                        ++Acount;
                                        toafarAxarray[Aindex] = fromafarAxarray[Aindex];
                                    }
                                }
                            }

                            for (int ClusterIndex = 0; ClusterIndex < localNcent; ClusterIndex++)
                            {
                                if (UsethisCluster[ClusterIndex] == 0)
                                {
                                    continue;
                                }
                                double tmp = localMalpha_k_[ProcessPointIndex][ClusterIndex] * Mfudge;
                                if (!Subtract_twiceDuplicatedCenter)
                                {
                                    tmp -= tmp * tmp;
                                }
                                // DiagonalTerm[ClusterIndex] = tmp / T;
                                DiagonalTerm[ClusterIndex] = tmp;
                            }

                            for (int betalocal = 0; betalocal < betatotal; betalocal++)
                            {
                                int betafull          = betastart + betalocal;
                                double dijforthiscase = PWCParallelism.getDistanceValue(ProcessPointIndex + PWCUtility.PointStart_Process, betafull);

                                bool PointIndicesEqual = (betafull == (ProcessPointIndex + PWCUtility.PointStart_Process));

                                for (int CenterVectorMu = 0; CenterVectorMu < localNcent; CenterVectorMu++)
                                {   // Start loop over Left Vector Cluster Index
                                    double MalphaMu = localMalpha_k_[ProcessPointIndex][CenterVectorMu];

                                    int AMucount = 0;
                                    if (UsethisCluster[CenterVectorMu] == 0)
                                    {
                                        continue;
                                    }
                                    AMucount++;
                                    for (int CenterVectorLambda = 0; CenterVectorLambda < localNcent; CenterVectorLambda++)
                                    {   // Start Loop over Right Vector Cluster Index
                                        int ALambdacount = 0;
                                        if (UsethisCluster[CenterVectorLambda] == 0)
                                        {
                                            continue;
                                        }
                                        int ALambdaindex = betalocal * NumberofAVectorsUsed + ALambdacount;
                                        ALambdacount++;
                                        if ((Methodology < 4) && (CenterVectorLambda != CenterVectorMu))
                                        {
                                            continue;
                                        }
                                        double MbetaLambda, AxbetaLambda;
                                        if (MPICommunicationSteps == 0)
                                        {
                                            MbetaLambda  = localMalpha_k_[betalocal][CenterVectorLambda];
                                            AxbetaLambda = oldAx[betalocal][CenterVectorLambda];
                                        }
                                        else
                                        {
                                            MbetaLambda  = fromafarMandB.Marray[betalocal * localNcent + CenterVectorLambda];
                                            AxbetaLambda = fromafarAxarray[ALambdaindex];
                                        }

                                        double FirstTerm = 0;
                                        if (PointIndicesEqual && (CenterVectorMu == CenterVectorLambda))
                                        {
                                            FirstTerm = DiagonalTerm[CenterVectorMu];
                                        }
                                        if ((Methodology == 4) && PointIndicesEqual && (CenterVectorMu != CenterVectorLambda))
                                        {
                                            FirstTerm = -MalphaMu * MbetaLambda;
                                            //  FirstTerm = -MalphaMu * MbetaLambda / T;
                                        }
                                        double tmp = 0.0;
                                        for (int CentersSummed = 0; CentersSummed < localNcent; CentersSummed++)
                                        {
                                            double BbetaCenterSummed, MbetaCenterSummed;
                                            if (MPICommunicationSteps == 0)
                                            {
                                                MbetaCenterSummed = localMalpha_k_[betalocal][CentersSummed];
                                                BbetaCenterSummed = localBalpha_k_[betalocal][CentersSummed];
                                            }
                                            else
                                            {
                                                MbetaCenterSummed = fromafarMandB.Marray[betalocal * localNcent + CentersSummed];
                                                BbetaCenterSummed = fromafarMandB.Barray[betalocal * localNcent + CentersSummed];
                                            }
                                            double MMmultiplier;
                                            double Mfudge_CenterCalculated = 1.0;
                                            if (Methodology <= 3)
                                            {
                                                if (CentersSummed == CenterVectorMu)
                                                {
                                                    Mfudge_CenterCalculated = Mfudge;
                                                    if (Subtract_twiceDuplicatedCenter)
                                                    {
                                                        MMmultiplier = 1.0;
                                                    }
                                                    else
                                                    {
                                                        MMmultiplier = (localMalpha_k_[ProcessPointIndex][CentersSummed] * Mfudge_CenterCalculated - 1.0)
                                                                       * (MbetaCenterSummed * Mfudge_CenterCalculated - 1.0);
                                                    }
                                                }
                                                else
                                                {
                                                    if (Subtract_twiceDuplicatedCenter)
                                                    {
                                                        MMmultiplier = 0.0;
                                                        continue;
                                                    }
                                                    else
                                                    {
                                                        MMmultiplier = localMalpha_k_[ProcessPointIndex][CentersSummed] * MbetaCenterSummed;
                                                    }
                                                }
                                            } // End case Methodology <= 3
                                            else
                                            { // Methodology = 4
                                                double DeltaSummedMu     = 0.0;
                                                double DeltaSummedLambda = 0.0;
                                                if (CentersSummed == CenterVectorMu)
                                                {
                                                    DeltaSummedMu = 1.0;
                                                }
                                                if (CentersSummed == CenterVectorLambda)
                                                {
                                                    DeltaSummedLambda = 1.0;
                                                }
                                                MMmultiplier = (localMalpha_k_[ProcessPointIndex][CentersSummed] - DeltaSummedMu) * (MbetaCenterSummed - DeltaSummedLambda);
                                            }

                                            tmp = tmp + (-2.0 * localA_k_[CentersSummed] - BbetaCenterSummed - localBalpha_k_[ProcessPointIndex][CentersSummed] + dijforthiscase) * MMmultiplier / (localC_k_[CentersSummed] * Mfudge_CenterCalculated);
                                        }       // End sum over Summed Centers in Second Derivative Matrix

                                        // double MatrixElement = FirstTerm + ((MalphaMu * MbetaLambda * Mfudge * Mfudge) / (T * T)) * tmp;
                                        double MatrixElement = FirstTerm + ((MalphaMu * MbetaLambda * Mfudge * Mfudge) / T) * tmp;

                                        if (PassIndicator == 1)
                                        {
                                            if (PointIndicesEqual && (CenterVectorMu == CenterVectorLambda))
                                            {
                                                int eigenposition = CenterVectorMu;
                                                if (Methodology == 4)
                                                {
                                                    eigenposition = Dist.PlaceforEigsforMultipleCluster;
                                                }
                                                MatrixElement = Eigenvalues_Pass0[eigenposition] - MatrixElement;
                                            }
                                            else
                                            {
                                                MatrixElement = -MatrixElement;
                                            }
                                        }

                                        vectorclass.Ax[ProcessPointIndex][CenterVectorMu] += MatrixElement * AxbetaLambda;
                                    } // End Loop over Right Matrix Center Indices Lambda
                                }     // End sum over centers (loop over Left Vector Index Mu) in major computation
                            }         // End sum over index beta
                        }             // End loop over index (alpha)
                    });               // End Delegate Code calculating power vectors Ax oldAx
                }                     // End communicationloop

                MandBset = true;
                GlobalReductions.FindVectorDoubleSum Find_sum_t0 = new GlobalReductions.FindVectorDoubleSum(PWCUtility.ThreadCount, localNcent);
                GlobalReductions.FindVectorDoubleSum Find_sum_t1 = new GlobalReductions.FindVectorDoubleSum(PWCUtility.ThreadCount, localNcent);
                GlobalReductions.FindVectorDoubleSum Find_sum_t2 = new GlobalReductions.FindVectorDoubleSum(PWCUtility.ThreadCount, localNcent);

                //	sum over threads to get Power Eigenvalues
                Parallel.For(0, Program.ParallelOptions.MaxDegreeOfParallelism, Program.ParallelOptions, (ThreadNo) =>
                {
                    double[] Accum_t0 = new double[localNcent];
                    double[] Accum_t1 = new double[localNcent];
                    double[] Accum_t2 = new double[localNcent];
                    for (int ClusterIndex = 0; ClusterIndex < localNcent; ClusterIndex++)
                    {
                        Accum_t0[ClusterIndex] = 0.0;
                        Accum_t1[ClusterIndex] = 0.0;
                        Accum_t2[ClusterIndex] = 0.0;
                    }

                    int indexlen   = PWCUtility.PointsperThread[ThreadNo];
                    int beginpoint = PWCUtility.StartPointperThread[ThreadNo] - PWCUtility.PointStart_Process;
                    for (int ProcessPointIndex = beginpoint; ProcessPointIndex < indexlen + beginpoint; ProcessPointIndex++)
                    {
                        double SubtractAverage = 0.0;
                        if (REMOVEZEROEigs == 1)
                        {   // All Clusters used in this case
                            for (int ClusterIndex = 0; ClusterIndex < localNcent; ClusterIndex++)
                            {
                                SubtractAverage += Ax[ProcessPointIndex][ClusterIndex];
                            }
                            SubtractAverage = SubtractAverage / localNcent;
                        }
                        for (int ClusterIndex = 0; ClusterIndex < localNcent; ClusterIndex++)
                        {
                            if (UsethisCluster[ClusterIndex] == 0)
                            {
                                continue;
                            }
                            double tmp = Ax[ProcessPointIndex][ClusterIndex] - SubtractAverage; // Remove null eigenvectors
                            Ax[ProcessPointIndex][ClusterIndex] = tmp;
                            double oldtmp           = oldAx[ProcessPointIndex][ClusterIndex];
                            Accum_t0[ClusterIndex] += tmp * oldtmp;
                            Accum_t1[ClusterIndex] += oldtmp * oldtmp;
                            Accum_t2[ClusterIndex] += tmp * tmp;
                        }
                    }
                    Find_sum_t0.addapoint(ThreadNo, Accum_t0);
                    Find_sum_t1.addapoint(ThreadNo, Accum_t1);
                    Find_sum_t2.addapoint(ThreadNo, Accum_t2);
                });

                Find_sum_t0.sumoverthreadsandmpi();
                Find_sum_t1.sumoverthreadsandmpi();
                Find_sum_t2.sumoverthreadsandmpi();

                double[] AxNormfactor  = new double[localNcent];
                int[]    ActiveAxvalue = new int[localNcent];
                for (int ClusterIndex = 0; ClusterIndex < localNcent; ClusterIndex++)
                {   // ClusterIndex loop checking eigenvalue and status determination for each cluster
                    ActiveAxvalue[ClusterIndex] = UsethisCluster[ClusterIndex];
                    if ((Methodology < 4) && (UsethisCluster[ClusterIndex] == 0))
                    {
                        continue;
                    }
                    if ((Methodology == 4) && (ClusterIndex != Dist.PlaceforEigsforMultipleCluster))
                    {
                        continue;
                    }
                    double[] globalsum_t012 = new double[3];
                    for (int eiglist = 0; eiglist < 3; eiglist++)
                    {
                        globalsum_t012[eiglist] = 0.0;
                    }

                    for (int ClusterSummed = 0; ClusterSummed < localNcent; ClusterSummed++)
                    {   // Cluster Summation for Methodology 4 (CenterSummed == ClusterIndex if Methodology < 4)
                        if ((Methodology < 4) && (ClusterSummed != ClusterIndex))
                        {
                            continue;
                        }

                        if (Methodology < 4)
                        {
                            globalsum_t012[0] = Find_sum_t0.TotalVectorSum[ClusterSummed];
                            globalsum_t012[1] = Find_sum_t1.TotalVectorSum[ClusterSummed];
                            globalsum_t012[2] = Find_sum_t2.TotalVectorSum[ClusterSummed];
                        }   //  End Cluster Summation for Methodology < 4
                        else
                        {
                            double[] globalsum_t012_temp = new double[3];
                            globalsum_t012_temp[0] = Find_sum_t0.TotalVectorSum[ClusterSummed];
                            globalsum_t012_temp[1] = Find_sum_t1.TotalVectorSum[ClusterSummed];
                            globalsum_t012_temp[2] = Find_sum_t2.TotalVectorSum[ClusterSummed];
                            for (int eiglist = 0; eiglist < 3; eiglist++)
                            {
                                globalsum_t012[eiglist] += globalsum_t012_temp[eiglist];
                            }
                        }   //  End Cluster Summation for Methodology 4
                    }

                    double eigenvalue = globalsum_t012[0] / globalsum_t012[1];
                    AxNormfactor[ClusterIndex] = 1.0 / Math.Sqrt(globalsum_t012[2]);

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

                        if (somethingtodo == 0)
                        {
                            vectorclass.eigenconverged[ClusterIndex] = 1 + NumPowerIterations;
                            UsethisCluster[ClusterIndex]             = 0;
                        }
                    }
                    Eigenvalues_Current[ClusterIndex] = eigenvalue;
                }       // End ClusterIndex loop checking eigenvalue status determination for each cluster

                Parallel.For(0, Program.ParallelOptions.MaxDegreeOfParallelism, Program.ParallelOptions, (ThreadNo) =>
                {       //	Code to normalize Power Eigenvalues
                    int indexlen   = PWCUtility.PointsperThread[ThreadNo];
                    int beginpoint = PWCUtility.StartPointperThread[ThreadNo] - PWCUtility.PointStart_Process;
                    for (int PointIndex = beginpoint; PointIndex < indexlen + beginpoint; PointIndex++)
                    {
                        for (int ClusterIndex = 0; ClusterIndex < localNcent; ClusterIndex++)
                        {
                            double Normfactor;
                            if (Methodology == 4)
                            {
                                Normfactor = AxNormfactor[Dist.PlaceforEigsforMultipleCluster];
                            }
                            else
                            {
                                Normfactor = AxNormfactor[ClusterIndex];
                            }
                            if (ActiveAxvalue[ClusterIndex] == 0)
                            {
                                continue;
                            }
                            vectorclass.oldAx[PointIndex][ClusterIndex] = vectorclass.Ax[PointIndex][ClusterIndex] * Normfactor;
                        }
                    }
                });
            } // End NumPowerIterations loop over Power Iteration Method
            return;
        }     // End PairwiseThread_SecDrv
Пример #2
0
        // Find the minimum eigenvalue of second derivative matrix -- called from shouldSplit
        public void getEigenvalues(int Methodology, double[][] localMalpha_k_, double[] localA_k_, double[][] localBalpha_k_, double[] localC_k_, int localNcent)
        {
            int cachelinesize = Program.cachelinesize;

            if (Ax == null)
            {   // Initialize arrays on first call
                Ax    = new double[PWCUtility.PointCount_Process][];
                oldAx = new double[PWCUtility.PointCount_Process][];
                for (int PointIndex = 0; PointIndex < PWCUtility.PointCount_Process; PointIndex++)
                {
                    Ax[PointIndex]    = new double[Program.maxNcent + cachelinesize];
                    oldAx[PointIndex] = new double[Program.maxNcent + cachelinesize];
                }

                Eigenvalues_Current = new double[Program.maxNcent + cachelinesize];
                Eigenvalues_Pass0   = new double[Program.maxNcent + cachelinesize];

                initialvector = new double[PWCUtility.PointCount_Process];
                double fudge = 1.0 / PWCUtility.PointCount_Global;

                GlobalReductions.FindDoubleSum Find_initnorm = new GlobalReductions.FindDoubleSum(PWCUtility.ThreadCount);

                Parallel.For(0, Program.ParallelOptions.MaxDegreeOfParallelism, Program.ParallelOptions, (ThreadNo) =>
                {
                    int indexlen   = PWCUtility.PointsperThread[ThreadNo];
                    int beginpoint = PWCUtility.StartPointperThread[ThreadNo] - PWCUtility.PointStart_Process;
                    for (int ProcessPointIndex = beginpoint; ProcessPointIndex < indexlen + beginpoint; ProcessPointIndex++)
                    {
                        initialvector[ProcessPointIndex] = 1.0 + 0.5 * (ProcessPointIndex + PWCUtility.PointStart_Process) * fudge;
                        Find_initnorm.addapoint(ThreadNo, initialvector[ProcessPointIndex] * initialvector[ProcessPointIndex]);
                    }
                });

                Find_initnorm.sumoverthreadsandmpi();
                double initnorm_global = Find_initnorm.Total;
                initnorm_global = 1.0 / Math.Sqrt(initnorm_global);

                Parallel.For(0, Program.ParallelOptions.MaxDegreeOfParallelism, Program.ParallelOptions, (threadIndex) =>
                {
                    //	Start Delegate Code normalizing initialvector
                    int indexlen   = PWCUtility.PointsperThread[threadIndex];
                    int beginpoint = PWCUtility.StartPointperThread[threadIndex] - PWCUtility.PointStart_Process;
                    for (int ProcessPointIndex = beginpoint; ProcessPointIndex < indexlen + beginpoint; ProcessPointIndex++)
                    {
                        initialvector[ProcessPointIndex] *= initnorm_global;
                    }
                });
            }   // End Initialize arrays on first call

            MaxlengthMandB  = localNcent * PWCUtility.PointCount_Largest;
            MandBRepository = new MPISecPacket[PWCUtility.MPI_Size];
            for (int localrank = 0; localrank < PWCUtility.MPI_Size; localrank++)
            {
                MandBRepository[localrank] = new MPISecPacket(MaxlengthMandB);
            }
            MandBset = false;

            Dist.PlaceforEigsforMultipleCluster = -1;
            // Set in Eigenvalues_Pass0 the maximum eigenvalue per center of second derivative matrix   on first pass
            if (Methodology > 2)
            {
                for (int ClusterIndex = 0; ClusterIndex < localNcent; ClusterIndex++)
                {
                    if (Dist.ClusterSelected[ClusterIndex] == 1)
                    {
                        Dist.PlaceforEigsforMultipleCluster = ClusterIndex;
                        break;
                    }
                }
            }

            //	Invoke PairwiseThread_SecDrv with Flag = 0
            PairwiseThread_SecDrv(Methodology, 0, localMalpha_k_, localA_k_, localBalpha_k_, localC_k_, localNcent);

            // Set in Eigenvalues_Pass0 the maximum eigenvalue per center of second derivative matrix   on first pass
            int[] savestatus = new int[Dist.RunningPWC.Ncent];
            for (int ClusterIndex = 0; ClusterIndex < localNcent; ClusterIndex++)
            {
                if ((Methodology > 2))
                {
                    if (ClusterIndex != Dist.PlaceforEigsforMultipleCluster)
                    {
                        continue;
                    }
                    if ((eigenconverged[ClusterIndex] <= 0) || (Eigenvalues_Current[ClusterIndex] <= 0.0))
                    {
                        Eigenvalues_Pass0[ClusterIndex]   = Eigenvalues_Current[ClusterIndex];
                        eigenconverged[ClusterIndex]      = -1;
                        Eigenvalues_Current[ClusterIndex] = -1.0 + Eigenvalues_Pass0[ClusterIndex];
                        ++Program.CountTotalPowerErrors;
                        MandBset = false;
                        return;
                    }
                }
                Eigenvalues_Pass0[ClusterIndex] = Eigenvalues_Current[ClusterIndex];
                savestatus[ClusterIndex]        = eigenconverged[ClusterIndex];
                if ((eigenconverged[ClusterIndex] <= 0) || (Eigenvalues_Current[ClusterIndex] <= 0.0))
                {
                    ++Program.CountTotalPowerErrors;
                }
            }

            //	Invoke PairwiseThread_SecDrv with Flag = 1
            PairwiseThread_SecDrv(Methodology, 1, localMalpha_k_, localA_k_, localBalpha_k_, localC_k_, localNcent);
            for (int ClusterIndex = 0; ClusterIndex < localNcent; ClusterIndex++)
            {
                if ((Methodology > 2) && (ClusterIndex != Dist.PlaceforEigsforMultipleCluster))
                {
                    continue;
                }
                if (savestatus[ClusterIndex] > 0 && eigenconverged[ClusterIndex] > 0)
                {
                    eigenconverged[ClusterIndex] += savestatus[ClusterIndex];
                }
                if (savestatus[ClusterIndex] > 0 && eigenconverged[ClusterIndex] < 0)
                {
                    ++Program.CountTotalPowerErrors;
                }
            }
            MandBset = false;
            return;
        }       // End getEigenvalues
Пример #3
0
 public static void Membercopy(ref MPISecPacket One, ref MPISecPacket Two)
 {
     Two = (MPISecPacket)One.MemberwiseClone();
     return;
 }