/home/runner/work/DiFfRG_current/DiFfRG_current/DiFfRG/include/DiFfRG/timestepping/linear_solver/condition_estimate.hh Source File#

DiFfRG: /home/runner/work/DiFfRG_current/DiFfRG_current/DiFfRG/include/DiFfRG/timestepping/linear_solver/condition_estimate.hh Source File
DiFfRG
Discretization Framework for functional Renormalization Group flows
condition_estimate.hh
Go to the documentation of this file.
1#pragma once
2
3#include <algorithm>
4#include <cmath>
5#include <cstddef>
6#include <limits>
7#include <vector>
8
9namespace DiFfRG::internal
10{
11 template <typename MatrixType> double matrix_one_norm(const MatrixType &matrix)
12 {
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());
18 }
19
20 template <typename VectorType, typename Solve, typename SolveTranspose>
21 double estimate_inverse_one_norm(const std::size_t n, Solve &&solve, SolveTranspose &&solve_transpose,
22 const unsigned int max_iterations = 5)
23 {
24 if (n == 0) return std::numeric_limits<double>::quiet_NaN();
25
26 VectorType x(n), y(n), signs(n), z(n);
27 x = 1. / static_cast<double>(n);
28 double estimate = 0.;
29 std::size_t previous_index = n;
30
31 for (unsigned int iteration = 0; iteration < max_iterations; ++iteration) {
32 solve(x, y);
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);
36
37 for (std::size_t i = 0; i < n; ++i)
38 signs[i] = y[i] >= 0. ? 1. : -1.;
39 solve_transpose(signs, z);
40
41 std::size_t index = 0;
42 double maximum = 0.;
43 for (std::size_t i = 0; i < n; ++i) {
44 const double value = std::abs(z[i]);
45 if (value > maximum) {
46 maximum = value;
47 index = i;
48 }
49 }
50
51 if (index == previous_index) break;
52 previous_index = index;
53 x = 0.;
54 x[index] = 1.;
55 }
56
57 return estimate;
58 }
59
60 template <typename MatrixType>
61 void build_maximum_equilibration(const MatrixType &matrix, std::vector<double> &row_scale,
62 std::vector<double> &column_scale, double &scaled_one_norm)
63 {
64 constexpr double min_norm = 1.e-300;
65 row_scale.assign(matrix.m(), 0.);
66 column_scale.assign(matrix.n(), 0.);
67
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);
73 }
74
75 const auto inverse_sqrt = [](const double norm) {
76 if (!std::isfinite(norm) || norm <= min_norm) return 1.;
77 return 1. / std::sqrt(norm);
78 };
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);
81
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());
88 }
89} // namespace DiFfRG::internal
Definition config_tree.hh:14
double matrix_one_norm(const MatrixType &matrix)
Definition condition_estimate.hh:11
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