Beispiel #1
0
        /// <summary>
        /// Calculates the initial approximation to the linear system's solution vector, by using a series of conjugate direction
        /// vectors that have been stored previously by PCG during the solution of other linear systems with the same matrix.
        /// This method should be used to solve linear systems with different right hand side vectors and the same matrix.
        /// </summary>
        /// <param name="rhsNew">The right hand side vector of the new linear system.</param>
        /// <param name="initialSolution">
        /// The initial approximation to the solution vector, which PCG will improve. It will be overwritten by this method.
        /// </param>
        /// <param name="isSolutionZero">
        /// Set to true if <paramref name="initialSolution"/> is the zero vector, to avoid clearing it.
        /// </param>
        /// <exception cref="InvalidOperationException">Thrown if there are no direction vectors stored yet.</exception>
        public void CalculateInitialSolutionFromStoredDirections(IVectorView rhsNew, IVector initialSolution,
                                                                 bool isSolutionZero)
        {
            if (reorthoCache.Directions.Count < 1)
            {
                throw new InvalidOperationException("There are no direction vectors stored.");
            }
            if (!isSolutionZero)
            {
                initialSolution.Clear();
            }

            //TODO: An implementation by G. Stavroulakis discarded the last stored direction vector at this point. Why?
            //reorthoCache.RemoveNewDirectionVectorData(1);

            // x0 = D_nd * x_d, x_d = inv(Q_nd * D_nd) * D_nd^T * b
            // D_nd = [d_1 ... d_nd], Q_nd = A * D_nd = [q_1 ... q_nd], Q_nd * D_nd = diag([d1*A*d1 ... d_nd*A*d_nd])
            for (int i = 0; i < reorthoCache.Directions.Count; ++i)
            {
                // x_d[i] = 1/(d_i * q_i) * (d_i * b)
                double xd = reorthoCache.Directions[i].DotProduct(rhsNew) / reorthoCache.DirectionsTimesMatrixTimesDirections[i];

                Debug.Assert(!double.IsNaN(xd));
                Debug.Assert(!double.IsPositiveInfinity(xd));
                Debug.Assert(!double.IsNegativeInfinity(xd));

                // x0 += d_i * x_d[i]
                initialSolution.AxpyIntoThis(reorthoCache.Directions[i], xd);
            }
        }
        // void Clear()
        internal void Clear <K, V>()
        {
            object _this = Unsafe.As <object>(this);

            if (_this is IMap <K, V> _this_map)
            {
                _this_map.Clear();
            }
            else
            {
                IVector <KeyValuePair <K, V> > _this_vector = Unsafe.As <IVector <KeyValuePair <K, V> > >(this);
                _this_vector.Clear();
            }
        }
        internal void Clear <K, V>()
        {
            object      obj = JitHelpers.UnsafeCast <object>(this);
            IMap <K, V> map = obj as IMap <K, V>;

            if (map != null)
            {
                map.Clear();
                return;
            }
            IVector <KeyValuePair <K, V> > vector = JitHelpers.UnsafeCast <IVector <KeyValuePair <K, V> > >(this);

            vector.Clear();
        }
        // void Clear()
        internal void Clear <K, V>()
        {
            object _this = JitHelpers.UnsafeCast <object>(this);

            IMap <K, V> _this_map = _this as IMap <K, V>;

            if (_this_map != null)
            {
                _this_map.Clear();
            }
            else
            {
                IVector <KeyValuePair <K, V> > _this_vector = JitHelpers.UnsafeCast <IVector <KeyValuePair <K, V> > >(this);
                _this_vector.Clear();
            }
        }
        public override IterativeStatistics Solve(ILinearTransformation matrix, IPreconditioner preconditioner, IVectorView rhs,
                                                  IVector solution, bool initialGuessIsZero, Func <IVector> zeroVectorInitializer)
        {
            //TODO: find a better way to handle optimizations for the case x0=0, than using an initialGuessIsZero flag
            Preconditions.CheckMultiplicationDimensions(matrix.NumColumns, solution.Length);
            Preconditions.CheckSystemSolutionDimensions(matrix.NumRows, rhs.Length);

            this.Matrix         = matrix;
            this.Preconditioner = preconditioner;
            this.Rhs            = rhs;

            // Initial solution and rhs (r = b - A * x)
            this.solution = solution;
            if (ReorthoCache.Directions.Count > 0)
            {
                if (!initialGuessIsZero)
                {
                    solution.Clear();
                }
                CalculateInitialSolutionFromStoredDirections(rhs, solution);
                residual = ExactResidual.Calculate(matrix, rhs, solution);
            }
            else             // preferably call base method
            {
                // r = b - A * x
                if (initialGuessIsZero)
                {
                    residual = rhs.Copy();
                }
                else
                {
                    residual = ExactResidual.Calculate(matrix, rhs, solution);
                }
            }

            // Initialize vectors
            //TODO: Pehaps I can just clear them from previous iterations
            precondResidual      = zeroVectorInitializer();
            direction            = zeroVectorInitializer();
            matrixTimesDirection = zeroVectorInitializer();

            int maxIterations = MaxIterationsProvider.GetMaxIterations(matrix.NumColumns);

            return(SolveInternal(maxIterations, zeroVectorInitializer));
        }
        // void Clear()
        internal void Clear <T>()
        {
            IVector <T> _this = Unsafe.As <IVector <T> >(this);

            _this.Clear();
        }
        // void Clear()
        internal void Clear <T>()
        {
            IVector <T> _this = JitHelpers.UnsafeCast <IVector <T> >(this);

            _this.Clear();
        }
        internal void Clear <T>()
        {
            IVector <T> vector = JitHelpers.UnsafeCast <IVector <T> >(this);

            vector.Clear();
        }