What's wrong with my random number generator in Fortran 95 please?

后端 未结 1 1059
南方客
南方客 2020-12-21 02:24

This a randon number generator module that I use to compile along with my main program (not listed here) When I try to compile my random number generator module to see if it

相关标签:
1条回答
  • 2020-12-21 03:05

    When the compiler says

    Error: size of 'put' argument of 'random_seed' intrinsic too small <4/12>

    it means that the size of your variable seed is too small.

    In this case you have seed of size 4 (and I guess the compiler must be expecting (at least) 12).

    The size of the array must be of a certain size which depends on the compiler. You can determine, portably, the required size by a call to random_seed with another argument

    integer seed_size
    integer, allocatable :: seed(:)
    
    call random_seed(size=seed_size)
    allocate(seed(seed_size))
    seed = ...
    call random_seed(put=seed)
    

    As Vladimir F points out in a comment, the gfortran document itself has an example of this approach.

    If you don't care about portable, you could just use an array of size 12 with your choice of values.


    As more advanced reading, I'll say another thing. The example I gave above really wasn't very comparable to your code. That is, you say that the input to the seed setting subroutine is guaranteed to be at least of size 4 and it may, or may not, contain values you want to use as seed.

    As I noted above, you could change that to 12, but that isn't portable. If you want to be portable things get more awkward.

    integer, dimension(4), intent(inout):: seed
    

    has as dummy argument an explicit shape array of size 4. The actual argument in the main program is an array at least that size. However, this size is a specification expression and, alas, call random_seed(size=seed_size) doesn't give us something we can use in a specification expression.

    Perhaps something like

    subroutine setSEED (seed)
      integer, allocatable, intent(inout) :: seed(:)
      integer seed_size
    
      ! Determine the correct size for the seed
      call random_seed(size=seed_size)
    
      ! If our seed isn't set, or is too small, kill it.
      if (ALLOCATED(seed)) then
        if (SIZE(seed)<seed_size.or.seed(LBOUND(seed,1))==0.) deallocate(seed)
      end if
    
      ! If seed isn't allocated (perhaps we killed it because it was too small)
      ! then allocate it to the correct size and initialize it.
      if (.not.ALLOCATED(seed)) then
        allocate(seed(seed_size))
        seed = ...  ! Our fallback seed initialization
      end if
    
      ! Finally, put the seed.  Using one we set, or the one originally given.
      call random_seed(put=seed)
    
    end subroutine
    

    This, of course, requires that the actual argument be allocatable, but if you're handling portable seed setting that's a good thing.

    0 讨论(0)
提交回复
热议问题