      PROGRAM qmwalk
      IMPLICIT NONE
      REAL*8 Esum, Vave, Vref, binsize, ds, dt, psi(-500:500), x(2000)
      INTEGER IR_, N, N0, i, imcs, mcs, nequil
      DATA psi, x/3001*0.0D0/
      CALL GWopen(IR_, 0)
      CALL initial(x,N,N0,Vref,binsize,ds,dt,mcs,nequil,Esum)
      DO i = 1, nequil                      ! 平衡化
         CALL walk(x,N,N0,Vref,Vave,ds,dt)
      END DO
      DO imcs = 1, mcs
         CALL walk(x,N,N0,Vref,Vave,ds,dt)
         CALL mydata(x,psi,N,Vref,Vave,Esum,imcs,binsize)
      END DO
      CALL plot_psi(psi,binsize)
      CALL GWquit(IR_)
      END
C
      SUBROUTINE initial(x,N,N0,Vref,binsize,ds,dt,mcs,nequil,Esum)
      IMPLICIT NONE
      REAL*8 width, x(2000), Vref, binsize, ds, dt, Esum, V
      REAL dmy, rnd
      INTEGER IR_, i, N, N0, mcs, nequil
      dmy = rnd(-1)
      WRITE(*,'(A,$)') 'desired number of walkers = '
      READ(*,*) N0
      WRITE(*,'(A,$)') 'step length = '
      READ(*,*) ds
      dt = ds*ds                            ! 時間刻み
      WRITE(*,'(A,$)') 'number of Monte Carlo steps per walker = '
      READ(*,*) mcs
      nequil = int(0.4D0*mcs)
*     初期の粒子数は任意に選ぶ
      N = N0
*     粒子の初期位置はランダムに選ぶ
      width = 1                             ! 粒子の領域の初期幅
      Vref = 0
      DO i = 1, N
         x(i) = (2*rnd(0) - 1)*width
         Vref = Vref + V(x(i))
      END DO
      Vref = Vref/N
      binsize = 2*ds                        ! 配列 psi に対応する区分け用の箱の幅
      Esum = 0
      CALL GWclear(IR_, -1)
      WRITE(*,'(4A12)') 'MC steps', 'N', 'E', 'Vref'
      WRITE(*,*)
      END
C
      SUBROUTINE walk(x,N,N0,Vref,Vave,ds,dt)
      IMPLICIT NONE
      REAL*8 Nin, Vsum, dV, potential, x(2000), Vref, Vave, ds, dt, V
      REAL rnd
      INTEGER i, N, N0
      Nin = N                               ! 試行の初めにおける粒子数
      Vsum = 0
      DO i = Nin, 1, -1
         IF(rnd(0) .LT. 0.5D0) THEN
            x(i) = x(i) + ds
         ELSE
            x(i) = x(i) - ds
         END IF
         potential = V(x(i))                ! x でのポテンシャル
         dV = potential - Vref
         IF(dV .LT. 0) THEN
            IF(rnd(0) .LT. -dV*dt) THEN
               N = N + 1
               x(N) = x(i)                  ! 新しい粒子
*              係数 2 は x に 2 個の粒子があるため
               Vsum = Vsum + 2*potential
            ELSE
               Vsum = Vsum + potential      ! 古い粒子のみ
            END IF
         ELSE
            IF(rnd(0) .LT. dV*dt) THEN
               x(i) = x(N)
               N = N - 1
            ELSE
               Vsum = Vsum + potential
            END IF
         END IF
      END DO
      Vave = Vsum/N                         ! 平均ポテンシャル
      Vref = Vave - (N - N0)/(N0*dt)        ! 新しい参照エネルギー
      END
C
      SUBROUTINE mydata(x,psi,N,Vref,Vave,Esum,imcs,binsize)
      IMPLICIT NONE
      REAL*8 x(2000), psi(-500:500), Vref, Vave, Esum, binsize
      INTEGER bin, i, N, imcs
*     データを積算する
      Esum = Esum + Vave
*     粒子を'箱'に入れる
      DO i = 1, N
         bin = int(x(i)/binsize)
         psi(bin) = psi(bin) + 1
      END DO
      IF(mod(imcs,10) .EQ. 0) THEN
         WRITE(*, '(I12,I12,F12.3,F12.3)') 
     +            imcs, N, Esum/imcs, Vref
      END IF
      END
C
      SUBROUTINE plot_psi(psi,binsize)
      IMPLICIT NONE
      REAL*8 P, norm, pmax, sum, ymax, psi(-500:500), binsize
      INTEGER IR_, i, imax
      LOGICAL Ltmp1_
      i = 0
      pmax = psi(i)*psi(i)
      sum = pmax
      Ltmp1_ = .TRUE.
      DO WHILE(Ltmp1_)
         i = i + 1
         P = psi(i)*psi(i) + psi(-i)*psi(-i)
         IF(P .GT. pmax) pmax = P
         sum = sum + P
         Ltmp1_ = P .NE. 0
      END DO
      imax = i
      norm = sqrt(sum*binsize)
      ymax = sqrt(pmax)/norm
      CALL GWindow(IR_, REAL(-imax), REAL(-0.1D0*ymax), REAL(imax)
     +, REAL(1.1D0*ymax))
      CALL GWline(IR_, REAL(-imax), 0.0, REAL(imax), 0.0)
      DO i = -imax, imax
         CALL GWline(IR_, REAL(i-1), REAL(psi(i-1)/norm), REAL(i)
     +   , REAL(psi(i)/norm))
      END DO
      END
C
      FUNCTION V(x)
      IMPLICIT NONE
      REAL*8 V, x
      V = 0.5D0*x*x
      END
