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