コード例 #1
0
        /// <summary>
        /// see <see cref="IMonkeyImplicitPrecond.DoPrecond"/>
        /// </summary>
        override public void DoPrecond()
        {
            m_PcOutput.CopyFrom(m_PcInput);

            // iterate
            // =======
            for (int i = 1; i < m_NoOfIter; i++)
            {
                // Jacobi iteration
                // ================
                //((CPU.RefMatrix)m_Matrix).useSingle = true;
                m_Matrix.SpMV_Expert(-1.0, _xComm, 0.0, tmp); // tmp = -M*x
                //((CPU.RefMatrix)m_Matrix).useSingle = true;
                tmp.Acc(1.0, m_PcInput);                      // tmp = -M*x + m_PcInput
                if (m_UnderRelaxationFactor != 1.0)
                {
                    tmp.Scale(m_UnderRelaxationFactor);
                }


                if (m_UnderRelaxationFactor != 1.0)
                {
                    tmp.Scale(m_UnderRelaxationFactor);
                }
                tmp.MultiplyElementWise(m_InvDiag);

                m_PcOutput.Acc(1.0, tmp);               //m_PcOutput = m_PcOutput + tmp
            }
        }
コード例 #2
0
ファイル: NeumannSeries.cs プロジェクト: xyuan/BoSSS
        /// <summary>
        /// this function implements the preconditioning according to the neumann preconditioner
        /// </summary>
        public override void DoPrecond()
        {
            mPcOutput.CopyFrom(mPcInput);

            for (int i = 1; i < m_NoOfIter; i++)
            {
                //_yNew = _yOld - m_matrix*_yOld;
                m_matrix.SpMV_Expert(-1.0, _yComm, 0.0, yNew);  //yNew = -m_matrix * yComm = -m_Matrix*yOld
                yNew.Acc(1.0, yOld);                            //yNew = yOld - m_Matrix*yOld;

                mPcOutput.Acc(1.0, yNew);                       //mPcOutput = mPcOutput + yNew
                yOld.Swap(yNew);
            }
        }
コード例 #3
0
        //[DllImport("Kernel32.dll")]
        //static extern bool QueryPerformanceCounter(out long lpPerformanceCount);


        /// <summary>
        /// implementation of the CG algorithm
        /// </summary>
        /// <param name="x"></param>
        /// <param name="rhs"></param>
        /// <param name="stats"></param>
        protected override void CallSolver(VectorBase x, VectorBase rhs, ref SolverResult stats)
        {
            VectorBase P = Device.CreateVector(x.Part);

            VectorBase.CommVector commP = P.CreateCommVector(m_Matrix);

            VectorBase R = rhs; // rhs is only needed once, so we can use it to store residuals
            VectorBase V = Device.CreateVector(x.Part);

            // lock objects
            // ============
            x.Lock();
            P.Lock();
            R.Lock();
            V.Lock();

            m_Matrix.Lock();


            // compute P0, R0
            // ==============

            // we only need to multiply x once by the Matrix, so we don't want to create
            // a seperate VectorBase.CommVector - object for x;
            // Instead, we're temporatily exchangeing the roles of x and P;
            P.Swap(x);
            x.CopyFrom(rhs);                               // x = rhs
            m_Matrix.SpMV_Expert(-1.0, commP, 1.0, x);     // x = rhs - M*x
            P.Swap(x);
            R.CopyFrom(P);

            double alpha   = R.TwoNormSquare();
            double alpha_0 = alpha;
            double ResNorm;

            if (m_ConvergenceType == ConvergenceTypes.Absolute)
            {
                ResNorm = Math.Sqrt(alpha);
            }
            else if (m_ConvergenceType == ConvergenceTypes.Relative)
            {
                ResNorm = 1.0;
            }
            else
            {
                throw new NotImplementedException("unknown convergence type: " + m_ConvergenceType.ToString());
            }

            //long total = 0;
            //long gemv = 0;
            //long rest = 0;
            //long st, en;

            // iterate
            // =======
            stats.Converged      = false;
            stats.NoOfIterations = 1; // one iteration has already been performed (P0, R0)
            for (int n = m_MaxIterations - 2; n >= 0; n--)
            {
                if (ResNorm <= m_Tolerance && stats.NoOfIterations >= base.m_MinIterations)
                {
                    stats.Converged = true;
                    break;
                }

                if (Math.Abs(alpha) <= double.Epsilon)
                {
                    // numerical breakdown
                    break;
                }

                m_Matrix.SpMV_Expert(1.0, commP, 0, V);
                double lambda = alpha / V.InnerProd(P);


                x.Acc(lambda, P);

                R.Acc(-lambda, V);

                double alpha_neu = R.TwoNormSquare();

                // compute residual norm
                if (m_ConvergenceType == ConvergenceTypes.Absolute)
                {
                    ResNorm = Math.Sqrt(alpha);
                }
                else
                {
                    ResNorm = Math.Sqrt(alpha / alpha_0);
                }


                P.Scale(alpha_neu / alpha);
                P.Acc(1.0, R);

                alpha = alpha_neu;
                stats.NoOfIterations++;
                //QueryPerformanceCounter(out st);
                //rest += (st - en);
            }

            //Console.WriteLine("CG: R" + stats.NoOfIterations + " = " + ResNorm);

            // unlock objects
            // ==============
            x.Unlock();
            P.Unlock();
            R.Unlock();
            V.Unlock();

            m_Matrix.Unlock();

            commP.Dispose();
            P.Dispose();
            V.Dispose();
        }
コード例 #4
0
        /// <summary>
        /// implementation of the CG algorithm
        /// </summary>
        /// <param name="x"></param>
        /// <param name="rhs"></param>
        /// <param name="stats"></param>
        protected override void CallSolver(VectorBase x, VectorBase rhs, ref SolverResult stats)
        {
            VectorBase P = Device.CreateVector(x.Part);

            VectorBase.CommVector commP = P.CreateCommVector(m_Matrix);

            VectorBase R = rhs; // rhs is only needed once, so we can use it to store residuals
            VectorBase V = Device.CreateVector(x.Part);
            VectorBase Z = Device.CreateVector(x.Part);

            // lock objects
            // ============
            x.Lock();
            P.Lock();
            R.Lock();
            V.Lock();
            Z.Lock();

            m_Matrix.Lock();


            // configure Precond
            // =================

            if (m_NestedPrecond != null)
            {
                m_NestedPrecond.CreateTempObjects(Z, R, m_Matrix, this.Device);
            }


            // compute P0, R0
            // ==============
            P.Swap(x);
            m_Matrix.SpMV_Expert(-1.0, commP, 1.0, R);
            P.Swap(x);
            if (m_NestedPrecond != null)
            {
                m_NestedPrecond.DoPrecond();
                P.CopyFrom(Z);
            }
            else
            {
                P.CopyFrom(R);
            }

            double alpha   = R.InnerProd(P);
            double alpha_0 = alpha;
            double ResNorm;

            if (m_ConvergenceType == ConvergenceTypes.Absolute)
            {
                ResNorm = Math.Sqrt(alpha);
            }
            else if (m_ConvergenceType == ConvergenceTypes.Relative)
            {
                ResNorm = 1.0;
            }
            else
            {
                throw new NotImplementedException("unknown convergence type: " + m_ConvergenceType.ToString());
            }

            //long total = 0;
            //long gemv = 0;
            //long rest = 0;
            //long st, en;

            // iterate
            // =======
            stats.Converged      = false;
            stats.NoOfIterations = 1; // one iteration has allready been performed (P0, R0)
            for (int n = m_MaxIterations - 2; n >= 0; n--)
            {
                if (ResNorm <= m_Tolerance && stats.NoOfIterations >= base.m_MinIterations)
                {
                    stats.Converged = true;
                    break;
                }

                if (Math.Abs(alpha) <= double.Epsilon)
                {
                    // numerical breakdown
                    break;
                }

                m_Matrix.SpMV_Expert(1.0, commP, 0, V);
                double lambda = alpha / V.InnerProd(P);

                x.Acc(lambda, P);

                R.Acc(-lambda, V);

                if (m_IterationCallback != null)
                {
                    // pass approx. sol and residual to callback function

                    x.Unlock();
                    R.Unlock();

                    double[] x_approx = new double[x.Part.LocalLength];
                    x.CopyTo(x_approx, 0);

                    double[] R_curr = new double[R.Part.LocalLength];
                    R.CopyTo(R_curr, 0);

                    m_IterationCallback(stats.NoOfIterations, x_approx, R_curr);


                    x.Lock();
                    R.Lock();
                }

                if (m_NestedPrecond != null)
                {
                    Z.Clear();
                    m_NestedPrecond.DoPrecond();
                }
                else
                {
                    Z.CopyFrom(R);
                }

                double alpha_neu = R.InnerProd(Z);

                // compute residual norm
                if (m_ConvergenceType == ConvergenceTypes.Absolute)
                {
                    ResNorm = Math.Sqrt(alpha);
                }
                else
                {
                    ResNorm = Math.Sqrt(alpha / alpha_0);
                }
                ResNorm = Math.Sqrt(R.TwoNormSquare());

                P.Scale(alpha_neu / alpha);
                P.Acc(1.0, Z);

                alpha = alpha_neu;
                stats.NoOfIterations++;
            }

            // unlock objects
            // ==============

            if (m_NestedPrecond != null)
            {
                m_NestedPrecond.ReleaseTempObjects();
            }

            x.Unlock();
            P.Unlock();
            R.Unlock();
            V.Unlock();

            m_Matrix.Unlock();

            commP.Dispose();
            P.Dispose();
        }