/// <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(); }