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)
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;
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 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