/// <summary> /// Computes the result of the algorithm. /// </summary> /// <param name="numberOfIterations">The number of iterations.</param> /// <exception cref="ArgumentOutOfRangeException">The number of iterations is less than 1.</exception> public void Compute(Int32 numberOfIterations) { if (numberOfIterations < 1) { throw new ArgumentOutOfRangeException(nameof(numberOfIterations), NumericsMessages.NumberOfIterationsIsLessThan1); } if (this.source.NumberOfRows == 0 || this.source.NumberOfColumns == 0) { this.eigenvalues = new Double[0]; this.eigenvectors = new Vector[0]; return; } Matrix resultMatrix = this.source; Matrix resultQ = MatrixFactory.CreateIdentity(resultMatrix.NumberOfRows); QRDecomposition decomposition = null; for (Int32 iterationNumber = 0; iterationNumber < numberOfIterations; iterationNumber++) { decomposition = new QRDecomposition(resultMatrix); decomposition.Compute(); resultMatrix = decomposition.R * decomposition.Q; resultQ = resultQ * decomposition.Q; } this.eigenvalues = new Double[resultMatrix.NumberOfRows]; for (Int32 rowIndex = 0; rowIndex < resultMatrix.NumberOfRows; rowIndex++) { this.eigenvalues[rowIndex] = resultMatrix[rowIndex, rowIndex]; } this.eigenvectors = new Vector[resultMatrix.NumberOfColumns]; for (Int32 columnIndex = 0; columnIndex < resultMatrix.NumberOfColumns; columnIndex++) { this.eigenvectors[columnIndex] = new Vector(resultQ.GetColumn(columnIndex)); } }
/// <summary> /// Computes the result of the algorithm. /// </summary> public void Compute() { if (this.source.NumberOfRows == 0 || this.source.NumberOfColumns == 0) { this.eigenvalues = new Double[0]; this.eigenvectors = new Vector[0]; return; } Matrix resultMatrix = this.source; Matrix resultQ = MatrixFactory.CreateIdentity(resultMatrix.NumberOfRows); Double value; Int32 minimumIterations = (Int32)Math.Pow(resultMatrix.NumberOfRows, 3); Int32 iterationNumber = 0; QRDecomposition decomposition; do { value = resultMatrix[0, 0]; decomposition = new QRDecomposition(resultMatrix); decomposition.Compute(); resultMatrix = decomposition.R * decomposition.Q; resultQ = resultQ * decomposition.Q; iterationNumber++; }while (iterationNumber < minimumIterations || Math.Abs(value - resultMatrix[0, 0]) > ConvergenceLimit); this.eigenvalues = new Double[resultMatrix.NumberOfColumns]; for (Int32 columnIndex = 0; columnIndex < resultMatrix.NumberOfColumns; columnIndex++) { this.eigenvalues[columnIndex] = resultMatrix[columnIndex, columnIndex]; } this.eigenvectors = new Vector[resultMatrix.NumberOfColumns]; for (Int32 columnIndex = 0; columnIndex < resultMatrix.NumberOfColumns; columnIndex++) { this.eigenvectors[columnIndex] = new Vector(resultQ.GetColumn(columnIndex)); } Int32 count = this.eigenvalues.Length; do { Int32 nextCount = 0; for (Int32 swapIndex = 0; swapIndex < count - 1; swapIndex++) { if (this.eigenvalues[swapIndex] < this.eigenvalues[swapIndex + 1]) { Swap(ref this.eigenvalues[swapIndex], ref this.eigenvalues[swapIndex + 1]); Swap(ref this.eigenvectors[swapIndex], ref this.eigenvectors[swapIndex + 1]); nextCount = swapIndex; } } count = nextCount; }while (count > 0); }