linSolPosdefBand¶
Solves a real symmetric positive definite system of linear equations Ax = b in band symmetric storage mode. Using optional arguments, any of several related computations can be performed. These extra tasks include computing the \(R^TR\) Cholesky factorization of A, computing the solution of \(Ax = b\) given the Cholesky factorization of A, or estimating the \(L_1\) condition number of A.
Required Arguments¶
- float
a[[]]
(Input) - Array of size (ncoda + 1) × n containing the n × n positive definite band coefficient matrix in band symmetric storage mode.
- int
ncoda
(Input) - Number of upper codiagonals of the matrix.
- float
b[]
(Input) - Array of size n containing the right-hand side.
Return Value¶
The solution x of the linear system \(Ax = b\). If no solution was
computed, then None
is returned.
Optional Arguments¶
factor
, (Output)An array of size (ncoda + 1) × n containing the \(LL^T\) factorization of A.
These parameters are “Input” if
solve
is specified. They are “Output” otherwise.condition
(Output)- A scalar containing an estimate of the \(L_1\) norm condition number
of the matrix A. This option cannot be used with the option
solveOnly
. factorOnly
- Compute the \(LL^T\) factorization of A. If
factorOnly
is used, eitherfactor
is required. The argumentb
is then ignored, and the returned value oflinSolPosdefBand
isNone
. solveOnly
- Solve \(Ax = b\) given the \(LL^T\) factorization previously computed
by
linSolPosdefBand
. By default, the solution to \(Ax = b\) is pointed to bylinSolPosdefBand
. IfsolveOnly
is used, argumentfactor
is required and the argument a is ignored.
Description¶
The function linSolPosdefBand
solves a system of linear algebraic
equations with a real symmetric positive definite band coefficient matrix
A. It computes the \(R^TR\) Cholesky factorization of A. R
is an upper triangular band matrix.
When the solution to the linear system or the inverse of the matrix is sought, an estimate of the \(L_1\) condition number of A is computed using Higham’s modifications to Hager’s method, as given in Higham (1988). If the estimated condition number is greater than 1/ɛ (where ɛ is the machine precision), a warning message is issued. This indicates that very small changes in A may produce large changes in the solution x.
The function linSolPosdefBand
fails if any submatrix of R is not
positive definite or if R has a zero diagonal element. These errors occur
only if A is very close to a singular matrix or to a matrix which is not
positive definite.
The function linSolPosdefBand
is partially based on the LINPACK
subroutines CPBFA
and SPBSL
; see Dongarra et al. (1979).
Example 1¶
Solves a system of linear equations \(Ax = b\), where
from numpy import *
from pyimsl.math.linSolPosdefBand import linSolPosdefBand
from pyimsl.math.writeMatrix import writeMatrix
n = 4
ncoda = 2
# Note that a is in band storage mode
a = array([[0.0, 0.0, -1.0, 1.0],
[0.0, 0.0, 2.0, -1.0],
[2.0, 4.0, 7.0, 3.0]])
b = array([6.0, -11.0, -11.0, 19.0])
factor = []
condition = []
x = linSolPosdefBand(a, ncoda, b)
writeMatrix("Solution, x, of Ax = b", x)
Output¶
Solution, x, of Ax = b
1 2 3 4
4 -6 2 9
Example 2¶
This example solves the same problem \(Ax = b\) given in the first example. The solution is returned and an estimate of \(\kappa_1(A)\) is computed. Additionally, the \(R^TR\) factorization is returned. Then, knowing that \(\kappa_1(A) = \|A\| \|A^{-1}\|\), the condition number is computed directly and compared to the estimate from Higham’s method.
from __future__ import print_function
from numpy import *
from pyimsl.math.linSolPosdefBand import linSolPosdefBand
from pyimsl.math.vectorNorm import vectorNorm
from pyimsl.math.writeMatrix import writeMatrix
n = 4
ncoda = 2
a = array([[0.0, 0.0, -1.0, 1.0],
[0.0, 0.0, 2.0, -1.0],
[2.0, 4.0, 7.0, 3.0]])
b = array([6.0, -11.0, -11.0, 19.0])
factor = []
condition = []
x1 = linSolPosdefBand(a, ncoda, b,
factor=factor,
condition=condition)
writeMatrix("Solution, x, of Ax = b", x1)
# Find one norm of inverse
inverse_norm = 0.0
e_i = empty((n), dtype=double)
for i in range(0, n):
for j in range(0, n):
e_i[j] = 0.0
e_i[i] = 1.0
# Determine one norm of each column of inverse
x = linSolPosdefBand(a, ncoda, e_i,
factor=factor,
solveOnly=True)
column_norm = vectorNorm(x, oneNorm=True)
# The max of the column norms is the norm of inv(A)
if (inverse_norm < column_norm):
inverse_norm = column_norm
print("\nHigham's condition estimate = %f" % condition[0])
print("Direct condition estimate = %f" % (11.0 * inverse_norm))
Output¶
Higham's condition estimate = 8.650485
Direct condition estimate = 8.650485
Solution, x, of Ax = b
1 2 3 4
4 -6 2 9
Warning Errors¶
IMSL_ILL_CONDITIONED |
The input matrix is too ill-conditioned.
An estimate of the reciprocal of its
\(L_1\) condition number is
“ The solution might not be accurate. |
Fatal Errors¶
IMSL_NONPOSITIVE_MATRIX |
The leading # by # submatrix of the input matrix is not positive definite. |
IMSL_SINGULAR_MATRIX |
The input matrix is singular. |