Esempio n. 1
0
        /// <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));
            }
        }
Esempio n. 2
0
        /// <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);
        }