2
3
4
5
6
7
8 INTEGER INFO, K, LDA, N
9
10
11 INTEGER ISEED( 4 )
12 REAL 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 REAL ZERO, ONE, HALF
59 parameter( zero = 0.0e+0, one = 1.0e+0, half = 0.5e+0 )
60
61
62 INTEGER I, J
63 REAL ALPHA, TAU, WA, WB, WN
64
65
68
69
70 REAL SDOT, SNRM2
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(
'SLAGSY', -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 slarnv( 3, iseed, n-i+1, work )
111 wn =
snrm2( 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 sscal( 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 ssymv(
'Lower', n-i+1, tau, a( i, i ), lda, work, 1, zero,
128 $ work( n+1 ), 1 )
129
130
131
132 alpha = -half*tau*
sdot( n-i+1, work( n+1 ), 1, work, 1 )
133 CALL saxpy( n-i+1,
alpha, work, 1, work( n+1 ), 1 )
134
135
136
137 CALL ssyr2(
'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 =
snrm2( 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 sscal( 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 sgemv(
'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 sger( 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 ssymv(
'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*
sdot( n-k-i+1, work, 1, a( k+i, i ), 1 )
175 CALL saxpy( n-k-i+1,
alpha, a( k+i, i ), 1, work, 1 )
176
177
178
179 CALL ssyr2(
'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 slarnv(idist, iseed, n, x)
SLARNV returns a vector of random numbers from a uniform or normal distribution.
subroutine xerbla(srname, info)
XERBLA
subroutine sscal(n, sa, sx, incx)
SSCAL
real function sdot(n, sx, incx, sy, incy)
SDOT
subroutine saxpy(n, sa, sx, incx, sy, incy)
SAXPY
real(wp) function snrm2(n, x, incx)
SNRM2
subroutine sgemv(trans, m, n, alpha, a, lda, x, incx, beta, y, incy)
SGEMV
subroutine ssyr2(uplo, n, alpha, x, incx, y, incy, a, lda)
SSYR2
subroutine ssymv(uplo, n, alpha, a, lda, x, incx, beta, y, incy)
SSYMV
subroutine sger(m, n, alpha, x, incx, y, incy, a, lda)
SGER