Chapter 1: Linear Systems > lin_svd_gen

lin_svd_gen

TextonSpedometerHPClogo.gif

Computes the SVD, A = USVT, of a real rectangular matrix A. An approximate generalized inverse and rank of A also can be computed.

Synopsis

#include <imsl.h>

float *imsl_f_lin_svd_gen (int m, int n, float a[],, 0)

The type double procedure is imsl_d_lin_svd_gen.

Required Arguments

int m   (Input)
Number of rows in the matrix.

int n   (Input)
Number of columns in the matrix.

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

Return Value

If no optional arguments are used, imsl_f_lin_svd_gen returns a pointer to an array of size min (mn) containing the ordered singular values of the matrix. To release this space, use imsl_free. If no value can be computed, then NULL is returned.

Synopsis with Optional Arguments

#include <imsl.h>

float *imsl_f_lin_svd_gen (int m, int n, float a[],

IMSL_A_COL_DIM, int a_col_dim,

IMSL_RETURN_USER, float s[],

IMSL_RANK, float tol, int *rank,

IMSL_U, float **p_u,

IMSL_U_USER, float u[],

IMSL_U_COL_DIM, int u_col_dim,

IMSL_V, float **p_v,

IMSL_V_USER, float v[],

IMSL_V_COL_DIM, int v_col_dim,

IMSL_INVERSE, float **p_gen_inva,

IMSL_INVERSE_USER, float gen_inva[],

IMSL_INV_COL_DIM, int gen_inva_col_dim,

0)

Optional Arguments

IMSL_A_COL_DIM, int a_col_dim   (Input)
The column dimension of the array a.
Default: a_col_dim = n

IMSL_RETURN_USER, float s[]   (Output)
A user-allocated array of size min (m+1, n) containing the singular values of A in its first min (mn) positions in nonincreasing order. If IMSL_RETURN_USER is used, the return value of imsl_f_lin_svd_gen is s.

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

float 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 si i is considered negligible if i.i  tol. If tol < 0, then a singular value si.i is considered negligible if si.i  |tol|*||A||. In this case, |tol| should be an estimate of relative error or uncertainty in the data.

int *rank (Input/Output)
Integer containing an estimate of the rank of A.

IMSL_U, float **p_u   (Output)
**p_u: The address of a pointer to an array of size m × min (mn) containing the min (mn) left-singular vectors of A. On return, the necessary space is allocated by imsl_f_lin_svd_gen. Typically, float *p_u is declared, and &p_u is used as an argument.

IMSL_U_USER, float u[]   (Output)
u[]: The address of a pointer to an array of size m × min (mn) containing the min (mn) left-singular vectors of A. If m ≥ n, the left-singular vectors can be returned using the storage locations of the array a.

IMSL_U_COL_DIM, int u_col_dim   (Input)
The column dimension of the array containing the left-singular vectors.
Default: u_col_dim = min (mn)

IMSL_V, float **p_v   (Output)
**p_v: The address of a pointer to an array of size n × n containing the right singular vectors of A. On return, the necessary space is allocated by imsl_f_lin_svd_gen. Typically, float *p_v is declared, and &p_v is used as an argument.

IMSL_V_USER, float v[]   (Output)
v[]: The address of a pointer to an array of size n × n containing the right singular vectors of A. The right-singular vectors can be returned using the storage locations of the array a. Note that the return of the left- and right-singular vectors cannot use the storage locations of a simultaneously.

IMSL_V_COL_DIM, int v_col_dim   (Input)
The column dimension of the array containing the right-singular vectors.
Default: v_col_dim =  n

IMSL_INVERSE, float **p_gen_inva   (Output)
The address of a pointer to an array of size n × m containing the generalized inverse of the matrix A. On return, the necessary space is allocated by imsl_f_lin_svd_gen. Typically, float *p_gen_inva is declared, and &p_gen_inva is used as an argument.

IMSL_INVERSE_USER, float gen_inva[]   (Output)
A user-allocated array of size n × m containing the general inverse of the matrix A.

IMSL_INV_COL_DIM, int gen_inva_col_dim   (Input)
The column dimension of the array containing the general inverse of the matrix A.
Default: gen_inva_col_dim = m

Description

The function imsl_f_lin_svd_gen 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 sk,k  tol or sk,k  |tol|*||A||. Since si+1,i+1  si,i, it follows that all the si,i satisfy the same inequality for i = k, …, min (m, n 1. The rank is set to the value k  1. If A = USVT, its generalized inverse is A+ = VS+ UT. Here,

Only singular values that are not negligible are reciprocated. If IMSL_INVERSE or IMSL_INVERSE_USER is specified, the function first computes the singular value decomposition of the matrix A. The generalized inverse is then computed. The function imsl_f_lin_svd_gen 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.

#include <imsl.h>

 

float a[] =   {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};

 

int main()

{

    int          m = 6, n = 4;

    float        *s;

                              /* Compute singular values */

    s = imsl_f_lin_svd_gen (m, n, a, 0);

                              /* Print singular values */

    imsl_f_write_matrix ("Singular values", 1, n, s, 0);

}

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 imsl_f_lin_svd_gen.

#include <imsl.h>

 

float a[] =  {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};

 

int main()

{

    int           m = 6, n = 4;

    float        s[4], *p_u, *p_v;

                                    /* Compute SVD */

    imsl_f_lin_svd_gen (m, n, a,

                        IMSL_RETURN_USER, s,

                        IMSL_U, &p_u,

                        IMSL_V, &p_v,

                        0);

                                    /* Print decomposition*/

 

    imsl_f_write_matrix ("Singular values, S", 1, n, s, 0);

    imsl_f_write_matrix ("Left singular vectors, U", m, n, p_u, 0);

    imsl_f_write_matrix ("Right singular vectors, V", n, n, p_v, 0);

}

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.

#include <imsl.h>

 

float a[] =  {1.0,   0.0,

               1.0,   1.0,

             100.0, -50.0};

 

int main()

{

    int           m = 3, n = 2;

    float         tol;

    float         gen_inva[6];

    float        *s;

    int          *rank;

                                  /* Compute generalized inverse */

    tol = 1.e-4;

    s = imsl_f_lin_svd_gen (m, n, a,

                            IMSL_RANK, tol, &rank,

                            IMSL_INVERSE_USER, gen_inva,

                            IMSL_INV_COL_DIM, m,

                            0);

                                  /* Print rank, singular values and  */

                                  /* generalized inverse. */

 

    printf ("Rank of matrix = %2d", rank);

 

    imsl_f_write_matrix ("Singular values", 1, n, s, 0);

 

    imsl_f_write_matrix ("Generalized inverse", n, m, gen_inva,

                          IMSL_A_COL_DIM, m,

                          0);

}

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.


RW_logo.jpg
Contact Support