8 #ifndef META_OCEAN_MATH_EQUATION_H
9 #define META_OCEAN_MATH_EQUATION_H
22 template <
typename T>
class EquationT;
64 static bool solveLinear(
const T a,
const T b, T& x);
76 static bool solveQuadratic(
const T a,
const T b,
const T c, T& x1, T& x2);
90 static unsigned int solveCubic(
const T a,
const T b,
const T c,
const T d, T& x1, T& x2, T& x3);
103 static unsigned int solveQuartic(
const T a,
const T b,
const T c,
const T d,
const T e, T* x);
106 template <
typename T>
122 template <
typename T>
135 const T value = b * b - 4 * a * c;
154 if (std::is_same<T, float>::value)
170 template <
typename T>
184 const T alpha = b * a1;
185 const T beta = c * a1;
186 const T gamma = d * a1;
191 const T alpha2 = alpha * alpha;
194 const T q = (alpha2 - 3 * beta) * T(0.11111111111111111111111111111111);
197 const T r = (2 * alpha2 * alpha - 9 * alpha * beta + 27 * gamma) * T(0.018518518518518518518518518518519);
203 const T q3 = q * q * q;
211 const T angle_3 =
NumericT<T>::acos(minmax<T>(-1, r / (q * sqrtQ), 1)) * T(0.33333333333333333333333333333333);
214 const T alpha_3 = alpha * T(0.33333333333333333333333333333333);
216 const T factor = -2 * sqrtQ;
222 x2 = factor *
NumericT<T>::cos(angle_3 + T(2.0943951023931954923084289221863)) - alpha_3;
225 x3 = factor *
NumericT<T>::cos(angle_3 - T(2.0943951023931954923084289221863)) - alpha_3;
229 const T value1 = a * x1 * x1 * x1 + b * x1 * x1 + c * x1 + d;
230 const T value2 = a * x2 * x2 * x2 + b * x2 * x2 + c * x2 + d;
231 const T value3 = a * x3 * x3 * x3 + b * x3 * x3 + c * x3 + d;
234 if (!std::is_same<T, float>::value)
255 x1 = m + n - alpha * T(0.33333333333333333333333333333333);
259 const T value1 = a * x1 * x1 * x1 + b * x1 * x1 + c * x1 + d;
262 if (!std::is_same<T, float>::value)
272 template <
typename T>
276 ocean_assert(x !=
nullptr);
289 const T a1 = T(1.0) / a;
292 const T b_a = b * a1;
295 const T c_a = c * a1;
298 const T b_a2 = b_a * b_a;
301 const T b_a3 = b_a2 * b_a;
304 const T d_a = d * a1;
307 const T alpha = T(-0.375) * b_a2 + c_a;
310 const T beta = T(0.125) * b_a3 - T(0.5) * b_a * c_a + d_a;
313 const T gamma = T(-0.01171875) * b_a3 * b_a + T(0.0625) * b_a2 * c_a - T(0.25) * b_a * d_a + e * a1;
319 const std::complex<T> cx1 = std::complex<T>(T(-0.25)) * std::complex<T>(b / a) +
NumericT<T>::sqrt(std::complex<T>(T(0.5)) * (std::complex<T>(-alpha) +
NumericT<T>::sqrt(std::complex<T>(alpha * alpha - 4 * gamma))));
320 const std::complex<T> cx2 = std::complex<T>(T(-0.25)) * std::complex<T>(b / a) +
NumericT<T>::sqrt(std::complex<T>(T(0.5)) * (std::complex<T>(-alpha) -
NumericT<T>::sqrt(std::complex<T>(alpha * alpha - 4 * gamma))));
321 const std::complex<T> cx3 = std::complex<T>(T(-0.25)) * std::complex<T>(b / a) -
NumericT<T>::sqrt(std::complex<T>(T(0.5)) * (std::complex<T>(-alpha) +
NumericT<T>::sqrt(std::complex<T>(alpha * alpha - 4 * gamma))));
322 const std::complex<T> cx4 = std::complex<T>(T(-0.25)) * std::complex<T>(b / a) -
NumericT<T>::sqrt(std::complex<T>(T(0.5)) * (std::complex<T>(-alpha) -
NumericT<T>::sqrt(std::complex<T>(alpha * alpha - 4 * gamma))));
324 ocean_assert((std::is_same<T, float>::value) ||
NumericT<T>::isWeakEqualEps(cx1 * cx1 * cx1 * cx1 * a + cx1 * cx1 * cx1 * b + cx1 * cx1 * c + cx1 * d + e));
325 ocean_assert((std::is_same<T, float>::value) ||
NumericT<T>::isWeakEqualEps(cx2 * cx2 * cx2 * cx2 * a + cx2 * cx2 * cx2 * b + cx2 * cx2 * c + cx2 * d + e));
326 ocean_assert((std::is_same<T, float>::value) ||
NumericT<T>::isWeakEqualEps(cx3 * cx3 * cx3 * cx3 * a + cx3 * cx3 * cx3 * b + cx3 * cx3 * c + cx3 * d + e));
327 ocean_assert((std::is_same<T, float>::value) ||
NumericT<T>::isWeakEqualEps(cx4 * cx4 * cx4 * cx4 * a + cx4 * cx4 * cx4 * b + cx4 * cx4 * c + cx4 * d + e));
329 unsigned int solutions = 0u;
333 const T solution = cx1.real();
334 if (
NumericT<T>::isWeakEqualEps(solution * solution * solution * solution * a + solution * solution * solution * b + solution * solution * c + solution * d + e))
336 x[solutions++] = solution;
342 const T solution = cx2.real();
343 if (
NumericT<T>::isWeakEqualEps(solution * solution * solution * solution * a + solution * solution * solution * b + solution * solution * c + solution * d + e))
345 x[solutions++] = solution;
351 const T solution = cx3.real();
352 if (
NumericT<T>::isWeakEqualEps(solution * solution * solution * solution * a + solution * solution * solution * b + solution * solution * c + solution * d + e))
354 x[solutions++] = solution;
360 const T solution = cx4.real();
361 if (
NumericT<T>::isWeakEqualEps(solution * solution * solution * solution * a + solution * solution * solution * b + solution * solution * c + solution * d + e))
363 x[solutions++] = solution;
371 const std::complex<T> p(T(-0.08333333333333333333333333333333) * alpha * alpha - gamma);
374 const std::complex<T> q(T(-0.00925925925925925925925925925926) * alpha * alpha * alpha + T(0.33333333333333333333333333333333) * alpha * gamma - T(0.125) * beta * beta);
376 const std::complex<T> qqSqr =
NumericT<T>::sqrt(std::complex<T>(T(0.25)) * q * q + std::complex<T>(T(0.03703703703703703703703703703704)) * p * p * p);
378 const std::complex<T> r(std::complex<T>(T(-0.5)) * q + qqSqr);
384 const std::complex<T> u =
NumericT<T>::pow(std::complex<T>(r), T(0.33333333333333333333333333333333));
394 y = std::complex<T>(T(-0.83333333333333333333333333333333) * alpha) + u -
NumericT<T>::pow(std::complex<T>(q), T(0.33333333333333333333333333333333));
398 y = std::complex<T>(T(-0.83333333333333333333333333333333) * alpha) + u - p / (std::complex<T>(3) * u);
402 const std::complex<T> w(
NumericT<T>::sqrt(std::complex<T>(T(0.25) * alpha) + std::complex<T>(T(0.5)) * y));
411 const std::complex<T> beta2_w(std::complex<T>(T(-0.25) * beta) / w);
412 const std::complex<T> alpha3y2 = std::complex<T>(T(-0.75) * alpha) - std::complex<T>(T(0.5)) * y;
413 const std::complex<T> b_a4(T(-0.25) * b_a);
418 const std::complex<T> cx1 = b_a4 + w + sqrtPositive;
419 const std::complex<T> cx2 = b_a4 + w - sqrtPositive;
420 const std::complex<T> cx3 = b_a4 - w + sqrtNegative;
421 const std::complex<T> cx4 = b_a4 - w - sqrtNegative;
423 unsigned int solutions = 0u;
427 const T solution = cx1.real();
428 if (
NumericT<T>::isWeakEqualEps(solution * solution * solution * solution * a + solution * solution * solution * b + solution * solution * c + solution * d + e))
430 x[solutions++] = solution;
436 const T solution = cx2.real();
437 if (
NumericT<T>::isWeakEqualEps(solution * solution * solution * solution * a + solution * solution * solution * b + solution * solution * c + solution * d + e))
439 x[solutions++] = solution;
445 const T solution = cx3.real();
446 if (
NumericT<T>::isWeakEqualEps(solution * solution * solution * solution * a + solution * solution * solution * b + solution * solution * c + solution * d + e))
448 x[solutions++] = solution;
454 const T solution = cx4.real();
455 if (
NumericT<T>::isWeakEqualEps(solution * solution * solution * solution * a + solution * solution * solution * b + solution * solution * c + solution * d + e))
457 x[solutions++] = solution;
This class provides several functions to solve equations with different degree using floating point v...
Definition: Equation.h:53
static unsigned int solveCubic(const T a, const T b, const T c, const T d, T &x1, T &x2, T &x3)
Solves a cubic equation with the from: ax^3 + bx^2 + cx + d = 0.
Definition: Equation.h:171
static bool solveQuadratic(const T a, const T b, const T c, T &x1, T &x2)
Solves an quadratic equation with the form: ax^2 + bx + c = 0.
Definition: Equation.h:123
static bool solveLinear(const T a, const T b, T &x)
Solves a linear eqation with the form: ax + b = 0.
Definition: Equation.h:107
static unsigned int solveQuartic(const T a, const T b, const T c, const T d, const T e, T *x)
Solves a quartic equation with the form: ax^4 + bx^3 + cx^2 + dx + e = 0.
Definition: Equation.h:273
This class provides basic numeric functionalities.
Definition: Numeric.h:57
static T pow(const T x, const T y)
Returns x raised to the power of y.
Definition: Numeric.h:1860
static T sqrt(const T value)
Returns the square root of a given value.
Definition: Numeric.h:1533
static constexpr T eps()
Returns a small epsilon.
static constexpr bool isEqualEps(const T value)
Returns whether a value is smaller than or equal to a small epsilon.
Definition: Numeric.h:2087
static constexpr T copySign(const T signReceiver, const T signProvider)
Copies the sign of a given value to another one.
Definition: Numeric.h:3264
static T cos(const T value)
Returns the cosine of a given value.
Definition: Numeric.h:1584
static T acos(const T value)
Returns the arccosine of a given value.
Definition: Numeric.h:2907
EquationT< Scalar > Equation
Definition of the Equation object, depending on the OCEAN_MATH_USE_SINGLE_PRECISION either with singl...
Definition: Equation.h:22
EquationT< float > EquationF
Definition of the Equation class using float values.
Definition: Equation.h:43
EquationT< double > EquationD
Definition of the Equation class using double values.
Definition: Equation.h:36
The namespace covering the entire Ocean framework.
Definition: Accessor.h:15