OGS
CubicRoots.h
Go to the documentation of this file.
1
10#pragma once
11
12#include <algorithm>
13#include <limits>
14#include <range/v3/algorithm/min.hpp>
15#include <range/v3/algorithm/sort.hpp>
16#include <range/v3/range/conversion.hpp>
17#include <range/v3/view/filter.hpp>
18#include <vector>
19
20#include "BaseLib/Error.h"
21#include "cubic_roots.hpp"
22namespace MathLib
23{
24
26{
27public:
28 CubicSolver(const double a, const double b, const double c, const double d)
29 : a_(a), b_(b), c_(c), d_(d)
30 {
31 if (std::abs(a_) < 1e-9)
32 {
33 OGS_FATAL("'a' must be non-zero for a cubic equation.");
34 }
35 }
36
37 // Method to solve the cubic equation using Boost
38 std::vector<double> solve()
39 {
40 // Solve using Boost's cubic_roots
41 std::array<double, 3> const roots =
42 boost::math::tools::cubic_roots<double>(a_, b_, c_, d_);
43
44 std::vector<double> filtered_roots =
45 ranges::views::ref(roots) |
46 ranges::views::filter([](double const root)
47 { return !std::isnan(root); }) |
48 ranges::to<std::vector>();
49 ranges::sort(filtered_roots);
50
51 return filtered_roots;
52 }
53
54 // Method that returns the smallest positive real root
56 {
57 std::vector<double> const roots = solve();
58
59 auto positive_roots =
60 roots | ranges::views::filter([](double root) { return root > 0; });
61
62 // If no positive root exists, return NaN
63 if (ranges::empty(positive_roots))
64 {
65 return std::numeric_limits<double>::quiet_NaN();
66 }
67
68 return ranges::min(positive_roots);
69 }
70
71private:
72 double a_, b_, c_, d_; // Coefficients of the cubic equation
73};
74
75} // namespace MathLib
#define OGS_FATAL(...)
Definition Error.h:26
double smallestPositiveRealRoot()
Definition CubicRoots.h:55
CubicSolver(const double a, const double b, const double c, const double d)
Definition CubicRoots.h:28
std::vector< double > solve()
Definition CubicRoots.h:38