dimod.ess.compute_ess#

compute_ess(x: ndarray, batch_size: int | None = None) float[source]#

Estimates the effective sample size of x.

NOTE: The estimate can be nan or negative for extreme cases (e.g., constants). This can occur by definition of the estimator and is not a bug.

Examples

These two examples demonstrate typical use cases of the estimator based on an energy statistic. The first example measures the QPU’s ESS. The second example measures the ESS of two Metropolis-Hastings samplers (one with one sweep, another with ten sweeps).

Example (1): QPU .. code-block:: python

import numpy as np from dimod.ess import estimate_effective_sample_size from dimod.generators import power_r from dwave.system import DWaveCliqueSampler

markov_chain_length = 100 num_vars = 100 num_chains = 10 bqm = power_r(512, num_vars) bqm.normalize() qpu = DWaveCliqueSampler() qpu_energy = np.array(

[qpu.sample(bqm, num_reads=markov_chain_length, answer_mode=”raw”).record.energy for _ in range(num_chains)]

) print(“Effective sample size per chain (QPU):”,

estimate_effective_sample_size(qpu_energy)/num_chains)

# Effective sample size per chain (QPU): 71.87414368659094

Example (2): Metropolis-Hastings

import numpy as np
from dwave.samplers import SimulatedAnnealingSampler
from dimod.ess import estimate_effective_sample_size
from dimod.generators import power_r

neal = SimulatedAnnealingSampler()
markov_chains = []
markov_chain_length = 100
num_vars = 100
num_chains = 10
num_sweeps = 1  # Increase number of sweeps to increase ESS
bqm = power_r(512, num_vars)
bqm.normalize()
initial_state = None
for chain_idx in range(num_chains):
    chain = []
    for time_idx in range(markov_chain_length):
        sample_set = neal.sample(
            bqm, beta_schedule=[1.0]*num_sweeps,
            beta_schedule_type="custom", initial_states=initial_state)
        chain.append(sample_set.record.energy.item())
        initial_state = (sample_set.record.sample, sample_set.variables)
    markov_chains.append(chain)
mc_energy = np.array(markov_chains)
print("Effective sample size per chain (MH):",
      estimate_effective_sample_size(mc_energy)/num_chains)
# Effective sample size per chain (MH): 12.496482970401358

Use a larger number of sweeps to achieve larger ESS >>> num_sweeps = 10 Effective sample size per chain (MH): 64.44999653861495

Parameters:
  • x – An (m, n) matrix where rows index independent Markov chains and columns index time steps.

  • batch_size – Batch size of the estimator. If None, then batch_size is set to the floor of the square root of n. Defaults to None.

Returns:

An estimate of the effective sample size of x. The estimate can be NaN or even negative when the input chain is nearly constant. This can occur by definition of the estimator and is not a bug.

Return type:

float