c=========================================================================== c c This file is part of TISEAN c c Copyright (c) 1998-2007 Rainer Hegger, Holger Kantz, Thomas Schreiber c c TISEAN is free software; you can redistribute it and/or modify c it under the terms of the GNU General Public License as published by c the Free Software Foundation; either version 2 of the License, or c (at your option) any later version. c c TISEAN is distributed in the hope that it will be useful, c but WITHOUT ANY WARRANTY; without even the implied warranty of c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the c GNU General Public License for more details. c c You should have received a copy of the GNU General Public License c along with TISEAN; if not, write to the Free Software c Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA c c=========================================================================== c locate unstable periodic points c author T. Schreiber (1998) c=========================================================================== parameter(nx=1000000,mper=20) dimension x(nx) character*72 file, fout common /period/ x, nmax, m, eps data frac/0./, iper/1/, teq/-1./, tdis/-1./, tacc/-1./, h/-1./ data iverb/1/ call whatido("locate unstable periodic points",iverb) m=max(imust("m"),1) eps=fcan("r",0.) frac=fcan("v",frac) teq=fcan("w",teq) tdis=fcan("W",tdis) h=fcan("s",h) tacc=fcan("a",tacc) iper=ican("p",iper) nmaxx=ican("l",nx) nexcl=ican("x",0) jcol=ican("c",0) icen=ican("n",nmaxx) isout=igetout(fout,iverb) if(eps.eq.0.and.frac.eq.0.) call usage() do 10 ifi=1,nstrings() call nthstring(ifi,file) nmax=nmaxx call readfile(nmax,x,nexcl,jcol,file,iverb) if(file.eq."-") file="stdin" if(isout.eq.1) call addsuff(fout,file,"_upo_") call rms(nmax,x,sc,sd) if(frac.gt.0) eps=sd*frac if(teq.lt.0.) teq=eps if(tdis.lt.0.) tdis=eps if(tacc.lt.0.) tacc=eps if(h.lt.0.) h=eps if(isout.eq.1) . write(fout(index(fout,"_upo_")+5:72),'(i2.2)') iper call outfile(fout,iunit,iverb) call findupo(iper,icen,teq,tdis,tacc,h,iunit,iverb) 10 if(iunit.ne.istdout()) close(iunit) end subroutine usage() c usage message call whatineed( . "-m# [-r# | -v#] [-p# -w# -W# -a# -s# -n#"// . " -o outfile -l# -x# -c# -V# -h] file(s)") call ptext("either -r or -v must be present") call popt("m","embedding dimension") call popt("r","absolute kernel bandwidth") call popt("v","same as fraction of standard deviation") call popt("p","period of orbit (1)") call popt("w","minimal separation of trial points (e)") call popt("W","minimal separation of distinct orbits (e)") call popt("a", . "maximal error of orbit to be plotted (all plotted)") call popt("s","initial separation for stability (e)") call popt("n","number of trials (all points)") call popt("l","number of values to be read (all)") call popt("x","number of values to be skipped (0)") call popt("c","column to be read (1 or file,#)") call pout("file_upo_pp") call pall() call ptext("Verbosity levels (add what you want):") call ptext(" 1 = input/output" ) call ptext(" 2 = print orbits found") call ptext(" 4 = status after 1000 points") call ptext(" 8 = status after 100 points") call ptext(" 16 = status after 10 points") stop end subroutine findupo(iper,icen,teq,tdis,tacc,h,iunit,iverb) parameter(nx=1000000,mper=20) external peri dimension x(nx),xp(mper),fvec(mper),xor(mper,nx), . iw(mper),w0(mper,mper),w1(mper),w2(mper),w3(mper), . w4(mper),w5(mper),w6(mper) common /period/ x, nmax, m, eps if(iper.gt.mper) stop "findupo: make mper larger." tol=sqrt(r1mach(4)) itry=0 ior=0 do 10 n=iper,nmax if(iv_10(iverb).eq.1) then if(mod(n,10).eq.0) write(istderr(),'(i7)') n else if(iv_100(iverb).eq.1) then if(mod(n,100).eq.0) write(istderr(),'(i7)') n else if(iv_1000(iverb).eq.1) then if(mod(n,1000).eq.0) write(istderr(),'(i7)') n endif if(known(n,iper,teq).eq.1) goto 10 itry=itry+1 if(itry.gt.icen) return do 20 i=1,iper 20 xp(i)=x(n-iper+i) call snls1(peri,1,iper,iper,xp,fvec,w0,mper,tol,tol,0., . 20*(iper+1),0.,w1,1,100.,0,info,nfev,ndum,iw,w2,w3,w4,w5,w6) err=enorm(iper,fvec) if(info.eq.-1.or.info.eq.5.or.err.gt.tacc) goto 10 ! unsuccessfull if(isold(iper,xp,ior,xor,tdis).eq.1) goto 10 ! already found ior=ior+1 ! a new orbit do 30 i=1,iper 30 xor(i,ior)=xp(i) ipor=iperiod(iper,xp,tdis) sor=ipor*stab(iper,xp,h)/real(iper) call print(iper,xp,ipor,sor,err,iunit,iverb) 10 continue end function known(n,iper,tol) c return 1 if equivalent starting point has been tried parameter(nx=1000000) dimension x(nx) common /period/ x, nmax, m, eps known=1 do 10 nn=iper,n-1 dis=0 do 20 i=1,iper 20 dis=dis+(x(n-iper+i)-x(nn-iper+i))**2 10 if(sqrt(dis).lt.tol) return known=0 end function isold(iper,xp,ior,xor,toler) c determine if orbit is in data base parameter(mper=20) dimension xp(iper), xor(mper,*) isold=1 do 10 ip=1,iper do 20 io=1,ior dor=0 do 30 i=1,iper 30 dor=dor+(xp(i)-xor(i,io))**2 20 if(sqrt(dor).le.toler) return 10 call oshift(iper,xp) isold=0 end subroutine oshift(iper,xp) c leftshift orbit circularly by one position dimension xp(*) h=xp(1) do 10 i=1,iper-1 10 xp(i)=xp(i+1) xp(iper)=h end function iperiod(iper,xp,tol) c determine shortest subperiod dimension xp(*) do 10 iperiod=1,iper dis=0 do 20 i=1,iper il=i-iperiod if(il.le.0) il=il+iper 20 dis=dis+(xp(i)-xp(il))**2 10 if(sqrt(dis).le.tol) return end subroutine peri(iflag,mf,iper,xp,fvec,fjac,ldfjac) c built discrepancy vector (as called by snls1) dimension xp(*),fvec(*) do 10 ip=1,iper fvec(ip)=xp(1)-fc(iper,xp,iflag) 10 call oshift(iper,xp) end function fc(iper,xp,iflag) c predict (cyclic) point 1, using iper,iper-1... parameter(nx=1000000) dimension xp(*), x(nx) common /period/ x, nmax, m, eps data cut/20/ eps2=1./(2*eps*eps) ft=0 sw=0 fc=0 do 10 n=m+1,nmax dis=0 do 20 i=1,m 20 dis=dis+(x(n-i)-xp(mod(m*iper-i,iper)+1))**2 ddis=dis*eps2 w=0 if(ddis.lt.cut) w=exp(-ddis) ft=ft+w*x(n) 10 sw=sw+w iflag=-1 if(sw.eq.0) return ! fc undefined, stop minimising fc=ft/sw iflag=1 end function stab(ilen,xp,h) c compute cycle stability by iteration of a tiny perturbation parameter(nx=1000000,mper=20,maxit=1000) dimension xp(*), x(nx), xcop(mper) common /period/ x, nmax, m, eps if(mper.lt.ilen) stop "stability: make mper larger." iflag=1 stab=0 do 10 i=2,m 10 xcop(i)=xp(mod(i-1,ilen)+1) xcop(1)=xp(1)+h do 20 it=1,maxit do 30 itt=1,ilen xx=fc(m,xcop,iflag) if(iflag.eq.-1) goto 1 call oshift(m,xcop) 30 xcop(m)=xx dis=0 do 40 i=1,m 40 dis=dis+(xcop(i)-xp(mod(i-1,ilen)+1))**2 dis=sqrt(dis) stab=stab+log(dis/h) do 20 i=1,m 20 xcop(i)=xp(mod(i-1,ilen)+1)*(1-h/dis) + xcop(i)*h/dis 1 stab=stab/max(it-1,1) end subroutine print(iper,xp,ipor,sor,err,iunit,iverb) c write orbit to iunit and to stdout dimension xp(*) write(iunit,*) write(iunit,*) "period / accuracy / stability" write(iunit,*) ipor, err, exp(sor) do 10 i=1,ipor 10 write(iunit,*) i, xp(i) if(iv_upo(iverb).eq.0) return write(istderr(),*) write(istderr(),*) "period / accuracy / stability" write(istderr(),*) ipor, err, exp(sor) do 20 i=1,ipor 20 write(istderr(),*) i, xp(i) end