| 
 | 1 | +!> \brief \b ICAMAX  | 
 | 2 | +!  | 
 | 3 | +!  =========== DOCUMENTATION ===========  | 
 | 4 | +!  | 
 | 5 | +! Online html documentation available at  | 
 | 6 | +!            http://www.netlib.org/lapack/explore-html/  | 
 | 7 | +!  | 
 | 8 | +!  Definition:  | 
 | 9 | +!  ===========  | 
 | 10 | +!  | 
 | 11 | +!       INTEGER FUNCTION ICAMAX(N,X,INCX)  | 
 | 12 | +!  | 
 | 13 | +!       .. Scalar Arguments ..  | 
 | 14 | +!       INTEGER INCX,N  | 
 | 15 | +!       ..  | 
 | 16 | +!       .. Array Arguments ..  | 
 | 17 | +!       COMPLEX X(*)  | 
 | 18 | +!       ..  | 
 | 19 | +!  | 
 | 20 | +!  | 
 | 21 | +!> \par Purpose:  | 
 | 22 | +!  =============  | 
 | 23 | +!>  | 
 | 24 | +!> \verbatim  | 
 | 25 | +!>  | 
 | 26 | +!>  ICAMAX finds the index of the first element having maximum |Re(.)| + |Im(.)|  | 
 | 27 | +!> \endverbatim  | 
 | 28 | +!  | 
 | 29 | +!  Arguments:  | 
 | 30 | +!  ==========  | 
 | 31 | +!  | 
 | 32 | +!> \param[in] N  | 
 | 33 | +!> \verbatim  | 
 | 34 | +!>          N is INTEGER  | 
 | 35 | +!>         number of elements in input vector(s)  | 
 | 36 | +!> \endverbatim  | 
 | 37 | +!>  | 
 | 38 | +!> \param[in] X  | 
 | 39 | +!> \verbatim  | 
 | 40 | +!>          X is COMPLEX array, dimension ( 1 + ( N - 1 )*abs( INCX ) )  | 
 | 41 | +!> \endverbatim  | 
 | 42 | +!>  | 
 | 43 | +!> \param[in] INCX  | 
 | 44 | +!> \verbatim  | 
 | 45 | +!>          INCX is INTEGER  | 
 | 46 | +!>         storage spacing between elements of X  | 
 | 47 | +!> \endverbatim  | 
 | 48 | +!  | 
 | 49 | +!  Authors:  | 
 | 50 | +!  ========  | 
 | 51 | +!  | 
 | 52 | +!> James Demmel, University of California Berkeley, USA  | 
 | 53 | +!> Weslley Pereira, National Renewable Energy Laboratory, USA  | 
 | 54 | +!  | 
 | 55 | +!> \ingroup iamax  | 
 | 56 | +!  | 
 | 57 | +!> \par Further Details:  | 
 | 58 | +!  =====================  | 
 | 59 | +!>  | 
 | 60 | +!> \verbatim  | 
 | 61 | +!>  | 
 | 62 | +!> James Demmel et al. Proposed Consistent Exception Handling for the BLAS and  | 
 | 63 | +!> LAPACK, 2022 (https://arxiv.org/abs/2207.09281).  | 
 | 64 | +!>  | 
 | 65 | +!> \endverbatim  | 
 | 66 | +!>  | 
 | 67 | +!  =====================================================================  | 
 | 68 | +integer function icamax(n, x, incx)  | 
 | 69 | +   integer, parameter :: wp = kind(1.e0)  | 
 | 70 | +!  | 
 | 71 | +!  -- Reference BLAS level1 routine --  | 
 | 72 | +!  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --  | 
 | 73 | +!  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--  | 
 | 74 | +!  | 
 | 75 | +!  .. Constants ..  | 
 | 76 | +   real(wp), parameter :: hugeval = huge(0.0_wp)  | 
 | 77 | +!  | 
 | 78 | +!  .. Scalar Arguments ..  | 
 | 79 | +   integer :: n, incx  | 
 | 80 | +!  | 
 | 81 | +!  .. Array Arguments ..  | 
 | 82 | +   complex(wp) :: x(*)  | 
 | 83 | +!  ..  | 
 | 84 | +!  .. Local Scalars ..  | 
 | 85 | +   integer :: i, j, ix, jx  | 
 | 86 | +   real(wp) :: val, smax  | 
 | 87 | +   logical :: scaledsmax  | 
 | 88 | +!  | 
 | 89 | +!  Quick return if possible  | 
 | 90 | +!  | 
 | 91 | +   icamax = 0  | 
 | 92 | +   if (n < 1 .or. incx < 1) return  | 
 | 93 | +!  | 
 | 94 | +   icamax = 1  | 
 | 95 | +   if (n == 1) return  | 
 | 96 | +!  | 
 | 97 | +   icamax = 0  | 
 | 98 | +   scaledsmax = .false.  | 
 | 99 | +   smax = -1  | 
 | 100 | +!  | 
 | 101 | +!  scaledsmax = .true. indicates that x(icamax) is finite but  | 
 | 102 | +!  abs(real(x(icamax))) + abs(imag(x(icamax))) overflows  | 
 | 103 | +!  | 
 | 104 | +   if (incx == 1) then  | 
 | 105 | +      ! code for increment equal to 1  | 
 | 106 | +      do i = 1, n  | 
 | 107 | +         if (x(i) /= x(i)) then  | 
 | 108 | +            ! return when first NaN found  | 
 | 109 | +            icamax = i  | 
 | 110 | +            return  | 
 | 111 | +         elseif (abs(real(x(i))) > hugeval .or. abs(imag(x(i))) > hugeval) then  | 
 | 112 | +            ! keep looking for first NaN  | 
 | 113 | +            do j = i+1, n  | 
 | 114 | +               if (x(j) /= x(j)) then  | 
 | 115 | +                  ! return when first NaN found  | 
 | 116 | +                  icamax = j  | 
 | 117 | +                  return  | 
 | 118 | +               endif  | 
 | 119 | +            enddo  | 
 | 120 | +            ! record location of first Inf  | 
 | 121 | +            icamax = i  | 
 | 122 | +            return  | 
 | 123 | +         else ! still no Inf found yet  | 
 | 124 | +            if (.not. scaledsmax) then  | 
 | 125 | +               ! no abs(real(x(i))) + abs(imag(x(i))) = Inf yet  | 
 | 126 | +               val = abs(real(x(i))) + abs(imag(x(i)))  | 
 | 127 | +               if (val > hugeval) then  | 
 | 128 | +                  scaledsmax = .true.  | 
 | 129 | +                  smax = 0.25*abs(real(x(i))) + 0.25*abs(imag(x(i)))  | 
 | 130 | +                  icamax = i  | 
 | 131 | +               elseif (val > smax) then ! everything finite so far  | 
 | 132 | +                  smax = val  | 
 | 133 | +                  icamax = i  | 
 | 134 | +               endif  | 
 | 135 | +            else ! scaledsmax  | 
 | 136 | +               val = 0.25*abs(real(x(i))) + 0.25*abs(imag(x(i)))  | 
 | 137 | +               if (val > smax) then  | 
 | 138 | +                  smax = val  | 
 | 139 | +                  icamax = i  | 
 | 140 | +               endif  | 
 | 141 | +            endif  | 
 | 142 | +         endif  | 
 | 143 | +      end do  | 
 | 144 | +   else  | 
 | 145 | +      ! code for increment not equal to 1  | 
 | 146 | +      ix = 1  | 
 | 147 | +      do i = 1, n  | 
 | 148 | +         if (x(ix) /= x(ix)) then  | 
 | 149 | +            ! return when first NaN found  | 
 | 150 | +            icamax = i  | 
 | 151 | +            return  | 
 | 152 | +         elseif (abs(real(x(ix))) > hugeval .or. abs(imag(x(ix))) > hugeval) then  | 
 | 153 | +            ! keep looking for first NaN  | 
 | 154 | +            jx = ix + incx  | 
 | 155 | +            do j = i+1, n  | 
 | 156 | +               if (x(jx) /= x(jx)) then  | 
 | 157 | +                  ! return when first NaN found  | 
 | 158 | +                  icamax = j  | 
 | 159 | +                  return  | 
 | 160 | +               endif  | 
 | 161 | +               jx = jx + incx  | 
 | 162 | +            enddo  | 
 | 163 | +            ! record location of first Inf  | 
 | 164 | +            icamax = i  | 
 | 165 | +            return  | 
 | 166 | +         else ! still no Inf found yet  | 
 | 167 | +            if (.not. scaledsmax) then  | 
 | 168 | +               ! no abs(real(x(ix))) + abs(imag(x(ix))) = Inf yet  | 
 | 169 | +               val = abs(real(x(ix))) + abs(imag(x(ix)))  | 
 | 170 | +               if (val > hugeval) then  | 
 | 171 | +                  scaledsmax = .true.  | 
 | 172 | +                  smax = 0.25*abs(real(x(ix))) + 0.25*abs(imag(x(ix)))  | 
 | 173 | +                  icamax = i  | 
 | 174 | +               elseif (val > smax) then ! everything finite so far  | 
 | 175 | +                  smax = val  | 
 | 176 | +                  icamax = i  | 
 | 177 | +               endif  | 
 | 178 | +            else ! scaledsmax  | 
 | 179 | +               val = 0.25*abs(real(x(ix))) + 0.25*abs(imag(x(ix)))  | 
 | 180 | +               if (val > smax) then  | 
 | 181 | +                  smax = val  | 
 | 182 | +                  icamax = i  | 
 | 183 | +               endif  | 
 | 184 | +            endif  | 
 | 185 | +         endif  | 
 | 186 | +         ix = ix + incx  | 
 | 187 | +      end do  | 
 | 188 | +   endif  | 
 | 189 | +end  | 
0 commit comments