using System.Numerics; using Skeleton.Algebra.AdditionalProperties; using Skeleton.Algebra.AdditionalProperties.Extensions; using Skeleton.Algebra.Extensions; using Skeleton.Algebra.FixableObjects; namespace Skeleton.Algebra; public static partial class CategoryOf { /// /// Matrices whose inverse is its hermitian /// AA* = I = A*A /// public class FUnitaryMatrix : OnField.FNormalMatrix, IUnitaryInvariantMatrix { /// public FUnitaryMatrix() => ResetOne(); /// public FUnitaryMatrix(IEnumerable.FVector> es, bool row = true) : base(es, row) => this.PostConstructionFix(); /// public FUnitaryMatrix(params Complex[] es) : base(es) => this.PostConstructionFix(); /// public FUnitaryMatrix(OnField.FMatrix u, OnField.FMatrix d) : base(u, d) => this.PostConstructionFix(); /// public FUnitaryMatrix(OnField.FNormalMatrix n) : base(n) => this.PostConstructionFix(); /// /// id matrix as unitary matrix /// public new static readonly FUnitaryMatrix One = new(); /// /// inverse of the matrix /// /// public new FUnitaryMatrix Inv() => Hermitian(); /// /// multiplication between unitary matrices /// /// /// /// public static FUnitaryMatrix operator *(FUnitaryMatrix self, FUnitaryMatrix other) => new(self.AsMatrix * other); /// /// transpose + conjugate /// /// public new FUnitaryMatrix Hermitian() => new(U, D.Hermitian()); internal override void InternalFix() { for (int i = 1; i <= FDim; i++) D[i, i] /= D[i, i].Magnitude; } private bool UnitaryNeedFix => !D.Diagonals.Aggregate((a, b) => a * b).Magnitude.IsEqualApprox(1); internal override bool NeedFix => base.NeedFix || UnitaryNeedFix; /// /// a conjugate on b => a b inv(a) /// /// /// /// public TUnitaryInvariant ConjugateOn(TUnitaryInvariant a) where TUnitaryInvariant : OnField.FMatrix, IUnitaryInvariantMatrix, new() { TUnitaryInvariant res = new(); res.Elements = (this * a * Hermitian()).ToArray(); res.Fix(); return res; } /// /// conjugate of real is itself
/// so if homomorphism h: R -> K kept the conj
/// h(x) = h(conj(x)) = conj(h(x))
/// h will map real diag matrix to hermitian matrix in K ///
/// /// public FHermitianMatrix ConjugateOn(OnField.FDiagonalMatrix a) { FHermitianMatrix g = a.AsComplex().MatrixCast(); return ConjugateOn(g); } /// /// log of unitary matrix /// /// public FLieUnitaryMatrix Log() { OnField.FMatrix logd = new(); for (int i = 1; i <= FDim; i++) logd[i, i] = Complex.Log(D[i, i]); return new(U, logd); } /* * /// * public override JDPair.FMatrix> EigenDecomposition() => this.UnitaryDecomposition(); * */ internal override void UnitaryFix(OnField.FMatrix a) => a.UnitaryFix(); protected override bool NeedPreNormalFix() => !Property.IsUnitary; protected override void PreNormalConstructionFix() { if (Property.IsDiagonal) { for (int i = 1; i <= Dim; i++) this[i, i] /= (this[i, i] * Complex.Conjugate(this[i, i])); } else { this[1] = this[1].Normalize; for (int i = 2; i <= Dim; i++) { for (int j = 1; j < i; j++) this[i] -= this[i].ProjectionOn(this[j]); this[i] = this[i].Normalize; } } } } }