private static Vector2 Eigenvector(this SymmetricMatrix2 @this, double lambda) { var rowX = new Vector2(@this.XX - lambda, @this.XY); var rowY = new Vector2(@this.XY, @this.YY - lambda); var normX2 = rowX.Norm2; var normY2 = rowY.Norm2; if (normX2 > normY2) { if (normX2 > BasicMath.Epsilon) { return(rowX.Rotate90() / Math.Sqrt(normX2)); } else { return(Vector2.UnitX); } } else { if (normY2 > BasicMath.Epsilon) { return(rowY.Rotate90() / Math.Sqrt(normY2)); } else { return(Vector2.UnitX); } } }
public static void ComputeEigenvalues(this SymmetricMatrix2 @this, out double low, out double high) { var halfTrace = @this.Trace() / 2; var disc = BasicMath.Sqrt(halfTrace * halfTrace - @this.Det()); low = halfTrace - disc; high = halfTrace + disc; }
// finds least-squares solution to a system of orthogonality equations (i.e. result is fitted to be orthogonal to vectors) public static void FitOrthogonal(IEnumerable <Vector2> vectors, out Vector2 result, out double residual) { var mat = SymmetricMatrix2.TensorSquare(vectors.First()); foreach (var vector in vectors.Skip(1)) { mat += SymmetricMatrix2.TensorSquare(vector); } mat.ComputeLowEigendata(out residual, out result); }
public void Eigenvectors_and_eigenvalues_of_satisfy_defining_equations ([Values(0.577, 0.577, 0.577, 0.577)] double xx, [Values(2.718, 0.577, 0.577, 0.577)] double yy, [Values(3.141, 0, 1e-40, 1e-60)] double xy) { var mat = new SymmetricMatrix2(xx, yy, xy); var loVal = mat.LowEigenvalue(); var loVec = mat.LowEigenvector(); Expect((mat - SymmetricMatrix2.Scalar(loVal)).Det(), Is.EqualTo(0).Within(_tolerance)); Expect(Vector2.Distance(mat * loVec, loVal * loVec), Is.LessThan(_tolerance)); var hiVal = mat.HighEigenvalue(); var hiVec = mat.HighEigenvector(); Expect((mat - SymmetricMatrix2.Scalar(hiVal)).Det(), Is.EqualTo(0).Within(_tolerance)); Expect(Vector2.Distance(mat * hiVec, hiVal * hiVec), Is.LessThan(_tolerance)); Expect(loVal, Is.LessThan(hiVal + _tolerance)); Expect(loVal + hiVal, Is.EqualTo(mat.Trace()).Within(_tolerance)); }
public static double HighEigenvalue(this SymmetricMatrix2 @this) { var halfTrace = @this.Trace() / 2; return(halfTrace + BasicMath.Sqrt(halfTrace * halfTrace - @this.Det())); }
public static double Trace(this SymmetricMatrix2 @this) { return(@this.XX + @this.YY); }
public static double Det(this SymmetricMatrix2 @this) { return(@this.XX * @this.YY - @this.XY * @this.XY); }
public static Vector2 RowY(this SymmetricMatrix2 @this) { return(new Vector2(@this.XY, @this.YY)); }
public static void ComputeEigendata(this SymmetricMatrix2 @this, out double lowEvalue, out double highEvalue, out Vector2 lowEvector) { @this.ComputeEigenvalues(out lowEvalue, out highEvalue); lowEvector = @this.Eigenvector(lowEvalue); }
public static void ComputeHighEigendata(this SymmetricMatrix2 @this, out double eigenvalue, out Vector2 eigenvector) { eigenvalue = @this.HighEigenvalue(); eigenvector = @this.Eigenvector(eigenvalue); }
public static void ComputeEigenvectors(this SymmetricMatrix2 @this, out Vector2 low, out Vector2 high) { low = @this.LowEigenvector(); high = low.Rotate90(); }
public static Vector2 HighEigenvector(this SymmetricMatrix2 @this) { return(@this.Eigenvector(@this.HighEigenvalue())); }