m_random.F90 1.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051
  1. module m_random
  2. contains
  3. subroutine random(work1,n)
  4. ! Returns a vector of random values N(variance=1,mean=0)
  5. implicit none
  6. integer, intent(in) :: n
  7. real, intent(out) :: work1(n)
  8. real, allocatable :: work2(:)
  9. real, parameter :: pi=3.141592653589
  10. allocate (work2(n))
  11. call random_number(work1)
  12. call random_number(work2)
  13. work1= sqrt(-2.0*log(work1))*cos(2.0*pi*work2)
  14. deallocate(work2)
  15. end subroutine random
  16. subroutine randn(n, vect)
  17. implicit none
  18. integer, intent(in) :: n
  19. real, intent(out) :: vect(n)
  20. integer :: i
  21. real :: a(2), r
  22. i = 0
  23. do while (i < n)
  24. call random_number(a)
  25. a = 2.0 * a - 1.0
  26. r = a(1) * a(1) + a(2) * a(2)
  27. if (r > 1.0) then
  28. cycle
  29. end if
  30. i = i + 1
  31. ! assume that r is never equal to 0 - PS
  32. r = sqrt(-2.0 * log(r) / r);
  33. vect(i) = r * a(1);
  34. if (i == n) then
  35. exit
  36. end if
  37. i = i + 1
  38. vect(i) = r * a(2);
  39. end do
  40. end subroutine randn
  41. end module m_random