상자 뮬러 알고리즘을 사용하여 더 많은 난수를 계산하는 함수로 lcg를 사용하는 프로그램을 작성하려고합니다. lcg를 작동 시켰지만 상자 뮬러 알고리즘을 사용하는 함수가 잘못된 값을 제공합니다.이 코드가 나에게 잘못된 대답을주는 이유는 무엇입니까?
module rng
implicit none
integer, parameter :: dp = selected_real_kind(15,300)
real(kind=dp) :: A=100, B= 104001, M = 714025
contains
function lcg(seed)
integer, optional, intent(in) :: seed
real(kind=dp) :: x = 0, lcg
if(present(seed)) x = seed
x = mod(A * x + B, M)
lcg = x/714025
end function
function muller(seed)
integer, parameter :: dp = selected_real_kind(15,300)
integer, optional, intent(in) :: seed
real(kind = dp) :: y1, y2, mean = 0.49, sd = 0.5, muller1, muller2,
muller, x1, x2, pi = 4.0*ATAN(1.0)
integer :: N = 0
! I had to add the do while loop to ensure that this chunk of code would
only execute once
do while (N<1)
x1 = lcg()
x2 = lcg()
N = N + 1
y1 = sd * SQRT(-2.0*LOG(x1)) * COS(2*pi*(x2)) + mean
y2 = sd * SQRT(-2.0*LOG(x1)) * SIN(2*pi*(x2)) + mean
print *, y1, y2, x1, x2 ! Printing x1 and x2 to allow me to use a
calculator to check program is working correctly
end do
end function
end module
program lcgtest
use rng
implicit none
integer :: N
real(kind=dp) :: lcgmean, ttl = 0, sumof, lcgvar, dev1, muller1, muller2,
lcgerr, lcgdev
real, dimension(10000) :: array
do N = 1, 10000
ttl = ttl + lcg()
dev1 = lcg() - lcgmean
sumof = sumof + dev1
end do
muller1 = muller()
muller2 = muller()
lcgmean = ttl/10000
lcgvar = ((sumof)**2)/10000
lcgdev = SQRT((sumof)**2)/10000
lcgerr = lcgdev/100
print *, lcg(), "mean=", lcgmean, "variance=", lcgvar, lcgerr
end program
의 핵심 부분은 뮬러 기능 섹션 :
여기 내 코드입니다. 계산기로 얻은 값을 확인한 후에, y1과 y2에 대한 답이 다른 것을 볼 수 있습니다.
도움을 주시면 감사하겠습니다.
[ask]를 읽으십시오. 어떤 대답을 줄 수 있습니까? 어떤 대답을 기대합니까? 왜? –
'y1'과'y2'는 지역 변수이므로 함수 결과에 할당하지 마십시오. 그 대답이지만, 도움이 될만한 것은 아닙니다. 함수가 어떻게 작동하는지에 대한 근본적인 이해가 많이 빠져있는 것처럼 보입니다. 좀 더 간단한 문제를 제시 할 수 있습니까? – francescalus
호기심, 왜 모듈 수준에서'double (kind = dp), parameter :: pi = 4.0 * ATAN (1.0)'을하지 않았습니까? 그래서 매번 다시 계산되지 않습니까? – ja72