/// <summary> /// Solve a quadratic equation in the form ax^2 + bx + c = 0 /// </summary> /// <returns>The two roots of the quadratic equation, which may be complex.</returns> public static (Complex r1, Complex r2) SolveQuadratic(Complex a, Complex b, Complex c) { Complex sqrt = Complex.Sqrt(b * b - 4 * a * c); Complex denom = 2 * a; return((-b + sqrt) / denom, (-b - sqrt) / denom); }
/// <summary> /// Find all three complex roots of the cubic equation d + c*x + b*x^2 + a*x^3 = 0. /// Note the special coefficient order ascending by exponent (consistent with polynomials). /// </summary> public static Tuple <Complex, Complex, Complex> Roots(double d, double c, double b, double a) { double A = b * b - 3 * a * c; double B = 2 * b * b * b - 9 * a * b * c + 27 * a * a * d; double s = -1 / (3 * a); double D = (B * B - 4 * A * A * A) / (-27 * a * a); if (D == 0d) { if (A == 0d) { var u = new Complex(s * b, 0d); return(new Tuple <Complex, Complex, Complex>(u, u, u)); } var v = new Complex((9 * a * d - b * c) / (2 * A), 0d); var w = new Complex((4 * a * b * c - 9 * a * a * d - b * b * b) / (a * A), 0d); return(new Tuple <Complex, Complex, Complex>(v, v, w)); } var C = (A == 0) ? new Complex(B, 0d).CubicRoots() : ((B + Complex.Sqrt(B * B - 4 * A * A * A)) / 2).CubicRoots(); return(new Tuple <Complex, Complex, Complex>( s * (b + C.Item1 + A / C.Item1), s * (b + C.Item2 + A / C.Item2), s * (b + C.Item3 + A / C.Item3))); }
/// <summary> /// Solve a quartic equation of the form ax^4 + bx^3 + cx^2 + dx + e = 0. /// </summary> /// <returns>The four roots of the quartic, which may be complex.</returns> public static (Complex r1, Complex r2, Complex r3, Complex r4) SolveQuartic(Complex a, Complex b, Complex c, Complex d, Complex e) { // https://math.stackexchange.com/a/57688 Complex A = (c / a) - ((3 * b * b) / (8 * a * a)); Complex B = (d / a) - ((b * c) / (2 * a * a)) + ((b * b * b) / (8 * a * a * a)); Complex C = (e / a) - ((b * d) / (4 * a * a)) + ((b * b * c) / (16 * a * a * a)) - ((3 * b * b * b * b) / (256 * a * a * a * a)); var(s1, s2, s3) = SolveCubic(8.0, -4.0 * A, -8.0 * C, (4.0 * A * C) - (B * B)); Complex cmp1 = 0.5 * Complex.Sqrt((2.0 * s1) - A); Complex cmp2 = (-2.0 * s1) - A; Complex cmp3 = (2.0 * B) / Complex.Sqrt((2.0 * s1) - A); Complex cmp4 = -b / (4.0 * a); Complex sqrt1 = 0.5 * Complex.Sqrt(cmp2 + cmp3); Complex sqrt2 = 0.5 * Complex.Sqrt(cmp2 - cmp3); Complex r1 = -cmp1 + sqrt1 + cmp4; Complex r2 = -cmp1 - sqrt1 + cmp4; Complex r3 = cmp1 + sqrt2 + cmp4; Complex r4 = cmp1 - sqrt2 + cmp4; return(r1, r2, r3, r4); }
/// <summary> /// Find all three complex roots of the cubic equation d + c*x + b*x^2 + a*x^3 = 0. /// Note the special coefficient order ascending by exponent (consistent with polynomials). /// </summary> public static Tuple <Complex, Complex, Complex> Roots(double d, double c, double b, double a) { double A = (b * b) - (3 * a * c); double B = ((2 * b * b * b) - (9 * a * b * c)) + (27 * a * a * d); double s = -1 / (3 * a); double D = ((B * B) - (4 * A * A * A)) / (-27 * a * a); if (D == 0d) { if (A == 0d) { var u = new Complex(s * b, 0d); return(new Tuple <Complex, Complex, Complex>(u, u, u)); } var v = new Complex(((9 * a * d) - (b * c)) / (2 * A), 0d); var w = new Complex(((4 * a * b * c) - (9 * a * a * d) - (b * b * b)) / (a * A), 0d); return(new Tuple <Complex, Complex, Complex>(v, v, w)); } var C = (A == 0) ? new Complex(B, 0d).CubicRoots() : ((B + Complex.Sqrt((B * B) - (4 * A * A * A))) / 2).CubicRoots(); return(new Tuple <Complex, Complex, Complex>( s * (b + C.Item1 + (A / C.Item1)), s * (b + C.Item2 + (A / C.Item2)), s * (b + C.Item3 + (A / C.Item3)))); }
public void ComplexMyToNet() { Complex myComplex = new Complex(-1.0, 2.0); NetComplex netComplex = myComplex; Assert.IsTrue(netComplex.Real == myComplex.Re); Assert.IsTrue(netComplex.Imaginary == myComplex.Im); Assert.IsTrue(NetComplex.Sqrt(netComplex) == NetComplex.Sqrt(myComplex)); }
/// <summary> /// Returns the spherical Bessel function of the first kind. /// <para>SphericalBesselJ(n, z) is given by Sqrt(pi/2) / Sqrt(z) * BesselJ(n + 1/2, z).</para> /// </summary> /// <param name="n">The order of the spherical Bessel function.</param> /// <param name="z">The value to compute the spherical Bessel function of.</param> /// <returns>The spherical Bessel function of the first kind.</returns> public static Complex SphericalBesselJ(double n, Complex z) { if (double.IsNaN(n) || double.IsNaN(z.Real) || double.IsNaN(z.Imaginary)) { return(new Complex(double.NaN, double.NaN)); } if (double.IsInfinity(z.Real)) { return((z.Imaginary == 0) ? Complex.Zero : new Complex(double.PositiveInfinity, double.PositiveInfinity)); } if (z.Real == 0 && z.Imaginary == 0) { return((n == 0) ? 1 : 0); } return(Constants.SqrtPiOver2 * BesselJ(n + 0.5, z) / Complex.Sqrt(z)); }
/// <summary> /// Solve a cubic equation in the form ax^3 + bx^2 + cx + d = 0 /// </summary> /// <returns>The three roots of the cubic, which may be complex.</returns> public static (Complex r1, Complex r2, Complex r3) SolveCubic(Complex a, Complex b, Complex c, Complex d) { Complex delta0 = (b * b) - (3 * a * c); Complex delta1 = (2 * b * b * b) - (9 * a * b * c) + (27 * a * a * d); Complex root = Complex.Sqrt((delta1 * delta1) - (4 * delta0 * delta0 * delta0)); double epsilon = 0.00001; if (Math.Abs(delta1.Real - root.Real) < epsilon && Math.Abs(delta1.Imaginary - root.Imaginary) < epsilon) { root = -root; } var(C1, C2, C3) = ComplexCubeRoot((delta1 - root) / 2.0); Complex r1 = -(1.0 / (3.0 * a)) * (b + C1 + (delta0 / C1)); Complex r2 = -(1.0 / (3.0 * a)) * (b + C2 + (delta0 / C2)); Complex r3 = -(1.0 / (3.0 * a)) * (b + C3 + (delta0 / C3)); return(r1, r2, r3); }