Skip to content

Commit 2904d87

Browse files
Algorithm precise and with no bias in the error
1 parent a49a659 commit 2904d87

File tree

1 file changed

+66
-14
lines changed

1 file changed

+66
-14
lines changed

SRC/clartg.f90

Lines changed: 66 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@
117117
subroutine CLARTG( f, g, c, s, r )
118118
use LA_CONSTANTS, &
119119
only: wp=>sp, zero=>szero, one=>sone, two=>stwo, czero, &
120-
rtmin=>srtmin, rtmax=>srtmax, safmin=>ssafmin, safmax=>ssafmax
120+
safmin=>ssafmin, safmax=>ssafmax
121121
!
122122
! -- LAPACK auxiliary routine (version 3.10.0) --
123123
! -- LAPACK is a software package provided by Univ. of Tennessee, --
@@ -129,7 +129,7 @@ subroutine CLARTG( f, g, c, s, r )
129129
complex(wp) f, g, r, s
130130
! ..
131131
! .. Local Scalars ..
132-
real(wp) :: d, f1, f2, g1, g2, h2, u, v, w
132+
real(wp) :: d, f1, f2, g1, g2, h2, u, v, w, rtmin, rtmax
133133
complex(wp) :: fs, gs, t
134134
! ..
135135
! .. Intrinsic Functions ..
@@ -141,6 +141,9 @@ subroutine CLARTG( f, g, c, s, r )
141141
! .. Statement Function definitions ..
142142
ABSSQ( t ) = real( t )**2 + aimag( t )**2
143143
! ..
144+
! .. Constants ..
145+
rtmin = sqrt( safmin )
146+
! ..
144147
! .. Executable Statements ..
145148
!
146149
if( g == czero ) then
@@ -150,6 +153,7 @@ subroutine CLARTG( f, g, c, s, r )
150153
else if( f == czero ) then
151154
c = zero
152155
g1 = max( abs(real(g)), abs(aimag(g)) )
156+
rtmax = sqrt( safmax/2 )
153157
if( g1 > rtmin .and. g1 < rtmax ) then
154158
!
155159
! Use unscaled algorithm
@@ -170,6 +174,7 @@ subroutine CLARTG( f, g, c, s, r )
170174
else
171175
f1 = max( abs(real(f)), abs(aimag(f)) )
172176
g1 = max( abs(real(g)), abs(aimag(g)) )
177+
rtmax = sqrt( safmax/4 )
173178
if( f1 > rtmin .and. f1 < rtmax .and. &
174179
g1 > rtmin .and. g1 < rtmax ) then
175180
!
@@ -178,14 +183,36 @@ subroutine CLARTG( f, g, c, s, r )
178183
f2 = ABSSQ( f )
179184
g2 = ABSSQ( g )
180185
h2 = f2 + g2
181-
if( f2 > rtmin .and. h2 < rtmax ) then
182-
d = sqrt( f2*h2 )
186+
! safmin <= f2 <= h2 <= safmax
187+
if( f2 >= h2 * safmin ) then
188+
! safmin <= f2/h2 <= 1, and h2/f2 is finite
189+
c = sqrt( f2 / h2 )
190+
r = f / c
191+
rtmax = rtmax * 2
192+
if( f2 > rtmin .and. h2 < rtmax ) then
193+
! safmin <= sqrt( f2*h2 ) <= safmax
194+
s = conjg( g ) * ( f / sqrt( f2*h2 ) )
195+
else
196+
s = conjg( g ) * ( r / h2 )
197+
end if
183198
else
184-
d = sqrt( f2 )*sqrt( h2 )
199+
! f2/h2 <= safmin may be subnormal, and h2/f2 may overflow.
200+
! Moreover,
201+
! safmin <= f2*f2 * safmax < f2 * h2 < h2*h2 * safmin <= safmax,
202+
! sqrt(safmin) <= sqrt(f2 * h2) <= sqrt(safmax).
203+
! Also,
204+
! g2 >> f2, which means that h2 = g2.
205+
d = sqrt( f2 * h2 )
206+
c = f2 / d
207+
if( c >= safmin ) then
208+
r = f / c
209+
else
210+
! f2 / sqrt(f2 * h2) < safmin, then
211+
! h2 / sqrt(f2 * h2) <= h2 * (safmin / f2) <= h2 <= safmax
212+
r = f * ( h2 / d )
213+
end if
214+
s = conjg( g ) * ( f / d )
185215
end if
186-
c = f2 / d
187-
s = conjg( g )*( f / d )
188-
r = f*( h2 / d )
189216
else
190217
!
191218
! Use scaled algorithm
@@ -212,14 +239,39 @@ subroutine CLARTG( f, g, c, s, r )
212239
f2 = ABSSQ( fs )
213240
h2 = f2 + g2
214241
end if
215-
if( f2 > rtmin .and. h2 < rtmax ) then
216-
d = sqrt( f2*h2 )
242+
! safmin <= f2 <= h2 <= safmax
243+
if( f2 >= h2 * safmin ) then
244+
! safmin <= f2/h2 <= 1, and h2/f2 is finite
245+
c = sqrt( f2 / h2 )
246+
r = fs / c
247+
rtmax = rtmax * 2
248+
if( f2 > rtmin .and. h2 < rtmax ) then
249+
! safmin <= sqrt( f2*h2 ) <= safmax
250+
s = conjg( gs ) * ( fs / sqrt( f2*h2 ) )
251+
else
252+
s = conjg( gs ) * ( r / h2 )
253+
end if
217254
else
218-
d = sqrt( f2 )*sqrt( h2 )
255+
! f2/h2 <= safmin may be subnormal, and h2/f2 may overflow.
256+
! Moreover,
257+
! safmin <= f2*f2 * safmax < f2 * h2 < h2*h2 * safmin <= safmax,
258+
! sqrt(safmin) <= sqrt(f2 * h2) <= sqrt(safmax).
259+
! Also,
260+
! g2 >> f2, which means that h2 = g2.
261+
d = sqrt( f2 * h2 )
262+
c = f2 / d
263+
if( c >= safmin ) then
264+
r = fs / c
265+
else
266+
! f2 / sqrt(f2 * h2) < safmin, then
267+
! h2 / sqrt(f2 * h2) <= h2 * (safmin / f2) <= h2 <= safmax
268+
r = fs * ( h2 / d )
269+
end if
270+
s = conjg( gs ) * ( fs / d )
219271
end if
220-
c = ( f2 / d )*w
221-
s = conjg( gs )*( fs / d )
222-
r = ( fs*( h2 / d ) )*u
272+
! Rescale c and r
273+
c = c * w
274+
r = r * u
223275
end if
224276
end if
225277
return

0 commit comments

Comments
 (0)