Commit 9c285563c30716b63de00e330bdfe930a39a21a3

Authored by kwagner
1 parent 00055ac083

Define constants in data statements as double precision

git-svn-id: https://lxsd.femto-st.fr/svn/fvn@71 b657c933-2333-4658-acf2-d3c7c2708721

Showing 1 changed file with 7 additions and 7 deletions Inline Diff

fvn_misc/fvn_misc.f90
module fvn_misc 1 1 module fvn_misc
use fvn_common 2 2 use fvn_common
implicit none 3 3 implicit none
4 4
! Muller 5 5 ! Muller
interface fvn_muller 6 6 interface fvn_muller
module procedure fvn_z_muller 7 7 module procedure fvn_z_muller
end interface fvn_muller 8 8 end interface fvn_muller
9 9
contains 10 10 contains
! 11 11 !
! Muller 12 12 ! Muller
! 13 13 !
! 14 14 !
! 15 15 !
! William Daniau 2007 16 16 ! William Daniau 2007
! 17 17 !
! This routine is a fortran 90 port of Hans D. Mittelmann's routine muller.f 18 18 ! This routine is a fortran 90 port of Hans D. Mittelmann's routine muller.f
! http://plato.asu.edu/ftp/other_software/muller.f 19 19 ! http://plato.asu.edu/ftp/other_software/muller.f
! 20 20 !
! it can be used as a replacement for imsl routine dzanly with minor changes 21 21 ! it can be used as a replacement for imsl routine dzanly with minor changes
! 22 22 !
!----------------------------------------------------------------------- 23 23 !-----------------------------------------------------------------------
! 24 24 !
! purpose - zeros of an analytic complex function 25 25 ! purpose - zeros of an analytic complex function
! using the muller method with deflation 26 26 ! using the muller method with deflation
! 27 27 !
! usage - call fvn_z_muller (f,eps,eps1,kn,n,nguess,x,itmax, 28 28 ! usage - call fvn_z_muller (f,eps,eps1,kn,n,nguess,x,itmax,
! infer,ier) 29 29 ! infer,ier)
! 30 30 !
! arguments f - a complex function subprogram, f(z), written 31 31 ! arguments f - a complex function subprogram, f(z), written
! by the user specifying the equation whose 32 32 ! by the user specifying the equation whose
! roots are to be found. f must appear in 33 33 ! roots are to be found. f must appear in
! an external statement in the calling pro- 34 34 ! an external statement in the calling pro-
! gram. 35 35 ! gram.
! eps - 1st stopping criterion. let fp(z)=f(z)/p 36 36 ! eps - 1st stopping criterion. let fp(z)=f(z)/p
! where p = (z-z(1))*(z-z(2))*,,,*(z-z(k-1)) 37 37 ! where p = (z-z(1))*(z-z(2))*,,,*(z-z(k-1))
! and z(1),...,z(k-1) are previously found 38 38 ! and z(1),...,z(k-1) are previously found
! roots. if ((cdabs(f(z)).le.eps) .and. 39 39 ! roots. if ((cdabs(f(z)).le.eps) .and.
! (cdabs(fp(z)).le.eps)), then z is accepted 40 40 ! (cdabs(fp(z)).le.eps)), then z is accepted
! as a root. (input) 41 41 ! as a root. (input)
! eps1 - 2nd stopping criterion. a root is accepted 42 42 ! eps1 - 2nd stopping criterion. a root is accepted
! if two successive approximations to a given 43 43 ! if two successive approximations to a given
! root agree within eps1. (input) 44 44 ! root agree within eps1. (input)
! note. if either or both of the stopping 45 45 ! note. if either or both of the stopping
! criteria are fulfilled, the root is 46 46 ! criteria are fulfilled, the root is
! accepted. 47 47 ! accepted.
! kn - the number of known roots which must be stored 48 48 ! kn - the number of known roots which must be stored
! in x(1),...,x(kn), prior to entry to muller 49 49 ! in x(1),...,x(kn), prior to entry to muller
! nguess - the number of initial guesses provided. these 50 50 ! nguess - the number of initial guesses provided. these
! guesses must be stored in x(kn+1),..., 51 51 ! guesses must be stored in x(kn+1),...,
! x(kn+nguess). nguess must be set equal 52 52 ! x(kn+nguess). nguess must be set equal
! to zero if no guesses are provided. (input) 53 53 ! to zero if no guesses are provided. (input)
! n - the number of new roots to be found by 54 54 ! n - the number of new roots to be found by
! muller (input) 55 55 ! muller (input)
! x - a complex vector of length kn+n. x(1),..., 56 56 ! x - a complex vector of length kn+n. x(1),...,
! x(kn) on input must contain any known 57 57 ! x(kn) on input must contain any known
! roots. x(kn+1),..., x(kn+n) on input may, 58 58 ! roots. x(kn+1),..., x(kn+n) on input may,
! on user option, contain initial guesses for 59 59 ! on user option, contain initial guesses for
! the n new roots which are to be computed. 60 60 ! the n new roots which are to be computed.
! if the user does not provide an initial 61 61 ! if the user does not provide an initial
! guess, zero is used. 62 62 ! guess, zero is used.
! on output, x(kn+1),...,x(kn+n) contain the 63 63 ! on output, x(kn+1),...,x(kn+n) contain the
! approximate roots found by muller. 64 64 ! approximate roots found by muller.
! itmax - the maximum allowable number of iterations 65 65 ! itmax - the maximum allowable number of iterations
! per root (input) 66 66 ! per root (input)
! infer - an integer vector of length kn+n. on 67 67 ! infer - an integer vector of length kn+n. on
! output infer(j) contains the number of 68 68 ! output infer(j) contains the number of
! iterations used in finding the j-th root 69 69 ! iterations used in finding the j-th root
! when convergence was achieved. if 70 70 ! when convergence was achieved. if
! convergence was not obtained in itmax 71 71 ! convergence was not obtained in itmax
! iterations, infer(j) will be greater than 72 72 ! iterations, infer(j) will be greater than
! itmax (output). 73 73 ! itmax (output).
! ier - error parameter (output) 74 74 ! ier - error parameter (output)
! warning error 75 75 ! warning error
! ier = 33 indicates failure to converge with- 76 76 ! ier = 33 indicates failure to converge with-
! in itmax iterations for at least one of 77 77 ! in itmax iterations for at least one of
! the (n) new roots. 78 78 ! the (n) new roots.
! 79 79 !
! 80 80 !
! remarks muller always returns the last approximation for root j 81 81 ! remarks muller always returns the last approximation for root j
! in x(j). if the convergence criterion is satisfied, 82 82 ! in x(j). if the convergence criterion is satisfied,
! then infer(j) is less than or equal to itmax. if the 83 83 ! then infer(j) is less than or equal to itmax. if the
! convergence criterion is not satisified, then infer(j) 84 84 ! convergence criterion is not satisified, then infer(j)
! is set to either itmax+1 or itmax+k, with k greater 85 85 ! is set to either itmax+1 or itmax+k, with k greater
! than 1. infer(j) = itmax+1 indicates that muller did 86 86 ! than 1. infer(j) = itmax+1 indicates that muller did
! not obtain convergence in the allowed number of iter- 87 87 ! not obtain convergence in the allowed number of iter-
! ations. in this case, the user may wish to set itmax 88 88 ! ations. in this case, the user may wish to set itmax
! to a larger value. infer(j) = itmax+k means that con- 89 89 ! to a larger value. infer(j) = itmax+k means that con-
! vergence was obtained (on iteration k) for the defla- 90 90 ! vergence was obtained (on iteration k) for the defla-
! ted function 91 91 ! ted function
! fp(z) = f(z)/((z-z(1)...(z-z(j-1))) 92 92 ! fp(z) = f(z)/((z-z(1)...(z-z(j-1)))
! 93 93 !
! but failed for f(z). in this case, better initial 94 94 ! but failed for f(z). in this case, better initial
! guesses might help or, it might be necessary to relax 95 95 ! guesses might help or, it might be necessary to relax
! the convergence criterion. 96 96 ! the convergence criterion.
! 97 97 !
!----------------------------------------------------------------------- 98 98 !-----------------------------------------------------------------------
! 99 99 !
subroutine fvn_z_muller (f,eps,eps1,kn,nguess,n,x,itmax,infer,ier) 100 100 subroutine fvn_z_muller (f,eps,eps1,kn,nguess,n,x,itmax,infer,ier)
implicit none 101 101 implicit none
double precision :: rzero,rten,rhun,rp01,ax,eps1,qz,eps,tpq,eps1w 102 102 double precision :: rzero,rten,rhun,rp01,ax,eps1,qz,eps,tpq,eps1w
double complex :: d,dd,den,fprt,frt,h,rt,t1,t2,t3, & 103 103 double complex :: d,dd,den,fprt,frt,h,rt,t1,t2,t3, &
tem,z0,z1,z2,bi,xx,xl,y0,y1,y2,x0, & 104 104 tem,z0,z1,z2,bi,xx,xl,y0,y1,y2,x0, &
zero,p1,one,four,p5 105 105 zero,p1,one,four,p5
106 106
double complex, external :: f 107 107 double complex, external :: f
integer :: ickmax,kn,nguess,n,itmax,ier,knp1,knpn,i,l,ic, & 108 108 integer :: ickmax,kn,nguess,n,itmax,ier,knp1,knpn,i,l,ic, &
knpng,jk,ick,nn,lm1,errcode 109 109 knpng,jk,ick,nn,lm1,errcode
double complex :: x(kn+n) 110 110 double complex :: x(kn+n)
integer :: infer(kn+n) 111 111 integer :: infer(kn+n)
112 112
113 113
data zero/(0.0,0.0)/,p1/(0.1,0.0)/, & 114 114 data zero/(0.0d0,0.0d0)/,p1/(0.1d0,0.0d0)/, &
one/(1.0,0.0)/,four/(4.0,0.0)/, & 115 115 one/(1.0d0,0.0d0)/,four/(4.0d0,0.0d0)/, &
p5/(0.5,0.0)/, & 116 116 p5/(0.5d0,0.0d0)/, &
rzero/0.0/,rten/10.0/,rhun/100.0/, & 117 117 rzero/0.0d0/,rten/10.0d0/,rhun/100.0d0/, &
ax/0.1/,ickmax/3/,rp01/0.01/ 118 118 ax/0.1d0/,ickmax/3/,rp01/0.01d0/
119 119
ier = 0 120 120 ier = 0
if (n .lt. 1) then ! What the hell are doing here then ... 121 121 if (n .lt. 1) then ! What the hell are doing here then ...
return 122 122 return
end if 123 123 end if
!eps1 = rten **(-nsig) 124 124 !eps1 = rten **(-nsig)
eps1w = min(eps1,rp01) 125 125 eps1w = min(eps1,rp01)
126 126
knp1 = kn+1 127 127 knp1 = kn+1
knpn = kn+n 128 128 knpn = kn+n
knpng = kn+nguess 129 129 knpng = kn+nguess
do i=1,knpn 130 130 do i=1,knpn
infer(i) = 0 131 131 infer(i) = 0
if (i .gt. knpng) x(i) = zero 132 132 if (i .gt. knpng) x(i) = zero
end do 133 133 end do
l= knp1 134 134 l= knp1
135 135
ic=0 136 136 ic=0
rloop: do while (l<=knpn) ! Main loop over new roots 137 137 rloop: do while (l<=knpn) ! Main loop over new roots
jk = 0 138 138 jk = 0
ick = 0 139 139 ick = 0
xl = x(l) 140 140 xl = x(l)
icloop: do 141 141 icloop: do
ic = 0 142 142 ic = 0
h = ax 143 143 h = ax
h = p1*h 144 144 h = p1*h
if (cdabs(xl) .gt. ax) h = p1*xl 145 145 if (cdabs(xl) .gt. ax) h = p1*xl
! first three points are 146 146 ! first three points are
! xl+h, xl-h, xl 147 147 ! xl+h, xl-h, xl
rt = xl+h 148 148 rt = xl+h
call deflated_work(errcode) 149 149 call deflated_work(errcode)
if (errcode == 1) then 150 150 if (errcode == 1) then
exit icloop 151 151 exit icloop
end if 152 152 end if
153 153
z0 = fprt 154 154 z0 = fprt
y0 = frt 155 155 y0 = frt
x0 = rt 156 156 x0 = rt
rt = xl-h 157 157 rt = xl-h
call deflated_work(errcode) 158 158 call deflated_work(errcode)
if (errcode == 1) then 159 159 if (errcode == 1) then
exit icloop 160 160 exit icloop
end if 161 161 end if
162 162
z1 = fprt 163 163 z1 = fprt
y1 = frt 164 164 y1 = frt
h = xl-rt 165 165 h = xl-rt
d = h/(rt-x0) 166 166 d = h/(rt-x0)
rt = xl 167 167 rt = xl
168 168
call deflated_work(errcode) 169 169 call deflated_work(errcode)
if (errcode == 1) then 170 170 if (errcode == 1) then
exit icloop 171 171 exit icloop
end if 172 172 end if
173 173
174 174
z2 = fprt 175 175 z2 = fprt
y2 = frt 176 176 y2 = frt
! begin main algorithm 177 177 ! begin main algorithm
iloop: do 178 178 iloop: do
dd = one + d 179 179 dd = one + d
t1 = z0*d*d 180 180 t1 = z0*d*d
t2 = z1*dd*dd 181 181 t2 = z1*dd*dd
xx = z2*dd 182 182 xx = z2*dd
t3 = z2*d 183 183 t3 = z2*d
bi = t1-t2+xx+t3 184 184 bi = t1-t2+xx+t3
den = bi*bi-four*(xx*t1-t3*(t2-xx)) 185 185 den = bi*bi-four*(xx*t1-t3*(t2-xx))
! use denominator of maximum amplitude 186 186 ! use denominator of maximum amplitude
t1 = cdsqrt(den) 187 187 t1 = sqrt(den)
qz = rhun*max(cdabs(bi),cdabs(t1)) 188 188 qz = rhun*max(cdabs(bi),cdabs(t1))
t2 = bi + t1 189 189 t2 = bi + t1
tpq = cdabs(t2)+qz 190 190 tpq = cdabs(t2)+qz
if (tpq .eq. qz) t2 = zero 191 191 if (tpq .eq. qz) t2 = zero
t3 = bi - t1 192 192 t3 = bi - t1
tpq = cdabs(t3) + qz 193 193 tpq = cdabs(t3) + qz
if (tpq .eq. qz) t3 = zero 194 194 if (tpq .eq. qz) t3 = zero
den = t2 195 195 den = t2
qz = cdabs(t3)-cdabs(t2) 196 196 qz = cdabs(t3)-cdabs(t2)
if (qz .gt. rzero) den = t3 197 197 if (qz .gt. rzero) den = t3
! test for zero denominator 198 198 ! test for zero denominator
if (cdabs(den) .eq. rzero) then 199 199 if (cdabs(den) .eq. rzero) then
call trans_rt() 200 200 call trans_rt()
call deflated_work(errcode) 201 201 call deflated_work(errcode)
if (errcode == 1) then 202 202 if (errcode == 1) then
exit icloop 203 203 exit icloop
end if 204 204 end if
z2 = fprt 205 205 z2 = fprt
y2 = frt 206 206 y2 = frt
cycle iloop 207 207 cycle iloop
end if 208 208 end if
209 209
210 210
d = -xx/den 211 211 d = -xx/den
d = d+d 212 212 d = d+d
h = d*h 213 213 h = d*h
rt = rt + h 214 214 rt = rt + h
! check convergence of the first kind 215 215 ! check convergence of the first kind
if (cdabs(h) .le. eps1w*max(cdabs(rt),ax)) then 216 216 if (cdabs(h) .le. eps1w*max(cdabs(rt),ax)) then
if (ic .ne. 0) then 217 217 if (ic .ne. 0) then
exit icloop 218 218 exit icloop
end if 219 219 end if
ic = 1 220 220 ic = 1
z0 = y1 221 221 z0 = y1
z1 = y2 222 222 z1 = y2
z2 = f(rt) 223 223 z2 = f(rt)
xl = rt 224 224 xl = rt
ick = ick+1 225 225 ick = ick+1
if (ick .le. ickmax) then 226 226 if (ick .le. ickmax) then
cycle iloop 227 227 cycle iloop
end if 228 228 end if
! warning error, itmax = maximum 229 229 ! warning error, itmax = maximum
jk = itmax + jk 230 230 jk = itmax + jk
ier = 33 231 231 ier = 33
end if 232 232 end if
if (ic .ne. 0) then 233 233 if (ic .ne. 0) then
cycle icloop 234 234 cycle icloop
end if 235 235 end if
call deflated_work(errcode) 236 236 call deflated_work(errcode)
if (errcode == 1) then 237 237 if (errcode == 1) then
exit icloop 238 238 exit icloop
end if 239 239 end if
240 240
do while ( (cdabs(fprt)-cdabs(z2)*rten) .ge. rzero) 241 241 do while ( (cdabs(fprt)-cdabs(z2)*rten) .ge. rzero)
! take remedial action to induce 242 242 ! take remedial action to induce
! convergence 243 243 ! convergence
d = d*p5 244 244 d = d*p5
h = h*p5 245 245 h = h*p5
rt = rt-h 246 246 rt = rt-h
call deflated_work(errcode) 247 247 call deflated_work(errcode)
if (errcode == 1) then 248 248 if (errcode == 1) then
exit icloop 249 249 exit icloop
end if 250 250 end if
end do 251 251 end do
z0 = z1 252 252 z0 = z1
z1 = z2 253 253 z1 = z2
z2 = fprt 254 254 z2 = fprt
y0 = y1 255 255 y0 = y1
y1 = y2 256 256 y1 = y2
y2 = frt 257 257 y2 = frt
end do iloop 258 258 end do iloop
end do icloop 259 259 end do icloop
x(l) = rt 260 260 x(l) = rt
infer(l) = jk 261 261 infer(l) = jk
l = l+1 262 262 l = l+1
end do rloop 263 263 end do rloop
264 264
contains 265 265 contains
subroutine trans_rt() 266 266 subroutine trans_rt()
tem = rten*eps1w 267 267 tem = rten*eps1w
if (cdabs(rt) .gt. ax) tem = tem*rt 268 268 if (cdabs(rt) .gt. ax) tem = tem*rt
rt = rt+tem 269 269 rt = rt+tem
d = (h+tem)*d/h 270 270 d = (h+tem)*d/h
h = h+tem 271 271 h = h+tem
end subroutine trans_rt 272 272 end subroutine trans_rt
273 273
subroutine deflated_work(errcode) 274 274 subroutine deflated_work(errcode)
! errcode=0 => no errors 275 275 ! errcode=0 => no errors
! errcode=1 => jk>itmax or convergence of second kind achieved 276 276 ! errcode=1 => jk>itmax or convergence of second kind achieved
integer :: errcode,flag 277 277 integer :: errcode,flag
278 278
flag=1 279 279 flag=1
loop1: do while(flag==1) 280 280 loop1: do while(flag==1)
errcode=0 281 281 errcode=0
jk = jk+1 282 282 jk = jk+1
if (jk .gt. itmax) then 283 283 if (jk .gt. itmax) then
ier=33 284 284 ier=33
errcode=1 285 285 errcode=1
return 286 286 return
end if 287 287 end if
frt = f(rt) 288 288 frt = f(rt)
fprt = frt 289 289 fprt = frt
if (l /= 1) then 290 290 if (l /= 1) then
lm1 = l-1 291 291 lm1 = l-1
do i=1,lm1 292 292 do i=1,lm1
tem = rt - x(i) 293 293 tem = rt - x(i)
if (cdabs(tem) .eq. rzero) then 294 294 if (cdabs(tem) .eq. rzero) then
!if (ic .ne. 0) go to 15 !! ?? possible? 295 295 !if (ic .ne. 0) go to 15 !! ?? possible?
call trans_rt() 296 296 call trans_rt()
cycle loop1 297 297 cycle loop1