9#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN
35static auto dvinit(
int n)
51 Eigen::Vector3d b_exact(1, 2, 3);
52 Eigen::Vector3d x_exact = A.ldlt().solve(b_exact);
61 auto FML = [&](
DVec &xin,
DVec &MLx) { MLx = xin; };
62 auto fDot = [](
DVec &a,
DVec &
b) ->
double {
return a.
data.dot(
b.data); };
63 auto fStop = [](int,
double res,
double resB) ->
bool {
return res < 1e-14 * resB; };
65 bool converged = gmres.
solve(FA, FML, fDot,
b,
x, 10, fStop);
68 double err = (
x.data - x_exact).norm();
69 std::cout <<
"[GMRES/3x3] err=" << std::scientific <<
err << std::endl;
76 Eigen::MatrixXd R = Eigen::MatrixXd::Random(
n,
n);
77 Eigen::MatrixXd A = R.transpose() * R +
n * Eigen::MatrixXd::Identity(
n,
n);
78 Eigen::VectorXd b_exact = Eigen::VectorXd::Ones(
n);
79 Eigen::VectorXd x_exact = A.ldlt().solve(b_exact);
88 auto FML = [&](
DVec &xin,
DVec &MLx) { MLx = xin; };
89 auto fDot = [](
DVec &a,
DVec &
b) ->
double {
return a.
data.dot(
b.data); };
90 auto fStop = [](int,
double res,
double resB) ->
bool {
return res < 1e-12 * resB; };
92 bool converged = gmres.
solve(FA, FML, fDot,
b,
x, 20, fStop);
95 double err = (
x.data - x_exact).norm();
96 std::cout <<
"[GMRES/10x10] err=" << std::scientific <<
err << std::endl;
100TEST_CASE(
"GMRES: diagonal preconditioner improves convergence")
103 Eigen::MatrixXd A = Eigen::MatrixXd::Zero(
n,
n);
104 for (
int i = 0; i <
n; i++)
105 A(i, i) = (i + 1) * 10.0;
108 Eigen::VectorXd b_exact = Eigen::VectorXd::Ones(
n);
109 Eigen::VectorXd x_exact = A.fullPivLu().solve(b_exact);
115 int restarts_npc = 0;
116 auto fStop1 = [&](
int iRestart,
double res,
double resB) ->
bool {
117 restarts_npc = iRestart;
118 return res < 1e-12 * resB;
122 [](
DVec &xin,
DVec &MLx) { MLx = xin; },
131 auto fStop2 = [&](
int iRestart,
double res,
double resB) ->
bool {
132 restarts_pc = iRestart;
133 return res < 1e-12 * resB;
135 Eigen::VectorXd diagInv = A.diagonal().cwiseInverse();
138 [&](
DVec &xin,
DVec &MLx) { MLx.data = diagInv.asDiagonal() * xin.
data; },
142 double err2 = (x2.
data - x_exact).norm();
145 CHECK(restarts_pc <= restarts_npc);
155 Eigen::MatrixXd R = Eigen::MatrixXd::Random(
n,
n);
156 R << 1, 0.1, 0, 0, 0,
161 Eigen::MatrixXd A = (R + R.transpose()) / 2.0;
162 Eigen::VectorXd b_exact = Eigen::VectorXd::Ones(
n);
163 Eigen::VectorXd x_exact = A.ldlt().solve(b_exact);
165 using TScalar = double;
171 auto FA = [&](
DVec &p,
DVec &Ap) { Ap.data = A * p.
data; };
173 auto FResPrec = [&](
DVec &xin,
DVec &
z) {
z.data = b_exact - A * xin.
data; };
174 auto fDot = [](
DVec &a,
DVec &
b) -> TScalar {
return a.
data.dot(
b.data); };
175 auto fStop = [](int, TScalar zrDot, TScalar) ->
bool {
return std::abs(zrDot) < 1e-24; };
177 bool converged = pcg.
solve(FA, FM, FResPrec, fDot,
x, 100, fStop);
180 double err = (
x.data - x_exact).norm();
181 std::cout <<
"[PCG/5x5] err=" << std::scientific <<
err << std::endl;
bool solve(TFA &&FA, TFML &&FML, TFDot &&fDot, TDATA &b, TDATA &x, uint32_t nRestart, TFstop &&FStop)
bool solve(TFA &&FA, TFM &&FM, TFResPrec &&FResPrec, TFDot &&fDot, TDATA &x, uint32_t niter, TFstop &&FStop)
the host side operators are provided as implemented
void addTo(const DVec &o, double s)
void operator*=(double s)
DVec & operator=(const DVec &)=default
void setConstant(double s)
void operator+=(const DVec &o)
void operator*=(const DVec &o)
Eigen::Matrix< real, 5, 1 > v
TEST_CASE("3D: VFV P2 HQM error < P1 on sinCos3D")
Eigen::Vector3d n(1.0, 0.0, 0.0)