Fix: Unitary Decomposition -> Conj inplace not handled correct
This commit is contained in:
@@ -172,7 +172,6 @@ public static class ComplexMatrixExtension
|
||||
{
|
||||
for (int i = 1; i <= a.Dim; i++)
|
||||
a[i, i] /= (a[i, i] * Complex.Conjugate(a[i, i]));
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -186,7 +185,5 @@ public static class ComplexMatrixExtension
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Numerics;
|
||||
using Skeleton.Algebra.Extensions;
|
||||
|
||||
namespace Skeleton.Algebra.FieldStructures;
|
||||
|
||||
@@ -119,4 +120,11 @@ public class ComplexFieldStructure : FieldStructure<Complex>
|
||||
|
||||
/// <inheritdoc />
|
||||
public override Complex Exp(Complex x) => Complex.Exp(x);
|
||||
|
||||
public override Complex Sign(Complex x)
|
||||
{
|
||||
if(x.IsEqualApprox(0))
|
||||
return Complex.Zero;
|
||||
return x / x.Magnitude;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Numerics;
|
||||
using System.Reflection.Metadata;
|
||||
using Skeleton.Algebra.Extensions;
|
||||
using Skeleton.DataStructure.Packs;
|
||||
|
||||
@@ -81,6 +82,7 @@ public abstract class FieldStructure<TScalar> : FieldStructure
|
||||
/// <returns></returns>
|
||||
public virtual TScalar Division(TScalar self, TScalar other)
|
||||
=> Multiplication(self, MultiplicationInverse(other));
|
||||
|
||||
/// <summary>
|
||||
/// conjugate of the scalar
|
||||
/// </summary>
|
||||
@@ -261,23 +263,30 @@ public abstract class FieldStructure<TScalar> : FieldStructure
|
||||
return new QuadraticRoots<TScalar>(x1, x2);
|
||||
}
|
||||
|
||||
internal TScalar WilkinsonShift(TScalar a1, TScalar b1, TScalar b2, TScalar a2)
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="x"></param>
|
||||
/// <returns></returns>
|
||||
public virtual TScalar Sign(TScalar x) => MultiplicationUnit;
|
||||
|
||||
internal TScalar WilkinsonShift(TScalar a11, TScalar a12, TScalar a21, TScalar a22)
|
||||
{
|
||||
QuadraticRoots<TScalar> es = QuadraticRoot(
|
||||
AdditionUnit,
|
||||
AdditionInverse(Addition(a1, a2)),
|
||||
Subtraction(Multiplication(a1, a2), Multiplication(b1, b2))
|
||||
AdditionInverse(Addition(a11, a22)),
|
||||
Subtraction(Multiplication(a11, a22), Multiplication(a12, a21))
|
||||
);
|
||||
TScalar k = a2;
|
||||
TScalar s = Addition(Addition(Abs(a1), Abs(b1)), Addition(Abs(b2), Abs(a2)));
|
||||
TScalar k = a22;
|
||||
TScalar s = Addition(Addition(Abs(a11), Abs(a12)), Addition(Abs(a21), Abs(a22)));
|
||||
if (IsEqualApprox(s, AdditionUnit))
|
||||
return k;
|
||||
TScalar q = Multiplication(Division(b1, s), Division(b2, s));
|
||||
TScalar q = Multiplication(Division(a12, s), Division(a21, s));
|
||||
|
||||
if (IsEqualApprox(q, AdditionUnit))
|
||||
return k;
|
||||
TScalar p = Division(
|
||||
Subtraction(Division(a1, s), Division(a2, s)),
|
||||
Subtraction(Division(a11, s), Division(a22, s)),
|
||||
Addition(MultiplicationUnit, MultiplicationUnit)
|
||||
);
|
||||
TScalar r = SquareRoot(Addition(Multiplication(p, p), q));
|
||||
@@ -289,6 +298,36 @@ public abstract class FieldStructure<TScalar> : FieldStructure
|
||||
return k;
|
||||
}
|
||||
|
||||
|
||||
internal TScalar WilkinsonShiftV2(TScalar a11, TScalar a12, TScalar a21, TScalar a22)
|
||||
{
|
||||
TScalar a = a11;
|
||||
TScalar b = a12;
|
||||
TScalar c = a22;
|
||||
TScalar two = Addition(MultiplicationUnit, MultiplicationUnit);
|
||||
TScalar delta = Division(Subtraction(a, c), two);
|
||||
TScalar square(TScalar x) => Multiplication(x, x);
|
||||
TScalar frb = Addition (
|
||||
Abs(delta),
|
||||
SquareRoot(
|
||||
Addition(
|
||||
square(delta),
|
||||
square(Abs(b))
|
||||
)
|
||||
)
|
||||
);
|
||||
return Subtraction(
|
||||
c,
|
||||
Division(
|
||||
Multiplication(
|
||||
Sign(delta),
|
||||
square(Abs(b))
|
||||
),
|
||||
frb
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// homomorphism from complex to this field
|
||||
/// </summary>
|
||||
@@ -310,5 +349,6 @@ public abstract class FieldStructure<TScalar> : FieldStructure
|
||||
/// <param name="x"></param>
|
||||
/// <returns></returns>
|
||||
public virtual TScalar Exp(TScalar x) => MultiplicationUnit;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Numerics;
|
||||
using Skeleton.Algebra.Extensions;
|
||||
|
||||
namespace Skeleton.Algebra.FieldStructures;
|
||||
|
||||
@@ -70,6 +71,13 @@ public class RealFieldStructure : FieldStructure<double>
|
||||
.ToArray()
|
||||
);
|
||||
|
||||
public override double Sign(double x)
|
||||
{
|
||||
if (x.IsEqualApprox(0))
|
||||
return 0;
|
||||
return x > 0 ? 1 : -1;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override double MaxError(double a) => Math.Abs(a);
|
||||
|
||||
|
||||
@@ -455,12 +455,15 @@ public abstract class Matrix<TScalar, TVector, TMatrix> : Matrix<TVector, TMatri
|
||||
internal override void SelfHermitian()
|
||||
{
|
||||
for(int i = 1; i <= Dim; i++)
|
||||
for(int j = 1; j<i;j++)
|
||||
{
|
||||
for (int j = 1; j < i; j++)
|
||||
{
|
||||
TScalar hij = Structure.Conj(this[i, j]);
|
||||
TScalar hji = Structure.Conj(this[j, i]);
|
||||
(this[i, j], this[j, i]) = (hji, hij);
|
||||
}
|
||||
this[i, i] = Structure.Conj(this[i, i]);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
@@ -1253,7 +1256,7 @@ public abstract class Matrix<TScalar, TVector, TMatrix> : Matrix<TVector, TMatri
|
||||
return new JDPair<TMatrix>(u, d);
|
||||
}
|
||||
|
||||
internal JDPair<TMatrix> InternalUnitaryDecomposition(bool triangle = false)
|
||||
public JDPair<TMatrix> InternalUnitaryDecompositionV1(bool triangle = false)
|
||||
{
|
||||
int maxIters = 5000;
|
||||
double firstTol = 1E-6;
|
||||
@@ -1320,6 +1323,18 @@ public abstract class Matrix<TScalar, TVector, TMatrix> : Matrix<TVector, TMatri
|
||||
Console.WriteLine(a.PythonRepresentation);
|
||||
throw new Exception("CONVERGE MIGHT FAILED");
|
||||
}
|
||||
|
||||
|
||||
internal JDPair<TMatrix> InternalUnitaryDecomposition(bool triangle = false)
|
||||
{
|
||||
JDPair<TMatrix> jd = InternalUnitaryDecompositionV1(triangle);
|
||||
if (IsEqualApprox(jd.J * jd.D * jd.J.Hermitian()))
|
||||
return jd;
|
||||
throw new Exception("IDK");
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// eigen values of the matrix
|
||||
|
||||
@@ -27,12 +27,21 @@ public partial class CategoryOf<TDimension>
|
||||
public FNormalMatrix() { }
|
||||
|
||||
/// <inheritdoc />
|
||||
public FNormalMatrix(IEnumerable<FVector> es, bool row = true) : base(es, row) =>
|
||||
public FNormalMatrix(IEnumerable<FVector> es, bool row = true) : base(es, row)
|
||||
{
|
||||
if (NeedPreNormalFix())
|
||||
PreNormalConstructionFix();
|
||||
this.PostConstructionFix();
|
||||
}
|
||||
|
||||
|
||||
/// <inheritdoc />
|
||||
public FNormalMatrix(params TScalar[] es) : base(es) =>
|
||||
public FNormalMatrix(params TScalar[] es) : base(es)
|
||||
{
|
||||
if(NeedPreNormalFix())
|
||||
PreNormalConstructionFix();
|
||||
this.PostConstructionFix();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// construct by unitary matrix and diagonal matrix
|
||||
@@ -99,6 +108,18 @@ public partial class CategoryOf<TDimension>
|
||||
|
||||
/// <inheritdoc />
|
||||
public override IEnumerable<TScalar> EigenValues() => D.Diagonals;
|
||||
|
||||
protected virtual bool NeedPreNormalFix() => Property.IsNormal;
|
||||
|
||||
protected virtual void PreNormalConstructionFix()
|
||||
{
|
||||
SelfAdd(Hermitian());
|
||||
TScalar two = Structure.Addition(Structure.MultiplicationUnit, Structure.MultiplicationUnit);
|
||||
for (int i = 1; i <= Dim; i++)
|
||||
for (int j = 1; j <= Dim; j++)
|
||||
this[i, j] = Structure.Division(this[i, j], two);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
using System.Numerics;
|
||||
using Skeleton.Algebra.AdditionalProperties;
|
||||
using Skeleton.Algebra.Extensions;
|
||||
using Skeleton.Algebra.FixableObjects;
|
||||
using Skeleton.DataStructure.Packs.MatrixDecompositions;
|
||||
|
||||
namespace Skeleton.Algebra;
|
||||
|
||||
@@ -88,7 +90,7 @@ public static partial class CategoryOf<TDimension>
|
||||
/// <returns></returns>
|
||||
public static FSpecialUnitaryMatrix operator /(FSpecialUnitaryMatrix a, FSpecialUnitaryMatrix b) =>
|
||||
a * b.Hermitian();
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -110,10 +110,31 @@ public static partial class CategoryOf<TDimension>
|
||||
return new(U, logd);
|
||||
}
|
||||
|
||||
/*/// <inheritdoc />
|
||||
public override JDPair<OnField<Complex>.FMatrix> EigenDecomposition() => this.UnitaryDecomposition();*/
|
||||
/*
|
||||
* /// <inheritdoc />
|
||||
* public override JDPair<OnField<Complex>.FMatrix> EigenDecomposition() => this.UnitaryDecomposition();
|
||||
* */
|
||||
|
||||
internal override void UnitaryFix(OnField<Complex>.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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -33,15 +33,15 @@ public class CacheItem<TObject> : CacheItem
|
||||
/// construct by provide a method to update the value
|
||||
/// </summary>
|
||||
/// <param name="rec"></param>
|
||||
public CacheItem(Func<CacheItem?, TObject> rec) => ProxyCalculator = rec;
|
||||
public CacheItem(Func<CacheItem, TObject> rec) => ProxyCalculator = rec;
|
||||
|
||||
public CacheItem() => ProxyCalculator = c => default;
|
||||
|
||||
protected TObject? Value { get; set; }
|
||||
protected TObject Value { get; set; }
|
||||
/// <summary>
|
||||
/// return cached/updated value when reference is not used to calculate another cache item
|
||||
/// </summary>
|
||||
public virtual TObject? Get
|
||||
public virtual TObject Get
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -57,14 +57,14 @@ public class CacheItem<TObject> : CacheItem
|
||||
/// <summary>
|
||||
/// provide trace information while calculating
|
||||
/// </summary>
|
||||
public Func<CacheItem, TObject?> ProxyCalculator { get; set; }
|
||||
public Func<CacheItem, TObject> ProxyCalculator { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// trace the dependency and return cached value/updated value
|
||||
/// </summary>
|
||||
/// <param name="d"></param>
|
||||
/// <returns></returns>
|
||||
public TObject? GetFrom(CacheItem d)
|
||||
public TObject GetFrom(CacheItem d)
|
||||
{
|
||||
References.Add(d);
|
||||
d.Dependencies.Add(this);
|
||||
@@ -74,7 +74,7 @@ public class CacheItem<TObject> : CacheItem
|
||||
/// update the formula of item value
|
||||
/// </summary>
|
||||
/// <param name="val"></param>
|
||||
public void UpdateCalculation(Func<CacheItem, TObject?> val)
|
||||
public void UpdateCalculation(Func<CacheItem, TObject> val)
|
||||
{
|
||||
Expire();
|
||||
foreach (CacheItem item in Dependencies)
|
||||
|
||||
Reference in New Issue
Block a user