dwave.system.temperatures.maximum_pseudolikelihood#

maximum_pseudolikelihood(en1: ndarray | None = None, bqms: None | List[BinaryQuadraticModel] = None, sampleset: None | SampleSet | Tuple[ndarray, List] = None, num_bootstrap_samples: int = 0, seed: int | None = None, x0: None | List | ndarray = None, optimize_method: str | None = None, kwargs_opt: dict | None = None, sample_weights: ndarray | None = None, return_optimize_object: bool = False, degenerate_fields: bool | None = None, use_jacobian: bool = True) Tuple[source]#

Maximimum pseudolikelihood estimator for exponential models.

Uses the SciPy optimize submodule to solve the maximum pseudolikelihood problem of weight estimation for an exponential model with the exponent defined by a weighted sum of binary quadratic models (BQM).

Assuming the probability of states \(s\) is given by an exponential model, \(P(s)=\frac{1}{Z} \textrm{exp}(- x_i H_i(s))\), for a given list of functions (BQMs), estimate \(x\). The exponential model is also called a Boltzmann distribution.

This function assumes the BQMs are dense (a function of all, or most of, the variables), although operations on sparse BQMs such as \(H(s)=h_i s_i\) or \(H(s)=J_{ij}s_i s_j\) are technically allowed.

If all provided samples define local minima or maxima (all energies for the en1 parameter are same sign), the limit of \(\pm \textrm{Inf}\) defines a maximum. In this special case, SciPy is not called and the limit result is returned. Note that excitations can be rare in low-temperature samplesets such as those derived from quantum annealing, so that this pathological case can be realized in applications of interest.

Common reasons for failures to infer parameters include:

  • Too few samples (insufficient to resolve parameters).

  • A sampleset that is singular or insensitive with respect to some parameter (e.g. local minima or plateus only).

  • BQMs that are too closely related, or weakly dependent on, the sampleset variability (e.g. nearly collinear).

Parameters:
  • en1 – Effective fields as an numpy.ndarray (site labels not required). If not provided, derived from the bqms and sampleset parameters. First dimension indexes samples and second dimension indexes sites. Ordering does not matter but should be consistent with the sample_weights parameter.

  • bqms – List of binary quadratic models \([H_i]\) describing the sample distribution as \(P(s) \approx \textrm{exp}(sum_i x_i H_i(s))\) for unknown model parameters \(x\).

  • sampleset – Set of samples, as a SampleSet or a samples_like object (an extension of the NumPy array_like structure); see as_samples().

  • num_bootstrap_samples – Number of bootstrap estimators to calculate. Bootstrapped estimates can be used to reliably estimate variance and bias if samples are uncorrelated. Currently supported for samplesets only with uniform sample_weights; an aggregated or weighted sampleset must be disaggregated (raw format) with repetitions.

  • seed – Seeds the bootstrap method (if provided), allowing reproducibility of the estimators.

  • x0 – Initial guess for the fitting parameters. Should have the same length as bqms, when provided.

  • optimize_method (str, optional, default=None) – Optimize method used by the SciPy root_scalar algorithm. The default method (type of solver) works well under default operation; the ‘bisect’ method can be numerically more stable for the scalar case (temperature estimation only).

  • kwargs_opt – Arguments used by the SciPy optimization methods. If using the ‘bisect’ optimization method and for a single BQM, bounds for the fitting parameter can be set using a tuple[float, float] for bracket.

  • sample_weights – A set of weights for the samples. If your sampleset parameter is of type SampleSet, defaults to sampleset.record.num_occurrences; otherwise uniform weighting is the default.

  • return_optimize_object – When True, and if the SciPy optimize submodule is invoked, the associated OptimizeResult is returned. Otherwise only the optimal parameter values are returned as floats.

  • degenerate_fields – If effective fields are degenerate owing to sparse connectivity, low precision, and/or large number of samples or low entropy, then histogramming (aggregating) of fields is used to accelerate the search stage. A value True is supported (as the default) for single-parameter esimation, len(bqms)=1; for multi-parameter estimation only value False is supported.

  • use_jacobian – By default (use_jacobian=True) the second derivative of the pseudolikelihood is calculated and used by ScipY root-finding methods. The associated complexity of this non-essential calculation is quadratic in len(bqms); use of the second derivative is disabled by setting this parameter to False.

Returns:

Optimal parameters and a list of bootstrapped estimates (x_estimate, x_bootstrap_estimates):

  • x_estimate: parameter estimates

  • x_bootstrap_estimates: NumPy array of bootstrap estimators

Return type:

Tuple

Examples

This example builds upon the maximum_pseudolikelihood_temperature() example.

Draw samples from a D-Wave quantum computer for a large spin-glass problem (random couplers \(J\), zero external field \(h\)). Establish a temperature and estimate of the background susceptibility \(\chi\), which is expected to be a small, negative value. Since background susceptiblity is a perturbation, and the problem Hamiltonian and correction Hamiltonian are correlated, a large number of samples can be required for confidence. Other perturbative corrections such as flux noise can also interfere with estimation of small parameters like \(\chi\).

>>> import dimod
>>> from dwave.system.temperatures import maximum_pseudolikelihood
>>> from dwave.system.temperatures import background_susceptibility_bqm
>>> from dwave.system import DWaveSampler
>>> from random import random
...
>>> sampler = DWaveSampler()
>>> bqm1 = dimod.BinaryQuadraticModel.from_ising({}, {e : 1-2*random() for e in sampler.edgelist})
>>> bqm2 = background_susceptibility_bqm(bqm1)
>>> sampleset = sampler.sample(bqm1, num_reads=1000, auto_scale=False)
>>> params, _ =  maximum_pseudolikelihood(bqms=[bqm1, bqm2], sampleset=sampleset)
>>> print('Effective temperature ', -1/params[0], 'Background susceptibliity', params[1]/params[0])    
Effective temperature  0.22298662677716122 Background susceptibliity -0.009343961890466117