public static bool Polynomial(Polynomial poly, out float[] roots, int digits = 6, float epsilon = 1E-05f) { float num = RootFinder.PolynomialBound(poly, 1E-05f); if (num == -1f) { roots = new float[0]; return(false); } return(RootFinder.Polynomial(poly, -num, num, out roots, digits, epsilon)); }
public static bool Quadratic(float c0, float c1, float c2, out QuadraticRoots roots, float epsilon = 1E-05f) { if (Mathf.Abs(c2) <= epsilon) { float x; bool flag = RootFinder.Linear(c0, c1, out x, epsilon); if (flag) { roots.X0 = x; roots.X1 = float.NaN; roots.RootCount = 1; } else { roots.X0 = float.NaN; roots.X1 = float.NaN; roots.RootCount = 0; } return(flag); } float num = c1 * c1 - 4f * c0 * c2; if (Mathf.Abs(num) <= epsilon) { num = 0f; } if (num < 0f) { roots.X0 = float.NaN; roots.X1 = float.NaN; roots.RootCount = 0; return(false); } float num2 = 0.5f / c2; if (num > 0f) { num = Mathf.Sqrt(num); roots.X0 = num2 * (-c1 - num); roots.X1 = num2 * (-c1 + num); roots.RootCount = 2; } else { roots.X0 = -num2 * c1; roots.X1 = float.NaN; roots.RootCount = 1; } return(true); }
public static bool Quartic(float c0, float c1, float c2, float c3, float c4, out QuarticRoots roots, float epsilon = 1E-05f) { roots.X0 = float.NaN; roots.X1 = float.NaN; roots.X2 = float.NaN; roots.X3 = float.NaN; if (Mathf.Abs(c4) <= epsilon) { CubicRoots cubicRoots; bool flag = RootFinder.Cubic(c0, c1, c2, c3, out cubicRoots, epsilon); if (flag) { roots.X0 = cubicRoots.X0; roots.X1 = cubicRoots.X1; roots.X2 = cubicRoots.X2; roots.RootCount = cubicRoots.RootCount; } else { roots.RootCount = 0; } return(flag); } float num = 1f / c4; c0 *= num; c1 *= num; c2 *= num; c3 *= num; float c5 = -c3 * c3 * c0 + 4f * c2 * c0 - c1 * c1; float c6 = c3 * c1 - 4f * c0; float c7 = -c2; CubicRoots cubicRoots2; RootFinder.Cubic(c5, c6, c7, 1f, out cubicRoots2, epsilon); float x = cubicRoots2.X0; roots.RootCount = 0; float num2 = 0.25f * c3 * c3 - c2 + x; if (Mathf.Abs(num2) <= epsilon) { num2 = 0f; } if (num2 > 0f) { float num3 = Mathf.Sqrt(num2); float num4 = 0.75f * c3 * c3 - num3 * num3 - 2f * c2; float num5 = (4f * c3 * c2 - 8f * c1 - c3 * c3 * c3) / (4f * num3); float num6 = num4 + num5; float num7 = num4 - num5; if (Mathf.Abs(num6) <= epsilon) { num6 = 0f; } if (Mathf.Abs(num7) <= epsilon) { num7 = 0f; } if (num6 >= 0f) { float num8 = Mathf.Sqrt(num6); roots.X0 = -0.25f * c3 + 0.5f * (num3 + num8); roots.X1 = -0.25f * c3 + 0.5f * (num3 - num8); roots.RootCount += 2; } if (num7 >= 0f) { float num9 = Mathf.Sqrt(num7); if (roots.RootCount == 0) { roots.X0 = -0.25f * c3 + 0.5f * (num9 - num3); roots.X1 = -0.25f * c3 - 0.5f * (num9 + num3); } else { roots.X2 = -0.25f * c3 + 0.5f * (num9 - num3); roots.X3 = -0.25f * c3 - 0.5f * (num9 + num3); } roots.RootCount += 2; } } else if (num2 < 0f) { roots.RootCount = 0; } else { float num10 = x * x - 4f * c0; if (num10 >= -epsilon) { if (num10 < 0f) { num10 = 0f; } num10 = 2f * Mathf.Sqrt(num10); float num11 = 0.75f * c3 * c3 - 2f * c2; float num12 = num11 + num10; if (num12 >= epsilon) { float num13 = Mathf.Sqrt(num12); roots.X0 = -0.25f * c3 + 0.5f * num13; roots.X1 = -0.25f * c3 - 0.5f * num13; roots.RootCount += 2; } float num14 = num11 - num10; if (num14 >= epsilon) { float num15 = Mathf.Sqrt(num14); if (roots.RootCount == 0) { roots.X0 = -0.25f * c3 + 0.5f * num15; roots.X1 = -0.25f * c3 - 0.5f * num15; } else { roots.X2 = -0.25f * c3 + 0.5f * num15; roots.X3 = -0.25f * c3 - 0.5f * num15; } roots.RootCount += 2; } } } return(roots.RootCount > 0); }
public static bool Cubic(float c0, float c1, float c2, float c3, out CubicRoots roots, float epsilon = 1E-05f) { if (Mathf.Abs(c3) <= epsilon) { QuadraticRoots quadraticRoots; bool flag = RootFinder.Quadratic(c0, c1, c2, out quadraticRoots, epsilon); if (flag) { roots.X0 = quadraticRoots.X0; roots.X1 = quadraticRoots.X1; roots.X2 = float.NaN; roots.RootCount = quadraticRoots.RootCount; } else { roots.X0 = float.NaN; roots.X1 = float.NaN; roots.X2 = float.NaN; roots.RootCount = 0; } return(flag); } float num = 1f / c3; c2 *= num; c1 *= num; c0 *= num; float num2 = 0.333333343f * c2; float num3 = c1 - c2 * num2; float num4 = c0 + c2 * (2f * c2 * c2 - 9f * c1) * 0.0370370373f; float num5 = 0.5f * num4; float num6 = num5 * num5 + num3 * num3 * num3 * 0.0370370373f; if (Mathf.Abs(num6) <= epsilon) { num6 = 0f; } if (num6 > 0f) { num6 = Mathf.Sqrt(num6); float num7 = -num5 + num6; if (num7 >= 0f) { roots.X0 = Mathf.Pow(num7, 0.333333343f); } else { roots.X0 = -Mathf.Pow(-num7, 0.333333343f); } num7 = -num5 - num6; if (num7 >= 0f) { roots.X0 += Mathf.Pow(num7, 0.333333343f); } else { roots.X0 -= Mathf.Pow(-num7, 0.333333343f); } roots.X0 -= num2; roots.X1 = float.NaN; roots.X2 = float.NaN; roots.RootCount = 1; } else if (num6 < 0f) { float num8 = Mathf.Sqrt(-0.333333343f * num3); float f = 0.333333343f * Mathf.Atan2(Mathf.Sqrt(-num6), -num5); float num9 = Mathf.Cos(f); float num10 = Mathf.Sin(f); roots.X0 = 2f * num8 * num9 - num2; roots.X1 = -num8 * (num9 + RootFinder.sqrt3 * num10) - num2; roots.X2 = -num8 * (num9 - RootFinder.sqrt3 * num10) - num2; roots.RootCount = 3; } else { float num11; if (num5 >= 0f) { num11 = -Mathf.Pow(num5, 0.333333343f); } else { num11 = Mathf.Pow(-num5, 0.333333343f); } roots.X0 = 2f * num11 - num2; roots.X1 = -num11 - num2; roots.X2 = roots.X1; roots.RootCount = 3; } return(true); }