Weighted sampling in Fortran

2019-07-09 02:45发布

问题:

I'm newbee in Fortran and I would like to choose at random a specific variable (specifically its index) by using weights. The weights would be provided in a separate vector (element 1 would contain weight of variable 1 and so on).

I have the following code who does the job without weight (mind being an integer vector with the index of each variable in the original dataset)

call rrand(xrand)
j = int(nn * xrand) + 1
mvar = mind(j)

Thank you for your help!

回答1:

Here are two examples. The first one is

integer, parameter :: nn = 5
real :: weight( nn ), cumsum( nn ), x

weight( 1:nn ) = [ 1.0, 2.0, 5.0, 0.0, 2.0 ]

do j = 1, nn
    cumsum( j ) = sum( weight( 1:j ) ) / sum( weight( 1:nn ) )   !! cumulative sum
enddo

x = rand()
do j = 1, nn
    if ( x < cumsum( j ) ) exit
enddo

and the second one is taken from this page

real :: sum_weight
sum_weight = sum( weight( 1:nn ) )

x = rand() * sum_weight
do j = 1, nn
    if ( x < weight( j ) ) exit
    x = x - weight( j )
enddo

which is essentially the same as the first one. Both sample a random j from 1,2,...,5 with weight(j). 100000 trials give a distribution like

j     :    1           2           3           4       5
count :    10047       19879       50061       0       20013