13 std::vector<double> column_sums(matrix.n(), 0.);
14 for (std::size_t row = 0; row < matrix.m(); ++row)
15 for (
auto entry = matrix.begin(row); entry != matrix.end(row); ++entry)
16 column_sums[entry->column()] += std::abs(
static_cast<double>(entry->value()));
17 return column_sums.empty() ? 0. : *std::max_element(column_sums.begin(), column_sums.end());
22 const unsigned int max_iterations = 5)
24 if (n == 0)
return std::numeric_limits<double>::quiet_NaN();
26 VectorType x(n), y(n), signs(n), z(n);
27 x = 1. /
static_cast<double>(n);
29 std::size_t previous_index = n;
31 for (
unsigned int iteration = 0; iteration < max_iterations; ++iteration) {
33 const double next_estimate = y.l1_norm();
34 if (!std::isfinite(next_estimate))
return std::numeric_limits<double>::quiet_NaN();
35 estimate = std::max(estimate, next_estimate);
37 for (std::size_t i = 0; i < n; ++i)
38 signs[i] = y[i] >= 0. ? 1. : -1.;
39 solve_transpose(signs, z);
41 std::size_t index = 0;
43 for (std::size_t i = 0; i < n; ++i) {
44 const double value = std::abs(z[i]);
45 if (value > maximum) {
51 if (index == previous_index)
break;
52 previous_index = index;
62 std::vector<double> &column_scale,
double &scaled_one_norm)
64 constexpr double min_norm = 1.e-300;
65 row_scale.assign(matrix.m(), 0.);
66 column_scale.assign(matrix.n(), 0.);
68 for (std::size_t row = 0; row < matrix.m(); ++row)
69 for (
auto entry = matrix.begin(row); entry != matrix.end(row); ++entry) {
70 const double value = std::abs(
static_cast<double>(entry->value()));
71 row_scale[row] = std::max(row_scale[row], value);
72 column_scale[entry->column()] = std::max(column_scale[entry->column()], value);
75 const auto inverse_sqrt = [](
const double norm) {
76 if (!std::isfinite(norm) || norm <= min_norm)
return 1.;
77 return 1. / std::sqrt(norm);
79 std::transform(row_scale.begin(), row_scale.end(), row_scale.begin(), inverse_sqrt);
80 std::transform(column_scale.begin(), column_scale.end(), column_scale.begin(), inverse_sqrt);
82 std::vector<double> column_sums(matrix.n(), 0.);
83 for (std::size_t row = 0; row < matrix.m(); ++row)
84 for (
auto entry = matrix.begin(row); entry != matrix.end(row); ++entry)
85 column_sums[entry->column()] +=
86 std::abs(row_scale[row] *
static_cast<double>(entry->value()) * column_scale[entry->column()]);
87 scaled_one_norm = column_sums.empty() ? 0. : *std::max_element(column_sums.begin(), column_sums.end());
void build_maximum_equilibration(const MatrixType &matrix, std::vector< double > &row_scale, std::vector< double > &column_scale, double &scaled_one_norm)
Definition condition_estimate.hh:61
double estimate_inverse_one_norm(const std::size_t n, Solve &&solve, SolveTranspose &&solve_transpose, const unsigned int max_iterations=5)
Definition condition_estimate.hh:21