perf(math): route ordinary products through MKL and preserve arithmetic
This commit is contained in:
@@ -129,4 +129,44 @@ TEST(TangentSolver, RejectsSolveBeforeSuccessfulFactorization) {
|
||||
EXPECT_DOUBLE_EQ(correction[1U], -9.0);
|
||||
}
|
||||
|
||||
TEST(TangentSolver, ReusesRhsButFreshValuesAndFailureCannotReuseStaleState) {
|
||||
fesa::MklPardisoTangentSolver solver;
|
||||
ASSERT_TRUE(solver.FactorizeFresh(MakeDenseCsr(2U, {2.0, 1.0, 0.0, 3.0}))
|
||||
.IsOk());
|
||||
fesa::Vector correction{2U};
|
||||
for (double scale : {1.0, -2.0, 0.5}) {
|
||||
ASSERT_TRUE(solver.SolveCorrection(MakeVector({4.0 * scale, 6.0 * scale}),
|
||||
correction).IsOk());
|
||||
EXPECT_NEAR(correction[0U], scale, 1.0e-14);
|
||||
EXPECT_NEAR(correction[1U], 2.0 * scale, 1.0e-14);
|
||||
}
|
||||
const auto bad_rhs = MakeVector({std::numeric_limits<double>::quiet_NaN(), 0});
|
||||
correction = MakeVector({17, -4});
|
||||
EXPECT_FALSE(solver.SolveCorrection(bad_rhs, correction).IsOk());
|
||||
EXPECT_DOUBLE_EQ(correction[0U], 17);
|
||||
EXPECT_DOUBLE_EQ(correction[1U], -4);
|
||||
ASSERT_TRUE(solver.SolveCorrection(MakeVector({4, 6}), correction).IsOk());
|
||||
ASSERT_TRUE(solver.FactorizeFresh(MakeDenseCsr(2U, {4, 0, 1, 2})).IsOk());
|
||||
ASSERT_TRUE(solver.SolveCorrection(MakeVector({4, 5}), correction).IsOk());
|
||||
EXPECT_NEAR(correction[0U], 1, 1.0e-14);
|
||||
EXPECT_NEAR(correction[1U], 2, 1.0e-14);
|
||||
auto diagonal = fesa::SparseMatrix::FromCoo(
|
||||
2U, 2U, {{0U, 0U, 5, 0U, 0U}, {1U, 1U, 7, 1U, 0U}},
|
||||
{{0U, 1U, 2U}, {0U, 1U}});
|
||||
ASSERT_TRUE(diagonal.HasValue());
|
||||
ASSERT_TRUE(solver.FactorizeFresh(diagonal.Value()).IsOk());
|
||||
ASSERT_TRUE(solver.SolveCorrection(MakeVector({10, -7}), correction).IsOk());
|
||||
EXPECT_NEAR(correction[0U], 2, 1.0e-14);
|
||||
EXPECT_NEAR(correction[1U], -1, 1.0e-14);
|
||||
EXPECT_FALSE(solver.FactorizeFresh(MakeDenseCsr(2U, {0, 0, 0, 0})).IsOk());
|
||||
correction = MakeVector({19, -8});
|
||||
const auto stale = solver.SolveCorrection(MakeVector({10, -7}), correction);
|
||||
ASSERT_FALSE(stale.IsOk());
|
||||
EXPECT_EQ(stale.Diagnostics().front().code, "solver-not-factorized");
|
||||
EXPECT_DOUBLE_EQ(correction[0U], 19);
|
||||
EXPECT_DOUBLE_EQ(correction[1U], -8);
|
||||
ASSERT_TRUE(solver.FactorizeFresh(diagonal.Value()).IsOk());
|
||||
EXPECT_TRUE(solver.SolveCorrection(MakeVector({10, -7}), correction).IsOk());
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
Reference in New Issue
Block a user