2
3
4
5
6
7
8 INTEGER INFO, K, LDA, N
9
10
11 INTEGER ISEED( 4 )
12 DOUBLE PRECISION A( LDA, * ), D( * ), WORK( * )
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 DOUBLE PRECISION ZERO, ONE, HALF
59 parameter( zero = 0.0d+0, one = 1.0d+0, half = 0.5d+0 )
60
61
62 INTEGER I, J
63 DOUBLE PRECISION ALPHA, TAU, WA, WB, WN
64
65
68
69
70 DOUBLE PRECISION DDOT, DNRM2
72
73
75
76
77
78
79
80 info = 0
81 IF( n.LT.0 ) THEN
82 info = -1
83 ELSE IF( k.LT.0 .OR. k.GT.n-1 ) THEN
84 info = -2
85 ELSE IF( lda.LT.
max( 1, n ) )
THEN
86 info = -5
87 END IF
88 IF( info.LT.0 ) THEN
89 CALL xerbla(
'DLAGSY', -info )
90 RETURN
91 END IF
92
93
94
95 DO 20 j = 1, n
96 DO 10 i = j + 1, n
97 a( i, j ) = zero
98 10 CONTINUE
99 20 CONTINUE
100 DO 30 i = 1, n
101 a( i, i ) = d( i )
102 30 CONTINUE
103
104
105
106 DO 40 i = n - 1, 1, -1
107
108
109
110 CALL dlarnv( 3, iseed, n-i+1, work )
111 wn =
dnrm2( n-i+1, work, 1 )
112 wa = sign( wn, work( 1 ) )
113 IF( wn.EQ.zero ) THEN
114 tau = zero
115 ELSE
116 wb = work( 1 ) + wa
117 CALL dscal( n-i, one / wb, work( 2 ), 1 )
118 work( 1 ) = one
119 tau = wb / wa
120 END IF
121
122
123
124
125
126
127 CALL dsymv(
'Lower', n-i+1, tau, a( i, i ), lda, work, 1, zero,
128 $ work( n+1 ), 1 )
129
130
131
132 alpha = -half*tau*
ddot( n-i+1, work( n+1 ), 1, work, 1 )
133 CALL daxpy( n-i+1,
alpha, work, 1, work( n+1 ), 1 )
134
135
136
137 CALL dsyr2(
'Lower', n-i+1, -one, work, 1, work( n+1 ), 1,
138 $ a( i, i ), lda )
139 40 CONTINUE
140
141
142
143 DO 60 i = 1, n - 1 - k
144
145
146
147 wn =
dnrm2( n-k-i+1, a( k+i, i ), 1 )
148 wa = sign( wn, a( k+i, i ) )
149 IF( wn.EQ.zero ) THEN
150 tau = zero
151 ELSE
152 wb = a( k+i, i ) + wa
153 CALL dscal( n-k-i, one / wb, a( k+i+1, i ), 1 )
154 a( k+i, i ) = one
155 tau = wb / wa
156 END IF
157
158
159
160 CALL dgemv(
'Transpose', n-k-i+1, k-1, one, a( k+i, i+1 ), lda,
161 $ a( k+i, i ), 1, zero, work, 1 )
162 CALL dger( n-k-i+1, k-1, -tau, a( k+i, i ), 1, work, 1,
163 $ a( k+i, i+1 ), lda )
164
165
166
167
168
169 CALL dsymv(
'Lower', n-k-i+1, tau, a( k+i, k+i ), lda,
170 $ a( k+i, i ), 1, zero, work, 1 )
171
172
173
174 alpha = -half*tau*
ddot( n-k-i+1, work, 1, a( k+i, i ), 1 )
175 CALL daxpy( n-k-i+1,
alpha, a( k+i, i ), 1, work, 1 )
176
177
178
179 CALL dsyr2(
'Lower', n-k-i+1, -one, a( k+i, i ), 1, work, 1,
180 $ a( k+i, k+i ), lda )
181
182 a( k+i, i ) = -wa
183 DO 50 j = k + i + 1, n
184 a( j, i ) = zero
185 50 CONTINUE
186 60 CONTINUE
187
188
189
190 DO 80 j = 1, n
191 DO 70 i = j + 1, n
192 a( j, i ) = a( i, j )
193 70 CONTINUE
194 80 CONTINUE
195 RETURN
196
197
198
subroutine dlarnv(idist, iseed, n, x)
DLARNV returns a vector of random numbers from a uniform or normal distribution.
subroutine xerbla(srname, info)
XERBLA
subroutine dscal(n, da, dx, incx)
DSCAL
double precision function ddot(n, dx, incx, dy, incy)
DDOT
subroutine daxpy(n, da, dx, incx, dy, incy)
DAXPY
subroutine dsymv(uplo, n, alpha, a, lda, x, incx, beta, y, incy)
DSYMV
subroutine dgemv(trans, m, n, alpha, a, lda, x, incx, beta, y, incy)
DGEMV
subroutine dsyr2(uplo, n, alpha, x, incx, y, incy, a, lda)
DSYR2
subroutine dger(m, n, alpha, x, incx, y, incy, a, lda)
DGER
real(wp) function dnrm2(n, x, incx)
DNRM2