6#include "TTauri/Foundation/math.hpp"
10template<
typename T,
int N>
12 static constexpr int maxCount = N;
13 using element_type = T;
14 using const_iterator =
typename std::array<T,N>::const_iterator;
19 results() noexcept : count(0), value() {}
21 gsl_suppress(bounds.4)
22 results(T a) noexcept : count(1), value() {
26 gsl_suppress(bounds.4)
27 results(T a, T b) noexcept : count(2), value() {
33 gsl_suppress(bounds.4)
34 results(T a, T b, T c) noexcept : count(3), value() {
41 template<
int O,
typename std::enable_if_t<std::less<
int>{}(O,N),
int> = 0>
42 gsl_suppress2(bounds.2,bounds.4)
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();
68 void sort()
noexcept {
72 void add(T a)
noexcept {
73 value.
at(count++) = a;
78template<
typename T,
int N,
typename U>
79gsl_suppress2(bounds.2,bounds.4)
80inline
results<T, N> operator-(
results<T, N> lhs, U const &rhs) noexcept
82 for (
int i = 0; i < lhs.maxCount; i++) {
89inline results<T,0> infinitResults() noexcept {
95template<
typename T,
int N>
99 tt_assert(r.count <= r.maxCount);
100 for (
int i = 0; i < r.count; i++) {
121inline results<T,1> solvePolynomial(T
const &a, T
const &b)
noexcept {
126 return infinitResults<T>();
145inline results<T,2> solvePolynomial(T
const &a, T
const &b, T
const &c)
noexcept {
147 return solvePolynomial(b, c);
149 ttlet D = b*b -
static_cast<T
>(4)*a*c;
153 return { -b / (
static_cast<T
>(2)*a) };
155 ttlet Dsqrt =
sqrt(D);
157 (-b - Dsqrt) / (
static_cast<T
>(2)*a),
158 (-b + Dsqrt) / (
static_cast<T
>(2)*a)
167inline results<T,3> solveDepressedCubicTrig(T
const &p, T
const &q)
noexcept {
168 constexpr T oneThird =
static_cast<T
>(1) /
static_cast<T
>(3);
169 constexpr T pi2_3 = (
static_cast<T
>(2) /
static_cast<T
>(3)) *
static_cast<T
>(pi);
170 constexpr T pi4_3 = (
static_cast<T
>(4) /
static_cast<T
>(3)) *
static_cast<T
>(pi);
172 ttlet U = oneThird *
acos(((
static_cast<T
>(3)*q) / (
static_cast<T
>(2)*p)) *
sqrt(
static_cast<T
>(-3)/p));
173 ttlet V =
static_cast<T
>(2) *
sqrt(-oneThird * p);
175 ttlet t0 = V *
cos(U);
176 ttlet t1 = V *
cos(U - pi2_3);
177 ttlet t2 = V *
cos(U - pi4_3);
178 return { t0, t1, t2 };
182inline results<T,3> solveDepressedCubicCardano(T
const &p, T
const &q, T
const &D)
noexcept {
183 ttlet sqrtD =
sqrt(D);
184 ttlet minusHalfQ =
static_cast<T
>(-0.5) * q;
185 ttlet v =
cbrt(minusHalfQ + sqrtD);
186 ttlet w =
cbrt(minusHalfQ - sqrtD);
205inline results<T,3> solveDepressedCubic(T
const &p, T
const &q)
noexcept {
206 constexpr T oneForth =
static_cast<T
>(1) /
static_cast<T
>(4);
207 constexpr T oneTwentySeventh =
static_cast<T
>(1) /
static_cast<T
>(27);
209 if (p == 0.0 && q == 0.0) {
210 return {
static_cast<T
>(0) };
213 ttlet D = oneForth*q*q + oneTwentySeventh*p*p*p;
215 if (D < 0 && p != 0.0) {
217 return solveDepressedCubicTrig(p, q);
219 }
else if (D == 0 && p != 0.0) {
221 ttlet t0 = (
static_cast<T
>(3)*q) / p;
222 ttlet t1 = (
static_cast<T
>(-3)*q) / (
static_cast<T
>(2)*p);
227 return solveDepressedCubicCardano(p, q, D);
241inline results<T,3> solvePolynomial(T
const &a, T
const &b, T
const &c, T
const &d)
noexcept {
243 return solvePolynomial(b, c, d);
246 ttlet p = (
static_cast<T
>(3)*a*c - b*b) / (
static_cast<T
>(3)*a*a);
247 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);
249 ttlet r = solveDepressedCubic(p, q);
251 ttlet b_3a = b / (
static_cast<T
>(3)*a);
Definition polynomial.hpp:11