This commit is contained in:
h z
2024-06-21 21:48:07 +08:00
commit 42ba33d229
129 changed files with 10711 additions and 0 deletions

View File

@@ -0,0 +1,39 @@
using System.Numerics;
using Skeleton.Analysis.AnalyticFunctions.Implements;
namespace Skeleton.Analysis.AnalyticFunctions.Arithmetics;
/// <summary>
/// addition
/// </summary>
public class AnalyticAddition : Analytic
{
/// <summary>
/// constructor
/// </summary>
/// <param name="left"></param>
/// <param name="right"></param>
public AnalyticAddition(Analytic left, Analytic right)
{
Left = left;
Right = right;
}
private Analytic Left { get; }
private Analytic Right { get; }
/// <summary>
/// d (f+g)/dx
/// </summary>
public override Analytic Derivative => Left.Derivative + Right.Derivative;
/// <summary>
/// [f+g](x)
/// </summary>
/// <param name="x"></param>
/// <returns></returns>
public override Complex Evaluate(Complex x)
{
return Left.Evaluate(x) + Right.Evaluate(x);
}
}

View File

@@ -0,0 +1,39 @@
using System.Numerics;
using Skeleton.Analysis.AnalyticFunctions.Implements;
namespace Skeleton.Analysis.AnalyticFunctions.Arithmetics;
/// <summary>
/// f(x),g(x) -> f(g(x))
/// </summary>
public class AnalyticApply : Analytic
{
/// <summary>
/// Constructor
/// </summary>
/// <param name="outer"></param>
/// <param name="inner"></param>
public AnalyticApply(Analytic outer, Analytic inner)
{
Outer = outer;
Inner = inner;
}
private Analytic Outer { get; }
private Analytic Inner { get; }
/// <summary>
/// d(f(g(x)))/dx
/// </summary>
public override Analytic Derivative => Inner.Derivative * Outer.Derivative[Inner];
/// <summary>
/// f(g(x))
/// </summary>
/// <param name="x"></param>
/// <returns></returns>
public override Complex Evaluate(Complex x)
{
return Outer.Evaluate(Inner.Evaluate(x));
}
}

View File

@@ -0,0 +1,46 @@
using System.Numerics;
using Skeleton.Analysis.AnalyticFunctions.Implements;
namespace Skeleton.Analysis.AnalyticFunctions.Arithmetics;
/// <summary>
/// C
/// </summary>
public class AnalyticConstant : Analytic
{
/// <summary>
/// zero
/// </summary>
public static readonly AnalyticConstant Zero = new(0);
/// <summary>
/// one
/// </summary>
public static readonly AnalyticConstant One = new(1);
/// <summary>
/// constructor
/// </summary>
/// <param name="c"></param>
public AnalyticConstant(Complex c)
{
Constant = c;
}
private Complex Constant { get; }
/// <summary>
/// dc/dx = 0
/// </summary>
public override Analytic Derivative => Zero;
/// <summary>
/// c(x) = c
/// </summary>
/// <param name="x"></param>
/// <returns></returns>
public override Complex Evaluate(Complex x)
{
return Constant;
}
}

View File

@@ -0,0 +1,25 @@
using System.Numerics;
using Skeleton.Analysis.AnalyticFunctions.Implements;
namespace Skeleton.Analysis.AnalyticFunctions.Arithmetics;
/// <summary>
/// f(x) = x
/// </summary>
public class AnalyticIdentity : Analytic
{
/// <summary>
/// dx/dx = 1
/// </summary>
public override Analytic Derivative => AnalyticConstant.One;
/// <summary>
/// x = x
/// </summary>
/// <param name="x"></param>
/// <returns></returns>
public override Complex Evaluate(Complex x)
{
return x;
}
}

View File

@@ -0,0 +1,36 @@
using System.Numerics;
using Skeleton.Analysis.AnalyticFunctions.Implements;
namespace Skeleton.Analysis.AnalyticFunctions.Arithmetics;
/// <summary>
/// -f
/// </summary>
public class AnalyticNegation : Analytic
{
/// <summary>
/// constructor
/// </summary>
/// <param name="element"></param>
public AnalyticNegation(Analytic element)
{
Element = element;
}
private Analytic Element { get; }
/// <summary>
/// d[-f]/dx = -df/dx
/// </summary>
public override Analytic Derivative => -Element.Derivative;
/// <summary>
/// [-f](x) = -x
/// </summary>
/// <param name="x"></param>
/// <returns></returns>
public override Complex Evaluate(Complex x)
{
return -Element.Evaluate(x);
}
}

View File

@@ -0,0 +1,39 @@
using System.Numerics;
using Skeleton.Analysis.AnalyticFunctions.Implements;
namespace Skeleton.Analysis.AnalyticFunctions.Arithmetics;
/// <summary>
/// f(x), g(x) -> f(x)g(x)
/// </summary>
public class AnalyticProduction : Analytic
{
/// <summary>
/// Constructor
/// </summary>
/// <param name="left"></param>
/// <param name="right"></param>
public AnalyticProduction(Analytic left, Analytic right)
{
Left = left;
Right = right;
}
private Analytic Left { get; }
private Analytic Right { get; }
/// <summary>
/// dfg/dx = fdg/dx + gdf/dx
/// </summary>
public override Analytic Derivative => Left.Derivative * Right + Left * Right.Derivative;
/// <summary>
/// f(x)*g(x)
/// </summary>
/// <param name="x"></param>
/// <returns></returns>
public override Complex Evaluate(Complex x)
{
return Left.Evaluate(x) * Right.Evaluate(x);
}
}

View File

@@ -0,0 +1,19 @@
using System.Numerics;
using Skeleton.Analysis.AnalyticFunctions.Implements;
namespace Skeleton.Analysis.AnalyticFunctions;
/// <summary>
/// </summary>
public interface IAnalytic
{
/// <summary>
/// </summary>
Analytic Derivative { get; }
/// <summary>
/// </summary>
/// <param name="x"></param>
/// <returns></returns>
Complex Evaluate(Complex x);
}

View File

@@ -0,0 +1,63 @@
using System.Numerics;
using Skeleton.Analysis.AnalyticFunctions.Arithmetics;
namespace Skeleton.Analysis.AnalyticFunctions.Implements;
/// <summary>
/// analytic functions
/// </summary>
public abstract class Analytic : IAnalytic
{
/// <summary>
/// f(g)(x) -> f(g(x))
/// </summary>
/// <param name="inner"></param>
public Analytic this[Analytic inner] => new AnalyticApply(this, inner);
/// <summary>
/// df/dx
/// </summary>
public abstract Analytic Derivative { get; }
/// <summary>
/// f(x)
/// </summary>
/// <param name="x"></param>
/// <returns></returns>
public abstract Complex Evaluate(Complex x);
/// <summary>
/// [f+g](x) = f(x) + g(x)
/// </summary>
/// <param name="a"></param>
/// <param name="b"></param>
/// <returns></returns>
public static Analytic operator +(Analytic a, Analytic b)
=> new AnalyticAddition(a, b);
/// <summary>
/// [-f](x) = -f(x)
/// </summary>
/// <param name="a"></param>
/// <returns></returns>
public static Analytic operator -(Analytic a)
=> new AnalyticNegation(a);
/// <summary>
/// [f-g](x) = f(x) - g(x)
/// </summary>
/// <param name="a"></param>
/// <param name="b"></param>
/// <returns></returns>
public static Analytic operator -(Analytic a, Analytic b)
=> -b + a;
/// <summary>
/// [fg](x) = f(x)g(x)
/// </summary>
/// <param name="a"></param>
/// <param name="b"></param>
/// <returns></returns>
public static Analytic operator *(Analytic a, Analytic b)
=> new AnalyticProduction(a, b);
}

View File

@@ -0,0 +1,29 @@
using System.Numerics;
using Skeleton.Analysis.BivariantFunctions.Real.Implements;
namespace Skeleton.Analysis.AnalyticFunctions.Polynomials;
/// <summary>
/// </summary>
public interface IPolynomial : IAnalytic
{
/// <summary>
/// </summary>
int Dim { get; }
/// <summary>
/// </summary>
int Degree { get; }
/// <summary>
/// </summary>
Complex[] Coefficients { get; set; }
/// <summary>
/// </summary>
BivariantContinuous Re { get; }
/// <summary>
/// </summary>
BivariantContinuous Im { get; }
}

View File

@@ -0,0 +1,61 @@
using System.Numerics;
using Skeleton.Analysis.BivariantFunctions.Real.Arithmetics;
using Skeleton.Analysis.BivariantFunctions.Real.Implements;
namespace Skeleton.Analysis.AnalyticFunctions.Polynomials.Implements;
/// <summary>
/// p = a0
/// </summary>
public class C0Polynomial : Polynomial
{
/// <summary>
/// constructor
/// </summary>
/// <param name="a0"></param>
public C0Polynomial(Complex a0)
{
Coefficients = new[] { a0 };
Fix();
}
/// <summary>
/// a0
/// </summary>
public Complex A0 => Coefficients[0];
/// <summary>
/// 0
/// </summary>
public override Polynomial Derivative => Zero;
/// <summary>
/// real part
/// </summary>
public override BivariantContinuous Re => new BivariantContinuousConstant(A0.Real);
/// <summary>
/// imaginary part
/// </summary>
public override BivariantContinuous Im => new BivariantContinuousConstant(A0.Imaginary);
/// <summary>
/// string for debug
/// </summary>
public override string Representation => $"{A0.Real} + {A0.Imaginary}i";
/// <inheritdoc />
public override int Dim => 0;
/// <inheritdoc />
public override IEnumerable<Complex> Roots => Array.Empty<Complex>();
/// <summary>
/// </summary>
/// <param name="x"></param>
/// <returns></returns>
public override Complex Evaluate(Complex x)
{
return A0;
}
}

View File

@@ -0,0 +1,54 @@
using System.Numerics;
using Skeleton.Analysis.BivariantFunctions.Real.Implements;
namespace Skeleton.Analysis.AnalyticFunctions.Polynomials.Implements;
/// <summary>
/// p(x) = a0 + a1 x
/// </summary>
public class C1Polynomial : Polynomial
{
private static readonly BivariantContinuous X = BivariantContinuous.X;
private static readonly BivariantContinuous Y = BivariantContinuous.Y;
/// <inheritdoc />
public C1Polynomial()
{
Coefficients = new Complex[2];
Fix();
}
/// <inheritdoc />
public C1Polynomial(Complex a0, Complex a1)
{
Coefficients = new[] { a0, a1 };
Fix();
}
private Complex A0 => Coefficients[0];
private Complex A1 => Coefficients[1];
/// <inheritdoc />
public override string Representation => $"{A0.Real} + {A0.Imaginary}i + ({A1.Real} + {A1.Imaginary}i)x";
/// <inheritdoc />
public override int Dim => 1;
/// <inheritdoc />
public override Polynomial Derivative => new C0Polynomial(A1);
/// <inheritdoc />
public override IEnumerable<Complex> Roots => new[] { -A0 / A1 };
/// <inheritdoc />
public override BivariantContinuous Re => A0.Real + A1.Real * X - A1.Imaginary * Y;
/// <inheritdoc />
public override BivariantContinuous Im => A0.Imaginary + A1.Real * Y + A1.Imaginary * X;
/// <inheritdoc />
public override Complex Evaluate(Complex x)
{
return A0 + x * A1;
}
}

View File

@@ -0,0 +1,74 @@
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 C2Polynomial : Polynomial
{
/// <inheritdoc />
public C2Polynomial()
{
Coefficients = new Complex[3];
Fix();
}
/// <inheritdoc />
public C2Polynomial(Complex a0, Complex a1, Complex a2)
{
Coefficients = new[] { a0, a1, a2 };
Fix();
}
/// <summary>
/// </summary>
public Complex A0 => Coefficients[0];
/// <summary>
/// </summary>
public Complex A1 => Coefficients[1];
/// <summary>
/// </summary>
public Complex A2 => Coefficients[2];
/// <inheritdoc />
public override string Representation =>
$"{A0.Real} + {A0.Imaginary}i + ({A1.Real} + {A1.Imaginary}i)x + ({A2.Real} + {A2.Imaginary}i)x2";
/// <inheritdoc />
public override int Dim => 2;
/// <inheritdoc />
public override Polynomial Derivative => new C1Polynomial(A1, A2 * 2);
/// <inheritdoc />
public override IEnumerable<Complex> Roots => Decorators.WithTol(1E-20,
() =>
{
if (A2.IsEqualApprox(0))
return new C1Polynomial(A0, A1).Roots;
if (A0.IsEqualApprox(0))
return new C1Polynomial(A1, A2).Roots.Concat(new[] { Complex.Zero });
Complex x1 = (-A1 + Complex.Sqrt(A1 * A1 - 4 * A2 * A0)) / (2 * A2);
Complex x2 = (-A1 - Complex.Sqrt(A1 * A1 - 4 * A2 * A0)) / (2 * A2);
return new[] { x1, x2 };
}
);
/// <inheritdoc />
public override BivariantContinuous Re => new PolyCHelper.PolyC2Re(A0, A1, A2);
/// <inheritdoc />
public override BivariantContinuous Im => new PolyCHelper.PolyC2Im(A0, A1, A2);
/// <inheritdoc />
public override Complex Evaluate(Complex x)
{
return A0 + x * (A1 + x * A2);
}
}

View File

@@ -0,0 +1,105 @@
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 C3Polynomial : Polynomial
{
/// <inheritdoc />
public C3Polynomial()
{
Coefficients = new Complex[4];
Fix();
}
/// <inheritdoc />
public C3Polynomial(Complex a0, Complex a1, Complex a2, Complex a3)
{
Coefficients = new[] { a0, a1, a2, a3 };
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];
/// <inheritdoc />
public override int Dim => 3;
/// <inheritdoc />
public override Polynomial Derivative => new C2Polynomial(A1, A2 * 2, A3 * 3);
/// <inheritdoc />
public override IEnumerable<Complex> Roots =>
Decorators.WithTol(1E-20, () =>
{
if (A3.IsEqualApprox(0))
return new C2Polynomial(A0, A1, A2).Roots;
if (A0.IsEqualApprox(0))
return new C2Polynomial(A1, A2, A3).Roots.Concat(new[] { Complex.Zero });
Polynomial gcd = GreatestCommonDivisor(Derivative);
if (!gcd.IsConstant)
{
Polynomial div = LongDivision(gcd).Quotient;
return div.Roots.Concat(gcd.Roots);
}
Complex a = A3;
Complex b = A2;
Complex c = A1;
Complex d = A0;
Complex D0 = b * b - 3d * a * c;
Complex D1 = 2d * b * b * b - 9d * a * b * c + 27d * a * a * d;
if (D0.IsEqualApprox(0) && D1.IsEqualApprox(0))
{
Complex root = -b / (a * 3d);
return new[] { root, root, root };
}
Complex C = Complex.Pow((D1 + Complex.Sqrt(D1 * D1 - 4d * D0 * D0 * D0)) / 2d, 1d / 3d);
if (C.IsEqualApprox(0))
C = Complex.Pow((D1 - Complex.Sqrt(D1 * D1 - 4d * D0 * D0 * D0)) / 2d, 1d / 3d);
if (C.IsEqualApprox(0))
throw new Exception($"Unknown situation with {a}, {b}, {c}, {d}"); //TODO
Complex ee = (-1d + Complex.Sqrt(-3d)) / 2d;
return new[]
{
-1d / (3d * a) * (b + C + D0 / C),
-1d / (3d * a) * (b + ee * C + D0 / (ee * C)),
-1d / (3d * a) * (b + ee * ee * C + D0 / (ee * ee * C))
};
});
/// <inheritdoc />
public override BivariantContinuous Re => new PolyCHelper.PolyC3Re(A0, A1, A2, A3);
/// <inheritdoc />
public override BivariantContinuous Im => new PolyCHelper.PolyC3Im(A0, A1, A2, A3);
/// <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";
/// <inheritdoc />
public override Complex Evaluate(Complex x)
{
return A0 + x * (A1 + x * (A2 + x * A3));
}
}

View File

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

View File

@@ -0,0 +1,29 @@
using System.Numerics;
using Skeleton.Analysis.BivariantFunctions.Real.Implements;
namespace Skeleton.Analysis.AnalyticFunctions.Polynomials.Implements;
/// <inheritdoc />
public class GeneralPolynomial : Polynomial
{
/// <inheritdoc />
public GeneralPolynomial(int dim, Complex[] coefficients)
{
PDim = dim;
Coefficients = new Complex[dim + 1];
for (int i = 0; i <= Dim; i++)
Coefficients[i] = coefficients[i];
}
private int PDim { get; }
public override IEnumerable<Complex> Roots { get; }
/// <inheritdoc />
public override int Dim => PDim;
/// <inheritdoc />
public override BivariantContinuous Re { get; }
/// <inheritdoc />
public override BivariantContinuous Im { get; }
}

View File

@@ -0,0 +1,262 @@
using System.Numerics;
using Skeleton.Algebra.Extensions;
using Skeleton.Algebra.ScalarFieldStructure;
using Skeleton.Analysis.AnalyticFunctions.Implements;
using Skeleton.Analysis.BivariantFunctions.Real.Implements;
using Skeleton.DataStructure.Packs;
using Skeleton.Utils.Helpers;
namespace Skeleton.Analysis.AnalyticFunctions.Polynomials.Implements;
/// <summary>
/// </summary>
public abstract class Polynomial : Analytic, IPolynomial
{
/// <summary>
/// </summary>
protected static readonly Polynomial Zero = new C0Polynomial(0);
private static readonly Polynomial One = new C0Polynomial(1);
private static readonly Polynomial X = new C1Polynomial(0, 1);
private static readonly Polynomial X2 = new C2Polynomial(0, 0, 1);
private static readonly Polynomial X3 = new C3Polynomial(0, 0, 0, 1);
private static readonly Polynomial X4 = new C4Polynomial(0, 0, 0, 0, 1);
private bool IsZero => Decorators.WithTol(1e-30, () => Coefficients.All(x => x.IsEqualApprox(Complex.Zero)));
/// <summary>
/// </summary>
public bool IsConstant =>
Decorators.WithTol(1E-30, () => Coefficients.Skip(1).All(x => x.IsEqualApprox(Complex.Zero)));
/// <inheritdoc />
public override Polynomial Derivative
{
get
{
Complex[] coeff = new Complex[Dim];
for (int i = 1; i <= Dim; i++)
coeff[i - 1] = Coefficients[i] * i;
return Dispatch(coeff);
}
}
/// <summary>
/// </summary>
public virtual string Representation =>
string.Join(
" + ",
Coefficients
.Zip(Enumerable.Range(0, Degree + 1))
.Select(
x
=> "(" +
ComplexFieldStructure.Structure.Representation(x.First) +
$")x^{x.Second}"
)
);
/// <summary>
/// </summary>
public abstract IEnumerable<Complex> Roots { get; }
/// <inheritdoc />
public abstract int Dim { get; }
/// <inheritdoc />
public int Degree
{
get
{
for (int i = 0; i <= Dim; i++)
if (Coefficients[^(i + 1)] != Complex.Zero)
return Dim - i;
return 0;
}
}
/// <inheritdoc />
public Complex[] Coefficients { get; set; } = Array.Empty<Complex>();
/// <inheritdoc />
public abstract BivariantContinuous Re { get; }
/// <inheritdoc />
public abstract BivariantContinuous Im { get; }
/// <summary>
/// </summary>
/// <param name="coefficients"></param>
/// <returns></returns>
/// <exception cref="Exception"></exception>
public static Polynomial Dispatch(Complex[] coefficients)
{
return coefficients.Length switch
{
1 => new C0Polynomial(coefficients[0]),
2 => new C1Polynomial(coefficients[0], coefficients[1]),
3 => new C2Polynomial(coefficients[0], coefficients[1], coefficients[2]),
4 => new C3Polynomial(coefficients[0], coefficients[1], coefficients[2], coefficients[3]),
5 => new C4Polynomial(coefficients[0], coefficients[1], coefficients[2], coefficients[3], coefficients[4]),
_ => new GeneralPolynomial(coefficients.Length - 1, coefficients)
};
}
/// <summary>
/// </summary>
/// <param name="a"></param>
/// <param name="b"></param>
/// <returns></returns>
public static Polynomial operator +(Polynomial a, Complex b) => a + new C0Polynomial(b);
/// <summary>
/// </summary>
/// <param name="b"></param>
/// <param name="a"></param>
/// <returns></returns>
public static Polynomial operator +(Complex b, Polynomial a) => a + b;
/// <summary>
/// </summary>
/// <param name="a"></param>
/// <param name="b"></param>
/// <returns></returns>
public static Polynomial operator -(Polynomial a, Complex b) => a + new C0Polynomial(-b);
/// <summary>
/// </summary>
/// <param name="a"></param>
/// <param name="b"></param>
/// <returns></returns>
public static Polynomial operator +(Polynomial a, Polynomial b)
{
int d = Math.Max(a.Degree, b.Degree);
int md = Math.Min(a.Degree, b.Degree);
Polynomial lp = new[] { a, b }.MaxBy(p => p.Degree)!;
Complex[] coefficients = new Complex[d + 1];
for (int i = 0; i <= d; i++)
if (i <= md)
coefficients[i] = a.Coefficients[i] + b.Coefficients[i];
else
coefficients[i] = lp.Coefficients[i];
return Dispatch(coefficients);
}
/// <summary>
/// </summary>
/// <param name="a"></param>
/// <returns></returns>
public static Polynomial operator -(Polynomial a)
=> Dispatch(a.Coefficients.Select(x => -x).ToArray());
/// <summary>
/// </summary>
/// <param name="a"></param>
/// <param name="b"></param>
/// <returns></returns>
public static Polynomial operator -(Polynomial a, Polynomial b) => -b + a;
/// <summary>
/// </summary>
/// <param name="a"></param>
/// <param name="b"></param>
/// <returns></returns>
public static Polynomial operator *(Polynomial a, Complex b)
=> Dispatch(a.Coefficients.Select(x => x * b).ToArray());
/// <summary>
/// </summary>
/// <param name="b"></param>
/// <param name="a"></param>
/// <returns></returns>
public static Polynomial operator *(Complex b, Polynomial a) => a * b;
/// <summary>
/// </summary>
/// <param name="a"></param>
/// <param name="b"></param>
/// <returns></returns>
public static Polynomial operator /(Polynomial a, Complex b)
=> Dispatch(a.Coefficients.Select(x => x / b).ToArray());
/// <summary>
/// </summary>
/// <param name="a"></param>
/// <param name="b"></param>
/// <returns></returns>
/// <exception cref="Exception"></exception>
public static Polynomial operator *(Polynomial a, Polynomial b)
{
int cd = a.Degree + b.Degree;
if (cd > 4)
throw new Exception("TODO");
Complex[] coefficients = new Complex[cd + 1];
for (int i = 0; i <= a.Degree; i++)
for (int j = 0; j <= b.Degree; j++)
coefficients[i + j] += a.Coefficients[i] * b.Coefficients[j];
return Dispatch(coefficients);
}
/// <summary>
/// </summary>
/// <param name="a"></param>
/// <returns></returns>
public PolynomialDivisionResult LongDivision(Polynomial a)
{
if (a.Degree > Degree)
return new PolynomialDivisionResult(Zero, a);
Complex leadingC = Coefficients[Degree] / a.Coefficients[a.Degree];
int degreeDifference = Degree - a.Degree;
Polynomial q = leadingC * new Xd(degreeDifference);
Complex[] rCoefficients = Coefficients.Select(x => x).ToArray();
rCoefficients[Degree] = 0;
Polynomial r = Dispatch(rCoefficients); //this - q * a;
if (r.Degree < a.Degree || (r.Degree == 0 && a.Degree == 0))
return new PolynomialDivisionResult(q, r);
PolynomialDivisionResult rDiv = r.LongDivision(a);
return new PolynomialDivisionResult(q + rDiv.Quotient, rDiv.Remainder);
}
/// <summary>
/// </summary>
/// <param name="o"></param>
/// <returns></returns>
public Polynomial GreatestCommonDivisor(Polynomial o)
{
Polynomial g, l;
if (Degree > o.Degree)
{
g = this;
l = o;
}
else
{
g = o;
l = this;
}
while (!l.IsZero)
{
PolynomialDivisionResult div = g.LongDivision(l); // = g.LongDivision(l);
g = l;
l = div.Remainder;
}
return g;
}
/// <summary>
/// </summary>
protected void Fix()
{
for (int i = 0; i < Dim; i++)
Coefficients[i] = ComplexFieldStructure.Structure.Fix(Coefficients[i]);
}
/// <inheritdoc />
public override Complex Evaluate(Complex x)
=> Enumerable
.Range(0, Degree + 1)
.Reverse()
.Select(i => Coefficients[i])
.Aggregate((x1, x2) => x1 * x + x2);
}

View File

@@ -0,0 +1,13 @@
using System.Numerics;
namespace Skeleton.Analysis.AnalyticFunctions.Polynomials.Implements;
/// <summary>
/// x^d
/// </summary>
public class Xd : GeneralPolynomial
{
/// <inheritdoc />
public Xd(int degree) : base(degree, new Complex[degree + 1])
=> Coefficients[^1] = 1;
}

View File

@@ -0,0 +1,30 @@
using Skeleton.Analysis.BivariantFunctions.Real.Implements;
namespace Skeleton.Analysis.BivariantFunctions.Real.Arithmetics;
/// <summary>
/// </summary>
public class BivariantContinuousAddition : BivariantContinuous
{
/// <inheritdoc />
public BivariantContinuousAddition(BivariantContinuous left, BivariantContinuous right)
{
Left = left;
Right = right;
}
private BivariantContinuous Left { get; }
private BivariantContinuous Right { get; }
/// <inheritdoc />
public override BivariantContinuous Dx => Left.Dx + Right.Dx;
/// <inheritdoc />
public override BivariantContinuous Dy => Left.Dy + Right.Dy;
/// <inheritdoc />
public override double Evaluate(double x, double y)
{
throw new NotImplementedException();
}
}

View File

@@ -0,0 +1,36 @@
using Skeleton.Analysis.BivariantFunctions.Real.Implements;
namespace Skeleton.Analysis.BivariantFunctions.Real.Arithmetics;
/// <summary>
/// </summary>
public class BivariantContinuousConstant : BivariantContinuous
{
/// <summary>
/// </summary>
public static readonly BivariantContinuousConstant COne = new(1);
/// <summary>
/// </summary>
public static readonly BivariantContinuousConstant CZero = new(0);
/// <inheritdoc />
public BivariantContinuousConstant(double c)
{
Constant = c;
}
private double Constant { get; }
/// <inheritdoc />
public override BivariantContinuous Dx => CZero;
/// <inheritdoc />
public override BivariantContinuous Dy => CZero;
/// <inheritdoc />
public override double Evaluate(double x, double y)
{
return Constant;
}
}

View File

@@ -0,0 +1,17 @@
using Skeleton.Analysis.BivariantFunctions.Real.Implements;
namespace Skeleton.Analysis.BivariantFunctions.Real.Arithmetics;
/// <summary>
/// </summary>
public class BivariantContinuousIdentityX : BivariantContinuous
{
/// <inheritdoc />
public override BivariantContinuous Dx => BivariantContinuousConstant.COne;
/// <inheritdoc />
public override BivariantContinuous Dy => BivariantContinuousConstant.CZero;
/// <inheritdoc />
public override double Evaluate(double x, double y) => x;
}

View File

@@ -0,0 +1,17 @@
using Skeleton.Analysis.BivariantFunctions.Real.Implements;
namespace Skeleton.Analysis.BivariantFunctions.Real.Arithmetics;
/// <summary>
/// </summary>
public class BivariantContinuousIdentityY : BivariantContinuous
{
/// <inheritdoc />
public override BivariantContinuous Dx => BivariantContinuousConstant.CZero;
/// <inheritdoc />
public override BivariantContinuous Dy => BivariantContinuousConstant.COne;
/// <inheritdoc />
public override double Evaluate(double x, double y) => y;
}

View File

@@ -0,0 +1,22 @@
using Skeleton.Analysis.BivariantFunctions.Real.Implements;
namespace Skeleton.Analysis.BivariantFunctions.Real.Arithmetics;
/// <summary>
/// </summary>
public class BivariantContinuousNegation : BivariantContinuous
{
/// <inheritdoc />
public BivariantContinuousNegation(BivariantContinuous e) => Element = e;
private BivariantContinuous Element { get; }
/// <inheritdoc />
public override BivariantContinuous Dx => -Element.Dx;
/// <inheritdoc />
public override BivariantContinuous Dy => -Element.Dy;
/// <inheritdoc />
public override double Evaluate(double x, double y) => -Element.Evaluate(x, y);
}

View File

@@ -0,0 +1,30 @@
using Skeleton.Analysis.BivariantFunctions.Real.Implements;
namespace Skeleton.Analysis.BivariantFunctions.Real.Arithmetics;
/// <summary>
/// </summary>
public class BivariantContinuousProduction : BivariantContinuous
{
/// <inheritdoc />
public BivariantContinuousProduction(BivariantContinuous l, BivariantContinuous r)
{
Left = l;
Right = r;
}
private BivariantContinuous Left { get; }
private BivariantContinuous Right { get; }
/// <inheritdoc />
public override BivariantContinuous Dx => Left.Dx * Right + Left * Right.Dx;
/// <inheritdoc />
public override BivariantContinuous Dy => Left.Dy * Right + Left * Right.Dy;
/// <inheritdoc />
public override double Evaluate(double x, double y)
{
return Left.Evaluate(x, y) * Right.Evaluate(x, y);
}
}

View File

@@ -0,0 +1,15 @@
using Skeleton.Analysis.BivariantFunctions.Real.Implements;
namespace Skeleton.Analysis.BivariantFunctions.Real.Arithmetics;
/// <summary>
/// </summary>
public class BivariantContinuousX2 : BivariantContinuous
{
/// <inheritdoc />
public override BivariantContinuous Dx => 2 * X;
/// <inheritdoc />
public override BivariantContinuous Dy => Zero;
/// <inheritdoc />
public override double Evaluate(double x, double y) => x * x;
}

View File

@@ -0,0 +1,20 @@
using Skeleton.Analysis.BivariantFunctions.Real.Implements;
namespace Skeleton.Analysis.BivariantFunctions.Real.Arithmetics;
/// <summary>
/// </summary>
public class BivariantContinuousX3 : BivariantContinuous
{
/// <inheritdoc />
public override BivariantContinuous Dx => 3 * X2;
/// <inheritdoc />
public override BivariantContinuous Dy => Zero;
/// <inheritdoc />
public override double Evaluate(double x, double y)
{
return x * x * x;
}
}

View File

@@ -0,0 +1,20 @@
using Skeleton.Analysis.BivariantFunctions.Real.Implements;
namespace Skeleton.Analysis.BivariantFunctions.Real.Arithmetics;
/// <summary>
/// </summary>
public class BivariantContinuousX4 : BivariantContinuous
{
/// <inheritdoc />
public override BivariantContinuous Dx => 4 * X3;
/// <inheritdoc />
public override BivariantContinuous Dy => Zero;
/// <inheritdoc />
public override double Evaluate(double x, double y)
{
return x * x * x * x;
}
}

View File

@@ -0,0 +1,20 @@
using Skeleton.Analysis.BivariantFunctions.Real.Implements;
namespace Skeleton.Analysis.BivariantFunctions.Real.Arithmetics;
/// <summary>
/// </summary>
public class BivariantContinuousY2 : BivariantContinuous
{
/// <inheritdoc />
public override BivariantContinuous Dx => Zero;
/// <inheritdoc />
public override BivariantContinuous Dy => 2 * Y;
/// <inheritdoc />
public override double Evaluate(double x, double y)
{
return y * y;
}
}

View File

@@ -0,0 +1,20 @@
using Skeleton.Analysis.BivariantFunctions.Real.Implements;
namespace Skeleton.Analysis.BivariantFunctions.Real.Arithmetics;
/// <summary>
/// </summary>
public class BivariantContinuousY3 : BivariantContinuous
{
/// <inheritdoc />
public override BivariantContinuous Dx => Zero;
/// <inheritdoc />
public override BivariantContinuous Dy => 3 * Y2;
/// <inheritdoc />
public override double Evaluate(double x, double y)
{
return y * y * y;
}
}

View File

@@ -0,0 +1,20 @@
using Skeleton.Analysis.BivariantFunctions.Real.Implements;
namespace Skeleton.Analysis.BivariantFunctions.Real.Arithmetics;
/// <summary>
/// </summary>
public class BivariantContinuousY4 : BivariantContinuous
{
/// <inheritdoc />
public override BivariantContinuous Dx => Zero;
/// <inheritdoc />
public override BivariantContinuous Dy => 4 * Y3;
/// <inheritdoc />
public override double Evaluate(double x, double y)
{
return y * y * y * y;
}
}

View File

@@ -0,0 +1,23 @@
using Skeleton.Analysis.BivariantFunctions.Real.Implements;
namespace Skeleton.Analysis.BivariantFunctions.Real;
/// <summary>
/// </summary>
public interface IBivariantContinuous
{
/// <summary>
/// </summary>
BivariantContinuous Dx { get; }
/// <summary>
/// </summary>
BivariantContinuous Dy { get; }
/// <summary>
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
/// <returns></returns>
double Evaluate(double x, double y);
}

View File

@@ -0,0 +1,156 @@
using Skeleton.Analysis.BivariantFunctions.Real.Arithmetics;
namespace Skeleton.Analysis.BivariantFunctions.Real.Implements;
/// <summary>
/// </summary>
public abstract class BivariantContinuous : IBivariantContinuous
{
/// <summary>
/// </summary>
public static readonly BivariantContinuous X = new BivariantContinuousIdentityX();
/// <summary>
/// </summary>
public static readonly BivariantContinuous Y = new BivariantContinuousIdentityY();
/// <summary>
/// </summary>
public static readonly BivariantContinuous Zero = BivariantContinuousConstant.CZero;
/// <summary>
/// </summary>
public static readonly BivariantContinuous One = BivariantContinuousConstant.COne;
/// <summary>
/// </summary>
public static readonly BivariantContinuous X2 = new BivariantContinuousX2();
/// <summary>
/// </summary>
public static readonly BivariantContinuous Y2 = new BivariantContinuousY2();
/// <summary>
/// </summary>
public static readonly BivariantContinuous X3 = new BivariantContinuousX3();
/// <summary>
/// </summary>
public static readonly BivariantContinuous Y3 = new BivariantContinuousY3();
/// <summary>
/// </summary>
public static readonly BivariantContinuous X4 = new BivariantContinuousX4();
/// <summary>
/// </summary>
public static readonly BivariantContinuous Y4 = new BivariantContinuousY4();
/// <inheritdoc />
public abstract double Evaluate(double x, double y);
/// <inheritdoc />
public abstract BivariantContinuous Dx { get; }
/// <inheritdoc />
public abstract BivariantContinuous Dy { get; }
/// <summary>
/// </summary>
/// <param name="a"></param>
/// <param name="b"></param>
/// <returns></returns>
public static BivariantContinuous operator +(BivariantContinuous a, BivariantContinuous b)
{
return new BivariantContinuousAddition(a, b);
}
/// <summary>
/// </summary>
/// <param name="a"></param>
/// <returns></returns>
public static BivariantContinuous operator -(BivariantContinuous a)
{
return new BivariantContinuousNegation(a);
}
/// <summary>
/// </summary>
/// <param name="a"></param>
/// <param name="b"></param>
/// <returns></returns>
public static BivariantContinuous operator -(BivariantContinuous a, BivariantContinuous b)
{
return -b + a;
}
/// <summary>
/// </summary>
/// <param name="a"></param>
/// <param name="b"></param>
/// <returns></returns>
public static BivariantContinuous operator *(BivariantContinuous a, BivariantContinuous b)
{
return new BivariantContinuousProduction(a, b);
}
/// <summary>
/// </summary>
/// <param name="a"></param>
/// <param name="b"></param>
/// <returns></returns>
public static BivariantContinuous operator +(BivariantContinuous a, double b)
{
return a + new BivariantContinuousConstant(b);
}
/// <summary>
/// </summary>
/// <param name="b"></param>
/// <param name="a"></param>
/// <returns></returns>
public static BivariantContinuous operator +(double b, BivariantContinuous a)
{
return a + b;
}
/// <summary>
/// </summary>
/// <param name="a"></param>
/// <param name="b"></param>
/// <returns></returns>
public static BivariantContinuous operator -(BivariantContinuous a, double b)
{
return a + new BivariantContinuousConstant(-b);
}
/// <summary>
/// </summary>
/// <param name="a"></param>
/// <param name="b"></param>
/// <returns></returns>
public static BivariantContinuous operator -(double a, BivariantContinuous b)
{
return new BivariantContinuousConstant(a) - b;
}
/// <summary>
/// </summary>
/// <param name="a"></param>
/// <param name="b"></param>
/// <returns></returns>
public static BivariantContinuous operator *(BivariantContinuous a, double b)
{
return a * new BivariantContinuousConstant(b);
}
/// <summary>
/// </summary>
/// <param name="b"></param>
/// <param name="a"></param>
/// <returns></returns>
public static BivariantContinuous operator *(double b, BivariantContinuous a)
{
return a * b;
}
}

View File

@@ -0,0 +1,435 @@
using System.Numerics;
using Skeleton.Analysis.BivariantFunctions.Real.Arithmetics;
using Skeleton.Analysis.BivariantFunctions.Real.Implements;
namespace Skeleton.Analysis.BivariantFunctions.Real.PolynomialHelpers;
/// <summary>
/// </summary>
public static class PolyCHelper
{
/// <inheritdoc />
public class PolyC4Re : BivariantContinuous
{
/// <inheritdoc />
public PolyC4Re(Complex c0, Complex c1, Complex c2, Complex c3, Complex c4)
{
A0 = c0.Real;
B0 = c0.Imaginary;
A1 = c1.Real;
B1 = c1.Imaginary;
A2 = c2.Real;
B2 = c2.Imaginary;
A3 = c3.Real;
B3 = c3.Imaginary;
A4 = c4.Real;
B4 = c4.Imaginary;
}
private double A0 { get; }
private double B0 { get; set; }
private double A1 { get; }
private double B1 { get; }
private double A2 { get; }
private double B2 { get; }
private double A3 { get; }
private double B3 { get; }
private double A4 { get; }
private double B4 { get; }
/// <inheritdoc />
public override BivariantContinuous Dx =>
new PolyC3Re(A1, 0, 2 * A2, 2 * B2, 3 * A3, 3 * B3, 4 * A4, 4 * B4);
/// <inheritdoc />
public override BivariantContinuous Dy =>
new PolyC3Re(-B1, 0, -2 * B2, 2 * A2, -3 * B3, 3 * A3, 4 * A4, -4 * B4);
/// <inheritdoc />
public override double Evaluate(double x, double y)
{
double x2 = x * x;
double y2 = y * y;
double x3 = x2 * x;
double y3 = y2 * y;
double x4 = x2 * x2;
double y4 = y2 * y2;
return
+A0
+ A1 * x - B1 * y
+ A2 * (x2 - y2) - B2 * 2 * x * y
+ A3 * (x3 - 3 * x * y2) + B3 * (y3 - 3 * x2 * y)
+ A4 * (x4 - 6 * x2 * y2 + y4) - B4 * (4 * (x3 * y + x * y3));
}
}
/// <inheritdoc />
public class PolyC4Im : BivariantContinuous
{
/// <inheritdoc />
public PolyC4Im(Complex c0, Complex c1, Complex c2, Complex c3, Complex c4)
{
A0 = c0.Real;
B0 = c0.Imaginary;
A1 = c1.Real;
B1 = c1.Imaginary;
A2 = c2.Real;
B2 = c2.Imaginary;
A3 = c3.Real;
B3 = c3.Imaginary;
A4 = c4.Real;
B4 = c4.Imaginary;
}
private double A0 { get; set; }
private double B0 { get; }
private double A1 { get; }
private double B1 { get; }
private double A2 { get; }
private double B2 { get; }
private double A3 { get; }
private double B3 { get; }
private double A4 { get; }
private double B4 { get; }
/// <inheritdoc />
public override BivariantContinuous Dx =>
new PolyC3Im(0, B1, 2 * A2, 2 * B2, 3 * A3, 3 * B3, 4 * A4, 4 * B4);
/// <inheritdoc />
public override BivariantContinuous Dy =>
new PolyC3Im(0, A1, -2 * B2, 2 * A2, -3 * B3, 3 * A3, -4 * B4, 4 * A4);
/// <inheritdoc />
public override double Evaluate(double x, double y)
{
double x2 = x * x;
double y2 = y * y;
double x3 = x2 * x;
double y3 = y2 * y;
double x4 = x2 * x2;
double y4 = y2 * y2;
return
+B0
+ A1 * y + B1 * x
+ A2 * 2 * x * y + B2 * (x2 - y2)
+ A3 * (3 * x2 * y - y3) + B3 * (x3 - 3 * x * y2)
+ A4 * (4 * (x3 * y - x * y3)) + B4 * (x4 - 6 * x2 * y2 + y4);
}
}
/// <inheritdoc />
public class PolyC3Re : BivariantContinuous
{
/// <inheritdoc />
public PolyC3Re(Complex c0, Complex c1, Complex c2, Complex c3)
{
A0 = c0.Real;
B0 = c0.Imaginary;
A1 = c1.Real;
B1 = c1.Imaginary;
A2 = c2.Real;
B2 = c2.Imaginary;
A3 = c3.Real;
B3 = c3.Imaginary;
}
/// <inheritdoc />
public PolyC3Re(double a0, double b0, double a1, double b1, double a2, double b2, double a3, double b3)
{
A0 = a0;
B0 = b0;
A1 = a1;
B1 = b1;
A2 = a2;
B2 = b2;
A3 = a3;
B3 = b3;
}
private double A0 { get; }
private double B0 { get; set; }
private double A1 { get; }
private double B1 { get; }
private double A2 { get; }
private double B2 { get; }
private double A3 { get; }
private double B3 { get; }
/// <inheritdoc />
public override BivariantContinuous Dx => new PolyC2Re(A1, 0, 2 * A2, 2 * B2, 3 * A3, 3 * B3);
/// <inheritdoc />
public override BivariantContinuous Dy => new PolyC2Re(-B1, 0, -2 * B2, 2 * A2, -3 * B3, 3 * A3);
/// <inheritdoc />
public override double Evaluate(double x, double y)
{
double x2 = x * x;
double y2 = y * y;
double x3 = x2 * x;
double y3 = y2 * y;
//ddx =>
// A1 +2A2 x - 2B2 y + 3A3 x2 - 6B3 xy -3A3 y2
//ddy =>
// -B1 -2B2 x -2A2 y - 3B3 X2 - 6A3 xy + 3B3 y2
return
+A0
+ A1 * x - B1 * y
+ A2 * (x2 - y2) - B2 * 2 * x * y
+ A3 * (x3 - 3 * x * y2) + B3 * (y3 - 3 * x2 * y);
}
}
/// <inheritdoc />
public class PolyC3Im : BivariantContinuous
{
/// <inheritdoc />
public PolyC3Im(Complex c0, Complex c1, Complex c2, Complex c3)
{
A0 = c0.Real;
B0 = c0.Imaginary;
A1 = c1.Real;
B1 = c1.Imaginary;
A2 = c2.Real;
B2 = c2.Imaginary;
A3 = c3.Real;
B3 = c3.Imaginary;
}
/// <inheritdoc />
public PolyC3Im(double a0, double b0, double a1, double b1, double a2, double b2, double a3, double b3)
{
A0 = a0;
B0 = b0;
A1 = a1;
B1 = b1;
A2 = a2;
B2 = b2;
A3 = a3;
B3 = b3;
}
private double A0 { get; set; }
private double B0 { get; }
private double A1 { get; }
private double B1 { get; }
private double A2 { get; }
private double B2 { get; }
private double A3 { get; }
private double B3 { get; }
/// <inheritdoc />
public override BivariantContinuous Dx => new PolyC2Im(0, B1, 2 * A2, 2 * B2, 3 * A3, 3 * B3);
/// <inheritdoc />
public override BivariantContinuous Dy => new PolyC2Im(0, A1, -2 * B2, 2 * A2, -3 * B3, 3 * A3);
/// <inheritdoc />
public override double Evaluate(double x, double y)
{
double x2 = x * x;
double y2 = y * y;
double x3 = x2 * x;
double y3 = y2 * y;
//ddx =>
// B1 + 2B2 x + 2A2 y + 6A3 xy + 3B3 (x2 - y2)
//ddy =>
// A1 + 2A2 x - 2B2 y - 6B3 xy + 3A3 (x2 - y2)
return
+B0
+ A1 * y + B1 * x
+ A2 * 2 * x * y + B2 * (x2 - y2) +
-A3 * (y3 - 3 * x2 * y) + B3 * (x3 - 3 * x * y2);
}
}
/// <inheritdoc />
public class PolyC2Re : BivariantContinuous
{
/// <inheritdoc />
public PolyC2Re(Complex c0, Complex c1, Complex c2)
{
A0 = c0.Real;
B0 = c0.Imaginary;
A1 = c1.Real;
B1 = c1.Imaginary;
A2 = c2.Real;
B2 = c2.Imaginary;
}
/// <inheritdoc />
public PolyC2Re(double a0, double b0, double a1, double b1, double a2, double b2)
{
A0 = a0;
B0 = b0;
A1 = a1;
B1 = b1;
A2 = a2;
B2 = b2;
}
private double A0 { get; }
private double B0 { get; set; }
private double A1 { get; }
private double B1 { get; }
private double A2 { get; }
private double B2 { get; }
/// <inheritdoc />
public override BivariantContinuous Dx => new PolyC1Re(A1, 0, 2 * A2, 2 * B2);
/// <inheritdoc />
public override BivariantContinuous Dy => new PolyC1Re(-B1, 0, -2 * B2, 2 * A2);
/// <inheritdoc />
public override double Evaluate(double x, double y)
{
double x2 = x * x;
double y2 = y * y;
return //-B1 -2B2x - 2A2y
+A0
+ A1 * x - B1 * y
+ A2 * (x2 - y2) - B2 * 2 * x * y;
}
}
/// <inheritdoc />
public class PolyC2Im : BivariantContinuous
{
/// <inheritdoc />
public PolyC2Im(Complex c0, Complex c1, Complex c2)
{
A0 = c0.Real;
B0 = c0.Imaginary;
A1 = c1.Real;
B1 = c1.Imaginary;
A2 = c2.Real;
B2 = c2.Imaginary;
}
/// <inheritdoc />
public PolyC2Im(double a0, double b0, double a1, double b1, double a2, double b2)
{
A0 = a0;
B0 = b0;
A1 = a1;
B1 = b1;
A2 = a2;
B2 = b2;
}
private double A0 { get; set; }
private double B0 { get; }
private double A1 { get; }
private double B1 { get; }
private double A2 { get; }
private double B2 { get; }
/// <inheritdoc />
public override BivariantContinuous Dx => new PolyC1Im(0, B1, 2 * B2, 2 * A2);
/// <inheritdoc />
public override BivariantContinuous Dy => new PolyC1Im(0, A1, -2 * B2, 2 * A2);
/// <inheritdoc />
public override double Evaluate(double x, double y)
{
double x2 = x * x;
double y2 = y * y;
return // B1 + 2B2x + 2A2y
+B0
+ A1 * y + B1 * x +
+A2 * 2 * x * y + B2 * (x2 - y2);
}
}
/// <inheritdoc />
public class PolyC1Re : BivariantContinuous
{
/// <inheritdoc />
public PolyC1Re(Complex c0, Complex c1)
{
A0 = c0.Real;
B0 = c0.Imaginary;
A1 = c1.Real;
B1 = c1.Imaginary;
}
/// <inheritdoc />
public PolyC1Re(double a0, double b0, double a1, double b1)
{
A0 = a0;
B0 = b0;
A1 = a1;
B1 = b1;
}
private double A0 { get; }
private double B0 { get; set; }
private double A1 { get; }
private double B1 { get; }
/// <inheritdoc />
public override BivariantContinuous Dx => new BivariantContinuousConstant(A1);
/// <inheritdoc />
public override BivariantContinuous Dy => new BivariantContinuousConstant(-B1);
/// <inheritdoc />
public override double Evaluate(double x, double y)
{
return
+A0
+ A1 * x - B1 * y;
}
}
/// <inheritdoc />
public class PolyC1Im : BivariantContinuous
{
/// <inheritdoc />
public PolyC1Im(Complex c0, Complex c1)
{
A0 = c0.Real;
B0 = c0.Imaginary;
A1 = c1.Real;
B1 = c1.Imaginary;
}
/// <inheritdoc />
public PolyC1Im(double a0, double b0, double a1, double b1)
{
A0 = a0;
B0 = b0;
A1 = a1;
B1 = b1;
}
private double A0 { get; set; }
private double B0 { get; }
private double A1 { get; }
private double B1 { get; }
/// <inheritdoc />
public override BivariantContinuous Dx => new BivariantContinuousConstant(B1);
/// <inheritdoc />
public override BivariantContinuous Dy => new BivariantContinuousConstant(A1);
/// <inheritdoc />
public override double Evaluate(double x, double y)
{
return
+B0
+ A1 * y + B1 * x;
}
}
}

View File

@@ -0,0 +1,27 @@
using Skeleton.Analysis.ContinuousFunctions.Implements;
namespace Skeleton.Analysis.ContinuousFunctions.Arithmetics;
/// <summary>
/// </summary>
public class ContinuousAddition : Continuous
{
/// <inheritdoc />
public ContinuousAddition(Continuous left, Continuous right)
{
Left = left;
Right = right;
}
private Continuous Left { get; }
private Continuous Right { get; }
/// <inheritdoc />
public override Continuous Derivative => Left.Derivative + Right.Derivative;
/// <inheritdoc />
public override double Evaluate(double x)
{
return Left.Evaluate(x) + Right.Evaluate(x);
}
}

View File

@@ -0,0 +1,27 @@
using Skeleton.Analysis.ContinuousFunctions.Implements;
namespace Skeleton.Analysis.ContinuousFunctions.Arithmetics;
/// <summary>
/// </summary>
public class ContinuousApply : Continuous
{
/// <inheritdoc />
public ContinuousApply(Continuous o, Continuous i)
{
Outer = o;
Inner = i;
}
private Continuous Outer { get; }
private Continuous Inner { get; }
/// <inheritdoc />
public override Continuous Derivative => Inner.Derivative * Outer.Derivative[Inner];
/// <inheritdoc />
public override double Evaluate(double x)
{
return Outer.Evaluate(Inner.Evaluate(x));
}
}

View File

@@ -0,0 +1,33 @@
using Skeleton.Analysis.ContinuousFunctions.Implements;
namespace Skeleton.Analysis.ContinuousFunctions.Arithmetics;
/// <summary>
/// </summary>
public class ContinuousConstant : Continuous
{
/// <summary>
/// </summary>
public static readonly ContinuousConstant Zero = new(0);
/// <summary>
/// </summary>
public static readonly ContinuousConstant One = new(1);
/// <inheritdoc />
public ContinuousConstant(double c)
{
Constant = c;
}
private double Constant { get; }
/// <inheritdoc />
public override Continuous Derivative => Zero;
/// <inheritdoc />
public override double Evaluate(double x)
{
return Constant;
}
}

View File

@@ -0,0 +1,25 @@
using Skeleton.Analysis.ContinuousFunctions.Implements;
namespace Skeleton.Analysis.ContinuousFunctions.Arithmetics;
/// <summary>
/// </summary>
public class ContinuousNegation : Continuous
{
/// <inheritdoc />
public ContinuousNegation(Continuous e)
{
Element = e;
}
private Continuous Element { get; }
/// <inheritdoc />
public override Continuous Derivative => -Element.Derivative;
/// <inheritdoc />
public override double Evaluate(double x)
{
return -Element.Evaluate(x);
}
}

View File

@@ -0,0 +1,27 @@
using Skeleton.Analysis.ContinuousFunctions.Implements;
namespace Skeleton.Analysis.ContinuousFunctions.Arithmetics;
/// <summary>
/// </summary>
public class ContinuousProduction : Continuous
{
/// <inheritdoc />
public ContinuousProduction(Continuous left, Continuous right)
{
Left = left;
Right = right;
}
private Continuous Left { get; }
private Continuous Right { get; }
/// <inheritdoc />
public override Continuous Derivative => Left * Right.Derivative + Left.Derivative * Right;
/// <inheritdoc />
public override double Evaluate(double x)
{
return Left.Evaluate(x) * Right.Evaluate(x);
}
}

View File

@@ -0,0 +1,18 @@
using Skeleton.Analysis.ContinuousFunctions.Implements;
namespace Skeleton.Analysis.ContinuousFunctions;
/// <summary>
/// </summary>
public interface IContinuous
{
/// <summary>
/// </summary>
Continuous Derivative { get; }
/// <summary>
/// </summary>
/// <param name="x"></param>
/// <returns></returns>
double Evaluate(double x);
}

View File

@@ -0,0 +1,58 @@
using Skeleton.Analysis.ContinuousFunctions.Arithmetics;
namespace Skeleton.Analysis.ContinuousFunctions.Implements;
/// <summary>
/// </summary>
public abstract class Continuous : IContinuous
{
/// <summary>
/// </summary>
/// <param name="c"></param>
public Continuous this[Continuous c] => new ContinuousApply(this, c);
/// <inheritdoc />
public abstract Continuous Derivative { get; }
/// <inheritdoc />
public abstract double Evaluate(double x);
/// <summary>
/// </summary>
/// <param name="a"></param>
/// <param name="b"></param>
/// <returns></returns>
public static Continuous operator +(Continuous a, Continuous b)
{
return new ContinuousAddition(a, b);
}
/// <summary>
/// </summary>
/// <param name="a"></param>
/// <returns></returns>
public static Continuous operator -(Continuous a)
{
return new ContinuousNegation(a);
}
/// <summary>
/// </summary>
/// <param name="a"></param>
/// <param name="b"></param>
/// <returns></returns>
public static Continuous operator -(Continuous a, Continuous b)
{
return -b + a;
}
/// <summary>
/// </summary>
/// <param name="a"></param>
/// <param name="b"></param>
/// <returns></returns>
public static Continuous operator *(Continuous a, Continuous b)
{
return new ContinuousProduction(a, b);
}
}