| 1 |
C dnrm2.f |
| 2 |
C is freely available from netlib. It is not subject to any GNU License |
| 3 |
C set by the authors of the ASCEND math programming system. |
| 4 |
C $Date: 1996/04/30 18:14:07 $ $Revision: 1.1.1.1 $ |
| 5 |
C |
| 6 |
double precision function dnrm2 ( n, dx, incx) |
| 7 |
integer next |
| 8 |
double precision dx(*), cutlo, cuthi, hitest, sum, xmax,zero,one |
| 9 |
data zero, one /0.0d0, 1.0d0/ |
| 10 |
c |
| 11 |
c euclidean norm of the n-vector stored in dx() with storage |
| 12 |
c increment incx . |
| 13 |
c if n .le. 0 return with result = 0. |
| 14 |
c if n .ge. 1 then incx must be .ge. 1 |
| 15 |
c |
| 16 |
c c.l.lawson, 1978 jan 08 |
| 17 |
c |
| 18 |
c four phase method using two built-in constants that are |
| 19 |
c hopefully applicable to all machines. |
| 20 |
c cutlo = maximum of dsqrt(u/eps) over all known machines. |
| 21 |
c cuthi = minimum of dsqrt(v) over all known machines. |
| 22 |
c where |
| 23 |
c eps = smallest no. such that eps + 1. .gt. 1. |
| 24 |
c u = smallest positive no. (underflow limit) |
| 25 |
c v = largest no. (overflow limit) |
| 26 |
c |
| 27 |
c brief outline of algorithm.. |
| 28 |
c |
| 29 |
c phase 1 scans zero components. |
| 30 |
c move to phase 2 when a component is nonzero and .le. cutlo |
| 31 |
c move to phase 3 when a component is .gt. cutlo |
| 32 |
c move to phase 4 when a component is .ge. cuthi/m |
| 33 |
c where m = n for x() real and m = 2*n for complex. |
| 34 |
c |
| 35 |
c values for cutlo and cuthi.. |
| 36 |
c from the environmental parameters listed in the imsl converter |
| 37 |
c document the limiting values are as follows.. |
| 38 |
c cutlo, s.p. u/eps = 2**(-102) for honeywell. close seconds are |
| 39 |
c univac and dec at 2**(-103) |
| 40 |
c thus cutlo = 2**(-51) = 4.44089e-16 |
| 41 |
c cuthi, s.p. v = 2**127 for univac, honeywell, and dec. |
| 42 |
c thus cuthi = 2**(63.5) = 1.30438e19 |
| 43 |
c cutlo, d.p. u/eps = 2**(-67) for honeywell and dec. |
| 44 |
c thus cutlo = 2**(-33.5) = 8.23181d-11 |
| 45 |
c cuthi, d.p. same as s.p. cuthi = 1.30438d19 |
| 46 |
c data cutlo, cuthi / 8.232d-11, 1.304d19 / |
| 47 |
c data cutlo, cuthi / 4.441e-16, 1.304e19 / |
| 48 |
data cutlo, cuthi / 8.232d-11, 1.304d19 / |
| 49 |
c |
| 50 |
if(n .gt. 0) go to 10 |
| 51 |
dnrm2 = zero |
| 52 |
go to 300 |
| 53 |
c |
| 54 |
10 assign 30 to next |
| 55 |
sum = zero |
| 56 |
nn = n * incx |
| 57 |
c begin main loop |
| 58 |
i = 1 |
| 59 |
20 go to next,(30, 50, 70, 110) |
| 60 |
30 if( dabs(dx(i)) .gt. cutlo) go to 85 |
| 61 |
assign 50 to next |
| 62 |
xmax = zero |
| 63 |
c |
| 64 |
c phase 1. sum is zero |
| 65 |
c |
| 66 |
50 if( dx(i) .eq. zero) go to 200 |
| 67 |
if( dabs(dx(i)) .gt. cutlo) go to 85 |
| 68 |
c |
| 69 |
c prepare for phase 2. |
| 70 |
assign 70 to next |
| 71 |
go to 105 |
| 72 |
c |
| 73 |
c prepare for phase 4. |
| 74 |
c |
| 75 |
100 i = j |
| 76 |
assign 110 to next |
| 77 |
sum = (sum / dx(i)) / dx(i) |
| 78 |
105 xmax = dabs(dx(i)) |
| 79 |
go to 115 |
| 80 |
c |
| 81 |
c phase 2. sum is small. |
| 82 |
c scale to avoid destructive underflow. |
| 83 |
c |
| 84 |
70 if( dabs(dx(i)) .gt. cutlo ) go to 75 |
| 85 |
c |
| 86 |
c common code for phases 2 and 4. |
| 87 |
c in phase 4 sum is large. scale to avoid overflow. |
| 88 |
c |
| 89 |
110 if( dabs(dx(i)) .le. xmax ) go to 115 |
| 90 |
sum = one + sum * (xmax / dx(i))**2 |
| 91 |
xmax = dabs(dx(i)) |
| 92 |
go to 200 |
| 93 |
c |
| 94 |
115 sum = sum + (dx(i)/xmax)**2 |
| 95 |
go to 200 |
| 96 |
c |
| 97 |
c |
| 98 |
c prepare for phase 3. |
| 99 |
c |
| 100 |
75 sum = (sum * xmax) * xmax |
| 101 |
c |
| 102 |
c |
| 103 |
c for real or d.p. set hitest = cuthi/n |
| 104 |
c for complex set hitest = cuthi/(2*n) |
| 105 |
c |
| 106 |
85 hitest = cuthi/float( n ) |
| 107 |
c |
| 108 |
c phase 3. sum is mid-range. no scaling. |
| 109 |
c |
| 110 |
do 95 j =i,nn,incx |
| 111 |
if(dabs(dx(j)) .ge. hitest) go to 100 |
| 112 |
95 sum = sum + dx(j)**2 |
| 113 |
dnrm2 = dsqrt( sum ) |
| 114 |
go to 300 |
| 115 |
c |
| 116 |
200 continue |
| 117 |
i = i + incx |
| 118 |
if ( i .le. nn ) go to 20 |
| 119 |
c |
| 120 |
c end of main loop. |
| 121 |
c |
| 122 |
c compute square root and adjust for scaling. |
| 123 |
c |
| 124 |
dnrm2 = xmax * dsqrt(sum) |
| 125 |
300 continue |
| 126 |
return |
| 127 |
end |
| 128 |
|