/// <summary> /// Construct an eigenvalue decomposition.</summary> /// <param name="value"> /// The matrix to be decomposed.</param> /// <param name="assumeSymmetric"> /// Defines if the matrix should be assumed as being symmetric /// regardless if it is or not. Default is <see langword="false"/>.</param> /// <param name="inPlace"> /// Pass <see langword="true"/> to perform the decomposition in place. The matrix /// <paramref name="value"/> will be destroyed in the process, resulting in less /// memory comsumption.</param> public EigenvalueDecompositionF(Single[,] value, bool assumeSymmetric, bool inPlace) { if (value == null) { throw new ArgumentNullException("value", "Matrix cannot be null."); } if (value.GetLength(0) != value.GetLength(1)) { throw new ArgumentException("Matrix is not a square matrix.", "value"); } n = value.GetLength(1); V = new Single[n, n]; d = new Single[n]; e = new Single[n]; this.symmetric = assumeSymmetric; if (this.symmetric) { V = inPlace ? value : (Single[,])value.Clone(); // Tridiagonalize. this.tred2(); // Diagonalize. this.tql2(); } else { H = inPlace ? value : (Single[,])value.Clone(); ort = new Single[n]; // Reduce to Hessenberg form. this.orthes(); // Reduce Hessenberg to real Schur form. this.hqr2(); } }
/// <summary> /// Construct an eigenvalue decomposition.</summary> /// /// <param name="value"> /// The matrix to be decomposed.</param> /// <param name="assumeSymmetric"> /// Defines if the matrix should be assumed as being symmetric /// regardless if it is or not. Default is <see langword="false"/>.</param> /// <param name="inPlace"> /// Pass <see langword="true"/> to perform the decomposition in place. The matrix /// <paramref name="value"/> will be destroyed in the process, resulting in less /// memory comsumption.</param> /// <param name="sort"> /// Pass <see langword="true"/> to sort the eigenvalues and eigenvectors at the end /// of the decomposition.</param> /// public EigenvalueDecompositionF(Single[,] value, bool assumeSymmetric, bool inPlace = false, bool sort = false) { if (value == null) throw new ArgumentNullException("value", "Matrix cannot be null."); if (value.GetLength(0) != value.GetLength(1)) throw new ArgumentException("Matrix is not a square matrix.", "value"); n = value.GetLength(1); V = new Single[n, n]; d = new Single[n]; e = new Single[n]; this.symmetric = assumeSymmetric; if (this.symmetric) { V = inPlace ? value : (Single[,])value.Clone(); // Tridiagonalize. this.tred2(); // Diagonalize. this.tql2(); } else { H = inPlace ? value : (Single[,])value.Clone(); ort = new Single[n]; // Reduce to Hessenberg form. this.orthes(); // Reduce Hessenberg to real Schur form. this.hqr2(); } if (sort) { // Sort eigenvalues and vectors in descending order var idx = Vector.Range(n); Array.Sort(idx, (i, j) => { if (Math.Abs(d[i]) == Math.Abs(d[j])) return -Math.Abs(e[i]).CompareTo(Math.Abs(e[j])); return -Math.Abs(d[i]).CompareTo(Math.Abs(d[j])); }); this.d = this.d.Get(idx); this.e = this.e.Get(idx); this.V = this.V.Get(null, idx); } }