linSvdGenComplex

Computes the SVD, \(A = USV^H\), of a complex rectangular matrix A. An approximate generalized inverse and rank of A also can be computed.

Synopsis

linSvdGenComplex (a)

Required Arguments

complex a[[]] (Input)
Array of size m × n containing the matrix.

Return Value

Using only required arguments, linSvdGenComplex returns a complex array of length min (m, n) containing the singular values of the matrix. If no value can be computed then None is returned.

Optional Arguments

rank, float tol, int rank (Input/Output)

tol (Input)
Scalar containing the tolerance used to determine when a singular value is negligible and replaced by the value zero. If tol > 0, then a singular value \(s_{i,i}\) is considered negligible if \(s_{i,i}\)tol. If tol < 0, then a singular value \(s_{i,i}\) is considered negligible if \(s_{i,i} \leq |\mathtt{tol}| * \|A\|_\infty\). In this case, should be an estimate of relative error or uncertainty in the data.
rank (Input/Output)
Integer containing an estimate of the rank of A.
u (Output)
An array of size m × min (m, n) containing the min (m, n) left-singular vectors of A.
v (Output)
An array of size n × n containing the right singular vectors of A.
inverse (Output)
An array of size n × m containing the generalized inverse of the matrix A.

Description

The function linSvdGenComplex computes the singular value decomposition of a complex matrix A. It first reduces the matrix A to a bidiagonal matrix B by pre- and post-multiplying Householder transformations. Then, the singular value decomposition of B is computed using the implicit-shifted QR algorithm. An estimate of the rank of the matrix A is obtained by finding the smallest integer k such that \(s_{k,k}\)tol or \(s_{k,k} \leq |\mathtt{tol}| * \|A\|_\infty\). Since \(s_{i+1,i+1} \leq s_{i,i}\), it follows that all the \(s_{i,i}\) satisfy the same inequality for i = k, …, min (m, n) − 1. The rank is set to the value k − 1. If \(A = USV^H\), its generalized inverse is \(A^+ = VS^+ U^T\).

Here,

\[S^+ = \mathit{diag}\left(s_{1,1}^{-1}, \ldots, s_{i,i}^{-1}, 0, \ldots, 0\right)\]

Only singular values that are not negligible are reciprocated. If inverse is specified, the function first computes the singular value decomposition of the matrix A. The generalized inverse is then computed. The function linSvdGenComplex fails if the QR algorithm does not converge after 30 iterations isolating an individual singular value.

Examples

Example 1

This example computes the singular values of a 6 × 3 complex matrix.

from numpy import *
from pyimsl.math.linSvdGenComplex import linSvdGenComplex
from pyimsl.math.writeMatrixComplex import writeMatrixComplex

a = array([[1.0 + 2.0j, 3.0 + 2.0j, 1.0 - 4.0j],
           [3.0 - 2.0j, 2.0 - 4.0j, 1.0 + 3.0j],
           [4.0 + 3.0j, -2.0 + 1.0j, 1.0 + 4.0j],
           [2.0 - 1.0j, 3.0 + 0.0j, 3.0 - 1.0j],
           [1.0 - 5.0j, 2.0 - 5.0j, 2.0 + 2.0j],
           [1.0 + 2.0j, 4.0 - 2.0j, 2.0 - 3.0j]])

# Compute SVD of a
s = linSvdGenComplex(a)

# Print decomposition
writeMatrixComplex("Singular values, S", s, column=True)

Output

 
     Singular values, S
1  (      11.77,       0.00)
2  (       9.30,       0.00)
3  (       4.99,       0.00)

Example 2

This example computes the singular value decomposition of the 6 × 3 complex matrix A. The singular values are returned in the user-provided array. The matrices U and V are returned in the space provided by the function linSvdGenComplex.

from numpy import *
from pyimsl.math.linSvdGenComplex import linSvdGenComplex
from pyimsl.math.writeMatrixComplex import writeMatrixComplex

m = 6
n = 3
p_u = []
p_v = []
a = array([[1.0 + 2.0j, 3.0 + 2.0j, 1.0 - 4.0j],
           [3.0 - 2.0j, 2.0 - 4.0j, 1.0 + 3.0j],
           [4.0 + 3.0j, -2.0 + 1.0j, 1.0 + 4.0j],
           [2.0 - 1.0j, 3.0 + 0.0j, 3.0 - 1.0j],
           [1.0 - 5.0j, 2.0 - 5.0j, 2.0 + 2.0j],
           [1.0 + 2.0j, 4.0 - 2.0j, 2.0 - 3.0j]])

# Compute SVD of a
s = linSvdGenComplex(a, u=p_u, v=p_v)

# Print decomposition
writeMatrixComplex("Singular values, S", s, column=True)
writeMatrixComplex("Left singular vectors, U", p_u)
writeMatrixComplex("Right singular vectors, V", p_v)

Output

 
     Singular values, S
1  (      11.77,       0.00)
2  (       9.30,       0.00)
3  (       4.99,       0.00)
 
               Left singular vectors, U
                           1                          2
1  (     0.1968,     0.2186)  (     0.5011,     0.0217)
2  (     0.3443,    -0.3542)  (    -0.2933,     0.0248)
3  (     0.1457,     0.2307)  (    -0.5424,     0.1381)
4  (     0.3016,    -0.0844)  (     0.2157,     0.2659)
5  (     0.2283,    -0.6008)  (    -0.1325,     0.1433)
6  (     0.2876,    -0.0350)  (     0.4377,    -0.0400)
 
                           3
1  (     0.2007,     0.1003)
2  (    -0.1155,     0.2338)
3  (     0.4361,     0.4407)
4  (     0.0523,     0.0894)
5  (    -0.3152,     0.0090)
6  (    -0.0458,     0.6205)
 
               Right singular vectors, V
                           1                          2
1  (     0.6616,     0.0000)  (    -0.2651,     0.0000)
2  (     0.7355,     0.0379)  (     0.3850,    -0.0707)
3  (     0.0507,    -0.1317)  (     0.1724,     0.8642)
 
                           3
1  (     0.7014,     0.0000)
2  (    -0.5482,    -0.0624)
3  (     0.0173,     0.4509)

Example 3

This example computes the rank and generalized inverse of a 6 × 4 matrix A. The rank and the 4 × 6 generalized inverse matrix \(A^+\) are printed.

from __future__ import print_function
from numpy import *
from pyimsl.math.linSvdGenComplex import linSvdGenComplex
from pyimsl.math.writeMatrixComplex import writeMatrixComplex

a = array([[1.0 + 2.0j, 3.0 + 2.0j, 1.0 - 4.0j, 1.0 + 0.0j],
           [3.0 - 2.0j, 2.0 - 4.0j, 1.0 + 3.0j, 0.0 + 1.0j],
           [4.0 + 3.0j, -2.0 + 1.0j, 1.0 + 4.0j, 0.0 + 0.0j],
           [2.0 - 1.0j, 3.0 + 0.0j, 3.0 - 1.0j, 2.0 + 1.0j],
           [1.0 - 5.0j, 2.0 - 5.0j, 2.0 + 2.0j, 1.0 + 3.1j],
           [1.0 + 2.0j, 4.0 - 2.0j, 2.0 - 3.0j, 1.4 + 1.9j]])

# Factor a
rank = {'tol': 1.e-4}
gen_inva = []
s = linSvdGenComplex(a, rank=rank,
                     inverse=gen_inva)

# Print rank and generalized inverse matrix
print("Rank = %2d" % rank['rank'])
writeMatrixComplex("Singular values", s, column=True)
writeMatrixComplex("Generalized inverse", gen_inva)

Output

Rank =  4
 
       Singular values
1  (      12.13,       0.00)
2  (       9.53,       0.00)
3  (       5.67,       0.00)
4  (       1.74,       0.00)
 
                  Generalized inverse
                           1                          2
1  (     0.0266,    -0.0164)  (    -0.0185,    -0.0453)
2  (     0.0061,    -0.0280)  (     0.0820,     0.1156)
3  (    -0.0019,     0.0572)  (     0.1174,    -0.0812)
4  (     0.0380,    -0.0298)  (    -0.0758,     0.2158)
 
                           3                          4
1  (     0.0720,    -0.0700)  (    -0.0220,     0.0428)
2  (    -0.0410,     0.0242)  (     0.0959,    -0.0885)
3  (     0.0499,    -0.0463)  (    -0.0234,    -0.1033)
4  (     0.0356,     0.0557)  (     0.2918,     0.0763)
 
                           5                          6
1  (    -0.0003,     0.0709)  (     0.0254,    -0.1050)
2  (    -0.0187,    -0.0287)  (    -0.0218,     0.1109)
3  (    -0.0769,    -0.0103)  (     0.0810,     0.1074)
4  (     0.0881,    -0.2070)  (    -0.1531,    -0.0814)

Warning Errors

IMSL_SLOWCONVERGENT_MATRIX Convergence cannot be reached after 30 iterations.