forked from liebannam/pipes
/
test_dgesvd.cpp
145 lines (127 loc) · 5.13 KB
/
test_dgesvd.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
/*******************************************************************************
* Copyright (C) 2009-2014 Intel Corporation. All Rights Reserved.
* The information and material ("Material") provided below is owned by Intel
* Corporation or its suppliers or licensors, and title to such Material remains
* with Intel Corporation or its suppliers or licensors. The Material contains
* proprietary information of Intel or its suppliers and licensors. The Material
* is protected by worldwide copyright laws and treaty provisions. No part of
* the Material may be copied, reproduced, published, uploaded, posted,
* transmitted, or distributed in any way without Intel's prior express written
* permission. No license under any patent, copyright or other intellectual
* property rights in the Material is granted to or conferred upon you, either
* expressly, by implication, inducement, estoppel or otherwise. Any license
* under such intellectual property rights must be express and approved by Intel
* in writing.
*
********************************************************************************
*/
/*
DGESVD Example.
==============
Program computes the singular value decomposition of a general
rectangular matrix A:
8.79 9.93 9.83 5.45 3.16
6.11 6.91 5.04 -0.27 7.98
-9.15 -7.93 4.86 4.85 3.01
9.57 1.64 8.83 0.74 5.80
-3.49 4.02 9.80 10.00 4.27
9.84 0.15 -8.99 -6.02 -5.31
Description.
============
The routine computes the singular value decomposition (SVD) of a real
m-by-n matrix A, optionally computing the left and/or right singular
vectors. The SVD is written as
A = U*SIGMA*VT
where SIGMA is an m-by-n matrix which is zero except for its min(m,n)
diagonal elements, U is an m-by-m orthogonal matrix and VT (V transposed)
is an n-by-n orthogonal matrix. The diagonal elements of SIGMA
are the singular values of A; they are real and non-negative, and are
returned in descending order. The first min(m, n) columns of U and V are
the left and right singular vectors of A.
Note that the routine returns VT, not V.
Example Program Results.
========================
DGESVD Example Program Results
Singular values
27.47 22.64 8.56 5.99 2.01
Left singular vectors (stored columnwise)
-0.59 0.26 0.36 0.31 0.23
-0.40 0.24 -0.22 -0.75 -0.36
-0.03 -0.60 -0.45 0.23 -0.31
-0.43 0.24 -0.69 0.33 0.16
-0.47 -0.35 0.39 0.16 -0.52
0.29 0.58 -0.02 0.38 -0.65
Right singular vectors (stored rowwise)
-0.25 -0.40 -0.69 -0.37 -0.41
0.81 0.36 -0.25 -0.37 -0.10
-0.26 0.70 -0.22 0.39 -0.49
0.40 -0.45 0.25 0.43 -0.62
-0.22 0.14 0.59 -0.63 -0.44
*/
#include <cstdlib>
#include <cstdio>
#include "lapack.h"
/* DGESVD prototype */
//extern "C" {
// void dgesvd( char* jobu, char* jobvt, int* m, int* n, double* a,
// int* lda, double* s, double* u, int* ldu, double* vt, int* ldvt,
// double* work, int* lwork, int* info );
/* Auxiliary routines prototypes */
//}
void print_matrix( char* desc, int m, int n, double* a, int lda );
/* Parameters */
#define M 6
#define N 5
#define LDA M
#define LDU M
#define LDVT N
/* Main program */
int main() {
/* Locals */
int m = M, n = N, lda = LDA, ldu = LDU, ldvt = LDVT, info, lwork;
double wkopt;
double* work;
/* Local arrays */
double s[N], u[LDU*M], vt[LDVT*N];
double a[LDA*N] = {
8.79, 6.11, -9.15, 9.57, -3.49, 9.84,
9.93, 6.91, -7.93, 1.64, 4.02, 0.15,
9.83, 5.04, 4.86, 8.83, 9.80, -8.99,
5.45, -0.27, 4.85, 0.74, 10.00, -6.02,
3.16, 7.98, 3.01, 5.80, 4.27, -5.31
};
/* Executable statements */
printf( " DGESVD Example Program Results\n" );
/* Query and allocate the optimal workspace */
lwork = -1;
dgesvd( "All", "All", &m, &n, a, &lda, s, u, &ldu, vt, &ldvt, &wkopt, &lwork,
&info );
lwork = (int)wkopt;
work = (double*)malloc( lwork*sizeof(double) );
/* Compute SVD */
dgesvd( "All", "All", &m, &n, a, &lda, s, u, &ldu, vt, &ldvt, work, &lwork,
&info );
/* Check for convergence */
if( info > 0 ) {
printf( "The algorithm computing SVD failed to converge.\n" );
exit( 1 );
}
/* Print singular values */
print_matrix( "Singular values", 1, n, s, 1 );
/* Print left singular vectors */
print_matrix( "Left singular vectors (stored columnwise)", m, n, u, ldu );
/* Print right singular vectors */
print_matrix( "Right singular vectors (stored rowwise)", n, n, vt, ldvt );
/* Free workspace */
free( (void*)work );
exit( 0 );
} /* End of DGESVD Example */
/* Auxiliary routine: printing a matrix */
void print_matrix( char* desc, int m, int n, double* a, int lda ) {
int i, j;
printf( "\n %s\n", desc );
for( i = 0; i < m; i++ ) {
for( j = 0; j < n; j++ ) printf( " %6.2f", a[i+j*lda] );
printf( "\n" );
}
}