/// <summary> /// Set status to <see cref="CalculationFailure"/> /// </summary> private void SetStatusToFailed() { if (!(_status is CalculationFailure)) { _status = new CalculationFailure(); } }
/// <summary> /// Set status to <see cref="CalculationDiverged"/> /// </summary> private void SetStatusToDiverged() { if (!(_status is CalculationDiverged)) { _status = new CalculationDiverged(); } }
/// <summary> /// Set status to <see cref="CalculationFailure"/> /// </summary> private void SetStatusToFinished() { if (!(_status is CalculationStoppedWithoutConvergence)) { _status = new CalculationStoppedWithoutConvergence(); } }
/// <summary> /// Set status to <see cref="CalculationRunning"/> /// </summary> private void SetStatusToRunning() { if (!(_status is CalculationRunning)) { _status = new CalculationRunning(); } }
/// <summary> /// Determines the status of the iterative calculation based on the stop criteria stored /// by the current <see cref="IIterator{T}"/>. Result is set into <c>Status</c> field. /// </summary> /// <param name="iterationNumber">The number of iterations that have passed so far.</param> /// <param name="solutionVector">The vector containing the current solution values.</param> /// <param name="sourceVector">The right hand side vector.</param> /// <param name="residualVector">The vector containing the current residual vectors.</param> /// <remarks> /// The individual iterators may internally track the progress of the calculation based /// on the invocation of this method. Therefore this method should only be called if the /// calculation has moved forwards at least one step. /// </remarks> public void DetermineStatus(int iterationNumber, Vector <float> solutionVector, Vector <float> sourceVector, Vector <float> residualVector) { if (_stopCriterias.Count == 0) { throw new ArgumentException(Resources.StopCriteriumMissing); } if (iterationNumber < 0) { throw new ArgumentOutOfRangeException("iterationNumber"); } if (solutionVector == null) { throw new ArgumentNullException("solutionVector"); } if (sourceVector == null) { throw new ArgumentNullException("sourceVector"); } if (residualVector == null) { throw new ArgumentNullException("residualVector"); } // While we're cancelled we don't call on the stop-criteria. if (_wasIterationCancelled) { return; } foreach (var stopCriterium in _stopCriterias.Select(pair => pair.Value)) { stopCriterium.DetermineStatus(iterationNumber, solutionVector, sourceVector, residualVector); var status = stopCriterium.Status; // Check if the status is: // - Running --> keep going // - Indetermined --> keep going // Anything else: // Stop looping and set that status if ((status is CalculationRunning) || (status is CalculationIndetermined)) { continue; } _status = status; return; } // Got all the way through // So we're running because we had vectors passed to us. if (!(_status is CalculationRunning)) { _status = new CalculationRunning(); } }
/// <summary> /// Resets the <see cref="IIterator{T}"/> to the pre-calculation state. /// </summary> public void ResetToPrecalculationState() { // Indicate that we're no longer cancelled. _wasIterationCancelled = false; // Reset the status. _status = DefaultStatus; // Reset the stop-criteria foreach (var stopCriterium in _stopCriterias.Select(pair => pair.Value)) { stopCriterium.ResetToPrecalculationState(); } }
/// <summary> /// Resets the <see cref="IterationCountStopCriterium"/> to the pre-calculation state. /// </summary> public void ResetToPrecalculationState() { _status = DefaultStatus; }
/// <summary> /// Resets the <see cref="IIterationStopCriterium"/> to the pre-calculation state. /// </summary> public void ResetToPrecalculationState() { _status = DefaultStatus; _lastIteration = DefaultLastIterationNumber; }
/// <summary> /// Resets the <see cref="IIterationStopCriterium"/> to the pre-calculation state. /// </summary> public void ResetToPrecalculationState() { _status = DefaultStatus; _lastIteration = DefaultLastIterationNumber; _residualHistory = null; }
/// <summary> /// Indicates to the iterator that the iterative process has been cancelled. /// </summary> /// <remarks> /// Does not reset the stop-criteria. /// </remarks> public void IterationCancelled() { _wasIterationCancelled = true; _status = new CalculationCancelled(); }
/// <summary> /// Solves the matrix equation Ax = b, where A is the coefficient matrix, b is the /// solution vector and x is the unknown vector. /// </summary> /// <param name="matrix">The coefficient matrix, <c>A</c>.</param> /// <param name="input">The solution vector, <c>b</c></param> /// <param name="result">The result vector, <c>x</c></param> public void Solve(Matrix matrix, Vector input, Vector result) { // If we were stopped before, we are no longer // We're doing this at the start of the method to ensure // that we can use these fields immediately. _hasBeenStopped = false; _currentSolver = null; // Error checks if (matrix == null) { throw new ArgumentNullException("matrix"); } if (matrix.RowCount != matrix.ColumnCount) { throw new ArgumentException(Resources.ArgumentMatrixSquare, "matrix"); } if (input == null) { throw new ArgumentNullException("input"); } if (result == null) { throw new ArgumentNullException("result"); } if (result.Count != input.Count) { throw new ArgumentException(Resources.ArgumentVectorsSameLength); } // Initialize the solver fields // Set the convergence monitor if (_iterator == null) { _iterator = Iterator.CreateDefault(); } // Load the solvers into our own internal data structure // Once we have solvers we can always reuse them. if (_solvers.Count == 0) { LoadSolvers(); } // Create a copy of the solution and result vectors so we can use them // later on var internalInput = (Vector)input.Clone(); var internalResult = (Vector)result.Clone(); foreach (var solver in _solvers.TakeWhile(solver => !_hasBeenStopped)) { // Store a reference to the solver so we can stop it. _currentSolver = solver; try { // Reset the iterator and pass it to the solver _iterator.ResetToPrecalculationState(); solver.SetIterator(_iterator); // Start the solver solver.Solve(matrix, internalInput, internalResult); } catch (Exception) { // The solver broke down. // Log a message about this // Switch to the next preconditioner. // Reset the solution vector to the previous solution input.CopyTo(internalInput); _status = RunningStatus; continue; } // There was no fatal breakdown so check the status if (_iterator.Status is CalculationConverged) { // We're done internalResult.CopyTo(result); break; } // We're not done // Either: // - calculation finished without convergence if (_iterator.Status is CalculationStoppedWithoutConvergence) { // Copy the internal result to the result vector and // continue with the calculation. internalResult.CopyTo(result); } else { // - calculation failed --> restart with the original vector // - calculation diverged --> restart with the original vector // - Some unknown status occurred --> To be safe restart. input.CopyTo(internalInput); } } // Inside the loop we already copied the final results (if there are any) // So no need to do that again. // Clean up // No longer need the current solver _currentSolver = null; // Set the final status _status = _iterator.Status; }
/// <summary> /// Resets the <see cref="IIterator"/> to the pre-calculation state. /// </summary> public void ResetToPrecalculationState() { // Indicate that we're no longer cancelled. _wasIterationCancelled = false; // Reset the status. _status = DefaultStatus; // Reset the stop-criteria foreach (var stopCriterium in _stopCriterias.Select(pair => pair.Value)) { stopCriterium.ResetToPrecalculationState(); } }
/// <summary> /// Determines the status of the iterative calculation based on the stop criteria stored /// by the current <c>IIterator</c>. Result is set into <c>Status</c> field. /// </summary> /// <param name="iterationNumber">The number of iterations that have passed so far.</param> /// <param name="solutionVector">The vector containing the current solution values.</param> /// <param name="sourceVector">The right hand side vector.</param> /// <param name="residualVector">The vector containing the current residual vectors.</param> /// <remarks> /// The individual iterators may internally track the progress of the calculation based /// on the invocation of this method. Therefore this method should only be called if the /// calculation has moved forwards at least one step. /// </remarks> public void DetermineStatus(int iterationNumber, Vector solutionVector, Vector sourceVector, Vector residualVector) { if (_stopCriterias.Count == 0) { throw new ArgumentException(Resources.StopCriteriumMissing); } if (iterationNumber < 0) { throw new ArgumentOutOfRangeException("iterationNumber"); } if (solutionVector == null) { throw new ArgumentNullException("solutionVector"); } if (sourceVector == null) { throw new ArgumentNullException("sourceVector"); } if (residualVector == null) { throw new ArgumentNullException("residualVector"); } // While we're cancelled we don't call on the stop-criteria. if (_wasIterationCancelled) { return; } foreach (var stopCriterium in _stopCriterias.Select(pair => pair.Value)) { stopCriterium.DetermineStatus(iterationNumber, solutionVector, sourceVector, residualVector); var status = stopCriterium.Status; // Check if the status is: // - Running --> keep going // - Indetermined --> keep going // Anything else: // Stop looping and set that status if ((status is CalculationRunning) || (status is CalculationIndetermined)) { continue; } _status = status; return; } // Got all the way through // So we're running because we had vectors passed to us. if (!(_status is CalculationRunning)) { _status = new CalculationRunning(); } }