DimensionMismatchException, NonSelfAdjointOperatorException,
NonPositiveDefiniteOperatorException, IllConditionedOperatorException,
MaxCountExceededException {
checkParameters(a, m, b, x);
final IterationManager manager = getIterationManager();
/* Initialization counts as an iteration. */
manager.resetIterationCount();
manager.incrementIterationCount();
final State state;
state = new State(a, m, b, goodb, shift, delta, check);
state.init();
state.refineSolution(x);
IterativeLinearSolverEvent event;
event = new DefaultIterativeLinearSolverEvent(this,
manager.getIterations(),
x,
b,
state.getNormOfResidual());
if (state.bEqualsNullVector()) {
/* If b = 0 exactly, stop with x = 0. */
manager.fireTerminationEvent(event);
return x;
}
/* Cause termination if beta is essentially zero. */
final boolean earlyStop;
earlyStop = state.betaEqualsZero() || state.hasConverged();
manager.fireInitializationEvent(event);
if (!earlyStop) {
do {
manager.incrementIterationCount();
event = new DefaultIterativeLinearSolverEvent(this,
manager.getIterations(),
x,
b,
state.getNormOfResidual());
manager.fireIterationStartedEvent(event);
state.update();
state.refineSolution(x);
event = new DefaultIterativeLinearSolverEvent(this,
manager.getIterations(),
x,
b,
state.getNormOfResidual());
manager.fireIterationPerformedEvent(event);
} while (!state.hasConverged());
}
event = new DefaultIterativeLinearSolverEvent(this,
manager.getIterations(),
x,
b,
state.getNormOfResidual());
manager.fireTerminationEvent(event);
return x;
}