Computes the SVD, A = USVT, of a real rectangular matrix A. An approximate generalized inverse and rank of A also can be computed.
#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.
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.
If no optional arguments are used, imsl_f_lin_svd_gen returns a pointer to an array of size min (m, n) containing the ordered singular values of the matrix. To release this space, use free. If no value can be computed, then NULL is returned.
#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)
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 (m, n) 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)
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 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.
*rank: 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 (m, n)
containing the min (m, n) 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 (m, n) containing the
min (m, n) 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
(m, n)
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
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.
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};
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);
}
Singular values
1
2
3
4
11.49
3.27
2.65 2.09
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};
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);
}
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
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};
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);
}
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
IMSL_SLOWCONVERGENT_MATRIX Convergence cannot be reached after 30 iterations.
|
Visual Numerics, Inc. PHONE: 713.784.3131 FAX:713.781.9260 |