Capping random numbers for filtering in CustomRuleNumpy transition
Created by: VolodyaCO
When using the MetropolisCustom
sampler, the CustomRuleNumpy
makes transitions based on the move operators passed to MetropolisCustom
. This makes use of the operator's get_conn_filtered
method, for which a list filters
has to be provided. At the moment, this is done by the _pick_random_and_init
function which works like this:
@jit(nopython=True)
def _pick_random_and_init(batch_size, move_cumulative, rnd_uniform, out):
for i in range(batch_size):
p = rnd_uniform[i]
out[i] = np.searchsorted(move_cumulative, p)
Here move_cumulative
is a monotonically increasing vector of numbers coming from an expression like (weights/weights.sum()).cumsum()
. Thus, the maximum of this vector should be 1, and the out
vector should be filled with indices between 0 and batch_size - 1, as rnd_uniform
is a bunch of random numbers between 0 and 1. The only way for np.searchsorted(move_cumulative, p)
to return batch_size
is if p=1
, which would be problematic, as out
is the filters
vector.
In practice, the maximum of move_cumulative
, however, is 0.9999995. If we generate rnd_uniform
between 0 and 1, there is a small chance that one of those numbers is greater than 0.9999995, which would lead to having a filter which is batch_size
. This has happened to me:
...
File "/Users/vladimirvargas/Documents/Projects/physics/netket/netket/sampler/rules/custom_numpy.py", line 93, in transition
state.σ, rule_state.sections, rule_state.rand_op_n
File "/Users/vladimirvargas/Documents/Projects/physics/netket/netket/operator/_local_operator.py", line 1043, in get_conn_filtered
filters,
File "/Users/vladimirvargas/Documents/Projects/physics/netket/netket/operator/_local_operator.py", line 1081, in _get_conn_filtered_kernel
assert i < n_o
Thus, this PR fixes the way that rnd_uniform
is generated, capping the upper bound of the random generator to the maximum value in move_cumulative
.