13template<
typename T,
int N>
15 static constexpr int maxCount = N;
16 using element_type = T;
18 using const_iterator =
typename array_type::const_iterator;
23 results() noexcept : count(0), value() {}
25 results(T a) noexcept : count(1), value() {
29 results(T a, T b) noexcept : count(2), value() {
35 results(T a, T b, T c) noexcept : count(3), value() {
42 template<
int O,
typename std::enable_if_t<O < N,
int> = 0>
43 results(results<T,O> const &other) noexcept : count(other.count), value() {
44 if constexpr (O > 0) {
45 for (
int i = 0; i < other.maxCount; i++) {
46 value[i] = other.value[i];
51 int size() const noexcept {
52 return (count >= 0) ? count : 0;
55 bool hasInfiniteResults() const noexcept {
59 const_iterator
begin() const noexcept {
63 const_iterator
end() const noexcept {
64 return value.begin() + size();
67 void sort() noexcept {
68 std::sort(value.begin(), value.begin() + size());
71 void add(T a)
noexcept {
72 value.at(count++) = a;
77template<
typename T,
int N,
typename U>
78inline results<T, N> operator-(results<T, N> lhs, U
const &rhs)
noexcept
80 for (
int i = 0; i < lhs.maxCount; i++) {
87inline results<T,0> infinitResults() noexcept {
93template<
typename T,
int N>
97 tt_assert(r.count <= r.maxCount);
98 for (
int i = 0; i < r.count; i++) {
121inline results<T,1> solvePolynomial(T
const &a, T
const &b)
noexcept {
126 return infinitResults<T>();
147inline results<T,2> solvePolynomial(T
const &a, T
const &b, T
const &c)
noexcept {
149 return solvePolynomial(b, c);
151 ttlet D = b*b -
static_cast<T
>(4)*a*c;
155 return { -b / (
static_cast<T
>(2)*a) };
157 ttlet Dsqrt =
sqrt(D);
159 (-b - Dsqrt) / (
static_cast<T
>(2)*a),
160 (-b + Dsqrt) / (
static_cast<T
>(2)*a)
169inline results<T,3> solveDepressedCubicTrig(T
const &p, T
const &q)
noexcept {
170 constexpr T oneThird =
static_cast<T
>(1) /
static_cast<T
>(3);
171 constexpr T pi2_3 = (
static_cast<T
>(2) /
static_cast<T
>(3)) * std::numbers::pi_v<T>;
172 constexpr T pi4_3 = (
static_cast<T
>(4) /
static_cast<T
>(3)) * std::numbers::pi_v<T>;
174 ttlet U = oneThird *
acos(((
static_cast<T
>(3)*q) / (
static_cast<T
>(2)*p)) *
sqrt(
static_cast<T
>(-3)/p));
175 ttlet V =
static_cast<T
>(2) *
sqrt(-oneThird * p);
177 ttlet t0 = V *
cos(U);
178 ttlet t1 = V *
cos(U - pi2_3);
179 ttlet t2 = V *
cos(U - pi4_3);
180 return { t0, t1, t2 };
184inline results<T,3> solveDepressedCubicCardano(T
const &p, T
const &q, T
const &D)
noexcept {
185 ttlet sqrtD =
sqrt(D);
186 ttlet minusHalfQ =
static_cast<T
>(-0.5) * q;
187 ttlet v =
cbrt(minusHalfQ + sqrtD);
188 ttlet w =
cbrt(minusHalfQ - sqrtD);
209inline results<T,3> solveDepressedCubic(T
const &p, T
const &q)
noexcept {
210 constexpr T oneForth =
static_cast<T
>(1) /
static_cast<T
>(4);
211 constexpr T oneTwentySeventh =
static_cast<T
>(1) /
static_cast<T
>(27);
213 if (p == 0.0 && q == 0.0) {
214 return {
static_cast<T
>(0) };
217 ttlet D = oneForth*q*q + oneTwentySeventh*p*p*p;
219 if (D < 0 && p != 0.0) {
221 return solveDepressedCubicTrig(p, q);
223 }
else if (D == 0 && p != 0.0) {
225 ttlet t0 = (
static_cast<T
>(3)*q) / p;
226 ttlet t1 = (
static_cast<T
>(-3)*q) / (
static_cast<T
>(2)*p);
231 return solveDepressedCubicCardano(p, q, D);
245inline results<T,3> solvePolynomial(T
const &a, T
const &b, T
const &c, T
const &d)
noexcept {
247 return solvePolynomial(b, c, d);
250 ttlet p = (
static_cast<T
>(3)*a*c - b*b) / (
static_cast<T
>(3)*a*a);
251 ttlet q = (
static_cast<T
>(2)*b*b*b -
static_cast<T
>(9)*a*b*c +
static_cast<T
>(27)*a*a*d) / (
static_cast<T
>(27)*a*a*a);
253 ttlet r = solveDepressedCubic(p, q);
255 ttlet b_3a = b / (
static_cast<T
>(3)*a);
Definition polynomial.hpp:14