* solver changes.
*
* The Bicgstab-method has two additional parameters: the first is a
- * boolean, deciding whether to compute the actual residual in each
- * step (@p true) or to use the length of the computed orthogonal
- * residual (@p false). Remark, that computing the residual causes a
- * third matrix-vector-multiplication, though no additional
- * preconditioning, in each step. The reason for doing this is, that
- * the size of the orthogonalized residual computed during the
- * iteration may be larger by orders of magnitude than the true
- * residual. This is due to numerical instabilities related to badly
- * conditioned matrices. Since this instability results in a bad
- * stopping criterion, the default for this parameter is @p true.
+ * boolean, deciding whether to compute the actual residual in each step (@p
+ * true) or to use the length of the computed orthogonal residual (@p
+ * false). Remark, that computing the residual causes a third
+ * matrix-vector-multiplication, though no additional preconditioning, in
+ * each step. The reason for doing this is, that the size of the
+ * orthogonalized residual computed during the iteration may be larger by
+ * orders of magnitude than the true residual. This is due to numerical
+ * instabilities related to badly conditioned matrices. Since this
+ * instability results in a bad stopping criterion, the default for this
+ * parameter is @p true. Whenever the user knows that the estimated residual
+ * works reasonably as well, it the flag should be set to @p false in order
+ * to increase the performance of the solver.
*
* The second parameter is the size of a breakdown criterion. It is
* difficult to find a general good criterion, so if things do not
{
public:
/**
- * There are two possibilities to compute
- * the residual: one is an estimate using
- * the computed value @p tau. The other
- * is exact computation using another matrix
- * vector multiplication.
+ * There are two possibilities to
+ * compute the residual: one is an
+ * estimate using the computed value @p
+ * tau. The other is exact computation
+ * using another matrix vector
+ * multiplication. This increases the
+ * costs of the algorithm, so it is
+ * should be set to false whenever the
+ * problem allows it.
*
- * Bicgstab, is susceptible to breakdowns, so
+ * Bicgstab is susceptible to breakdowns, so
* we need a parameter telling us, which
* numbers are considered zero.
*/
/**
* Constructor.
*
- * The default is exact residual
- * computation and breakdown
- * parameter 1e-16.
+ * The default is to perform an
+ * exact residual computation and
+ * breakdown parameter 1e-10.
*/
AdditionalData(bool exact_residual = true,
double breakdown=1.e-10) :
global_indices.resize(n_cols);
column_values.resize(n_cols);
- const unsigned int * index_ptr = &col_indices[0];
- const number * value_ptr = &values[0];
-
// First, search all the indices to find
// out which values we actually need to
// set.
// efficient.
for (unsigned int j=0; j<n_cols; ++j)
{
- const number value = *value_ptr++;
+ const number value = values[j];
Assert (numbers::is_finite(value),
ExcMessage("The given value is not finite but either "
"infinite or Not A Number (NaN)"));
if (value == 0 && elide_zero_values == true)
- {
- ++index_ptr;
- continue;
- }
+ continue;
- const unsigned int index = cols->operator()(row, *index_ptr++);
+ const unsigned int index = cols->operator()(row, col_indices[j]);
// it is allowed to set elements in
// the matrix that are not part of
n_columns++;
}
- index_ptr = &global_indices[0];
- value_ptr = &column_values[0];
+ const unsigned int * index_ptr = &global_indices[0];
+ const number * value_ptr = &column_values[0];
// Finally, go through the index list
// and set the elements one by one.
global_indices.resize(n_cols);
column_values.resize(n_cols);
- const unsigned int * index_ptr = &col_indices[0];
- const number * value_ptr = &values[0];
-
// First, search all the indices to find
// out which values we actually need to
// add.
// efficient.
for (unsigned int j=0; j<n_cols; ++j)
{
- const number value = *value_ptr++;
+ const number value = values[j];
Assert (numbers::is_finite(value),
ExcMessage("The given value is not finite but either "
"infinite or Not A Number (NaN)"));
if (value == 0 && elide_zero_values == true)
- {
- ++index_ptr;
- continue;
- }
+ continue;
- const unsigned int index = cols->operator()(row, *index_ptr++);
+ const unsigned int index = cols->operator()(row, col_indices[j]);
// it is allowed to add elements to
// the matrix that are not part of
n_columns++;
}
- index_ptr = &global_indices[0];
- value_ptr = &column_values[0];
-
+ const unsigned int * index_ptr = &global_indices[0];
+ const number * value_ptr = &column_values[0];
+
// Finally, go through the index list
// and add the elements one by one.
for (unsigned int j=0; j<n_columns; ++j)