function isamax ( n, x, incx ) !*****************************************************************************80 ! !! ISAMAX indexes the array element of maximum absolute value. ! ! Discussion: ! ! This routine uses single precision real arithmetic. ! ! Modified: ! ! 08 April 1999 ! ! Author: ! ! Jack Dongarra ! ! Fortran90 translation by John Burkardt. ! ! Reference: ! ! Jack Dongarra, Jim Bunch, Cleve Moler, Pete Stewart, ! LINPACK User's Guide, ! SIAM, 1979, ! ISBN13: 978-0-898711-72-1, ! LC: QA214.L56. ! ! Charles Lawson, Richard Hanson, David Kincaid, Fred Krogh, ! Algorithm 539, ! Basic Linear Algebra Subprograms for Fortran Usage, ! ACM Transactions on Mathematical Software, ! Volume 5, Number 3, September 1979, pages 308-323. ! ! Parameters: ! ! Input, integer N, the number of entries in the vector. ! ! Input, real X(*), the vector to be examined. ! ! Input, integer INCX, the increment between successive entries of SX. ! ! Output, integer ISAMAX, the index of the element of SX of maximum ! absolute value. ! implicit none integer i integer incx integer isamax integer ix integer n real samax real x(*) if ( n <= 0 ) then isamax = 0 else if ( n == 1 ) then isamax = 1 else if ( incx == 1 ) then isamax = 1 samax = abs ( x(1) ) do i = 2, n if ( samax < abs ( x(i) ) ) then isamax = i samax = abs ( x(i) ) end if end do else if ( 0 <= incx ) then ix = 1 else ix = ( - n + 1 ) * incx + 1 end if isamax = 1 samax = abs ( x(ix) ) ix = ix + incx do i = 2, n if ( samax < abs ( x(ix) ) ) then isamax = i samax = abs ( x(ix) ) end if ix = ix + incx end do end if return end function lsame ( ca, cb ) !*****************************************************************************80 ! !! LSAME returns TRUE if CA is the same letter as CB regardless of case. ! ! Modified: ! ! 16 May 2005 ! ! Author: ! ! Fortran90 translation by John Burkardt. ! ! Reference: ! ! Jack Dongarra, Jim Bunch, Cleve Moler, Pete Stewart, ! LINPACK User's Guide, ! SIAM, 1979, ! ISBN13: 978-0-898711-72-1, ! LC: QA214.L56. ! ! Charles Lawson, Richard Hanson, David Kincaid, Fred Krogh, ! Algorithm 539, ! Basic Linear Algebra Subprograms for Fortran Usage, ! ACM Transactions on Mathematical Software, ! Volume 5, Number 3, September 1979, pages 308-323. ! ! Parameters: ! ! Input, character CA, CB, the character to compare. ! ! Output, logical LSAME, is TRUE if the characters are equal, ! disregarding case. ! implicit none character ca character cb integer inta integer intb logical lsame integer zcode ! ! Test if the characters are equal ! lsame = ( ca == cb ) if ( lsame ) then return end if ! ! Now test for equivalence if both characters are alphabetic. ! zcode = ichar ( 'Z' ) ! ! Use 'Z' rather than 'A' so that ASCII can be detected on Prime ! machines, on which ICHAR returns a value with bit 8 set. ! ICHAR('A') on Prime machines returns 193 which is the same as ! ICHAR('A') on an EBCDIC machine. ! inta = ichar ( ca ) intb = ichar ( cb ) if ( zcode == 90 .or. zcode == 122 ) then ! ! ASCII is assumed - zcode is the ASCII code of either lower or ! upper case 'Z'. ! if ( 97 <= inta .and. inta <= 122 ) then inta = inta - 32 end if if ( 97 <= intb .and. intb <= 122 ) then intb = intb - 32 end if else if ( zcode == 233 .or. zcode == 169 ) then ! ! EBCDIC is assumed - zcode is the EBCDIC code of either lower or ! upper case 'Z'. ! if ( 129 <= inta .and. inta <= 137 .or. & 145 <= inta .and. inta <= 153 .or. & 162 <= inta .and. inta <= 169 ) then inta = inta + 64 end if if ( 129 <= intb .and. intb <= 137 .or. & 145 <= intb .and. intb <= 153 .or. & 162 <= intb .and. intb <= 169 ) then intb = intb + 64 end if else if ( zcode == 218 .or. zcode == 250 ) then ! ! ASCII is assumed, on Prime machines - zcode is the ASCII code ! plus 128 of either lower or upper case 'Z'. ! if ( 225 <= inta .and. inta <= 250 ) then inta = inta - 32 end if if ( 225 <= intb .and. intb <= 250 ) then intb = intb - 32 end if end if lsame = ( inta == intb ) return end function sasum ( n, x, incx ) !*****************************************************************************80 ! !! SASUM takes the sum of the absolute values of a vector. ! ! Discussion: ! ! This routine uses single precision real arithmetic. ! ! Modified: ! ! 15 February 2001 ! ! Author: ! ! Jack Dongarra ! ! Fortran90 translation by John Burkardt. ! ! Reference: ! ! Jack Dongarra, Jim Bunch, Cleve Moler, Pete Stewart, ! LINPACK User's Guide, ! SIAM, 1979, ! ISBN13: 978-0-898711-72-1, ! LC: QA214.L56. ! ! Charles Lawson, Richard Hanson, David Kincaid, Fred Krogh, ! Algorithm 539, ! Basic Linear Algebra Subprograms for Fortran Usage, ! ACM Transactions on Mathematical Software, ! Volume 5, Number 3, September 1979, pages 308-323. ! ! Parameters: ! ! Input, integer N, the number of entries in the vector. ! ! Input, real X(*), the vector to be examined. ! ! Input, integer INCX, the increment between successive entries of X. ! INCX must not be negative. ! ! Output, real SASUM, the sum of the absolute values of X. ! implicit none integer incx integer n real sasum real x(*) sasum = sum ( abs ( x(1:1+(n-1)*incx:incx) ) ) return end subroutine saxpy ( n, sa, x, incx, y, incy ) !*****************************************************************************80 ! !! SAXPY adds a constant times one vector to another. ! ! Discussion: ! ! This routine uses single precision real arithmetic. ! ! Modified: ! ! 08 April 1999 ! ! Author: ! ! Jack Dongarra ! ! Fortran90 translation by John Burkardt. ! ! Reference: ! ! Jack Dongarra, Jim Bunch, Cleve Moler, Pete Stewart, ! LINPACK User's Guide, ! SIAM, 1979, ! ISBN13: 978-0-898711-72-1, ! LC: QA214.L56. ! ! Charles Lawson, Richard Hanson, David Kincaid, Fred Krogh, ! Algorithm 539, ! Basic Linear Algebra Subprograms for Fortran Usage, ! ACM Transactions on Mathematical Software, ! Volume 5, Number 3, September 1979, pages 308-323. ! ! Parameters: ! ! Input, integer N, the number of entries in the vector. ! ! Input, real SA, the multiplier. ! ! Input, real X(*), the vector to be scaled and added to Y. ! ! Input, integer INCX, the increment between successive entries of X. ! ! Input/output, real Y(*), the vector to which a multiple of X is to ! be added. ! ! Input, integer INCY, the increment between successive entries of Y. ! implicit none integer i integer incx integer incy integer ix integer iy integer n real sa real x(*) real y(*) if ( n <= 0 ) then else if ( sa == 0.0E+00 ) then else if ( incx == 1 .and. incy == 1 ) then y(1:n) = y(1:n) + sa * x(1:n) else if ( 0 <= incx ) then ix = 1 else ix = ( - n + 1 ) * incx + 1 end if if ( 0 <= incy ) then iy = 1 else iy = ( - n + 1 ) * incy + 1 end if do i = 1, n y(iy) = y(iy) + sa * x(ix) ix = ix + incx iy = iy + incy end do end if return end subroutine scopy ( n, x, incx, y, incy ) !*****************************************************************************80 ! !! SCOPY copies one vector into another. ! ! Discussion: ! ! This routine uses single precision real arithmetic. ! ! Modified: ! ! 08 April 1999 ! ! Author: ! ! Jack Dongarra ! ! Fortran90 translation by John Burkardt. ! ! Reference: ! ! Jack Dongarra, Jim Bunch, Cleve Moler, Pete Stewart, ! LINPACK User's Guide, ! SIAM, 1979, ! ISBN13: 978-0-898711-72-1, ! LC: QA214.L56. ! ! Charles Lawson, Richard Hanson, David Kincaid, Fred Krogh, ! Algorithm 539, ! Basic Linear Algebra Subprograms for Fortran Usage, ! ACM Transactions on Mathematical Software, ! Volume 5, Number 3, September 1979, pages 308-323. ! ! Parameters: ! ! Input, integer N, the number of entries in the vector. ! ! Input, real X(*), the vector to be copied into Y. ! ! Input, integer INCX, the increment between successive entries of X. ! ! Output, real Y(*), the copy of X. ! ! Input, integer INCY, the increment between successive elements of Y. ! implicit none integer i integer incx integer incy integer ix integer iy integer n real x(*) real y(*) if ( n <= 0 ) then else if ( incx == 1 .and. incy == 1 ) then y(1:n) = x(1:n) else if ( 0 <= incx ) then ix = 1 else ix = ( - n + 1 ) * incx + 1 end if if ( 0 <= incy ) then iy = 1 else iy = ( - n + 1 ) * incy + 1 end if do i = 1, n y(iy) = x(ix) ix = ix + incx iy = iy + incy end do end if return end function sdot ( n, x, incx, y, incy ) !*****************************************************************************80 ! !! SDOT forms the dot product of two vectors. ! ! Discussion: ! ! This routine uses single precision real arithmetic. ! ! Modified: ! ! 02 June 2000 ! ! Author: ! ! Jack Dongarra ! ! Fortran90 translation by John Burkardt. ! ! Reference: ! ! Jack Dongarra, Jim Bunch, Cleve Moler, Pete Stewart, ! LINPACK User's Guide, ! SIAM, 1979, ! ISBN13: 978-0-898711-72-1, ! LC: QA214.L56. ! ! Charles Lawson, Richard Hanson, David Kincaid, Fred Krogh, ! Algorithm 539, ! Basic Linear Algebra Subprograms for Fortran Usage, ! ACM Transactions on Mathematical Software, ! Volume 5, Number 3, September 1979, pages 308-323. ! ! Parameters: ! ! Input, integer N, the number of entries in the vectors. ! ! Input, real X(*), one of the vectors to be multiplied. ! ! Input, integer INCX, the increment between successive entries of X. ! ! Input, real Y(*), one of the vectors to be multiplied. ! ! Input, integer INCY, the increment between successive elements of Y. ! ! Output, real SDOT, the dot product of X and Y. ! implicit none integer i integer incx integer incy integer ix integer iy integer n real sdot real stemp real x(*) real y(*) if ( n <= 0 ) then sdot = 0.0E+00 else if ( incx == 1 .and. incy == 1 ) then sdot = dot_product ( x(1:n), y(1:n) ) else if ( 0 <= incx ) then ix = 1 else ix = ( - n + 1 ) * incx + 1 end if if ( 0 <= incy ) then iy = 1 else iy = ( - n + 1 ) * incy + 1 end if stemp = 0.0E+00 do i = 1, n stemp = stemp + x(ix) * y(iy) ix = ix + incx iy = iy + incy end do sdot = stemp end if return end function smach ( job ) !*****************************************************************************80 ! !! SMACH computes machine parameters for single precision arithmetic. ! ! Discussion: ! ! Assume the computer has ! ! B = base of arithmetic; ! T = number of base B digits; ! L = smallest possible exponent; ! U = largest possible exponent; ! ! then ! ! EPS = B**(1-T) ! TINY = 100.0 * B**(-L+T) ! HUGE = 0.01 * B**(U-T) ! ! Modified: ! ! 19 February 2006 ! ! Author: ! ! FORTRAN90 version by John Burkardt ! ! Reference: ! ! Jack Dongarra, Jim Bunch, Cleve Moler, Pete Stewart, ! LINPACK User's Guide, ! SIAM, 1979, ! ISBN13: 978-0-898711-72-1, ! LC: QA214.L56. ! ! Charles Lawson, Richard Hanson, David Kincaid, Fred Krogh, ! Algorithm 539, ! Basic Linear Algebra Subprograms for Fortran Usage, ! ACM Transactions on Mathematical Software, ! Volume 5, Number 3, pages 308-323, 1979. ! ! Parameters: ! ! Input, integer JOB: ! 1, EPS is desired; ! 2, TINY is desired; ! 3, HUGE is desired. ! ! Output, real SMACH, the requested value. ! implicit none real eps real huge integer job real s real smach real tiny eps = 1.0E+00 do eps = eps / 2.0E+00 s = 1.0E+00 + eps if ( s <= 1.0E+00 ) then exit end if end do eps = 2.0E+00 * eps s = 1.0E+00 do tiny = s s = s / 16.0E+00 if ( s * 1.0E+00 == 0.0E+00 ) then exit end if end do tiny = ( tiny / eps ) * 100.0E+00 huge = 1.0E+00 / tiny if ( job == 1 ) then smach = eps else if ( job == 2 ) then smach = tiny else if ( job == 3 ) then smach = huge else smach = 0.0E+00 end if return end function snrm2 ( n, x, incx ) !*****************************************************************************80 ! !! SNRM2 computes the Euclidean norm of a vector. ! ! Discussion: ! ! This routine uses single precision real arithmetic. ! ! Modified: ! ! 01 June 2000 ! ! Author: ! ! Sven Hammarling ! ! Fortran90 translation by John Burkardt. ! ! Reference: ! ! Jack Dongarra, Jim Bunch, Cleve Moler, Pete Stewart, ! LINPACK User's Guide, ! SIAM, 1979, ! ISBN13: 978-0-898711-72-1, ! LC: QA214.L56. ! ! Charles Lawson, Richard Hanson, David Kincaid, Fred Krogh, ! Algorithm 539, ! Basic Linear Algebra Subprograms for Fortran Usage, ! ACM Transactions on Mathematical Software, ! Volume 5, Number 3, September 1979, pages 308-323. ! ! Parameters: ! ! Input, integer N, the number of entries in the vector. ! ! Input, real X(*), the vector whose norm is to be computed. ! ! Input, integer INCX, the increment between successive entries of X. ! ! Output, real SNRM2, the Euclidean norm of X. ! implicit none real absxi integer incx integer ix integer n real norm real scale real snrm2 real ssq real x(*) if ( n < 1 .or. incx < 1 ) then norm = 0.0E+00 else if ( n == 1 ) then norm = abs ( x(1) ) else scale = 0.0E+00 ssq = 1.0E+00 do ix = 1, 1 + ( n - 1 )*incx, incx if ( x(ix) /= 0.0E+00 ) then absxi = abs ( x(ix) ) if ( scale < absxi ) then ssq = 1.0E+00 + ssq * ( scale / absxi )**2 scale = absxi else ssq = ssq + ( absxi / scale )**2 end if end if end do norm = scale * sqrt( ssq ) end if snrm2 = norm return end subroutine srot ( n, x, incx, y, incy, c, s ) !*****************************************************************************80 ! !! SROT applies a plane rotation. ! ! Discussion: ! ! This routine uses single precision real arithmetic. ! ! Modified: ! ! 08 April 1999 ! ! Author: ! ! Jack Dongarra ! ! Fortran90 translation by John Burkardt. ! ! Reference: ! ! Jack Dongarra, Jim Bunch, Cleve Moler, Pete Stewart, ! LINPACK User's Guide, ! SIAM, 1979, ! ISBN13: 978-0-898711-72-1, ! LC: QA214.L56. ! ! Charles Lawson, Richard Hanson, David Kincaid, Fred Krogh, ! Algorithm 539, ! Basic Linear Algebra Subprograms for Fortran Usage, ! ACM Transactions on Mathematical Software, ! Volume 5, Number 3, September 1979, pages 308-323. ! ! Parameters: ! ! Input, integer N, the number of entries in the vectors. ! ! Input/output, real X(*), one of the vectors to be rotated. ! ! Input, integer INCX, the increment between successive entries of X. ! ! Input/output, real Y(*), one of the vectors to be rotated. ! ! Input, integer INCY, the increment between successive elements of Y. ! ! Input, real C, S, parameters (presumably the cosine and sine of ! some angle) that define a plane rotation. ! implicit none real c integer i integer incx integer incy integer ix integer iy integer n real s real stemp real x(*) real y(*) if ( n <= 0 ) then else if ( incx == 1 .and. incy == 1 ) then do i = 1, n stemp = c * x(i) + s * y(i) y(i) = c * y(i) - s * x(i) x(i) = stemp end do else if ( 0 <= incx ) then ix = 1 else ix = ( - n + 1 ) * incx + 1 end if if ( 0 <= incy ) then iy = 1 else iy = ( - n + 1 ) * incy + 1 end if do i = 1, n stemp = c * x(ix) + s * y(iy) y(iy) = c * y(iy) - s * x(ix) x(ix) = stemp ix = ix + incx iy = iy + incy end do end if return end subroutine srotg ( sa, sb, c, s ) !*****************************************************************************80 ! !! SROTG constructs a Givens plane rotation. ! ! Discussion: ! ! This routine uses single precision real arithmetic. ! ! Given values A and B, this routine computes ! ! SIGMA = sign ( A ) if abs ( A ) > abs ( B ) ! = sign ( B ) if abs ( A ) <= abs ( B ); ! ! R = SIGMA * ( A * A + B * B ); ! ! C = A / R if R is not 0 ! = 1 if R is 0; ! ! S = B / R if R is not 0, ! 0 if R is 0. ! ! The computed numbers then satisfy the equation ! ! ( C S ) ( A ) = ( R ) ! ( -S C ) ( B ) = ( 0 ) ! ! The routine also computes ! ! Z = S if abs ( A ) > abs ( B ), ! = 1 / C if abs ( A ) <= abs ( B ) and C is not 0, ! = 1 if C is 0. ! ! The single value Z encodes C and S, and hence the rotation: ! ! If Z = 1, set C = 0 and S = 1; ! If abs ( Z ) < 1, set C = sqrt ( 1 - Z * Z ) and S = Z; ! if abs ( Z ) > 1, set C = 1/ Z and S = sqrt ( 1 - C * C ); ! ! Modified: ! ! 15 May 2006 ! ! Author: ! ! Jack Dongarra ! ! Fortran90 translation by John Burkardt. ! ! Reference: ! ! Jack Dongarra, Jim Bunch, Cleve Moler, Pete Stewart, ! LINPACK User's Guide, ! SIAM, 1979, ! ISBN13: 978-0-898711-72-1, ! LC: QA214.L56. ! ! Charles Lawson, Richard Hanson, David Kincaid, Fred Krogh, ! Algorithm 539, ! Basic Linear Algebra Subprograms for Fortran Usage, ! ACM Transactions on Mathematical Software, ! Volume 5, Number 3, September 1979, pages 308-323. ! ! Parameters: ! ! Input/output, real SA, SB. On input, SA and SB are the values ! A and B. On output, SA is overwritten with R, and SB is ! overwritten with Z. ! ! Output, real C, S, the cosine and sine of the Givens rotation. ! implicit none real c real r real roe real s real sa real sb real scale real z if ( abs ( sb ) < abs ( sa ) ) then roe = sa else roe = sb end if scale = abs ( sa ) + abs ( sb ) if ( scale == 0.0E+00 ) then c = 1.0E+00 s = 0.0E+00 r = 0.0E+00 else r = scale * sqrt ( ( sa / scale )**2 + ( sb / scale )**2 ) r = sign ( 1.0E+00, roe ) * r c = sa / r s = sb / r end if if ( 0.0E+00 < abs ( c ) .and. abs ( c ) <= s ) then z = 1.0E+00 / c else z = s end if sa = r sb = z return end subroutine sscal ( n, sa, x, incx ) !*****************************************************************************80 ! !! SSCAL scales a vector by a constant. ! ! Discussion: ! ! This routine uses single precision real arithmetic. ! ! Modified: ! ! 08 April 1999 ! ! Author: ! ! Jack Dongarra ! ! Fortran90 translation by John Burkardt. ! ! Reference: ! ! Jack Dongarra, Jim Bunch, Cleve Moler, Pete Stewart, ! LINPACK User's Guide, ! SIAM, 1979, ! ISBN13: 978-0-898711-72-1, ! LC: QA214.L56. ! ! Charles Lawson, Richard Hanson, David Kincaid, Fred Krogh, ! Algorithm 539, ! Basic Linear Algebra Subprograms for Fortran Usage, ! ACM Transactions on Mathematical Software, ! Volume 5, Number 3, September 1979, pages 308-323. ! ! Parameters: ! ! Input, integer N, the number of entries in the vector. ! ! Input, real SA, the multiplier. ! ! Input/output, real X(*), the vector to be scaled. ! ! Input, integer INCX, the increment between successive entries of X. ! implicit none integer i integer incx integer ix integer m integer n real sa real x(*) if ( n <= 0 ) then else if ( incx == 1 ) then m = mod ( n, 5 ) x(1:m) = sa * x(1:m) do i = m+1, n, 5 x(i) = sa * x(i) x(i+1) = sa * x(i+1) x(i+2) = sa * x(i+2) x(i+3) = sa * x(i+3) x(i+4) = sa * x(i+4) end do else if ( 0 <= incx ) then ix = 1 else ix = ( - n + 1 ) * incx + 1 end if do i = 1, n x(ix) = sa * x(ix) ix = ix + incx end do end if return end subroutine sswap ( n, x, incx, y, incy ) !*****************************************************************************80 ! !! SSWAP interchanges two vectors. ! ! Discussion: ! ! This routine uses single precision real arithmetic. ! ! Modified: ! ! 08 April 1999 ! ! Author: ! ! Fortran90 translation by John Burkardt. ! ! Reference: ! ! Jack Dongarra, Jim Bunch, Cleve Moler, Pete Stewart, ! LINPACK User's Guide, ! SIAM, 1979, ! ISBN13: 978-0-898711-72-1, ! LC: QA214.L56. ! ! Charles Lawson, Richard Hanson, David Kincaid, Fred Krogh, ! Algorithm 539, ! Basic Linear Algebra Subprograms for Fortran Usage, ! ACM Transactions on Mathematical Software, ! Volume 5, Number 3, September 1979, pages 308-323. ! ! Parameters: ! ! Input, integer N, the number of entries in the vectors. ! ! Input/output, real X(*), one of the vectors to swap. ! ! Input, integer INCX, the increment between successive entries of X. ! ! Input/output, real Y(*), one of the vectors to swap. ! ! Input, integer INCY, the increment between successive elements of Y. ! implicit none integer i integer incx integer incy integer ix integer iy integer m integer n real temp real x(*) real y(*) if ( n <= 0 ) then else if ( incx == 1 .and. incy == 1 ) then m = mod ( n, 3 ) do i = 1, m temp = x(i) x(i) = y(i) y(i) = temp end do do i = m+1, n, 3 temp = x(i) x(i) = y(i) y(i) = temp temp = x(i+1) x(i+1) = y(i+1) y(i+1) = temp temp = x(i+2) x(i+2) = y(i+2) y(i+2) = temp end do else if ( 0 <= incx ) then ix = 1 else ix = ( - n + 1 ) * incx + 1 end if if ( 0 <= incy ) then iy = 1 else iy = ( - n + 1 ) * incy + 1 end if do i = 1, n temp = x(ix) x(ix) = y(iy) y(iy) = temp ix = ix + incx iy = iy + incy end do end if return end subroutine xerbla ( srname, info ) !*****************************************************************************80 ! !! XERBLA is an error handler for the LAPACK routines. ! ! Modified: ! ! 16 May 2005 ! ! Author: ! ! Fortran90 translation by John Burkardt. ! ! Reference: ! ! Jack Dongarra, Jim Bunch, Cleve Moler, Pete Stewart, ! LINPACK User's Guide, ! SIAM, 1979, ! ISBN13: 978-0-898711-72-1, ! LC: QA214.L56. ! ! Charles Lawson, Richard Hanson, David Kincaid, Fred Krogh, ! Algorithm 539, ! Basic Linear Algebra Subprograms for Fortran Usage, ! ACM Transactions on Mathematical Software, ! Volume 5, Number 3, September 1979, pages 308-323. ! ! Parameters: ! ! Input, character ( len = 6 ) SRNAME, the name of the routine ! which called XERBLA. ! ! Input, integer INFO, the position of the invalid parameter in ! the parameter list of the calling routine. ! implicit none integer info character ( len = 6 ) srname write ( *, '(a,a6,a,i2,a)' ) ' ** On entry to ', srname, & ' parameter number ', info, ' had an illegal value.' stop end