예제 #1
0
        /// <summary>
        /// Solves a linear system Ax=b, where A is symmetric positive definite.
        /// </summary>
        /// <param name="input">Right hand side b.</param>
        /// <param name="result">Solution vector x.</param>
        public void Solve(double[] input, double[] result)
        {
            if (input == null)
            {
                throw new ArgumentNullException("input");
            }

            if (result == null)
            {
                throw new ArgumentNullException("result");
            }

            double[] x = new double[n];

            Permutation.ApplyInverse(S.pinv, input, x, n); // x = P*b

            var lx = L.Values;
            var lp = L.ColumnPointers;
            var li = L.RowIndices;

            var d = this.D;

            int end;

            // Solve lower triangular system by forward elimination, x = L\x.
            for (int i = 0; i < n; i++)
            {
                end = lp[i + 1];
                for (int p = lp[i]; p < end; p++)
                {
                    x[li[p]] -= lx[p] * x[i];
                }
            }

            // Solve diagonal system, x = D\x.
            for (int i = 0; i < n; i++)
            {
                x[i] /= d[i];
            }

            // Solve upper triangular system by backward elimination, x = L'\x.
            for (int i = n - 1; i >= 0; i--)
            {
                end = lp[i + 1];
                for (int p = lp[i]; p < end; p++)
                {
                    x[i] -= lx[p] * x[li[p]];
                }
            }

            Permutation.Apply(S.pinv, x, result, n); // b = P'*x
        }
예제 #2
0
        /// <summary>
        /// Solves a system of linear equations, <c>A'x = b</c>.
        /// </summary>
        /// <param name="input">The right hand side vector, <c>b</c>.</param>
        /// <param name="result">The left hand side vector, <c>x</c>.</param>
        public void SolveTranspose(Complex[] input, Complex[] result)
        {
            if (input == null)
            {
                throw new ArgumentNullException(nameof(input));
            }

            if (result == null)
            {
                throw new ArgumentNullException(nameof(result));
            }

            int m2 = S.m2;

            var x = new Complex[m2];

            if (m >= n)
            {
                // x(q(0:m-1)) = b(0:m-1)
                Permutation.Apply(S.q, input, x, n);

                SolverHelper.SolveUpperTranspose(R, x); // x = R'\x

                // Apply Householder reflection to x.
                for (int k = n - 1; k >= 0; k--)
                {
                    ApplyHouseholder(Q, k, beta[k], x);
                }

                // b(0:n-1) = x(p(0:n-1))
                Permutation.Apply(S.pinv, x, result, m);
            }
            else
            {
                // x(0:m-1) = b(p(0:m-1)
                Permutation.ApplyInverse(S.pinv, input, x, n);

                // Apply Householder reflection to x.
                for (int k = 0; k < m; k++)
                {
                    ApplyHouseholder(Q, k, beta[k], x);
                }

                SolverHelper.SolveUpper(R, x); // x = R\x

                // b(q(0:n-1)) = x(0:n-1)
                Permutation.ApplyInverse(S.q, x, result, m);
            }
        }
예제 #3
0
        /// <summary>
        /// Solves a system of linear equations, <c>Ax = b</c>.
        /// </summary>
        /// <param name="input">The right hand side vector, <c>b</c>.</param>
        /// <param name="result">The left hand side vector, <c>x</c>.</param>
        /// <remarks>
        /// Let A be a m-by-n matrix. If m >= n a least-squares problem (min |Ax-b|)
        /// is solved. If m &lt; n the underdetermined system is solved.
        /// </remarks>
        public override void Solve(double[] input, double[] result)
        {
            if (input == null)
            {
                throw new ArgumentNullException("input");
            }

            if (result == null)
            {
                throw new ArgumentNullException("result");
            }

            var x = new double[S.m2];

            if (m >= n)
            {
                // x(0:m-1) = b(p(0:m-1)
                Permutation.ApplyInverse(S.pinv, input, x, m);

                // Apply Householder reflection to x.
                for (int k = 0; k < n; k++)
                {
                    ApplyHouseholder(Q, k, beta[k], x);
                }

                SolverHelper.SolveUpper(R, x); // x = R\x

                // b(q(0:n-1)) = x(0:n-1)
                Permutation.ApplyInverse(S.q, x, result, n);
            }
            else
            {
                // x(q(0:m-1)) = b(0:m-1)
                Permutation.Apply(S.q, input, x, m);

                SolverHelper.SolveUpperTranspose(R, x); // x = R'\x

                // Apply Householder reflection to x.
                for (int k = m - 1; k >= 0; k--)
                {
                    ApplyHouseholder(Q, k, beta[k], x);
                }

                // b(0:n-1) = x(p(0:n-1))
                Permutation.Apply(S.pinv, x, result, n);
            }
        }
예제 #4
0
        // TODO: implement SolveTranspose

        /// <summary>
        /// Solves a linear system Ax=b, where A is square and nonsingular.
        /// </summary>
        /// <param name="b">Right hand side, overwritten with solution</param>
        public void Solve(double[] b)
        {
            if (b == null)
            {
                throw new ArgumentNullException("b");
            }

            var x = new double[n];

            Permutation.ApplyInverse(pinv, b, x, n); // x = b(p)

            // LinearSolve lower triangular system by forward elimination, x = L\x.
            var lux = L.Values;
            var lup = L.ColumnPointers;
            var lui = L.RowIndices;

            for (int i = 0; i < n; i++)
            {
                x[i] /= lux[lup[i]];
                for (int p = lup[i] + 1; p < lup[i + 1]; p++)
                {
                    x[lui[p]] -= lux[p] * x[i];
                }
            }

            // LinearSolve upper triangular system by backward elimination, x = U\x.
            lux = U.Values;
            lup = U.ColumnPointers;
            lui = U.RowIndices;

            for (int i = n - 1; i >= 0; i--)
            {
                x[i] /= lux[lup[i + 1] - 1];
                for (int p = lup[i]; p < lup[i + 1] - 1; p++)
                {
                    x[lui[p]] -= lux[p] * x[i];
                }
            }

            Permutation.ApplyInverse(symFactor.q, x, b, n); // b(q) = x
        }
예제 #5
0
        /// <summary>
        /// Solves a system of linear equations, <c>Ax = b</c>.
        /// </summary>
        /// <param name="input">The right hand side vector, <c>b</c>.</param>
        /// <param name="result">The left hand side vector, <c>x</c>.</param>
        public void Solve(Complex[] input, Complex[] result)
        {
            if (input == null)
            {
                throw new ArgumentNullException(nameof(input));
            }

            if (result == null)
            {
                throw new ArgumentNullException(nameof(result));
            }

            var x = this.temp;

            Permutation.ApplyInverse(S.pinv, input, x, n); // x = P*b

            SolverHelper.SolveLower(L, x);                 // x = L\x

            SolverHelper.SolveLowerTranspose(L, x);        // x = L'\x

            Permutation.Apply(S.pinv, x, result, n);       // b = P'*x
        }
예제 #6
0
        /// <summary>
        /// Solves a system of linear equations, <c>Ax = b</c>.
        /// </summary>
        /// <param name="input">The right hand side vector, <c>b</c>.</param>
        /// <param name="result">The left hand side vector, <c>x</c>.</param>
        public void Solve(Complex[] input, Complex[] result)
        {
            if (input == null)
            {
                throw new ArgumentNullException(nameof(input));
            }

            if (result == null)
            {
                throw new ArgumentNullException(nameof(result));
            }

            var x = this.temp;

            Permutation.ApplyInverse(pinv, input, x, n); // x = b(p)

            SolverHelper.SolveLower(L, x);               // x = L\x.

            SolverHelper.SolveUpper(U, x);               // x = U\x.

            Permutation.ApplyInverse(S.q, x, result, n); // b(q) = x
        }
예제 #7
0
        // TODO: implement SolveTranspose

        /// <summary>
        /// Solves a linear system Ax=b, where A is symmetric positive definite.
        /// </summary>
        /// <param name="b">Right hand side, overwritten with solution</param>
        public void Solve(double[] b)
        {
            if (b == null)
            {
                throw new ArgumentNullException("b");
            }

            double[] x = new double[n];

            Permutation.ApplyInverse(symFactor.pinv, b, x, n); // x = P*b

            var lx = L.Values;
            var lp = L.ColumnPointers;
            var li = L.RowIndices;

            // LinearSolve lower triangular system by forward elimination, x = L\x.
            for (int i = 0; i < n; i++)
            {
                x[i] /= lx[lp[i]];
                for (int p = lp[i] + 1; p < lp[i + 1]; p++)
                {
                    x[li[p]] -= lx[p] * x[i];
                }
            }

            // LinearSolve upper triangular system by backward elimination, x = L'\x.
            for (int i = n - 1; i >= 0; i--)
            {
                for (int p = lp[i] + 1; p < lp[i + 1]; p++)
                {
                    x[i] -= lx[p] * x[li[p]];
                }
                x[i] /= lx[lp[i]];
            }

            Permutation.Apply(symFactor.pinv, x, b, n); // b = P'*x
        }
예제 #8
0
        // TODO: implement SolveTranspose

        /// <summary>
        /// LinearSolve a least-squares problem (min ||Ax-b||_2, where A is m-by-n
        /// with m >= n) or underdetermined system (Ax=b, where m &lt; n)
        /// </summary>
        /// <param name="b">size max(m,n), b (size m) on input, x(size n) on output</param>
        /// <returns>true if successful, false on error</returns>
        public void Solve(double[] b)
        {
            if (b == null)
            {
                throw new ArgumentNullException("b");
            }

            var x = new double[symFactor.m2];

            var up = R.ColumnPointers;
            var ui = R.RowIndices;
            var ux = R.Values;

            if (m >= n)
            {
                // x(0:m-1) = b(p(0:m-1)
                Permutation.ApplyInverse(symFactor.pinv, b, x, m);

                // Apply Householder reflection to x.
                for (int k = 0; k < n; k++)
                {
                    ApplyHouseholder(Q, k, beta[k], x);
                }

                // LinearSolve upper triangular system, x = R\x.
                for (int i = n - 1; i >= 0; i--)
                {
                    x[i] /= ux[up[i + 1] - 1];
                    for (int p = up[i]; p < up[i + 1] - 1; p++)
                    {
                        x[ui[p]] -= ux[p] * x[i];
                    }
                }

                // b(q(0:n-1)) = x(0:n-1)
                Permutation.ApplyInverse(symFactor.q, x, b, n);
            }
            else
            {
                // x(q(0:m-1)) = b(0:m-1)
                Permutation.Apply(symFactor.q, b, x, m);

                // TODO: int n = R.ColumnCount;

                // LinearSolve lower triangular system, x = R'\x.
                for (int i = 0; i < n; i++)
                {
                    for (int p = up[i]; p < up[i + 1] - 1; p++)
                    {
                        x[i] -= ux[p] * x[ui[p]];
                    }
                    x[i] /= ux[up[i + 1] - 1];
                }

                // Apply Householder reflection to x.
                for (int k = m - 1; k >= 0; k--)
                {
                    ApplyHouseholder(Q, k, beta[k], x);
                }

                // b(0:n-1) = x(p(0:n-1))
                Permutation.Apply(symFactor.pinv, x, b, n);
            }
        }