using System.Numerics; using Skeleton.Algebra.AdditionalProperties; using Skeleton.Algebra.Extensions; using Skeleton.Algebra.FixableObjects; namespace Skeleton.Algebra; public static partial class CategoryOf { /// /// equivalence class of skew hermitian matrices with trace = 2 k pi i /// by A~B if A eigenvalues of A = eigenvalues of B + 2 k pi i /// public class FSpecialLieUnitaryMatrix : FLieUnitaryMatrix, IUnitaryInvariantMatrix { /// /// zero matrix as skew hermitian matrix with trace = 2 k pi i /// public new static readonly FSpecialLieUnitaryMatrix Zero = new(); /// public FSpecialLieUnitaryMatrix() { } /// public FSpecialLieUnitaryMatrix(IEnumerable.FVector> es, bool row = true) : base(es, row) => this.PostConstructionFix(); /// public FSpecialLieUnitaryMatrix(params Complex[] es) : base(es) => this.PostConstructionFix(); /// public FSpecialLieUnitaryMatrix(OnField.FMatrix u, OnField.FMatrix d) : base(u, d) => this.PostConstructionFix(); /// public FSpecialLieUnitaryMatrix(OnField.FNormalMatrix n) : base(n) => this.PostConstructionFix(); internal override bool NeedFix => base.NeedFix || !Complex.Exp(Trace()).IsEqualApprox(1); /// /// addition of matrices /// /// left operand /// right operand /// public static FSpecialLieUnitaryMatrix operator +(FSpecialLieUnitaryMatrix a, FSpecialLieUnitaryMatrix b) => new(a.AsMatrix + b); /// /// scalar multiplication
/// LieSU x R -> LieSU ///
/// /// /// public static FSpecialLieUnitaryMatrix operator *(FSpecialLieUnitaryMatrix a, double b) => new(a.U, a.D * b); /// /// scalar multiplication
/// LieSU x R -> LieSU ///
/// /// /// public static FSpecialLieUnitaryMatrix operator *(double b, FSpecialLieUnitaryMatrix a) => a * b; /// /// exp of the matrix /// /// public new FSpecialUnitaryMatrix Exp() { OnField.FMatrix expd = new(); for (int i = 1; i <= FDim; i++) expd[i, i] = Complex.Exp(D[i, i]); return new(U, expd); } internal override void InternalFix() { base.InternalFix(); Complex e = D.Trace(); double eMin = e.Imaginary; for (int i = 1; i <= Dim; i++) { double errP = e.Imaginary - i * Math.PI; double errN = e.Imaginary + i * Math.PI; if (Math.Abs(errP) < Math.Abs(eMin)) eMin = errP; if (Math.Abs(errN) < Math.Abs(eMin)) eMin = errN; } for (int i = 1; i <= Dim; i++) D[i, i] = (D[i, i].Imaginary - eMin / Dim) * Complex.ImaginaryOne; } /// /// commutator /// /// /// /// public static FSpecialLieUnitaryMatrix operator ^(FSpecialLieUnitaryMatrix a, FSpecialLieUnitaryMatrix b) => new(Commutator(a, b)); } }