c
c Simulation of the Lorenz map
c        - Euler or Runge-Kutta (2nd order usual one)
c Fortran version written by H. Nakanishi, need to be compiled with "-lpepl".
c Line 89 was originally incorrect, corrected to "t1 = t(i-1)+0.5*dt"
c
	program lorenz
c
c       Declare the arrays we will need
c
	implicit real*8 (a-h,o-z)
	dimension x(500003),y(500003),z(500003),t(500003)
c
c       Use subroutines to do the work
c
	call initialize(x,y,z,t,sigma,r,b,dt,lsym,nsym,k,nstep,m,nout)
	call calculate(x,y,z,t,sigma,r,b,dt,lsym,nsym,k,nstep,m)
	if(nout.eq.1) then
		open(1,file='out.lorenz')
		rewind(1)
		do 10 i=1,nstep
			write(1,15) t(i),x(i),y(i),z(i)
10		continue
		close(1)
15		format(1x,1p,4(e12.5,1x))
	else
		call display(x,y,z,t,sigma,r,b,dt,lsym,nsym,k,nstep,m)
	endif
	stop
	end
c
	subroutine initialize(x,y,z,t,sigma,r,b,dt,lsym,nsym,k,n,m,nout)
c
c       Initialize variables
c
	implicit real*8 (a-h,o-z)
        dimension x(1),y(1),z(1),t(1)
	character ans,yes
	yes='y'
	print *,'Lorenz model: Euler (1) or Runge-Kutta [2nd ord] (2)?'
	read(5,*) m
	print *,'parameters: sigma, r, b ?'
	read(5,*) sigma,r,b
	print *,'initial x, y, z ?'
	read(5,*) x(1),y(1),z(1)
	print *,'time step, how many steps ?'
	read(5,*) dt,n
	t(1)=0
	print *,'record output to a file [out.lorenz] ?'
	read(5,14) ans
	if(ans.eq.yes) then
		nout=1
	else
		nout=2
		print *,'plot [z vs t,z vs x](1) or [x , y vs t](2)?'
		read(5,*) k
		if(k.ne.1.and.k.ne.2) then
			print *,'must select 1 or 2 ...'
			stop
		endif
		print *,'set line, symbol?'
		read(5,14) ans
14		format(a1)
		if(ans.eq.yes) then
			print *,'lsym, nsym ? -> '
			read(5,*) lsym,nsym
		else
			lsym=0
			nsym=1
		endif
	endif
	return
	end
c
	subroutine calculate(x,y,z,t,sigma,r,b,dt,lsym,nsym,k,nstep,m)
c
c       Now use Euler or Runge-Kutta (2nd order)
c
	implicit real*8 (a-h,o-z)
	dimension x(1),y(1),z(1),t(1)
	nstep=min(nstep,500000)
	if(m.eq.2) then
	   do 10 i = 2,nstep
		t(i) = t(i-1)+dt
		call dv(x(i-1),y(i-1),z(i-1),t(i-1),sigma,r,b,dx,dy,dz)
         	x1 = x(i-1)+0.5*dt*dx
         	y1 = y(i-1)+0.5*dt*dy
         	z1 = z(i-1)+0.5*dt*dz
		t1 = t(i-1)+0.5*dt
		call dv(x1,y1,z1,t1,sigma,r,b,dx,dy,dz)
		x(i)=x(i-1)+dt*dx
		y(i)=y(i-1)+dt*dy
		z(i)=z(i-1)+dt*dz
10	   continue
	else
	   do 20 i = 2,nstep
		t(i) = t(i-1)+dt
		call dv(x(i-1),y(i-1),z(i-1),t(i-1),sigma,r,b,dx,dy,dz)
         	x(i) = x(i-1)+dt*dx
         	y(i) = y(i-1)+dt*dy
         	z(i) = z(i-1)+dt*dz
20	   continue
	endif
	return
	end
c
	subroutine dv(x0,y0,z0,t0,sigma,r,b,dx,dy,dz)
	implicit real*8 (a-h,o-z)
	dx=sigma*(y0-x0)
	dy=-x0*z0+r*x0-y0
	dz=x0*y0-b*z0
	return
	end
c
	subroutine display(x,y,z,t,sigma,r,b,dt,lsym,nsym,k,n,m)
c
c       First set up title and label axes for graph. Plotting is a lot
c       of work in fortran.
c       This version displays output as well as writes to a file "graph.out".
c
	implicit real*8 (a-h,o-z)
	dimension x(1),y(1),z(1),t(1)
	real u(n+3),v(n+3),fac,pos,s1,r1,b1,dt1
	s1=sigma
	r1=r
	b1=b
	dt1=dt
	fac=0.8
	pos=10.2
	call usrmon(.true.,.false.,-0.5,9.,-0.5,12.)
	call pltlun(19,.true.,.false.)
	call pltlfn('graph.out')
	call plots
	call factor(fac)
	call plot(0.,1.,-3)
	if(m.eq.2) then
		call text(0.2,pos,0.2,'Lorenz: Runge-Kutta2',0.,20,0)
	else
		call text(0.2,pos,0.2,'Lorenz: Euler',0.,13,0)
	endif
	if(k.eq.1) then
		do 15 i=1,n
			u(i)=x(i)
			v(i)=z(i)
15		continue
		call text(0.2,4.0,0.2,'z vs x',0.,6,0)
		call scalex(u,6.,n,1)
		call axctl(0.15,0.04,0.15,0.2,0.2,-1)
		call axisx(0.,0.,'x',-1,6.,0.,u(n+1),u(n+2),u(n+3),4)
		call axisx(0.,3.5,' ',1,6.,0.,u(n+1),u(n+2),u(n+3),20)
		call scalex(v,3.5,n,1)
		call axctl(0.15,0.04,0.15,0.2,0.2,2)
		call axisx(0.,0.,'z',1,3.5,90.,v(n+1),v(n+2),v(n+3),-5)
	call axisx(6.,0.,' ',-1,3.5,90.,v(n+1),v(n+2),v(n+3),-21)
		call line(u,v,n,1,lsym,nsym)
		call number(0.5,3.7,0.1,s1,0.,'''sigma = '',f4.1')
		call number(1.7,3.7,0.1,r1,0.,'''r = '',f6.2')
		call number(2.7,3.7,0.1,b1,0.,'''b = '',f10.7')
		call number(4.1,3.7,0.1,dt1,0.,'''dt = '',f7.4')
		call plot(0.,5.5,-3)
		do 25 i=1,n
			u(i)=t(i)
25		continue
		call text(0.2,4.0,0.2,'z vs Time',0.,9,0)
		call scalex(u,6.,n,1)
		call axctl(0.15,0.04,0.15,0.2,0.2,-1)
		call axisx(0.,0.,'Time (s)',-8,6.,0.,
     c  	u(n+1),u(n+2),u(n+3),4)
		call axisx(0.,3.5,' ',1,6.,0.,u(n+1),u(n+2),u(n+3),20)
		call axctl(0.15,0.04,0.15,0.2,0.2,2)
		call axisx(0.,0.,'z',1,3.5,90.,v(n+1),v(n+2),v(n+3),-5)
		call axisx(6.,0.,' ',-1,3.5,90.
     c		,v(n+1),v(n+2),v(n+3),-21)
		call line(u,v,n,1,lsym,nsym)
		call number(0.5,3.7,0.1,s1,0.,'''sigma = '',f4.1')
		call number(1.7,3.7,0.1,r1,0.,'''r = '',f6.2')
		call number(2.7,3.7,0.1,b1,0.,'''b = '',f10.7')
		call number(4.1,3.7,0.1,dt1,0.,'''dt = '',f7.4')
	else
		do 35 i=1,n
			u(i)=t(i)
			v(i)=y(i)
35		continue
		call text(0.2,3.9,0.2,'y vs Time',0.,9,0)
		call scalex(u,6.,n,1)
		call axctl(0.15,0.04,0.15,0.2,0.2,-1)
		call axisx(0.,0.,'Time (s)',-8,6.,0.,u(n+1),u(n+2),u(n+3),4)
		call axisx(0.,3.5,' ',1,6.,0.,u(n+1),u(n+2),u(n+3),20)
		call scalex(v,3.5,n,1)
		call axctl(0.15,0.04,0.15,0.2,0.2,2)
		call axisx(0.,0.,'y',1,3.5,90.,v(n+1),v(n+2),v(n+3),-5)
	call axisx(6.,0.,' ',-1,3.5,90.,v(n+1),v(n+2),v(n+3),-21)
		call line(u,v,n,1,lsym,nsym)
		call number(0.5,3.7,0.1,s1,0.,'''sigma = '',f4.1')
		call number(1.7,3.7,0.1,r1,0.,'''r = '',f6.2')
		call number(2.7,3.7,0.1,b1,0.,'''b = '',f10.7')
		call number(4.1,3.7,0.1,dt1,0.,'''dt = '',f7.4')
		call plot(0.,5.5,-3)
		do 45 i=1,n
			v(i)=x(i)
45		continue
		call text(0.2,3.9,0.2,'x vs Time',0.,9,0)
		call axctl(0.15,0.04,0.15,0.2,0.2,-1)
		call axisx(0.,0.,'Time (s)',-8,6.,0.,
     c  	u(n+1),u(n+2),u(n+3),4)
		call axisx(0.,3.5,' ',1,6.,0.,u(n+1),u(n+2),u(n+3),20)
		call scalex(v,3.5,n,1)
		call axctl(0.15,0.04,0.15,0.2,0.2,2)
		call axisx(0.,0.,'x',1,3.5,90.,v(n+1),v(n+2),v(n+3),-5)
		call axisx(6.,0.,' ',-1,3.5,90.
     c		,v(n+1),v(n+2),v(n+3),-21)
		call line(u,v,n,1,lsym,nsym)
		call number(0.5,3.7,0.1,s1,0.,'''sigma = '',f4.1')
		call number(1.7,3.7,0.1,r1,0.,'''r = '',f6.2')
		call number(2.7,3.7,0.1,b1,0.,'''b = '',f10.7')
		call number(4.1,3.7,0.1,dt1,0.,'''dt = '',f7.4')
	endif
	call plot(0.,0.,999)
	return
	end

