Skip to content

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.

Merge request reports