Beispiel #1
0
        // End Initialize() in MDSLinearAlgebra

        //  MaxIndicator = 0 Find Maximum Eigenvalue of Matrix
        //  MaxIndicator = 1 Find Maximum Eigenvalue of (Maximizr - Matrix)
        public static int PowerIterate(Desertwind Solution, int MaxIndicator, double Maximizer,
                                       out double PowerEigenvalue)
        {
            if (DistributedNewIteratedVector == null)
            {
                Initialize();
            }
            Hotsun.UseDiagonalScaling       = true;
            Hotsun.AddMarquardtQDynamically = false;

            //  Set up Initial Power Vectors
            SetInitialPowerVector(DistributedNewIteratedVector);
            double AdotA = SALSABLAS.VectorScalarProduct(DistributedNewIteratedVector, DistributedNewIteratedVector);

            int somethingtodo       = 0;
            int PowerIterationCount = 0;

            PowerEigenvalue = -1.0;
            while (true)
            {
                // Iterate over Power Multiplications by Chisq Matrix

                //  Normalize Current A and move from New to Old

                double OldNorm = 1.0 / Math.Sqrt(AdotA);
                SALSABLAS.LinearCombineVector(DistributedOldIteratedVector, OldNorm,
                                              DistributedNewIteratedVector, 0.0, DistributedNewIteratedVector);

                //  Make a Global Vector of DistributedOldIteratedVector
                ManxcatCentral.MakeVectorGlobal(DistributedOldIteratedVector, GlobalOldIteratedVector);

                //  Form Chisq Matrix Product with Old Vector
                if (Hotsun.FullSecondDerivative)
                {
                    UserRoutines.GlobalMatrixVectorProduct(DistributedNewIteratedVector, Solution, true,
                                                           Hotsun.GlobalParameter, GlobalOldIteratedVector);
                }
                else
                {
                    UserRoutines.GlobalMatrixVectorProduct(DistributedNewIteratedVector, Solution, false,
                                                           Hotsun.GlobalParameter, GlobalOldIteratedVector);
                }

                //  Correct case MaxIndicator = 1
                if (MaxIndicator > 0)
                {
                    SALSABLAS.LinearCombineVector(DistributedNewIteratedVector, -1.0, DistributedNewIteratedVector,
                                                  Maximizer, DistributedOldIteratedVector);
                }
                SALSABLAS.LinearCombineVector(DistributedNewIteratedVector, 1.0, DistributedNewIteratedVector,
                                              Hotsun.addonforQcomputation, DistributedOldIteratedVector);

                //  Form Scalar Products
                double NewEigenvalue = SALSABLAS.VectorScalarProduct(DistributedNewIteratedVector,
                                                                     DistributedOldIteratedVector);
                AdotA = SALSABLAS.VectorScalarProduct(DistributedNewIteratedVector, DistributedNewIteratedVector);

                ++PowerIterationCount;
                somethingtodo = -1;
                if (SALSAUtility.MPI_Rank == 0)
                {
                    if (PowerIterationCount > 10 && (NewEigenvalue > 0.0))
                    {
                        // Arbitary criteria for starting +tests
                        somethingtodo = 0;
                        double scaleit = 1.0;
                        if (MaxIndicator > 0)
                        {
                            scaleit = Hotsun.extraprecision;
                        }
                        if (Math.Abs(NewEigenvalue - PowerEigenvalue) > PowerEigenvalue * scaleit * Hotsun.eigenvaluechange)
                        {
                            ++somethingtodo;
                        }
                        double delta = AdotA - NewEigenvalue * NewEigenvalue; // (Ax- Eigenvalue*Axold)**2
                        if (Math.Abs(delta) > NewEigenvalue * NewEigenvalue * scaleit * Hotsun.eigenvectorchange)
                        {
                            ++somethingtodo;
                        }
                    }
                }
                PowerEigenvalue = NewEigenvalue;

                if (SALSAUtility.MPI_Size > 1)
                {
                    SALSAUtility.StartSubTimer(SALSAUtility.MPIBROADCASTTiming);
                    SALSAUtility.MPI_communicator.Broadcast(ref somethingtodo, 0);
                    SALSAUtility.StopSubTimer(SALSAUtility.MPIBROADCASTTiming);
                }
                if (PowerIterationCount >= Hotsun.PowerIterationLimit)
                {
                    somethingtodo = -2;
                    break;
                }
                if (somethingtodo == 0)
                {
                    somethingtodo = PowerIterationCount;
                    break;
                }
            } // End while over PowerIterationCounts

            return(somethingtodo);
        }
Beispiel #2
0
        // End PowerIterate()

        //  Solve for Distributed Answer = (Matrix-1) First
        //  Note RealMatrixSize takes account of forced zero parameters which does not crop up in explicit
        //  algorithm as implemented in Matrix Vector Multiplier
        public static bool ConjugateGradientSolver(double[][] Answer, Desertwind Solution, bool useexact,
                                                   double[][] GlobalxVector, double[][] DistributedRHS,
                                                   ref int NumberofIterations, int RealMatrixSize, double LimitonNormofR)
        {
            bool matrixsuccess = true;

            //  Initialize
            SALSABLAS.zrword(Answer); // Zero Solution x called xshift in Manxcat and stored in Answer
            SALSABLAS.CopyVector(DistributedCGVector_R, DistributedRHS, 0, SALSAUtility.PointCount_Process);
            // Set R(0) = RHS
            double InitialRNorm = SALSABLAS.VectorScalarProduct(DistributedCGVector_R, DistributedCGVector_R);
            double RNormTest    = InitialRNorm * LimitonNormofR; // Limit for Test on Iteration of Norm of R
            var    SaveRNorm    = new double[RealMatrixSize + 1];

            SaveRNorm[0] = InitialRNorm;
            int CountSteps = 0;

            double lastrho    = 1.0;
            double currentrho = 1.0;

            //  Loop over Conjugate Gradient Steps
            while (true)
            {
                // Set value of rho
                lastrho    = currentrho;
                currentrho = SALSABLAS.VectorScalarProduct(DistributedCGVector_R, DistributedCGVector_R);

                // Set Vector P
                ++CountSteps;
                if (CountSteps == 1)
                {
                    SALSABLAS.CopyVector(DistributedCGVector_P, DistributedCGVector_R, 0,
                                         SALSAUtility.PointCount_Process);
                }
                else
                {
                    SALSABLAS.LinearCombineVector(DistributedCGVector_P, currentrho / lastrho, DistributedCGVector_P,
                                                  1.0, DistributedCGVector_R);
                }

                //  Make a Global Vector of DistributedCGVector_P
                ManxcatCentral.MakeVectorGlobal(DistributedCGVector_P, GlobalCGVector_P);

                //  Distributed Q = Matrix . Global P
                UserRoutines.GlobalMatrixVectorProduct(DistributedCGVector_Q, Solution, useexact,
                                                       Hotsun.GlobalParameter, GlobalCGVector_P);

                //  New Answer is Old answer + (Current Rho / (P dot Q)) Vector P
                double PdotQ = SALSABLAS.VectorScalarProduct(DistributedCGVector_P, DistributedCGVector_Q);
                double alpha = currentrho / PdotQ;
                SALSABLAS.LinearCombineVector(Answer, alpha, DistributedCGVector_P, 1.0, Answer);

                // New residual R = Old Residual - (Current Rho / (P dot Q)) Vector Q
                SALSABLAS.LinearCombineVector(DistributedCGVector_R, -alpha, DistributedCGVector_Q, 1.0,
                                              DistributedCGVector_R);

                //  See if we can or should End
                double CurrentRNorm = SALSABLAS.VectorScalarProduct(DistributedCGVector_R, DistributedCGVector_R);
                SaveRNorm[CountSteps] = CurrentRNorm;
                bool TestRNorm = CurrentRNorm <= RNormTest;
                SALSAUtility.SynchronizeMPIvariable(ref TestRNorm);
                if (TestRNorm)
                {
                    matrixsuccess = true;
                    break;
                }

                // Singular Matrix
                if (CountSteps >= RealMatrixSize)
                {
                    matrixsuccess = false;
                    ManxcatCentral.MakeVectorGlobal(DistributedCGVector_R, GlobalCGVector_R);
                    if (SALSAUtility.MPI_Rank == 0)
                    {
                        SALSAUtility.SALSAPrint(0, " CG Failure after " + RealMatrixSize.ToString() + " Steps");
                        string ListofNorms = "";
                        int    Normindex   = CountSteps;
                        for (int inorm = 0; inorm < 10; inorm++)
                        {
                            ListofNorms += " " + SaveRNorm[Normindex].ToString("E4");
                            --Normindex;
                            if (Normindex < 0)
                            {
                                break;
                            }
                        }
                        SALSAUtility.SALSAPrint(0, "Last 10 Norms " + ListofNorms);

                        string fname = ManxcatCentral.ResultDirectoryName + "\\BadCGVector" +
                                       Hotsun.TotalCGFailures.ToString();
                        var    sw           = new StreamWriter(fname, false, Encoding.UTF8);
                        double fractionnorm = 1.0 / Math.Sqrt(CurrentRNorm);
                        try
                        {
                            for (int GlobalPointIndex = 0;
                                 GlobalPointIndex < SALSAUtility.PointCount_Global;
                                 GlobalPointIndex++)
                            {
                                string Coordinates    = "";
                                int    UsedPointIndex = SALSAUtility.NaivetoActualUsedOrder[GlobalPointIndex];
                                double pointsize      = 0.0;
                                for (int LocalVectorIndex = 0;
                                     LocalVectorIndex < Hotsun.ParameterVectorDimension;
                                     LocalVectorIndex++)
                                {
                                    Coordinates += GlobalCGVector_R[UsedPointIndex][LocalVectorIndex].ToString("E4") +
                                                   "\t";
                                    pointsize += GlobalCGVector_R[UsedPointIndex][LocalVectorIndex] *
                                                 GlobalCGVector_R[UsedPointIndex][LocalVectorIndex];
                                }
                                pointsize = Math.Sqrt(pointsize) * fractionnorm;
                                sw.WriteLine(
                                    String.Format((GlobalPointIndex).ToString() + "\t" + Coordinates + " " +
                                                  pointsize.ToString("E4")));
                            }

                            sw.Flush();
                            sw.Close();
                        }
                        catch (Exception e)
                        {
                            Console.WriteLine("Failed writing data in CG Solver " + e);
                            throw (e);
                        }
                    }
                    break;
                }
            } // End Loop over Conjugate Gradient Steps

            NumberofIterations = CountSteps;
            return(matrixsuccess);
        }