112 lines
3.8 KiB
C#
112 lines
3.8 KiB
C#
using System.Numerics;
|
|
using Skeleton.Algebra.AdditionalProperties;
|
|
using Skeleton.Algebra.Extensions;
|
|
using Skeleton.Algebra.FixableObjects;
|
|
|
|
namespace Skeleton.Algebra;
|
|
|
|
public static partial class CategoryOf<TDimension>
|
|
{
|
|
/// <summary>
|
|
/// 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
|
|
/// </summary>
|
|
public class FSpecialLieUnitaryMatrix :
|
|
FLieUnitaryMatrix,
|
|
IUnitaryInvariantMatrix<FSpecialLieUnitaryMatrix>
|
|
{
|
|
/// <summary>
|
|
/// zero matrix as skew hermitian matrix with trace = 2 k pi i
|
|
/// </summary>
|
|
public new static readonly FSpecialLieUnitaryMatrix Zero = new();
|
|
|
|
/// <inheritdoc />
|
|
public FSpecialLieUnitaryMatrix() { }
|
|
|
|
/// <inheritdoc />
|
|
public FSpecialLieUnitaryMatrix(IEnumerable<OnField<Complex>.FVector> es, bool row = true) :
|
|
base(es, row) => this.PostConstructionFix();
|
|
|
|
/// <inheritdoc />
|
|
public FSpecialLieUnitaryMatrix(params Complex[] es) : base(es) => this.PostConstructionFix();
|
|
|
|
/// <inheritdoc />
|
|
public FSpecialLieUnitaryMatrix(OnField<Complex>.FMatrix u, OnField<Complex>.FMatrix d) : base(u, d) =>
|
|
this.PostConstructionFix();
|
|
|
|
/// <inheritdoc />
|
|
public FSpecialLieUnitaryMatrix(OnField<Complex>.FNormalMatrix n) : base(n) => this.PostConstructionFix();
|
|
|
|
internal override bool NeedFix => base.NeedFix || !Complex.Exp(Trace()).IsEqualApprox(1);
|
|
|
|
/// <summary>
|
|
/// addition of matrices
|
|
/// </summary>
|
|
/// <param name="a">left operand</param>
|
|
/// <param name="b">right operand</param>
|
|
/// <returns></returns>
|
|
public static FSpecialLieUnitaryMatrix operator +(FSpecialLieUnitaryMatrix a, FSpecialLieUnitaryMatrix b) =>
|
|
new(a.AsMatrix + b);
|
|
|
|
/// <summary>
|
|
/// scalar multiplication<br/>
|
|
/// LieSU x R -> LieSU
|
|
/// </summary>
|
|
/// <param name="a"></param>
|
|
/// <param name="b"></param>
|
|
/// <returns></returns>
|
|
public static FSpecialLieUnitaryMatrix operator *(FSpecialLieUnitaryMatrix a, double b) =>
|
|
new(a.U, a.D * b);
|
|
|
|
/// <summary>
|
|
/// scalar multiplication<br/>
|
|
/// LieSU x R -> LieSU
|
|
/// </summary>
|
|
/// <param name="b"></param>
|
|
/// <param name="a"></param>
|
|
/// <returns></returns>
|
|
public static FSpecialLieUnitaryMatrix operator *(double b, FSpecialLieUnitaryMatrix a) => a * b;
|
|
|
|
/// <summary>
|
|
/// exp of the matrix
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public new FSpecialUnitaryMatrix Exp()
|
|
{
|
|
OnField<Complex>.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;
|
|
}
|
|
|
|
/// <summary>
|
|
/// commutator
|
|
/// </summary>
|
|
/// <param name="a"></param>
|
|
/// <param name="b"></param>
|
|
/// <returns></returns>
|
|
public static FSpecialLieUnitaryMatrix operator ^(FSpecialLieUnitaryMatrix a, FSpecialLieUnitaryMatrix b) =>
|
|
new(Commutator(a, b));
|
|
|
|
}
|
|
}
|
|
|