module SDEClass use RandomClass use ArrayClass use MathClass implicit none integer(int32) :: PF_SDE_GeometricBrown = 1 type :: SDE_ real(real64), allocatable :: process(:) real(real64) :: c = 0.0d0 real(real64) :: sigma = 0.0d0 integer(int32) :: SDEType = 0 contains procedure, public :: init => initSDE procedure, public :: solve => solveSDE end type contains subroutine initSDE(obj, SDEType, c, sigma) class(SDE_), intent(inout) :: obj integer(int32), intent(in) :: SDEType real(real64), optional, intent(in) :: c, sigma if (SDEType == PF_SDE_GeometricBrown) then ! Geometric Brown Motion if (.not. present(c)) then print *, "ERROR :: initSDE >> arg c is necessary." stop end if if (.not. present(sigma)) then print *, "ERROR :: initSDE >> arg sigma is necessary." stop end if obj%c = c obj%sigma = sigma obj%SDEType = PF_SDE_GeometricBrown end if end subroutine function solveSDE(obj, X0, dt, step) result(ret) class(SDE_), intent(inout) :: obj real(real64), intent(in) :: X0, dt integer(int32), intent(in) :: step real(real64) ::t, Bt real(real64), allocatable :: ret(:) integer(int32) :: n, i type(Random_) :: random if (obj%SDEType == PF_SDE_GeometricBrown) then ! Geometric Brown Motion n = step ret = zeros(n) Bt = 0.0d0 t = 0.0d0 ret(1) = X0 do i = 2, n t = t + dt Bt = Bt + random%gauss(mu=0.0d0, sigma=1.0d0) ret(i) = X0*exp((obj%c - 0.50d0*obj%sigma*obj%sigma)*t + obj%sigma*Bt) end do end if end function end module SDEClass