The R Project SVN R

Rev

Rev 82211 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 82211 Rev 85772
Line 32... Line 32...
32
!> \par Purpose:
32
!> \par Purpose:
33
!  =============
33
!  =============
34
!>
34
!>
35
!> \verbatim
35
!> \verbatim
36
!>
36
!>
37
!> ZLASSQ  returns the values  scl  and  smsq  such that
37
!> ZLASSQ returns the values scale_out and sumsq_out such that
38
!>
38
!>
39
!>    ( scl**2 )*smsq = x( 1 )**2 +...+ x( n )**2 + ( scale**2 )*sumsq,
39
!>    (scale_out**2)*sumsq_out = x( 1 )**2 +...+ x( n )**2 + (scale**2)*sumsq,
40
!>
40
!>
41
!> where  x( i ) = X( 1 + ( i - 1 )*INCX ). The value of  sumsq  is
41
!> where x( i ) = X( 1 + ( i - 1 )*INCX ). The value of sumsq is
42
!> assumed to be non-negative.
42
!> assumed to be non-negative.
43
!>
43
!>
44
!> scale and sumsq must be supplied in SCALE and SUMSQ and
44
!> scale and sumsq must be supplied in SCALE and SUMSQ and
45
!> scl and smsq are overwritten on SCALE and SUMSQ respectively.
45
!> scale_out and sumsq_out are overwritten on SCALE and SUMSQ respectively.
46
!>
-
 
47
!> If scale * sqrt( sumsq ) > tbig then
-
 
48
!>    we require:   scale >= sqrt( TINY*EPS ) / sbig   on entry,
-
 
49
!> and if 0 < scale * sqrt( sumsq ) < tsml then
-
 
50
!>    we require:   scale <= sqrt( HUGE ) / ssml       on entry,
-
 
51
!> where
-
 
52
!>    tbig -- upper threshold for values whose square is representable;
-
 
53
!>    sbig -- scaling constant for big numbers; \see la_constants.f90
-
 
54
!>    tsml -- lower threshold for values whose square is representable;
-
 
55
!>    ssml -- scaling constant for small numbers; \see la_constants.f90
-
 
56
!> and
-
 
57
!>    TINY*EPS -- tiniest representable number;
-
 
58
!>    HUGE     -- biggest representable number.
-
 
59
!>
46
!>
60
!> \endverbatim
47
!> \endverbatim
61
!
48
!
62
!  Arguments:
49
!  Arguments:
63
!  ==========
50
!  ==========
Line 70... Line 57...
70
!>
57
!>
71
!> \param[in] X
58
!> \param[in] X
72
!> \verbatim
59
!> \verbatim
73
!>          X is DOUBLE COMPLEX array, dimension (1+(N-1)*abs(INCX))
60
!>          X is DOUBLE COMPLEX array, dimension (1+(N-1)*abs(INCX))
74
!>          The vector for which a scaled sum of squares is computed.
61
!>          The vector for which a scaled sum of squares is computed.
75
!>             x( i )  = X( 1 + ( i - 1 )*INCX ), 1 <= i <= n.
62
!>             x( i ) = X( 1 + ( i - 1 )*INCX ), 1 <= i <= n.
76
!> \endverbatim
63
!> \endverbatim
77
!>
64
!>
78
!> \param[in] INCX
65
!> \param[in] INCX
79
!> \verbatim
66
!> \verbatim
80
!>          INCX is INTEGER
67
!>          INCX is INTEGER
81
!>          The increment between successive values of the vector x.
68
!>          The increment between successive values of the vector x.
82
!>          If INCX > 0, X(1+(i-1)*INCX) = x(i) for 1 <= i <= n
69
!>          If INCX > 0, X(1+(i-1)*INCX) = x(i) for 1 <= i <= n
83
!>          If INCX < 0, X(1-(n-i)*INCX) = x(i) for 1 <= i <= n
70
!>          If INCX < 0, X(1-(n-i)*INCX) = x(i) for 1 <= i <= n
84
!>          If INCX = 0, x isn't a vector so there is no need to call
71
!>          If INCX = 0, x isn't a vector so there is no need to call
85
!>          this subroutine.  If you call it anyway, it will count x(1)
72
!>          this subroutine. If you call it anyway, it will count x(1)
86
!>          in the vector norm N times.
73
!>          in the vector norm N times.
87
!> \endverbatim
74
!> \endverbatim
88
!>
75
!>
89
!> \param[in,out] SCALE
76
!> \param[in,out] SCALE
90
!> \verbatim
77
!> \verbatim
91
!>          SCALE is DOUBLE PRECISION
78
!>          SCALE is DOUBLE PRECISION
92
!>          On entry, the value  scale  in the equation above.
79
!>          On entry, the value scale in the equation above.
93
!>          On exit, SCALE is overwritten with  scl , the scaling factor
80
!>          On exit, SCALE is overwritten by scale_out, the scaling factor
94
!>          for the sum of squares.
81
!>          for the sum of squares.
95
!> \endverbatim
82
!> \endverbatim
96
!>
83
!>
97
!> \param[in,out] SUMSQ
84
!> \param[in,out] SUMSQ
98
!> \verbatim
85
!> \verbatim
99
!>          SUMSQ is DOUBLE PRECISION
86
!>          SUMSQ is DOUBLE PRECISION
100
!>          On entry, the value  sumsq  in the equation above.
87
!>          On entry, the value sumsq in the equation above.
101
!>          On exit, SUMSQ is overwritten with  smsq , the basic sum of
88
!>          On exit, SUMSQ is overwritten by sumsq_out, the basic sum of
102
!>          squares from which  scl  has been factored out.
89
!>          squares from which scale_out has been factored out.
103
!> \endverbatim
90
!> \endverbatim
104
!
91
!
105
!  Authors:
92
!  Authors:
106
!  ========
93
!  ========
107
!
94
!
Line 128... Line 115...
128
!>  ACM Trans Math Softw 4:15--23
115
!>  ACM Trans Math Softw 4:15--23
129
!>  https://doi.org/10.1145/355769.355771
116
!>  https://doi.org/10.1145/355769.355771
130
!>
117
!>
131
!> \endverbatim
118
!> \endverbatim
132
!
119
!
133
!> \ingroup OTHERauxiliary
120
!> \ingroup lassq
134
!
121
!
135
!  =====================================================================
122
!  =====================================================================
136
subroutine ZLASSQ( n, x, incx, scl, sumsq )
123
subroutine ZLASSQ( n, x, incx, scale, sumsq )
137
   use LA_CONSTANTS, &
124
   use LA_CONSTANTS, &
138
      only: wp=>dp, zero=>dzero, one=>done, &
125
      only: wp=>dp, zero=>dzero, one=>done, &
139
            sbig=>dsbig, ssml=>dssml, tbig=>dtbig, tsml=>dtsml
126
            sbig=>dsbig, ssml=>dssml, tbig=>dtbig, tsml=>dtsml
140
   use LA_XISNAN
127
   use LA_XISNAN
141
!
128
!
Line 143... Line 130...
143
!  -- LAPACK is a software package provided by Univ. of Tennessee,    --
130
!  -- LAPACK is a software package provided by Univ. of Tennessee,    --
144
!  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
131
!  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
145
!
132
!
146
!  .. Scalar Arguments ..
133
!  .. Scalar Arguments ..
147
   integer :: incx, n
134
   integer :: incx, n
148
   real(wp) :: scl, sumsq
135
   real(wp) :: scale, sumsq
149
!  ..
136
!  ..
150
!  .. Array Arguments ..
137
!  .. Array Arguments ..
151
   complex(wp) :: x(*)
138
   complex(wp) :: x(*)
152
!  ..
139
!  ..
153
!  .. Local Scalars ..
140
!  .. Local Scalars ..
Line 156... Line 143...
156
   real(wp) :: abig, amed, asml, ax, ymax, ymin
143
   real(wp) :: abig, amed, asml, ax, ymax, ymin
157
!  ..
144
!  ..
158
!
145
!
159
!  Quick return if possible
146
!  Quick return if possible
160
!
147
!
161
   if( LA_ISNAN(scl) .or. LA_ISNAN(sumsq) ) return
148
   if( LA_ISNAN(scale) .or. LA_ISNAN(sumsq) ) return
162
   if( sumsq == zero ) scl = one
149
   if( sumsq == zero ) scale = one
163
   if( scl == zero ) then
150
   if( scale == zero ) then
164
      scl = one
151
      scale = one
165
      sumsq = zero
152
      sumsq = zero
166
   end if
153
   end if
167
   if (n <= 0) then
154
   if (n <= 0) then
168
      return
155
      return
169
   end if
156
   end if
Line 205... Line 192...
205
   end do
192
   end do
206
!
193
!
207
!  Put the existing sum of squares into one of the accumulators
194
!  Put the existing sum of squares into one of the accumulators
208
!
195
!
209
   if( sumsq > zero ) then
196
   if( sumsq > zero ) then
210
      ax = scl*sqrt( sumsq )
197
      ax = scale*sqrt( sumsq )
211
      if (ax > tbig) then
198
      if (ax > tbig) then
-
 
199
         if (scale > one) then
212
!        We assume scl >= sqrt( TINY*EPS ) / sbig
200
            scale = scale * sbig
213
         abig = abig + (scl*sbig)**2 * sumsq
201
            abig = abig + scale * (scale * sumsq)
-
 
202
         else
-
 
203
            ! sumsq > tbig^2 => (sbig * (sbig * sumsq)) is representable
-
 
204
            abig = abig + scale * (scale * (sbig * (sbig * sumsq)))
-
 
205
         end if
214
      else if (ax < tsml) then
206
      else if (ax < tsml) then
-
 
207
         if (notbig) then
-
 
208
            if (scale < one) then
215
!        We assume scl <= sqrt( HUGE ) / ssml
209
               scale = scale * ssml
216
         if (notbig) asml = asml + (scl*ssml)**2 * sumsq
210
               asml = asml + scale * (scale * sumsq)
-
 
211
            else
-
 
212
               ! sumsq < tsml^2 => (ssml * (ssml * sumsq)) is representable
-
 
213
               asml = asml + scale * (scale * (ssml * (ssml * sumsq)))
-
 
214
            end if
-
 
215
         end if
217
      else
216
      else
218
         amed = amed + scl**2 * sumsq
217
         amed = amed + scale * (scale * sumsq)
219
      end if
218
      end if
220
   end if
219
   end if
221
!
220
!
222
!  Combine abig and amed or amed and asml if more than one
221
!  Combine abig and amed or amed and asml if more than one
223
!  accumulator was used.
222
!  accumulator was used.
Line 227... Line 226...
227
!     Combine abig and amed if abig > 0.
226
!     Combine abig and amed if abig > 0.
228
!
227
!
229
      if (amed > zero .or. LA_ISNAN(amed)) then
228
      if (amed > zero .or. LA_ISNAN(amed)) then
230
         abig = abig + (amed*sbig)*sbig
229
         abig = abig + (amed*sbig)*sbig
231
      end if
230
      end if
232
      scl = one / sbig
231
      scale = one / sbig
233
      sumsq = abig
232
      sumsq = abig
234
   else if (asml > zero) then
233
   else if (asml > zero) then
235
!
234
!
236
!     Combine amed and asml if asml > 0.
235
!     Combine amed and asml if asml > 0.
237
!
236
!
Line 243... Line 242...
243
            ymax = asml
242
            ymax = asml
244
         else
243
         else
245
            ymin = asml
244
            ymin = asml
246
            ymax = amed
245
            ymax = amed
247
         end if
246
         end if
248
         scl = one
247
         scale = one
249
         sumsq = ymax**2*( one + (ymin/ymax)**2 )
248
         sumsq = ymax**2*( one + (ymin/ymax)**2 )
250
      else
249
      else
251
         scl = one / ssml
250
         scale = one / ssml
252
         sumsq = asml
251
         sumsq = asml
253
      end if
252
      end if
254
   else
253
   else
255
!
254
!
256
!     Otherwise all values are mid-range or zero
255
!     Otherwise all values are mid-range or zero
257
!
256
!
258
      scl = one
257
      scale = one
259
      sumsq = amed
258
      sumsq = amed
260
   end if
259
   end if
261
   return
260
   return
262
end subroutine
261
end subroutine