242 const T alpha = b * a1;
243 const T beta = c * a1;
244 const T gamma = d * a1;
249 const T alpha2 = alpha * alpha;
252 const T q = (alpha2 - T(3) * beta) * T(0.11111111111111111111111111111111);
255 const T r = (T(2) * alpha2 * alpha - T(9) * alpha * beta + T(27) * gamma) * T(0.018518518518518518518518518518519);
261 const T q3 = q * q * q;
269 const T angle_3 =
NumericT<T>::acos(minmax<T>(-1, r / (q * sqrtQ), 1)) * T(0.33333333333333333333333333333333);
272 const T alpha_3 = alpha * T(0.33333333333333333333333333333333);
274 const T factor = T(-2) * sqrtQ;
280 x2 = factor *
NumericT<T>::cos(angle_3 + T(2.0943951023931954923084289221863)) - alpha_3;
283 x3 = factor *
NumericT<T>::cos(angle_3 - T(2.0943951023931954923084289221863)) - alpha_3;
287 const T value1 = a * x1 * x1 * x1 + b * x1 * x1 + c * x1 + d;
288 const T value2 = a * x2 * x2 * x2 + b * x2 * x2 + c * x2 + d;
289 const T value3 = a * x3 * x3 * x3 + b * x3 * x3 + c * x3 + d;
292 if (!std::is_same<T, float>::value)
302 optimizeCubic(a, b, c, d, x1);
303 optimizeCubic(a, b, c, d, x2);
304 optimizeCubic(a, b, c, d, x3);
320 x1 = m + n - alpha * T(0.33333333333333333333333333333333);
324 const T value1 = a * x1 * x1 * x1 + b * x1 * x1 + c * x1 + d;
327 if (!std::is_same<T, float>::value)
336 optimizeCubic(a, b, c, d, x1);
346 ocean_assert(x !=
nullptr);
359 const T a1 = T(1.0) / a;
362 const T b_a = b * a1;
365 const T c_a = c * a1;
368 const T b_a2 = b_a * b_a;
371 const T b_a3 = b_a2 * b_a;
374 const T d_a = d * a1;
377 const T alpha = T(-0.375) * b_a2 + c_a;
380 const T beta = T(0.125) * b_a3 - T(0.5) * b_a * c_a + d_a;
383 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;
387 unsigned int solutions = 0u;
391 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))));
392 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))));
393 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))));
394 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))));
396 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));
397 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));
398 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));
399 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));
403 x[solutions++] = cx1.real();
408 x[solutions++] = cx2.real();
413 x[solutions++] = cx3.real();
418 x[solutions++] = cx4.real();
424 const std::complex<T> p(T(-0.08333333333333333333333333333333) * alpha * alpha - gamma);
427 const std::complex<T> q(T(-0.00925925925925925925925925925926) * alpha * alpha * alpha + T(0.33333333333333333333333333333333) * alpha * gamma - T(0.125) * beta * beta);
429 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);
431 const std::complex<T> r(std::complex<T>(T(-0.5)) * q + qqSqr);
437 const std::complex<T> u =
NumericT<T>::pow(std::complex<T>(r), T(0.33333333333333333333333333333333));
447 y = std::complex<T>(T(-0.83333333333333333333333333333333) * alpha) + u -
NumericT<T>::pow(std::complex<T>(q), T(0.33333333333333333333333333333333));
451 y = std::complex<T>(T(-0.83333333333333333333333333333333) * alpha) + u - p / (std::complex<T>(3) * u);
454 const std::complex<T> w(
NumericT<T>::sqrt(std::complex<T>(alpha) + std::complex<T>(T(2)) * y));
463 const std::complex<T> beta2_w(std::complex<T>(T(2) * beta) / w);
464 const std::complex<T> alpha3y2 = std::complex<T>(T(3) * alpha) + std::complex<T>(T(2)) * y;
465 const std::complex<T> b_a4(T(-0.25) * b_a);
470 const std::complex<T> cx1 = b_a4 + std::complex<T>(T(0.5)) * (w + sqrtPositive);
471 const std::complex<T> cx2 = b_a4 + std::complex<T>(T(0.5)) * (w - sqrtPositive);
472 const std::complex<T> cx3 = b_a4 + std::complex<T>(T(0.5)) * (-w + sqrtNegative);
473 const std::complex<T> cx4 = b_a4 + std::complex<T>(T(0.5)) * (-w - sqrtNegative);
477 x[solutions++] = cx1.real();
482 x[solutions++] = cx2.real();
487 x[solutions++] = cx3.real();
492 x[solutions++] = cx4.real();
500 for (
unsigned int n = 0u; n < solutions; ++n)
502 optimizeQuartic(a, b, c, d, e, x[n]);
508 unsigned int nOutput = 0u;
509 for (
unsigned int nInput = 0u; nInput < solutions; ++nInput)
511 const T value = x[nInput];
513 if (
NumericT<T>::isWeakEqualEps(value * value * value * value * a + value * value * value * b + value * value * c + value * d + e))
517 if (nOutput != nInput)
519 x[nOutput] = x[nInput];
static unsigned int solveQuartic(const T a, const T b, const T c, const T d, const T e, T *x, const bool refine=true)
Solves a quartic equation with the form:
Definition Equation.h:343
static unsigned int optimizeCubic(const T a, const T b, const T c, const T d, T &x, const unsigned int maxIterations=10u, const T updateFactor=T(1.0))
Optimizes a root of a cubic equation using Newton-Raphson iterations.
Definition Equation.h:532
static unsigned int optimizeQuartic(const T a, const T b, const T c, const T d, const T e, T &x, const unsigned int maxIterations=10u, const T updateFactor=T(1.0))
Optimizes a root of a quartic equation using Newton-Raphson iterations.
Definition Equation.h:584
static unsigned int solveCubic(const T a, const T b, const T c, const T d, T &x1, T &x2, T &x3, const bool refine=true)
Solves a cubic equation with the from:
Definition Equation.h:229