示例#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);
        }
示例#2
0
        // End VectorSum(double[] VTotal, double[] V2, double sign, double[] V1)

        public static void InitializeParameters(Desertwind Solution, int CountStartingPoints)
        {
            // Inversion
            InvertSolution = false;
            if ((CountStartingPoints / 2) * 2 != CountStartingPoints)
            {
                InvertSolution = true;
            }

            for (int LocalVectorIndex1 = 0; LocalVectorIndex1 < PointVectorDimension; LocalVectorIndex1++)
            {
                for (int LocalVectorIndex2 = 0; LocalVectorIndex2 < PointVectorDimension; LocalVectorIndex2++)
                {
                    CurrentCosmicScaling[LocalVectorIndex1, LocalVectorIndex2] = 0.0;
                }
                CurrentCosmicScaling[LocalVectorIndex1, LocalVectorIndex1] = 1.0;
            }
            if (InvertSolution)
            {
                for (int LocalVectorIndex1 = 0; LocalVectorIndex1 < PointVectorDimension; LocalVectorIndex1++)
                {
                    CurrentCosmicScaling[LocalVectorIndex1, LocalVectorIndex1] = -1.0;
                }
                if (PointVectorDimension == 2)
                {
                    CurrentCosmicScaling[0, 0] = 1.0;
                }
            }
            for (int LocalVectorIndex1 = 0; LocalVectorIndex1 < PointVectorDimension; LocalVectorIndex1++)
            {
                for (int LocalVectorIndex2 = 0; LocalVectorIndex2 < PointVectorDimension; LocalVectorIndex2++)
                {
                    SavedCosmicScaling[CountStartingPoints][LocalVectorIndex1, LocalVectorIndex2] =
                        CurrentCosmicScaling[LocalVectorIndex1, LocalVectorIndex2];
                }
            }

            //  Scaling
            double Scale = FirstScale / SecondScale;

            if (ScaleOption == 0)
            {
                Solution.param[ScalePosition][0] = Scale;
            }
            else
            {
                ScaleA1 = 0.5 * (ScaleAlpha + 1.0 / ScaleAlpha);
                ScaleA2 = 0.5 * Math.Abs(ScaleAlpha - 1.0 / ScaleAlpha);
                Solution.param[ScalePosition][0] = Math.Asin((ScaleA1 - 1.0) / ScaleA2);
                ScaleA1 *= Scale;
                ScaleA2 *= Scale;
            }

            var Randobject   = new Random();
            var RandomAngles = new double[3];

            if (SALSAUtility.MPI_Rank == 0)
            {
                for (int irand = 0; irand < 3; irand++)
                {
                    RandomAngles[irand] = Randobject.NextDouble();
                }
            }
            if (SALSAUtility.MPI_Size > 1)
            {
                SALSAUtility.StartSubTimer(SALSAUtility.MPIBROADCASTTiming);
                SALSAUtility.MPI_communicator.Broadcast(ref RandomAngles, 0);
                SALSAUtility.StopSubTimer(SALSAUtility.MPIBROADCASTTiming);
            }


            //  Translation and Rotation
            for (int LocalVectorIndex = 0; LocalVectorIndex < PointVectorDimension; LocalVectorIndex++)
            {
                Solution.param[LocalVectorIndex][0] = FirstMean[LocalVectorIndex] - Scale *
                                                      CurrentCosmicScaling[LocalVectorIndex, LocalVectorIndex] *
                                                      SecondMean[LocalVectorIndex];
                if (PointVectorDimension == 3)
                {
                    Solution.param[LocalVectorIndex + PointVectorDimension][0] = 0.0;
                    if (CountStartingPoints > 1)
                    {
                        Solution.param[LocalVectorIndex + PointVectorDimension][0] = Math.PI *
                                                                                     RandomAngles[LocalVectorIndex];
                    }
                }
            }
            if (PointVectorDimension == 2)
            {
                Solution.param[2][0] = 0.0;
                if (CountStartingPoints > 1)
                {
                    Solution.param[2][0] = Math.PI * RandomAngles[0];
                }
            }
        }
示例#3
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);
        }
示例#4
0
        // End SetupRotateMDS()

        public static bool Calcfg(Desertwind Solution)
        {
            // call Accum with value and derivative for each point

            bool   violat     = false;
            double Scale      = 1.0;
            double DerivScale = 1.0;

            if (ScaleOption == 0)
            {
                if ((Solution.param[ScalePosition][0] < 0.0) && (RotationOption_invert == 0))
                {
                    violat = true;
                    Solution.param[ScalePosition][0] = -Solution.param[ScalePosition][0];
                }
                Solution.param[ScalePosition][0] = Math.Max(ScaleAlpha * FirstScale / SecondScale,
                                                            Solution.param[ScalePosition][0]);
                Scale = Solution.param[ScalePosition][0];
            }
            else
            {
                Solution.param[ScalePosition][0] = ProperAngle(Solution.param[ScalePosition][0]);
                Scale      = CalculateScale(Solution.param[ScalePosition][0]);
                DerivScale = DifferentiateScale(Solution.param[ScalePosition][0]);
                // SALSAUtility.SALSAPrint(0, "Scale DerivScale " + Scale.ToString("E4") + " " + DerivScale.ToString("E4"));
            }

            //  Force Angles between -PI and PI
            if (PointVectorDimension == 3)
            {
                for (int LocalVectorIndex = 0; LocalVectorIndex < PointVectorDimension; LocalVectorIndex++)
                {
                    Solution.param[LocalVectorIndex + PointVectorDimension][0] =
                        ProperAngle(Solution.param[LocalVectorIndex + PointVectorDimension][0]);
                }
            }
            if (PointVectorDimension == 2)
            {
                Solution.param[2][0] = ProperAngle(Solution.param[2][0]);
            } // End Force Angles between -PI and PI

            //  Each Value is weight * (Scaling * Cosmic * Rotation * Second Vector + Translation - First Vector)
            //  Each Derivative is weight * ( Scaling * Cosmic * Rotation Term * Second Vectot + Treanslation Term )
            //  Rotation, Rotation Term, Translation, Translation Term are independent of Point
            //  weight depends on Option Used

            var Translation        = new double[PointVectorDimension];
            var Rotation           = new double[PointVectorDimension, PointVectorDimension];
            var DerivTranslation   = new double[Hotsun.npar][];
            var DerivRotationScale = new double[Hotsun.npar][, ];
            var SubRotation        = new double[NumberSubRotations][, ];
            var SubDeriveRotation  = new double[NumberSubRotations][, ];

            for (int ipar = 0; ipar < Hotsun.npar; ipar++)
            {
                DerivTranslation[ipar]   = new double[PointVectorDimension];
                DerivRotationScale[ipar] = new double[PointVectorDimension, PointVectorDimension];
                for (int LocalVectorIndex1 = 0; LocalVectorIndex1 < PointVectorDimension; LocalVectorIndex1++)
                {
                    DerivTranslation[ipar][LocalVectorIndex1] = 0.0;
                    for (int LocalVectorIndex2 = 0; LocalVectorIndex2 < PointVectorDimension; LocalVectorIndex2++)
                    {
                        if (ipar < PointVectorDimension)
                        {
                            DerivRotationScale[ipar][LocalVectorIndex1, LocalVectorIndex2] = 0.0;
                        }
                        // Rotation Matrix Zero for Translations
                    }
                }
            }

            for (int LocalVectorIndex = 0; LocalVectorIndex < PointVectorDimension; LocalVectorIndex++)
            {
                Translation[LocalVectorIndex] = Solution.param[LocalVectorIndex][0]; // Translations
                DerivTranslation[LocalVectorIndex][LocalVectorIndex] = 1.0;          // Deriv of Translation
            }

            for (int SubRotationIndex = 0; SubRotationIndex < NumberSubRotations; SubRotationIndex++)
            {
                SubRotation[SubRotationIndex]       = new double[PointVectorDimension, PointVectorDimension];
                SubDeriveRotation[SubRotationIndex] = new double[PointVectorDimension, PointVectorDimension];
                for (int LocalVectorIndex1 = 0; LocalVectorIndex1 < PointVectorDimension; LocalVectorIndex1++)
                {
                    for (int LocalVectorIndex2 = 0; LocalVectorIndex2 < PointVectorDimension; LocalVectorIndex2++)
                    {
                        SubDeriveRotation[SubRotationIndex][LocalVectorIndex1, LocalVectorIndex2] = 0.0;
                        SubRotation[SubRotationIndex][LocalVectorIndex1, LocalVectorIndex2]       = 0.0;
                    }
                }
                SetRotationMatrix(SubRotation[SubRotationIndex], SubRotationIndex,
                                  Solution.param[PointVectorDimension + SubRotationIndex][0], false);
                SetRotationMatrix(SubDeriveRotation[SubRotationIndex], SubRotationIndex,
                                  Solution.param[PointVectorDimension + SubRotationIndex][0], true);
            }
            if (PointVectorDimension == 3)
            {
                SetTotalRotation(Rotation, Scale, CurrentCosmicScaling, SubRotation[2], SubRotation[1], SubRotation[0]);
                SetTotalRotation(DerivRotationScale[PointVectorDimension], Scale, CurrentCosmicScaling, SubRotation[2],
                                 SubRotation[1], SubDeriveRotation[0]);                 // Rotation for First Angle
                SetTotalRotation(DerivRotationScale[PointVectorDimension + 1], Scale, CurrentCosmicScaling,
                                 SubRotation[2], SubDeriveRotation[1], SubRotation[0]); // Rotation for Second Angle
                SetTotalRotation(DerivRotationScale[PointVectorDimension + 2], Scale, CurrentCosmicScaling,
                                 SubDeriveRotation[2], SubRotation[1], SubRotation[0]); // Rotation for Third Angle
                SetTotalRotation(DerivRotationScale[ScalePosition], DerivScale, CurrentCosmicScaling, SubRotation[2],
                                 SubRotation[1], SubRotation[0]);                       // Rotation for Scale
            }
            if (PointVectorDimension == 2)
            {
                SetTotalRotation(Rotation, Scale, CurrentCosmicScaling, SubRotation[0]);
                SetTotalRotation(DerivRotationScale[PointVectorDimension], Scale, CurrentCosmicScaling,
                                 SubDeriveRotation[0]); // Rotation for First Angle
                SetTotalRotation(DerivRotationScale[ScalePosition], DerivScale, CurrentCosmicScaling, SubRotation[0]);
                // Rotation for Scale
            }

            //  Set up Accum
            GenericManxcat.ReInitializeAccum();

            //  Finally Loop over entries in Chisq
            Parallel.For(0, SALSAUtility.ParallelOptions.MaxDegreeOfParallelism, SALSAUtility.ParallelOptions,
                         (ThreadNo) =>
            {
                var DerivativeFl = new double[PointVectorDimension][];
                for (int LocalVectorIndex = 0;
                     LocalVectorIndex < PointVectorDimension;
                     LocalVectorIndex++)
                {
                    DerivativeFl[LocalVectorIndex] = new double[Hotsun.npar];
                }

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

                for (int DistributedPointIndex = beginpoint;
                     DistributedPointIndex < indexlen + beginpoint;
                     DistributedPointIndex++)
                {
                    int GlobalIndex = SALSAUtility.PointStart_Process + DistributedPointIndex;

                    // Setting weight to Math.Sqrt(1.0/SALSAUtility.PointCount_Global)* Fudge Factor/FirstScale
                    double weight = Math.Sqrt(1.0 / SALSAUtility.PointCount_Global) *
                                    ManxcatCentral.ChisqFunctionCalcMultiplier / FirstScale;

                    // RotationOption =0 is simple least squares sum; RotationOption = 1 implies use fractional errors
                    if (RotationOption == 1)
                    {
                        double size = 0.0;
                        for (int LocalVectorIndex = 0;
                             LocalVectorIndex < PointVectorDimension;
                             LocalVectorIndex++)
                        {
                            size += FirstData[GlobalIndex][LocalVectorIndex] *
                                    FirstData[GlobalIndex][LocalVectorIndex];
                        }
                        size    = Math.Sqrt(size);
                        size    = Math.Max(MinimumDistance, size);
                        weight *= FirstScale / size;
                    }

                    var ValueFl = new double[PointVectorDimension];
                    MatrixVectorProduct(ValueFl, Rotation, SecondData[GlobalIndex]);
                    VectorSum(ValueFl, Translation, +1.0, ValueFl);
                    VectorSum(ValueFl, ValueFl, -1.0, FirstData[GlobalIndex]);
                    for (int LocalVectorIndex = 0;
                         LocalVectorIndex < PointVectorDimension;
                         LocalVectorIndex++)
                    {
                        ValueFl[LocalVectorIndex] *= weight;
                    }


                    for (int ipar = 0; ipar < Hotsun.npar; ipar++)
                    {
                        if (ipar < PointVectorDimension)
                        {
                            // Translation Derivatives
                            for (int LocalVectorIndex = 0;
                                 LocalVectorIndex < PointVectorDimension;
                                 LocalVectorIndex++)
                            {
                                DerivativeFl[LocalVectorIndex][ipar] = weight *
                                                                       DerivTranslation[ipar][
                                    LocalVectorIndex];
                            }
                        }
                        else
                        {
                            var tempvector = new double[PointVectorDimension];
                            MatrixVectorProduct(tempvector, DerivRotationScale[ipar],
                                                SecondData[GlobalIndex]);
                            for (int LocalVectorIndex = 0;
                                 LocalVectorIndex < PointVectorDimension;
                                 LocalVectorIndex++)
                            {
                                DerivativeFl[LocalVectorIndex][ipar] = weight *
                                                                       tempvector[LocalVectorIndex];
                            }
                        }
                    }
                    for (int LocalVectorIndex = 0;
                         LocalVectorIndex < PointVectorDimension;
                         LocalVectorIndex++)
                    {
                        GenericManxcat.Accum(ThreadNo, ValueFl[LocalVectorIndex],
                                             DerivativeFl[LocalVectorIndex]);
                        if (GlobalIndex <= 0)
                        {
                            string deriv = "";
                            for (int ipar = 0; ipar < Hotsun.npar; ipar++)
                            {
                                deriv += DerivativeFl[LocalVectorIndex][ipar].ToString("E4") + " ";
                            }
                            // SALSAUtility.SALSAPrint(0, "Val " +  ValueFl[LocalVectorIndex].ToString("f4") + " Drv " + deriv);
                            GenericManxcat.AccumDebug(GlobalIndex);
                        }
                        if (GlobalIndex > (SALSAUtility.PointCount_Global - 2))
                        {
                            GenericManxcat.AccumDebug(GlobalIndex);
                        }
                    }
                }                // End loop over points in this thread
            });                  // End loop initialing Point dependent quantities

            // Add up MPI and Thread Contributions
            GenericManxcat.AddupChisqContributions(Solution);

            return(violat);
        }