Files
Skeleton/src/Algebra/Matrices/NormalMatrices/FSpecialLieUnitaryMatrix.cs
2024-06-21 21:48:07 +08:00

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