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 imsl_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};
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);
}
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};
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);
}
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};
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);
}
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 |