view main/system-identification/devel/tisean/source_f/upo.f @ 9894:82ff20b4d849 octave-forge

system-identitifaction: Adding devel TISEAN files
author jpicarbajal
date Wed, 28 Mar 2012 13:32:37 +0000
parents
children
line wrap: on
line source

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