linSvdGen

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

Synopsis

linSvdGen (a)

Required Arguments

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

Return Value

If no optional arguments are used, linSvdGen returns an array of size min (m, n) containing the ordered 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
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, ∣tol∣ should be an estimate of relative error or uncertainty in the data.
rank
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 linSvdGen computes the singular value decomposition of a real 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^T\), 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 linSvdGen 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 real 6 × 4 matrix.

from numpy import *
from pyimsl.math.linSvdGen import linSvdGen
from pyimsl.math.writeMatrix import writeMatrix

a = array([[1.0, 2.0, 1.0, 4.0],
           [3.0, 2.0, 1.0, 3.0],
           [4.0, 3.0, 1.0, 4.0],
           [2.0, 1.0, 3.0, 1.0],
           [1.0, 5.0, 2.0, 2.0],
           [1.0, 2.0, 2.0, 3.0]])

# Compute singular values
s = linSvdGen(a)

# Print singular values
writeMatrix("Singular values", s)

Output

 
                  Singular values
          1            2            3            4
      11.49         3.27         2.65         2.09

Example 2

This example computes the singular value decomposition of the 6 × 4 real 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 linSvdGen.

from numpy import *
from pyimsl.math.linSvdGen import linSvdGen
from pyimsl.math.writeMatrix import writeMatrix

a = array([[1.0, 2.0, 1.0, 4.0],
           [3.0, 2.0, 1.0, 3.0],
           [4.0, 3.0, 1.0, 4.0],
           [2.0, 1.0, 3.0, 1.0],
           [1.0, 5.0, 2.0, 2.0],
           [1.0, 2.0, 2.0, 3.0]])
m = 6
n = 4
p_u = []
p_v = []

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

# Print decomposition
writeMatrix("Singular values, S", s)
writeMatrix("Left singular vectors, U", p_u)
writeMatrix("Right singular vectors, V", p_v)

Output

 
                Singular values, S
          1            2            3            4
      11.49         3.27         2.65         2.09
 
              Left singular vectors, U
             1            2            3            4
1      -0.3805      -0.1197      -0.4391       0.5654
2      -0.4038      -0.3451       0.0566      -0.2148
3      -0.5451      -0.4293      -0.0514      -0.4321
4      -0.2648       0.0683       0.8839       0.2153
5      -0.4463       0.8168      -0.1419      -0.3213
6      -0.3546       0.1021       0.0043       0.5458
 
              Right singular vectors, V
             1            2            3            4
1      -0.4443      -0.5555       0.4354      -0.5518
2      -0.5581       0.6543      -0.2775      -0.4283
3      -0.3244       0.3514       0.7321       0.4851
4      -0.6212      -0.3739      -0.4444       0.5261

Example 3

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

from __future__ import print_function
from numpy import *
from pyimsl.math.linSvdGen import linSvdGen
from pyimsl.math.writeMatrix import writeMatrix

a = array([[1.0, 0.0],
           [1.0, 1.0],
           [100.0, -50.0]])
m = 3
n = 2
gen_inva = []

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

# Print rank, singular values and generalized inverse.
print("Rank of matrix = %2d" % (rank['rank']))
writeMatrix("Singular values", s)
writeMatrix("Generalized inverse", gen_inva)

Output

Rank of matrix =  2
 
     Singular values
          1            2
      111.8          1.4
 
           Generalized inverse
             1            2            3
1        0.100        0.300        0.006
2        0.200        0.600       -0.008

Warning Errors

IMSL_SLOWCONVERGENT_MATRIX Convergence cannot be reached after 30 iterations.