Пример #1
0
        /// <summary>
        /// Initializes a new instance of the <see cref="UserQR"/> class. This object will compute the
        /// QR factorization when the constructor is called and cache it's factorization.
        /// </summary>
        /// <param name="matrix">The matrix to factor.</param>
        /// <param name="method">The QR factorization method to use.</param>
        /// <exception cref="ArgumentNullException">If <paramref name="matrix"/> is <c>null</c>.</exception>
        public UserQR(Matrix <Complex32> matrix, QRMethod method = QRMethod.Full)
        {
            if (matrix == null)
            {
                throw new ArgumentNullException("matrix");
            }

            if (matrix.RowCount < matrix.ColumnCount)
            {
                throw Matrix.DimensionsDontMatch <ArgumentException>(matrix);
            }

            QrMethod = method;
            var minmn = Math.Min(matrix.RowCount, matrix.ColumnCount);
            var u     = new Complex32[minmn][];

            if (method == QRMethod.Full)
            {
                MatrixR = matrix.Clone();
                MatrixQ = matrix.CreateMatrix(matrix.RowCount, matrix.RowCount);

                for (var i = 0; i < matrix.RowCount; i++)
                {
                    MatrixQ.At(i, i, 1.0f);
                }

                for (var i = 0; i < minmn; i++)
                {
                    u[i] = GenerateColumn(MatrixR, i, i);
                    ComputeQR(u[i], MatrixR, i, matrix.RowCount, i + 1, matrix.ColumnCount,
                              Control.NumberOfParallelWorkerThreads);
                }

                for (var i = minmn - 1; i >= 0; i--)
                {
                    ComputeQR(u[i], MatrixQ, i, matrix.RowCount, i, matrix.RowCount,
                              Control.NumberOfParallelWorkerThreads);
                }
            }
            else
            {
                MatrixR = matrix.CreateMatrix(matrix.ColumnCount, matrix.ColumnCount);
                MatrixQ = matrix.Clone();

                for (var i = 0; i < minmn; i++)
                {
                    u[i] = GenerateColumn(MatrixQ, i, i);
                    ComputeQR(u[i], MatrixQ, i, matrix.RowCount, i + 1, matrix.ColumnCount,
                              Control.NumberOfParallelWorkerThreads);
                }

                MatrixR = MatrixQ.SubMatrix(0, matrix.ColumnCount, 0, matrix.ColumnCount);
                MatrixQ.Clear();

                for (var i = 0; i < matrix.ColumnCount; i++)
                {
                    MatrixQ.At(i, i, 1.0f);
                }

                for (var i = minmn - 1; i >= 0; i--)
                {
                    ComputeQR(u[i], MatrixQ, i, matrix.RowCount, i, matrix.ColumnCount,
                              Control.NumberOfParallelWorkerThreads);
                }
            }
        }