2016-06-15 14 views
1

저는 이중 정밀도로 숫자를 제공하는 Mersenne Twister 구현을 사용하고 있습니다.배정 밀도를 단 정밀도로 반올림 : 상한을 강제로 설정합니다.

http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/VERSIONS/FORTRAN/fortran.html 다른 정밀도, 단 정밀도 임의의 숫자와 숫자를 곱하면서 경고를 방지하기 위해, 그러나

내 응용 프로그램의 요구를 (츠요시 타다으로 포트란 77에서 구현, 나는 genrand_real2을 사용하고 있습니다). 그래서, 나는 두 개의 데이터 형식 사이의 변환 작은 기능을 썼다 :

function genrand_real() 

    real genrand_real 
    real*8 genrand_real2 

    genrand_real = real(genrand_real2()) 

    return 
    end 

는 내가 일하고 있어요 코드와 일치하는 실제 8 * 실제 사용하고 있습니다. 변환은 [0,1]을 [0 (으)로 변경하기 때문에 실제 RNG의 상한선을 변경하지만 실제로는 거의 완벽하게 작동합니다. ,1]. 나는 그것에 대해 문제가 생길 때까지는 그런 생각을하지 못했습니다.

제 질문은 어떻게 효율적으로 상한을 보장 할 수 있습니까? 또는 심지어 단 정밀도의 실수를 제공하는 genrand_real2 (원래의 함수)와 비슷한 함수를 작성할 수 있습니까? 받는 사람 (genrand_int32()에서) 그것을에만 제한 임의의 정수를, 내 생각 엔 난 단지 제수 4294967296.d0를 교체해야 되나하는 수

function genrand_real2() 

    double precision genrand_real2,r 
    integer genrand_int32 
    r=dble(genrand_int32()) 
    if(r.lt.0.d0)r=r+2.d0**32 
    genrand_real2=r/4294967296.d0 

    return 
    end 

답변

1

하여 게시 기능은 임의의 숫자를 생성하지 않습니다 모르겠어요 간격이 2^32 (정확히 4294967296)로 나누거나 int가 음수이면 처음으로 2^32를 더하여 간격 [0,1] 2^32는 표준 정수가 보유 할 수있는 값의 수입니다. 절반은 음수이고 다른 하나는 양수입니다 (약 1 개의 양수가 누락 됨). 따라서 genrand_int32() 함수에서옵니다.

-10에서 10까지의 숫자가 있고이를 [0,1] 간격으로 제한하려고한다고 가정 해보십시오. 가장 쉬운 해결책은 음수에 20을 더하는 것입니다 (양수가 0-10이고 음수가 10-20이됩니다). 정확히 10 기수 대신 2^31을 사용합니다.

기능 간격이 [0, 1] 인 이유가 궁금한 경우 : 숫자 0도 지점이 필요하고 비트 표현은 2^32 숫자 만 저장할 수 있기 때문에 2^31 음수와 2^31 양수 및 0입니다. 해답은 값 + 2^31 (가장 높은 양의 값)을 버리므로 결과적으로 1이 해당 간격에서 제외됩니다.

그래서 단일 precission까지 모든 일을 가지고 : 그들은 정수가 아닌 실수 관련이 있기 때문에

function genrand_real2() 

real genrand_real2,r 
integer genrand_int32 
r=real(genrand_int32()) 
if(r.lt.0)r=r+2**32 
genrand_real2=r/4294967296 

return 
end 

마법의 숫자는 동일하게 유지해야합니다.

편집 : 이미 스스로를했다, 그래서 난 그냥 다른 사람들을 위해 반복하는거야 : 이식성을 기술적으로 정밀도를 지정하지 않고 기본 유형을 사용하는 것은 좋지 않습니다. 따라서 sp = selected_real_kind(6, 37) (단 정밀도의 경우 sp) 어딘가에 real(kind=sp)...2.0_sp 등을 사용해야합니다. 그러나 이것은 더 많은 학문적 인 부분입니다.

+0

대단히 감사합니다! 당신은 내 문제를 해결할뿐만 아니라 내 프로그램을 훨씬 빨리 만들었습니다. mt19937 경과 : 11.5120001, 사용자 : 11.5120001, sys : 0.00000000 mt19937 단 정밀도 경과 : 4.83599997, 사용자 : 4.83599997, sys : 0.00000000 –

+0

안녕하세요. 그것은 단순히 더 높은 정밀도를 사용하지 않는 것의 효과입니다. 단점이 있습니다. http://stackoverflow.com/a/17951021/ (C#의 개념이지만 개념은 같습니다)을 참조하십시오. 그러나 나머지 프로그램이 단정도의 실수라면 어쨌든 중요하지 않습니다. – StefanS

+0

귀하의 도움에 감사 드리며, "그 사람"이되어서 미안하지만, 다음과 같은 질문이 있습니다. http://stackoverflow.com/questions/37859027/upper-bound-of-random-number-generator –