diff --git a/c/odrpack_capi.f90 b/c/odrpack_capi.f90 index dbf5d3a..5e2b716 100644 --- a/c/odrpack_capi.f90 +++ b/c/odrpack_capi.f90 @@ -468,7 +468,7 @@ pure subroutine diwinf_c(m, np, nq, iworkidx) bind(C) end subroutine diwinf_c - subroutine dwinf_c(n, m, np, nq, ldwe, ld2we, isodr, workidx) bind(C) + pure subroutine dwinf_c(n, m, np, nq, ldwe, ld2we, isodr, workidx) bind(C) !! Get storage locations within real work space. integer(c_int), intent(in) :: n !! Number of observations. @@ -562,7 +562,7 @@ subroutine dwinf_c(n, m, np, nq, ldwe, ld2we, isodr, workidx) bind(C) end subroutine dwinf_c - subroutine workspace_dimensions_c(n, m, np, nq, isodr, lwork, liwork) bind(C) + pure subroutine workspace_dimensions_c(n, m, np, nq, isodr, lwork, liwork) bind(C) !! Calculate the dimensions of the workspace arrays. integer(c_int), intent(in) :: n !! Number of observations. diff --git a/src/blas_interfaces.f90 b/src/blas_interfaces.f90 new file mode 100644 index 0000000..ea989c8 --- /dev/null +++ b/src/blas_interfaces.f90 @@ -0,0 +1,190 @@ +module blas_interfaces + !! Single and double precision interfaces for the BLAS procedures used by odrpack. + use odrpack_kinds, only: sp, dp + implicit none + + interface + + pure real(sp) function sasum(n, x, incx) + import :: sp + integer, intent(in) :: n + real(sp), intent(in) :: x(*) + integer, intent(in) :: incx + end function sasum + + pure real(dp) function dasum(n, x, incx) + !! Takes the sum of the absolute values. + import :: dp + integer, intent(in) :: n + real(dp), intent(in) :: x(*) + integer, intent(in) :: incx + end function dasum + + pure subroutine saxpy(n, a, x, incx, y, incy) + import :: sp + integer, intent(in) :: n + real(sp), intent(in) :: a + real(sp), intent(in) :: x(*) + integer, intent(in) :: incx + real(sp), intent(inout) :: y(*) + integer, intent(in) :: incy + end subroutine saxpy + + pure subroutine daxpy(n, a, x, incx, y, incy) + !! Constant times a vector plus a vector. + import :: dp + integer, intent(in) :: n + real(dp), intent(in) :: a + real(dp), intent(in) :: x(*) + integer, intent(in) :: incx + real(dp), intent(inout) :: y(*) + integer, intent(in) :: incy + end subroutine daxpy + + pure subroutine scopy(n, x, incx, y, incy) + import :: sp + integer, intent(in) :: n + real(sp), intent(in) :: x(*) + integer, intent(in) :: incx + real(sp), intent(inout) :: y(*) + integer, intent(in) :: incy + end subroutine scopy + + pure subroutine dcopy(n, x, incx, y, incy) + !! Copies a vector, x, to a vector, y. + import :: dp + integer, intent(in) :: n + real(dp), intent(in) :: x(*) + integer, intent(in) :: incx + real(dp), intent(inout) :: y(*) + integer, intent(in) :: incy + end subroutine dcopy + + pure real(sp) function sdot(n, x, incx, y, incy) + import :: sp + integer, intent(in) :: n + real(sp), intent(in) :: x(*) + integer, intent(in) :: incx + real(sp), intent(in) :: y(*) + integer, intent(in) :: incy + end function sdot + + pure real(dp) function ddot(n, x, incx, y, incy) + !! Forms the dot product of two vectors. + import :: dp + integer, intent(in) :: n + real(dp), intent(in) :: x(*) + integer, intent(in) :: incx + real(dp), intent(in) :: y(*) + integer, intent(in) :: incy + end function ddot + + pure real(sp) function snrm2(n, x, incx) + import :: sp + integer, intent(in) :: n + real(sp), intent(in) :: x(*) + integer, intent(in) :: incx + end function snrm2 + + pure real(dp) function dnrm2(n, x, incx) + !! Euclidean norm of a vector. + import :: dp + integer, intent(in) :: n + real(dp), intent(in) :: x(*) + integer, intent(in) :: incx + end function dnrm2 + + pure subroutine srot(n, x, incx, y, incy, c, s) + import :: sp + integer, intent(in) :: n + real(sp), intent(inout) :: x(*) + integer, intent(in) :: incx + real(sp), intent(inout) :: y(*) + integer, intent(in) :: incy + real(sp), intent(in) :: c + real(sp), intent(in) :: s + end subroutine srot + + pure subroutine drot(n, x, incx, y, incy, c, s) + !! Applies a plane rotation. + import :: dp + integer, parameter :: wp = dp + integer, intent(in) :: n + real(dp), intent(inout) :: x(*) + integer, intent(in) :: incx + real(dp), intent(inout) :: y(*) + integer, intent(in) :: incy + real(dp), intent(in) :: c + real(dp), intent(in) :: s + end subroutine drot + + pure subroutine srotg(a, b, c, s) + import :: sp + real(sp), intent(in) :: a + real(sp), intent(in) :: b + real(sp), intent(out) :: c + real(sp), intent(out) :: s + end subroutine srotg + + pure subroutine drotg(a, b, c, s) + import :: dp + real(dp), intent(in) :: a + real(dp), intent(in) :: b + real(dp), intent(out) :: c + real(dp), intent(out) :: s + end subroutine drotg + + pure subroutine sscal(n, a, x, incx) + import :: sp + integer, intent(in) :: n + real(sp), intent(in) :: a + real(sp), intent(inout) :: x(*) + integer, intent(in) :: incx + end subroutine sscal + + pure subroutine dscal(n, a, x, incx) + !! Scales a vector by a constant. + import :: dp + integer, intent(in) :: n + real(dp), intent(in) :: a + real(dp), intent(inout) :: x(*) + integer, intent(in) :: incx + end subroutine dscal + + pure subroutine sswap(n, x, incx, y, incy) + import :: sp + integer, intent(in) :: n + real(sp), intent(in) :: x(*) + integer, intent(in) :: incx + real(sp), intent(inout) :: y(*) + integer, intent(in) :: incy + end subroutine sswap + + pure subroutine dswap(n, x, incx, y, incy) + !! Interchanges two vectors. + import :: dp + integer, intent(in) :: n + real(dp), intent(in) :: x(*) + integer, intent(in) :: incx + real(dp), intent(inout) :: y(*) + integer, intent(in) :: incy + end subroutine dswap + + pure integer function isamax(n, x, incx) + import :: sp + integer, intent(in) :: n + real(sp), intent(in) :: x(*) + integer, intent(in) :: incx + end function isamax + + pure integer function idamax(n, x, incx) + !! Finds the index of the first element having maximum absolute value. + import :: dp + integer, intent(in) :: n + real(dp), intent(in) :: x(*) + integer, intent(in) :: incx + end function idamax + + end interface + +end module blas_interfaces diff --git a/src/linpack.f b/src/linpack.f index c0d1745..275d20f 100644 --- a/src/linpack.f +++ b/src/linpack.f @@ -4,7 +4,7 @@ MODULE LINPACK C CONTAINS *DCHEX - SUBROUTINE DCHEX(R,LDR,P,K,L,Z,LDZ,NZ,C,S,JOB) + PURE SUBROUTINE DCHEX(R,LDR,P,K,L,Z,LDZ,NZ,C,S,JOB) C***Begin Prologue DCHEX C***Date Written 780814 (YYMMDD) C***Revision Date 820801 (YYMMDD) @@ -95,6 +95,7 @@ SUBROUTINE DCHEX(R,LDR,P,K,L,Z,LDZ,NZ,C,S,JOB) C...Used modules use odrpack_kinds, only: wp + use blas_interfaces, only: drotg C...Scalar arguments INTEGER, INTENT(IN) :: JOB @@ -117,10 +118,6 @@ SUBROUTINE DCHEX(R,LDR,P,K,L,Z,LDZ,NZ,C,S,JOB) INTEGER & I,II,IL,IU,J,JJ,KM1,KP1,LM1,LMK -C...External subroutines - EXTERNAL - & DROTG - C...Intrinsic functions INTRINSIC & MAX0,MIN0 @@ -263,7 +260,7 @@ SUBROUTINE DCHEX(R,LDR,P,K,L,Z,LDZ,NZ,C,S,JOB) RETURN END *DPODI - SUBROUTINE DPODI(A,LDA,N,DET,JOB) + PURE SUBROUTINE DPODI(A,LDA,N,DET,JOB) C***Begin Prologue DPODI C***Date Written 780814 (YYMMDD) C***Revision Date 820801 (YYMMDD) @@ -318,6 +315,7 @@ SUBROUTINE DPODI(A,LDA,N,DET,JOB) C...Used modules use odrpack_kinds, only: wp + use blas_interfaces, only: daxpy, dscal C...Scalar arguments INTEGER, INTENT(IN) :: JOB @@ -332,9 +330,6 @@ SUBROUTINE DPODI(A,LDA,N,DET,JOB) REAL(wp) S,T INTEGER I,J,JM1,K,KP1 -C...External subroutines - EXTERNAL DAXPY,DSCAL - C...Intrinsic functions INTRINSIC MOD @@ -398,7 +393,7 @@ SUBROUTINE DPODI(A,LDA,N,DET,JOB) RETURN END *DQRDC - SUBROUTINE DQRDC(X,LDX,N,P,QRAUX,JPVT,WORK,JOB) + PURE SUBROUTINE DQRDC(X,LDX,N,P,QRAUX,JPVT,WORK,JOB) C***Begin Prologue DQRDC C***Date Written 780814 (YYMMDD) C***Revision Date 820801 (YYMMDD) @@ -472,6 +467,7 @@ SUBROUTINE DQRDC(X,LDX,N,P,QRAUX,JPVT,WORK,JOB) C...Used modules use odrpack_kinds, only: wp + use blas_interfaces, only: ddot, dnrm2, daxpy, dscal, dswap C...Scalar arguments INTEGER, INTENT(IN) :: JOB @@ -493,16 +489,6 @@ SUBROUTINE DQRDC(X,LDX,N,P,QRAUX,JPVT,WORK,JOB) LOGICAL & NEGJ,SWAPJ -C...External functions - REAL(wp) - & DDOT,DNRM2 - EXTERNAL - & DDOT,DNRM2 - -C...External subroutines - EXTERNAL - & DAXPY,DSCAL,DSWAP - C...Intrinsic functions INTRINSIC & DABS,DMAX1,DSIGN,DSQRT,MIN0 @@ -627,7 +613,7 @@ SUBROUTINE DQRDC(X,LDX,N,P,QRAUX,JPVT,WORK,JOB) RETURN END *DQRSL - SUBROUTINE DQRSL(X,LDX,N,K,QRAUX,Y,QY,QTY,B,RSD,XB,JOB,INFO) + PURE SUBROUTINE DQRSL(X,LDX,N,K,QRAUX,Y,QY,QTY,B,RSD,XB,JOB,INFO) C***Begin Prologue DQRSL C***Date Written 780814 (YYMMDD) C***Revision Date 820801 (YYMMDD) @@ -743,6 +729,7 @@ SUBROUTINE DQRSL(X,LDX,N,K,QRAUX,Y,QY,QTY,B,RSD,XB,JOB,INFO) C...Used modules use odrpack_kinds, only: wp + use blas_interfaces, only: ddot, daxpy, dcopy C...Scalar arguments INTEGER, INTENT(OUT) :: INFO @@ -769,13 +756,6 @@ SUBROUTINE DQRSL(X,LDX,N,K,QRAUX,Y,QY,QTY,B,RSD,XB,JOB,INFO) LOGICAL & CB,CQTY,CQY,CR,CXB -C...External functions - REAL(wp), EXTERNAL :: DDOT - -C...External subroutines - EXTERNAL - & DAXPY,DCOPY - C...Intrinsic functions INTRINSIC & MIN0,MOD @@ -907,7 +887,7 @@ SUBROUTINE DQRSL(X,LDX,N,K,QRAUX,Y,QY,QTY,B,RSD,XB,JOB,INFO) RETURN END *DTRCO - SUBROUTINE DTRCO(T,LDT,N,RCOND,Z,JOB) + PURE SUBROUTINE DTRCO(T,LDT,N,RCOND,Z,JOB) C***Begin Prologue DTRCO C***Date Written 780814 (YYMMDD) C***Revision Date 820801 (YYMMDD) @@ -959,6 +939,7 @@ SUBROUTINE DTRCO(T,LDT,N,RCOND,Z,JOB) C...Used modules use odrpack_kinds, only: wp + use blas_interfaces, only: dasum, daxpy, dscal C...Scalar arguments REAL(wp), INTENT(OUT) :: RCOND @@ -978,13 +959,6 @@ SUBROUTINE DTRCO(T,LDT,N,RCOND,Z,JOB) LOGICAL & LOWER -C...External functions - REAL(wp), EXTERNAL :: DASUM - -C...External subroutines - EXTERNAL - & DAXPY,DSCAL - C...Intrinsic functions INTRINSIC & DABS,DMAX1,DSIGN @@ -1094,7 +1068,7 @@ SUBROUTINE DTRCO(T,LDT,N,RCOND,Z,JOB) RETURN END *DTRSL - SUBROUTINE DTRSL(T,LDT,N,B,JOB,INFO) + PURE SUBROUTINE DTRSL(T,LDT,N,B,JOB,INFO) C***Begin Prologue DTRSL C***Date Written 780814 (YYMMDD) C***Revision Date 820801 (YYMMDD) @@ -1146,6 +1120,7 @@ SUBROUTINE DTRSL(T,LDT,N,B,JOB,INFO) C...Used modules use odrpack_kinds, only: wp + use blas_interfaces, only: ddot, daxpy C...Scalar arguments INTEGER, INTENT(OUT) :: INFO @@ -1163,13 +1138,6 @@ SUBROUTINE DTRSL(T,LDT,N,B,JOB,INFO) INTEGER & CASE,J,JJ -C...External functions - REAL(wp), EXTERNAL :: DDOT - -C...External subroutines - EXTERNAL - & DAXPY - C...Intrinsic functions INTRINSIC & MOD diff --git a/src/odrpack.f90 b/src/odrpack.f90 index 2c2b5ca..6415bc3 100644 --- a/src/odrpack.f90 +++ b/src/odrpack.f90 @@ -922,6 +922,7 @@ impure subroutine doddrv & use odrpack_core, only: fcn_t, detaf, dfctrw, dflags, diniwk, diwinf, djck, dodchk, & dpack, dsetn, dunpac, dwght, dwinf, derstep, mbfb use odrpack_reports, only: dodper + use blas_interfaces, only: ddot, dnrm2, dcopy logical, intent(inout) :: head !! The variable designating whether the heading is to be printed (`head = .true.`) @@ -1040,10 +1041,6 @@ impure subroutine doddrv & real(wp) :: betaj(np) integer :: interval(np) - ! External BLAS procedures - real(wp), external :: ddot, dnrm2 - external :: dcopy - ! Variable Definitions (alphabetically) ! ACTRSI: The location in array work of variable ACTRS. ! ALPHAI: The location in array work of variable ALPHA. @@ -1590,6 +1587,7 @@ impure subroutine dodmn & use odrpack_core, only: fcn_t, dacces, devjac, dflags, dunpac, dwght, dpack, dodvcv, & dodlm use odrpack_reports, only: dodpcr + use blas_interfaces, only: ddot, dnrm2, dcopy logical, intent(inout) :: head !! The variable designating whether the heading is to be printed (`head = .true.`) @@ -1648,11 +1646,11 @@ impure subroutine dodmn & !! The current estimated values of the unfixed `beta`s. real(wp), intent(out) :: betan(np) !! The new estimated values of the unfixed `beta`s. - real(wp), intent(in) :: betas(np) + real(wp), intent(inout) :: betas(np) !! The saved estimated values of the unfixed `beta`s. real(wp), intent(out) :: s(np) !! The step for `beta`. - real(wp), intent(in) :: delta(n, m) + real(wp), intent(inout) :: delta(n, m) !! The estimated errors in the explanatory variables. real(wp), intent(out) :: deltan(n, m) !! The new estimated errors in the explanatory variables. @@ -1736,10 +1734,6 @@ impure subroutine dodmn & ! Local arrays real(wp) :: loweru(np), upperu(np), wss(3) - ! External BLAS procedures - real(wp), external :: ddot, dnrm2 - external :: dcopy - ! Variable Definitions (alphabetically) ! ACCESS: The variable designating whether information is to be accessed from the work ! arrays (ACCESS=TRUE) or stored in them (ACCESS=FALSE). @@ -2499,7 +2493,7 @@ impure subroutine dodmn & end subroutine dodmn - subroutine workspace_dimensions(n, m, np, nq, isodr, lwork, liwork) + pure subroutine workspace_dimensions(n, m, np, nq, isodr, lwork, liwork) !! Calculate the dimensions of the workspace arrays. integer, intent(in) :: n !! Number of observations. diff --git a/src/odrpack_core.f90 b/src/odrpack_core.f90 index 9d5f725..2c6facb 100644 --- a/src/odrpack_core.f90 +++ b/src/odrpack_core.f90 @@ -68,6 +68,7 @@ subroutine dodlm & ! Revision Date 920619 (YYMMDD) use odrpack_kinds, only: zero + use blas_interfaces, only: ddot, dnrm2 integer, intent(in) :: n !! The number of observations. @@ -154,9 +155,6 @@ subroutine dodlm & integer :: i, iwrk, j, k logical :: forvcv - ! External BLAS procedures - real(wp), external :: ddot, dnrm2 - ! Variable Definitions (alphabetically) ! ALPHAN: The new Levenberg-Marquardt parameter. ! ALPHA1: The previous Levenberg-Marquardt parameter. @@ -1149,6 +1147,7 @@ subroutine devjac & ! Revision Date 920304 (YYMMDD) use odrpack_kinds, only: zero + use blas_interfaces, only: ddot procedure(fcn_t) :: fcn !! The user-supplied subroutine for evaluating the model. @@ -1242,9 +1241,6 @@ subroutine devjac & integer :: ideval, j, k, k1, l logical :: ferror - ! External BLAS procedures - real(wp), external :: ddot - ! Variable Definitions (alphabetically) ! ANAJAC: The variable designating whether the Jacobians are computed by finite differences ! (ANAJAC=FALSE) or not (ANAJAC=TRUE). @@ -1383,7 +1379,7 @@ subroutine devjac & end subroutine devjac - subroutine dfctr(oksemi, a, lda, n, info) + pure subroutine dfctr(oksemi, a, lda, n, info) !! Factor the positive (semi)definite matrix `a` using a modified Cholesky factorization. ! Adapted from LINPACK subroutine DPOFA. ! Routines Called DDOT @@ -1392,6 +1388,7 @@ subroutine dfctr(oksemi, a, lda, n, info) ! References Dongarra J.J., Bunch J.R., Moler C.B., Stewart G.W., *LINPACK Users Guide*, SIAM, 1979. use odrpack_kinds, only: zero, ten + use blas_interfaces, only: ddot logical, intent(in) :: oksemi !! The indicating whether the factored array can be positive semidefinite @@ -1415,9 +1412,6 @@ subroutine dfctr(oksemi, a, lda, n, info) real(wp) :: xi, s, t integer j, k - ! External BLAS procedures - real(wp), external :: ddot - ! Variable Definitions (alphabetically) ! A: The array to be factored. Upon return, A contains the upper triangular matrix ! R so that A = trans(R)*R where the strict lower triangle is set to zero. @@ -1475,7 +1469,7 @@ subroutine dfctr(oksemi, a, lda, n, info) end subroutine dfctr - subroutine dfctrw & + pure subroutine dfctrw & (n, m, nq, npp, & isodr, & we, ldwe, ld2we, wd, ldwd, ld2wd, & @@ -2106,7 +2100,7 @@ pure subroutine diwinf & end subroutine diwinf - subroutine diniwk & + pure subroutine diniwk & (n, m, np, work, lwork, iwork, liwork, & x, ldx, ifixx, ldifx, scld, ldscld, & beta, sclb, & @@ -2123,6 +2117,7 @@ subroutine diniwk & ! Revision Date 920304 (YYMMDD) use odrpack_kinds, only: zero, one, two, three + use blas_interfaces, only: dcopy integer, intent(in) :: n !! The number of observations. @@ -2211,9 +2206,6 @@ subroutine diniwk & integer :: i, j, istart logical :: anajac, cdjac, chkjac, dovcv, implct, initd, isodr, redoj, restrt - ! External BLAS procedures - external :: dcopy - ! Variable Definitions (alphabetically) ! ANAJAC: The variable designating whether the Jacobians are computed by finite differences ! (ANAJAC=FALSE) or not (ANAJAC=TRUE). @@ -4489,6 +4481,7 @@ subroutine dodstp & use odrpack_kinds, only: zero, one use linpack, only: dchex, dqrdc, dqrsl, dtrco, dtrsl + use blas_interfaces, only: dnrm2, drot, drotg, idamax integer, intent(in) :: n !! The number of observations. @@ -4582,11 +4575,6 @@ subroutine dodstp & ! Local arrays real(wp) :: dum(2) - ! External BLAS procedures - real(wp), external :: dnrm2 - integer, external :: idamax - external :: drot, drotg - ! Variable definitions (alphabetically) ! ALPHA: The Levenberg-Marquardt parameter. ! CO: The cosine from the plane rotation. @@ -5183,12 +5171,14 @@ subroutine dodvcv & end subroutine dodvcv - subroutine dpack(n2, n1, v1, v2, ifix) + pure subroutine dpack(n2, n1, v1, v2, ifix) !! Select the unfixed elements of `v2` and return them in `v1`. ! Routines Called DCOPY ! Date Written 860529 (YYMMDD) ! Revision Date 920304 (YYMMDD) + use blas_interfaces, only: dcopy + integer, intent(in) :: n2 !! The number of items in `v2`. integer, intent(out) :: n1 @@ -5203,9 +5193,6 @@ subroutine dpack(n2, n1, v1, v2, ifix) ! Local scalars integer :: i - ! External BLAS procedures - external :: dcopy - ! Variable definitions (alphabetically) ! I: An indexing variable. ! IFIX: The values designating whether the elements of V2 are fixed at their input @@ -5979,7 +5966,7 @@ pure subroutine dsetn(n, m, x, ldx, nrow) end subroutine dsetn - subroutine dsolve(n, t, ldt, b, job) + pure subroutine dsolve(n, t, ldt, b, job) !! Solve systems of the form: !! !! `t * x = b or trans(t) * x = b` @@ -5996,6 +5983,7 @@ subroutine dsolve(n, t, ldt, b, job) ! Revision Date 920619 (YYMMDD) use odrpack_kinds, only: zero + use blas_interfaces, only: daxpy, ddot integer, intent(in) :: n !! The number of rows and columns of data in array `t`. @@ -6016,10 +6004,6 @@ subroutine dsolve(n, t, ldt, b, job) real(wp) :: temp integer :: j1, j, jn - ! External BLAS procedures - real(wp), external :: ddot - external :: daxpy - ! Variable Definitions (alphabetically) ! B: On input: the right hand side; On exit: the solution ! J1: The first nonzero entry in T. @@ -6108,12 +6092,14 @@ subroutine dsolve(n, t, ldt, b, job) end subroutine dsolve - subroutine dunpac(n2, v1, v2, ifix) + pure subroutine dunpac(n2, v1, v2, ifix) !! Copy the elements of `v1` into the locations of `v2` which are unfixed. ! Routines Called DCOPY ! Date Written 860529 (YYMMDD) ! Revision Date 920304 (YYMMDD) + use blas_interfaces, only: dcopy + integer, intent(in) :: n2 !! The number of items in `v2`. real(wp), intent(in) :: v1(n2) @@ -6127,9 +6113,6 @@ subroutine dunpac(n2, v1, v2, ifix) ! Local scalars integer :: i, n1 - ! External BLAS procedures - external :: dcopy - ! Variable Definitions (alphabetically) ! I: An indexing variable. ! IFIX: The values designating whether the elements of V2 are fixed at their input @@ -6155,7 +6138,7 @@ subroutine dunpac(n2, v1, v2, ifix) end subroutine dunpac - subroutine dvevtr & + pure subroutine dvevtr & (m, nq, indx, & v, ldv, ld2v, e, lde, ve, ldve, ld2ve, vev, ldvev, & wrk5) diff --git a/src/odrpack_kinds.F90 b/src/odrpack_kinds.F90 index 76e418a..99425e2 100644 --- a/src/odrpack_kinds.F90 +++ b/src/odrpack_kinds.F90 @@ -4,16 +4,19 @@ module odrpack_kinds implicit none private - public :: wp + public :: sp, dp, wp public :: negone, zero, half, one, two, three, eight, ten, fiftn, hundred public :: pi + integer, parameter :: sp = real32 + integer, parameter :: dp = real64 + #ifdef REAL32 - integer, parameter :: wp = real32 + integer, parameter :: wp = sp #elif REAL64 - integer, parameter :: wp = real64 + integer, parameter :: wp = dp #else - integer, parameter :: wp = real64 + integer, parameter :: wp = dp #endif real(wp), parameter :: negone = -1.0_wp