Пример #1
0
        ///<summary>Solves a system on linear equations, AX=B, where A is the factored matrixed.</summary>
        ///<param name="B">RHS side of the system.</param>
        ///<returns>the solution matrix, X.</returns>
        ///<exception cref="ArgumentNullException">B is null.</exception>
        ///<exception cref="SingularMatrixException">Ais singular.</exception>
        ///<exception cref="ArgumentException">The number of rows of A and B must be the same.</exception>
        public FloatMatrix Solve(IROFloatMatrix B)
        {
            if (B == null)
            {
                throw new System.ArgumentNullException("B cannot be null.");
            }
            Compute();
            if (singular)
            {
                throw new SingularMatrixException();
            }
            else
            {
                if (B.Rows != order)
                {
                    throw new System.ArgumentException("Matrix row dimensions must agree.");
                }
#if MANAGED
                // Copy right hand side with pivoting
                int         nx = B.Columns;
                FloatMatrix X  = Pivot(B);

                // Solve L*Y = B(piv,:)
                for (int k = 0; k < order; k++)
                {
                    for (int i = k + 1; i < order; i++)
                    {
                        for (int j = 0; j < nx; j++)
                        {
                            X.data[i][j] -= X.data[k][j] * factor[i][k];
                        }
                    }
                }
                // Solve U*X = Y;
                for (int k = order - 1; k >= 0; k--)
                {
                    for (int j = 0; j < nx; j++)
                    {
                        X.data[k][j] /= factor[k][k];
                    }
                    for (int i = 0; i < k; i++)
                    {
                        for (int j = 0; j < nx; j++)
                        {
                            X.data[i][j] -= X.data[k][j] * factor[i][k];
                        }
                    }
                }
                return(X);
#else
                float[] rhs = FloatMatrix.ToLinearArray(B);
                Lapack.Getrs.Compute(Lapack.Transpose.NoTrans, order, B.Columns, factor, order, pivots, rhs, B.Rows);
                FloatMatrix ret = new FloatMatrix(order, B.Columns);
                ret.data = rhs;
                return(ret);
#endif
            }
        }
Пример #2
0
        ///<summary>Solves a system on linear equations, AX=B, where A is the factored matrixed.</summary>
        ///<param name="B">RHS side of the system.</param>
        ///<returns>the solution matrix, X.</returns>
        ///<exception cref="ArgumentNullException">B is null.</exception>
        ///<exception cref="NotPositiveDefiniteException">A is not positive definite.</exception>
        ///<exception cref="ArgumentException">The number of rows of A and B must be the same.</exception>
        public FloatMatrix Solve(IROFloatMatrix B)
        {
            if (B == null)
            {
                throw new System.ArgumentNullException("B cannot be null.");
            }
            Compute();
            if (!ispd)
            {
                throw new NotPositiveDefiniteException();
            }
            else
            {
                if (B.Rows != order)
                {
                    throw new System.ArgumentException("Matrix row dimensions must agree.");
                }
#if MANAGED
                // Copy right hand side.
                int         cols = B.Columns;
                FloatMatrix X    = new FloatMatrix(B);
                for (int c = 0; c < cols; c++)
                {
                    // Solve L*Y = B;
                    for (int i = 0; i < order; i++)
                    {
                        float sum = B[i, c];
                        for (int k = i - 1; k >= 0; k--)
                        {
                            sum -= l.data[i][k] * X.data[k][c];
                        }
                        X.data[i][c] = sum / l.data[i][i];
                    }

                    // Solve L'*X = Y;
                    for (int i = order - 1; i >= 0; i--)
                    {
                        float sum = X.data[i][c];
                        for (int k = i + 1; k < order; k++)
                        {
                            sum -= l.data[k][i] * X.data[k][c];
                        }
                        X.data[i][c] = sum / l.data[i][i];
                    }
                }

                return(X);
#else
                float[] rhs = FloatMatrix.ToLinearArray(B);
                Lapack.Potrs.Compute(Lapack.UpLo.Lower, order, B.Columns, l.data, order, rhs, B.Rows);
                FloatMatrix ret = new FloatMatrix(order, B.Columns);
                ret.data = rhs;
                return(ret);
#endif
            }
        }
Пример #3
0
        ///<summary>Solves a system on linear equations, AX=B, where A is the factored matrixed.</summary>
        ///<param name="B">RHS side of the system.</param>
        ///<returns>the solution vector, X.</returns>
        ///<exception cref="ArgumentNullException">B is null.</exception>
        ///<exception cref="NotPositiveDefiniteException">A is not positive definite.</exception>
        ///<exception cref="ArgumentException">The number of rows of A and the length of B must be the same.</exception>
        public FloatVector Solve(IReadOnlyList <float> B)
        {
            if (B == null)
            {
                throw new System.ArgumentNullException("B cannot be null.");
            }
            Compute();
            if (!ispd)
            {
                throw new NotPositiveDefiniteException();
            }
            else
            {
                if (B.Count != order)
                {
                    throw new System.ArgumentException("The length of B must be the same as the order of the matrix.");
                }
#if MANAGED
                // Copy right hand side.
                var X      = new FloatVector(B);
                var xarray = X.GetInternalData();
                // Solve L*Y = B;
                for (int i = 0; i < order; i++)
                {
                    float sum = B[i];
                    for (int k = i - 1; k >= 0; k--)
                    {
                        sum -= l.data[i][k] * xarray[k];
                    }
                    xarray[i] = sum / l.data[i][i];
                }
                // Solve L'*X = Y;
                for (int i = order - 1; i >= 0; i--)
                {
                    float sum = xarray[i];
                    for (int k = i + 1; k < order; k++)
                    {
                        sum -= l.data[k][i] * xarray[k];
                    }
                    xarray[i] = sum / l.data[i][i];
                }

                return(X);
#else
                float[] rhs = FloatMatrix.ToLinearArray(B);
                Lapack.Potrs.Compute(Lapack.UpLo.Lower, order, 1, l.data, order, rhs, B.Length);
                FloatVector ret = new FloatVector(order, B.Length);
                ret.data = rhs;
                return(ret);
#endif
            }
        }
Пример #4
0
        ///<summary>Solves a system on linear equations, AX=B, where A is the factored matrixed.</summary>
        ///<param name="B">RHS side of the system.</param>
        ///<returns>the solution vector, X.</returns>
        ///<exception cref="ArgumentNullException">B is null.</exception>
        ///<exception cref="SingularMatrixException">A is singular.</exception>
        ///<exception cref="ArgumentException">The number of rows of A and the length of B must be the same.</exception>
        public FloatVector Solve(IROFloatVector B)
        {
            if (B == null)
            {
                throw new System.ArgumentNullException("B cannot be null.");
            }
            Compute();
            if (singular)
            {
                throw new SingularMatrixException();
            }
            else
            {
                if (B.Length != order)
                {
                    throw new System.ArgumentException("The length of B must be the same as the order of the matrix.");
                }
#if MANAGED
                // Copy right hand side with pivoting
                FloatVector X = Pivot(B);

                // Solve L*Y = B(piv,:)
                for (int k = 0; k < order; k++)
                {
                    for (int i = k + 1; i < order; i++)
                    {
                        X[i] -= X[k] * factor[i][k];
                    }
                }
                // Solve U*X = Y;
                for (int k = order - 1; k >= 0; k--)
                {
                    X[k] /= factor[k][k];
                    for (int i = 0; i < k; i++)
                    {
                        X[i] -= X[k] * factor[i][k];
                    }
                }
                return(X);
#else
                float[] rhs = FloatMatrix.ToLinearArray(B);
                Lapack.Getrs.Compute(Lapack.Transpose.NoTrans, order, 1, factor, order, pivots, rhs, rhs.Length);
                return(new FloatVector(rhs));
#endif
            }
        }
Пример #5
0
        /// <summary>Finds the least squares solution of <c>A*X = B</c>, where <c>m &gt;= n</c></summary>
        /// <param name="B">A matrix with as many rows as A and any number of columns.</param>
        /// <returns>X that minimizes the two norm of <c>Q*R*X-B</c>.</returns>
        /// <exception cref="ArgumentException">Matrix row dimensions must agree.</exception>
        /// <exception cref="InvalidOperationException">Matrix is rank deficient or <c>m &lt; n</c>.</exception>
        public FloatMatrix Solve(IROMatrix <float> B)
        {
            if (B.RowCount != matrix.RowLength)
            {
                throw new ArgumentException("Matrix row dimensions must agree.");
            }
            if (matrix.RowLength < matrix.ColumnLength)
            {
                throw new System.InvalidOperationException("A must have at lest as a many rows as columns.");
            }
            Compute();
            if (!isFullRank)
            {
                throw new System.InvalidOperationException("Matrix is rank deficient.");
            }

            // Copy right hand side
            int m   = matrix.RowLength;
            int n   = matrix.ColumnLength;
            int nx  = B.ColumnCount;
            var ret = new FloatMatrix(n, nx);

#if MANAGED
            var X = new FloatMatrix(B);
            // Compute Y = transpose(Q)*B
            float[] column = new float[q_.RowLength];
            for (int j = 0; j < nx; j++)
            {
                for (int k = 0; k < m; k++)
                {
                    column[k] = X.data[k][j];
                }
                for (int i = 0; i < m; i++)
                {
                    float s = 0;
                    for (int k = 0; k < m; k++)
                    {
                        s += q_.data[k][i] * column[k];
                    }
                    X.data[i][j] = s;
                }
            }

            // Solve R*X = Y;
            for (int k = n - 1; k >= 0; k--)
            {
                for (int j = 0; j < nx; j++)
                {
                    X.data[k][j] /= r_.data[k][k];
                }
                for (int i = 0; i < k; i++)
                {
                    for (int j = 0; j < nx; j++)
                    {
                        X.data[i][j] -= X.data[k][j] * r_.data[i][k];
                    }
                }
            }
            for (int i = 0; i < n; i++)
            {
                for (int j = 0; j < nx; j++)
                {
                    ret.data[i][j] = X.data[i][j];
                }
            }
#else
            float[] c = FloatMatrix.ToLinearArray(B);
            Lapack.Ormqr.Compute(Lapack.Side.Left, Lapack.Transpose.Trans, m, nx, n, qr, m, tau, c, m);
            Blas.Trsm.Compute(Blas.Order.ColumnMajor, Blas.Side.Left, Blas.UpLo.Upper, Blas.Transpose.NoTrans, Blas.Diag.NonUnit,
                              n, nx, 1, qr, m, c, m);
            for (int i = 0; i < n; i++)
            {
                for (int j = 0; j < nx; j++)
                {
                    ret.data[j * n + i] = c[j * m + (jpvt[i] - 1)];
                }
            }
#endif
            return(ret);
        }