/// <summary> /// Initializes a new instance of the <see cref="DenseEvd"/> class. This object will compute the /// the eigenvalue decomposition when the constructor is called and cache it's decomposition. /// </summary> /// <param name="matrix">The matrix to factor.</param> /// <param name="symmetricity">If it is known whether the matrix is symmetric or not the routine can skip checking it itself.</param> /// <exception cref="ArgumentNullException">If <paramref name="matrix"/> is <c>null</c>.</exception> /// <exception cref="ArgumentException">If EVD algorithm failed to converge with matrix <paramref name="matrix"/>.</exception> public static DenseEvd Create(DenseMatrix matrix, Symmetricity symmetricity) { if (matrix.RowCount != matrix.ColumnCount) { throw new ArgumentException(Resources.ArgumentMatrixSquare); } var order = matrix.RowCount; // Initialize matrices for eigenvalues and eigenvectors var eigenVectors = DenseMatrix.CreateIdentity(order); var blockDiagonal = new DenseMatrix(order); var eigenValues = new DenseVector(order); bool isSymmetric; switch (symmetricity) { case Symmetricity.Hermitian: isSymmetric = true; break; case Symmetricity.Asymmetric: isSymmetric = false; break; default: isSymmetric = matrix.IsHermitian(); break; } Control.LinearAlgebraProvider.EigenDecomp(isSymmetric, order, matrix.Values, eigenVectors.Values, eigenValues.Values, blockDiagonal.Values); return(new DenseEvd(eigenVectors, eigenValues, blockDiagonal, isSymmetric)); }
/// <summary> /// Initializes a new instance of the <see cref="DenseEvd"/> class. This object will compute the /// the eigenvalue decomposition when the constructor is called and cache it's decomposition. /// </summary> /// <param name="matrix">The matrix to factor.</param> /// <param name="symmetricity">If it is known whether the matrix is symmetric or not the routine can skip checking it itself.</param> /// <exception cref="ArgumentNullException">If <paramref name="matrix"/> is <c>null</c>.</exception> /// <exception cref="ArgumentException">If EVD algorithm failed to converge with matrix <paramref name="matrix"/>.</exception> public static DenseEvd Create(DenseMatrix matrix, Symmetricity symmetricity) { if (matrix.RowCount != matrix.ColumnCount) { throw new ArgumentException(Resources.ArgumentMatrixSquare); } var order = matrix.RowCount; // Initialize matrices for eigenvalues and eigenvectors var eigenVectors = new DenseMatrix(order); var blockDiagonal = new DenseMatrix(order); var eigenValues = new LinearAlgebra.Complex.DenseVector(order); bool isSymmetric; switch (symmetricity) { case Symmetricity.Symmetric: case Symmetricity.Hermitian: isSymmetric = true; break; case Symmetricity.Asymmetric: isSymmetric = false; break; default: isSymmetric = matrix.IsSymmetric(); break; } Control.LinearAlgebraProvider.EigenDecomp(isSymmetric, order, matrix.Values, eigenVectors.Values, eigenValues.Values, blockDiagonal.Values); return new DenseEvd(eigenVectors, eigenValues, blockDiagonal, isSymmetric); }
/// <summary> /// Initializes a new instance of the <see cref="UserEvd"/> class. This object will compute the /// the eigenvalue decomposition when the constructor is called and cache it's decomposition. /// </summary> /// <param name="matrix">The matrix to factor.</param> /// <param name="symmetricity">If it is known whether the matrix is symmetric or not the routine can skip checking it itself.</param> /// <exception cref="ArgumentNullException">If <paramref name="matrix"/> is <c>null</c>.</exception> /// <exception cref="ArgumentException">If EVD algorithm failed to converge with matrix <paramref name="matrix"/>.</exception> public static UserEvd Create(Matrix <Complex> matrix, Symmetricity symmetricity) { if (matrix.RowCount != matrix.ColumnCount) { throw new ArgumentException(Resources.ArgumentMatrixSquare); } var order = matrix.RowCount; // Initialize matrices for eigenvalues and eigenvectors var eigenVectors = DenseMatrix.CreateIdentity(order); var blockDiagonal = Matrix <Complex> .Build.SameAs(matrix, order, order); var eigenValues = new DenseVector(order); bool isSymmetric; switch (symmetricity) { case Symmetricity.Hermitian: isSymmetric = true; break; case Symmetricity.Asymmetric: isSymmetric = false; break; default: isSymmetric = matrix.IsHermitian(); break; } if (isSymmetric) { var matrixCopy = matrix.ToArray(); var tau = new Complex[order]; var d = new double[order]; var e = new double[order]; SymmetricTridiagonalize(matrixCopy, d, e, tau, order); SymmetricDiagonalize(eigenVectors, d, e, order); SymmetricUntridiagonalize(eigenVectors, matrixCopy, tau, order); for (var i = 0; i < order; i++) { eigenValues[i] = new Complex(d[i], e[i]); } } else { var matrixH = matrix.ToArray(); NonsymmetricReduceToHessenberg(eigenVectors, matrixH, order); NonsymmetricReduceHessenberToRealSchur(eigenVectors, eigenValues, matrixH, order); } blockDiagonal.SetDiagonal(eigenValues); return(new UserEvd(eigenVectors, eigenValues, blockDiagonal, isSymmetric)); }
/// <summary> /// Initializes a new instance of the <see cref="UserEvd"/> class. This object will compute the /// the eigenvalue decomposition when the constructor is called and cache it's decomposition. /// </summary> /// <param name="matrix">The matrix to factor.</param> /// <param name="symmetricity">If it is known whether the matrix is symmetric or not the routine can skip checking it itself.</param> /// <exception cref="ArgumentNullException">If <paramref name="matrix"/> is <c>null</c>.</exception> /// <exception cref="ArgumentException">If EVD algorithm failed to converge with matrix <paramref name="matrix"/>.</exception> public static UserEvd Create(Matrix<Complex32> matrix, Symmetricity symmetricity) { if (matrix.RowCount != matrix.ColumnCount) { throw new ArgumentException(Resources.ArgumentMatrixSquare); } var order = matrix.RowCount; // Initialize matricies for eigenvalues and eigenvectors var eigenVectors = DenseMatrix.CreateIdentity(order); var blockDiagonal = Matrix<Complex32>.Build.SameAs(matrix, order, order); var eigenValues = new LinearAlgebra.Complex.DenseVector(order); bool isSymmetric; switch (symmetricity) { case Symmetricity.Hermitian: isSymmetric = true; break; case Symmetricity.Asymmetric: isSymmetric = false; break; default: isSymmetric = matrix.IsHermitian(); break; } if (isSymmetric) { var matrixCopy = matrix.ToArray(); var tau = new Complex32[order]; var d = new float[order]; var e = new float[order]; SymmetricTridiagonalize(matrixCopy, d, e, tau, order); SymmetricDiagonalize(eigenVectors, d, e, order); SymmetricUntridiagonalize(eigenVectors, matrixCopy, tau, order); for (var i = 0; i < order; i++) { eigenValues[i] = new Complex(d[i], e[i]); } } else { var matrixH = matrix.ToArray(); NonsymmetricReduceToHessenberg(eigenVectors, matrixH, order); NonsymmetricReduceHessenberToRealSchur(eigenVectors, eigenValues, matrixH, order); } for (var i = 0; i < eigenValues.Count; i++) { blockDiagonal.At(i, i, (Complex32) eigenValues[i]); } return new UserEvd(eigenVectors, eigenValues, blockDiagonal, isSymmetric); }
public override Evd <float> Evd(Symmetricity symmetricity = Symmetricity.Unknown) { return(UserEvd.Create(this, symmetricity)); }
public override Evd<double> Evd(Symmetricity symmetricity = Symmetricity.Unknown) { return DenseEvd.Create(this, symmetricity); }
/// <summary> /// Initializes a new instance of the <see cref="UserEvd"/> class. This object will compute the /// the eigenvalue decomposition when the constructor is called and cache it's decomposition. /// </summary> /// <param name="matrix">The matrix to factor.</param> /// <param name="symmetricity">If it is known whether the matrix is symmetric or not the routine can skip checking it itself.</param> /// <exception cref="ArgumentNullException">If <paramref name="matrix"/> is <c>null</c>.</exception> /// <exception cref="ArgumentException">If EVD algorithm failed to converge with matrix <paramref name="matrix"/>.</exception> public static UserEvd Create(Matrix <double> matrix, Symmetricity symmetricity) { if (matrix.RowCount != matrix.ColumnCount) { throw new ArgumentException(Resources.ArgumentMatrixSquare); } var order = matrix.RowCount; // Initialize matricies for eigenvalues and eigenvectors var eigenVectors = Matrix <double> .Build.SameAs(matrix, order, order); var blockDiagonal = Matrix <double> .Build.SameAs(matrix, order, order); var eigenValues = new LinearAlgebra.Complex.DenseVector(order); bool isSymmetric; switch (symmetricity) { case Symmetricity.Symmetric: case Symmetricity.Hermitian: isSymmetric = true; break; case Symmetricity.Asymmetric: isSymmetric = false; break; default: isSymmetric = matrix.IsSymmetric(); break; } var d = new double[order]; var e = new double[order]; if (isSymmetric) { matrix.CopyTo(eigenVectors); d = eigenVectors.Row(order - 1).ToArray(); SymmetricTridiagonalize(eigenVectors, d, e, order); SymmetricDiagonalize(eigenVectors, d, e, order); } else { var matrixH = matrix.ToArray(); NonsymmetricReduceToHessenberg(eigenVectors, matrixH, order); NonsymmetricReduceHessenberToRealSchur(eigenVectors, matrixH, d, e, order); } for (var i = 0; i < order; i++) { blockDiagonal.At(i, i, d[i]); if (e[i] > 0) { blockDiagonal.At(i, i + 1, e[i]); } else if (e[i] < 0) { blockDiagonal.At(i, i - 1, e[i]); } } for (var i = 0; i < order; i++) { eigenValues[i] = new Complex(d[i], e[i]); } return(new UserEvd(eigenVectors, eigenValues, blockDiagonal, isSymmetric)); }
/// <summary> /// Computes the EVD decomposition for a matrix. /// </summary> /// <returns>The EVD decomposition object.</returns> public abstract Evd <T> Evd(Symmetricity symmetricity = Symmetricity.Unknown);
/// <summary> /// Initializes a new instance of the <see cref="UserEvd"/> class. This object will compute the /// the eigenvalue decomposition when the constructor is called and cache it's decomposition. /// </summary> /// <param name="matrix">The matrix to factor.</param> /// <param name="symmetricity">If it is known whether the matrix is symmetric or not the routine can skip checking it itself.</param> /// <exception cref="ArgumentNullException">If <paramref name="matrix"/> is <c>null</c>.</exception> /// <exception cref="ArgumentException">If EVD algorithm failed to converge with matrix <paramref name="matrix"/>.</exception> public static UserEvd Create(Matrix<double> matrix, Symmetricity symmetricity) { if (matrix.RowCount != matrix.ColumnCount) { throw new ArgumentException(Resources.ArgumentMatrixSquare); } var order = matrix.RowCount; // Initialize matricies for eigenvalues and eigenvectors var eigenVectors = Matrix<double>.Build.SameAs(matrix, order, order); var blockDiagonal = Matrix<double>.Build.SameAs(matrix, order, order); var eigenValues = new LinearAlgebra.Complex.DenseVector(order); bool isSymmetric; switch (symmetricity) { case Symmetricity.Symmetric: case Symmetricity.Hermitian: isSymmetric = true; break; case Symmetricity.Asymmetric: isSymmetric = false; break; default: isSymmetric = matrix.IsSymmetric(); break; } var d = new double[order]; var e = new double[order]; if (isSymmetric) { matrix.CopyTo(eigenVectors); d = eigenVectors.Row(order - 1).ToArray(); SymmetricTridiagonalize(eigenVectors, d, e, order); SymmetricDiagonalize(eigenVectors, d, e, order); } else { var matrixH = matrix.ToArray(); NonsymmetricReduceToHessenberg(eigenVectors, matrixH, order); NonsymmetricReduceHessenberToRealSchur(eigenVectors, matrixH, d, e, order); } for (var i = 0; i < order; i++) { blockDiagonal.At(i, i, d[i]); if (e[i] > 0) { blockDiagonal.At(i, i + 1, e[i]); } else if (e[i] < 0) { blockDiagonal.At(i, i - 1, e[i]); } } for (var i = 0; i < order; i++) { eigenValues[i] = new Complex(d[i], e[i]); } return new UserEvd(eigenVectors, eigenValues, blockDiagonal, isSymmetric); }
public override Evd<double> Evd(Symmetricity symmetricity = Symmetricity.Unknown) { return UserEvd.Create(this, symmetricity); }