M2
This commit is contained in:
@@ -0,0 +1,140 @@
|
||||
using System.Numerics;
|
||||
using Skeleton.Algebra.Extensions;
|
||||
using Skeleton.Analysis.BivariantFunctions.Real.Implements;
|
||||
using Skeleton.Analysis.BivariantFunctions.Real.PolynomialHelpers;
|
||||
using Skeleton.Utils.Helpers;
|
||||
|
||||
namespace Skeleton.Analysis.AnalyticFunctions.Polynomials.Implements;
|
||||
|
||||
/// <summary>
|
||||
/// </summary>
|
||||
public class C4Polynomial : Polynomial
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public C4Polynomial()
|
||||
{
|
||||
Coefficients = new Complex[5];
|
||||
Fix();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public C4Polynomial(Complex a0, Complex a1, Complex a2, Complex a3, Complex a4)
|
||||
{
|
||||
Coefficients = new[] { a0, a1, a2, a3, a4 };
|
||||
Fix();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// </summary>
|
||||
public Complex A0 => Coefficients[0];
|
||||
|
||||
/// <summary>
|
||||
/// </summary>
|
||||
public Complex A1 => Coefficients[1];
|
||||
|
||||
/// <summary>
|
||||
/// </summary>
|
||||
public Complex A2 => Coefficients[2];
|
||||
|
||||
/// <summary>
|
||||
/// </summary>
|
||||
public Complex A3 => Coefficients[3];
|
||||
|
||||
/// <summary>
|
||||
/// </summary>
|
||||
public Complex A4 => Coefficients[4];
|
||||
|
||||
/// <inheritdoc />
|
||||
public override int Dim => 4;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override Polynomial Derivative => new C3Polynomial(A1, A2 * 2, A3 * 3, A4 * 4);
|
||||
|
||||
/// <inheritdoc />
|
||||
public override IEnumerable<Complex> Roots =>
|
||||
Decorators.WithTol(1e-20, () =>
|
||||
{
|
||||
if (A4.IsEqualApprox(Complex.Zero))
|
||||
return new C3Polynomial(A0, A1, A2, A3).Roots;
|
||||
if (A0.IsEqualApprox(Complex.Zero))
|
||||
return new C3Polynomial(A1, A2, A3, A4).Roots.Concat(new[] { Complex.Zero });
|
||||
if (A3.IsEqualApprox(Complex.Zero) && A1.IsEqualApprox(Complex.Zero))
|
||||
return new C2Polynomial(A0, A2, A4).Roots
|
||||
.SelectMany(x => new[] { Complex.Sqrt(x), -Complex.Sqrt(x) });
|
||||
|
||||
|
||||
Polynomial gcd = GreatestCommonDivisor(Derivative);
|
||||
if (!gcd.IsConstant)
|
||||
{
|
||||
Polynomial div = LongDivision(gcd).Quotient;
|
||||
return div.Roots.Concat(gcd.Roots);
|
||||
}
|
||||
|
||||
Complex a = A4;
|
||||
Complex b = A3;
|
||||
Complex c = A2;
|
||||
Complex d = A1;
|
||||
Complex e = A0;
|
||||
Complex P = (c * c + 12d * a * e - 3d * b * d) / 9d;
|
||||
Complex Q = (27d * a * d * d + 2d * c * c * c + 27d * b * b * e - 72d * a * c * e - 9d * b * c * d) / 54d;
|
||||
Complex D = Complex.Sqrt(Q * Q - P * P * P);
|
||||
Complex ua = Complex.Pow(Q + D, 1d / 3d);
|
||||
Complex ub = Complex.Pow(Q - D, 1d / 3d);
|
||||
Complex u = Complex.Abs(ua) > Complex.Abs(ub) ? ua : ub;
|
||||
Complex v = u.IsEqualApprox(0d) ? 0d : P / u;
|
||||
Complex omega = -0.5d + Complex.Sqrt(3d) * Complex.ImaginaryOne / 2d;
|
||||
|
||||
Complex m(int k)
|
||||
{
|
||||
return Complex.Sqrt(b * b - 8d / 3d * a * c +
|
||||
4d * a * (Utils.Utils.IterPow(omega, k - 1) * u +
|
||||
Utils.Utils.IterPow(omega, 4 - k) * v));
|
||||
}
|
||||
|
||||
Complex S(int k)
|
||||
{
|
||||
return 2d * b * b - 16d / 3d * a * c -
|
||||
4d * a * (Utils.Utils.IterPow(omega, k - 1) * u + Utils.Utils.IterPow(omega, 4 - k) * v);
|
||||
}
|
||||
|
||||
int i = new[] { 1, 2, 3 }.MaxBy(x => m(x).Magnitude);
|
||||
Complex mm = m(i);
|
||||
Complex SS = S(i);
|
||||
Complex T = 0;
|
||||
if (mm.Magnitude.IsEqualApprox(0))
|
||||
{
|
||||
mm = 0;
|
||||
SS = b * b - 8d / 3d * a * c;
|
||||
T = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
T = (8d * a * b * c - 16d * a * a * d - 2d * b * b * b) / mm;
|
||||
}
|
||||
|
||||
Complex x(int i)
|
||||
{
|
||||
return (-b + Utils.Utils.SPow(Math.Ceiling(i / 2f)) * mm + Utils.Utils.SPow(i + 1) *
|
||||
Complex.Sqrt(SS + Utils.Utils.SPow(Math.Ceiling(i / 2f)) * T)) /
|
||||
(4d * a);
|
||||
}
|
||||
|
||||
return new[] { x(1), x(2), x(3), x(4) };
|
||||
});
|
||||
|
||||
|
||||
/// <inheritdoc />
|
||||
public override BivariantContinuous Re => new PolyCHelper.PolyC4Re(A0, A1, A2, A3, A4);
|
||||
|
||||
/// <inheritdoc />
|
||||
public override BivariantContinuous Im => new PolyCHelper.PolyC4Im(A0, A1, A2, A3, A4);
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string Representation =>
|
||||
$"{A0.Real} + {A0.Imaginary}i + ({A1.Real} + {A1.Imaginary}i)x + ({A2.Real} + {A2.Imaginary}i)x2 + ({A3.Real} + {A3.Imaginary}i)X3 + ({A4.Real} + {A4.Imaginary}i)x4";
|
||||
|
||||
/// <inheritdoc />
|
||||
public override Complex Evaluate(Complex x)
|
||||
=> A0 + x * (A1 + x * (A2 + x * (A3 + x * A4)));
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user