Annealing

These function interface with C source code to provide fast execution of the simulated annealing algorithm. Note that the sim module will not be imported with from qubovert import *. You must import qubovert.sim explicitly. Here we show some functions to use the boolean and spin simulation to run simulated annealing on the models.

Please note that the qv.sim.anneal_qubo and qv.sim.anneal_quso functions perform faster than the qv.sim.anneal_pubo and qv.sim.anneal_puso functions. If your system has degree 2 or less, then you should use the QUBO or QUSO anneal functions!

Anneal PUBO

qubovert.sim.anneal_pubo(P, num_anneals=1, anneal_duration=1000, initial_state=None, temperature_range=None, schedule='geometric', in_order=True, seed=None)

anneal_pubo.

Run a simulated annealing algorithm to try to find the minimum of the PUBO given by P. anneal_pubo converts P to a PUSO and then uses qubovert.sim.anneal_quso. Please see all the parameters for details.

Please note that the qv.sim.anneal_qubo function performs faster than the qv.sim.anneal_pubo function. If your system has degree 2 or less, then you should use the qv.sim.anneal_qubo function.

Parameters
  • P (dict, or any type in qubovert.BOOLEAN_MODELS.) – Maps boolean labels to their values in the objective function. Please see the docstrings of any of the objects in qubovert.BOOLEAN_MODELS to see how P should be formatted.

  • num_anneals (int >= 1 (optional, defaults to 1)) – The number of times to run the simulated annealing algorithm.

  • anneal_duration (int >= 1 (optional, defaults to 1000)) – The total number of updates to the simulation during the anneal. This is related to the amount of time we spend in the cooling schedule. If an explicit schedule is provided, then anneal_duration will be ignored.

  • initial_state (dict (optional, defaults to None)) – The initial state to start the anneal in. initial_state must map the spin label names to their values in {0, 1}. If initial_state is None, then a random state will be chosen to start each anneal. Otherwise, initial_state will be the starting state for all of the anneals.

  • temperature_range (tuple (optional, defaults to None)) – The temperature to start and end the anneal at. temperature = (T0, Tf). T0 must be >= Tf. To see more details on picking a temperature range, please see the function qubovert.sim.anneal_temperature_range. If temperature_range is None, then it will by default be set to T0, Tf = qubovert.sim.anneal_temperature_range(P, spin=False).

  • schedule (str or iterable of tuple (optional, defaults to 'geometric')) – What type of cooling schedule to use. If schedule == 'linear', then the cooling schedule will be a linear interpolation between the values in temperature_range. If schedule == 'geometric', then the cooling schedule will be a geometric interpolation between the values in temperature_range. Otherwise, you can supply an explicit schedule. In this case, schedule should be an iterable of tuples, where each tuple is a (T, n) pair, where T denotes the temperature to update the simulation, and n denote the number of times to update the simulation at that temperature. This schedule will be sent directly into the qubovert.sim.PUBOSimulation.schedule_update method.

  • in_order (bool (optional, defaults to True)) – Whether to iterate through the variables in order or randomly during an update step. When in_order is False, the simulation is more physically realistic, but when using the simulation for annealing, often it is better to have in_order = True.

  • seed (number (optional, defaults to None)) – The number to seed Python’s builtin random module with. If seed is None, then random.seed will not be called.

Returns

resres contains information on the final states of the simulations. See Examples below for an example of how to read from res. See help(qubovert.sim.AnnealResults) for more info.

Return type

qubovert.sim.AnnealResults object.

Raises
  • ValueError – If the schedule argument provided is formatted incorrectly. See the Parameters section.

  • ValueError – If the initial temperature is less than the final temperature.

Warns
  • qubovert.utils.QUBOVertWarning – If both the temperature_range and explicit schedule arguments are provided.

  • qubovert.utils.QUBOVertWarning – If the degree of the model is 2 or less then a warning is issued that says you should use the anneal_qubo or anneal_quso functions.

Example

Consider the example of finding the ground state of the 1D antiferromagnetic Ising chain of length 5 in boolean form.

>>> import qubovert as qv
>>>
>>> H = sum(qv.spin_var(i) * qv.spin_var(i+1) for i in range(4))
>>> P = H.to_pubo()
>>> anneal_res = qv.sim.anneal_pubo(P, num_anneals=3)
>>>
>>> print(anneal_res.best.value)
-4
>>> print(anneal_res.best.state)
{0: 0, 1: 1, 2: 0, 3: 1, 4: 0}
>>> # now sort the results
>>> anneal_res.sort()
>>>
>>> # now iterate through all of the results in the sorted order
>>> for res in anneal_res:
>>>     print(res.value, res.state)
-4, {0: 0, 1: 1, 2: 0, 3: 1, 4: 0}
-4, {0: 1, 1: 0, 2: 1, 3: 0, 4: 1}
-4, {0: 0, 1: 1, 2: 0, 3: 1, 4: 0}

Anneal PUSO

qubovert.sim.anneal_puso(H, num_anneals=1, anneal_duration=1000, initial_state=None, temperature_range=None, schedule='geometric', in_order=True, seed=None)

anneal_puso.

Run a simulated annealing algorithm to try to find the minimum of the PUSO given by H. Please see all of the parameters for details.

Please note that the qv.sim.anneal_quso function performs faster than the qv.sim.anneal_puso function. If your system has degree 2 or less, then you should use the qv.sim.anneal_quso function.

Parameters
  • H (dict, or any type in qubovert.SPIN_MODELS.) – Maps spin labels to their values in the Hamiltonian. Please see the docstrings of any of the objects in qubovert.SPIN_MODELS to see how H should be formatted.

  • num_anneals (int >= 1 (optional, defaults to 1)) – The number of times to run the simulated annealing algorithm.

  • anneal_duration (int >= 1 (optional, defaults to 1000)) – The total number of updates to the simulation during the anneal. This is related to the amount of time we spend in the cooling schedule. If an explicit schedule is provided, then anneal_duration will be ignored.

  • initial_state (dict (optional, defaults to None)) – The initial state to start the anneal in. initial_state must map the spin label names to their values in {1, -1}. If initial_state is None, then a random state will be chosen to start each anneal. Otherwise, initial_state will be the starting state for all of the anneals.

  • temperature_range (tuple (optional, defaults to None)) – The temperature to start and end the anneal at. temperature = (T0, Tf). T0 must be >= Tf. To see more details on picking a temperature range, please see the function qubovert.sim.anneal_temperature_range. If temperature_range is None, then it will by default be set to T0, Tf = qubovert.sim.anneal_temperature_range(H, spin=True). Note that a temperature can only be zero if schedule is explicitly given or if schedule is linear.

  • schedule (str, or list of floats (optional, defaults to 'geometric').) – What type of cooling schedule to use. If schedule == 'linear', then the cooling schedule will be a linear interpolation between the values in temperature_range. If schedule == 'geometric', then the cooling schedule will be a geometric interpolation between the values in temperature_range. Otherwise, schedule must be an iterable of floats being the explicit temperature schedule for the anneal to follow.

  • in_order (bool (optional, defaults to True)) – Whether to iterate through the variables in order or randomly during an update step. When in_order is False, the simulation is more physically realistic, but when using the simulation for annealing, often it is better to have in_order = True.

  • seed (number (optional, defaults to None)) – The number to seed Python’s builtin random module with. If seed is None, then random.seed will not be called.

Returns

resres contains information on the final states of the simulations. See Examples below for an example of how to read from res. See help(qubovert.sim.AnnealResults) for more info.

Return type

qubovert.sim.AnnealResults object.

Raises
  • ValueError – If the schedule argument provided is formatted incorrectly. See the Parameters section.

  • ValueError – If the initial temperature is less than the final temperature.

Warns
  • qubovert.utils.QUBOVertWarning – If both the temperature_range and explicit schedule arguments are provided.

  • qubovert.utils.QUBOVertWarning – If the degree of the model is 2 or less then a warning is issued that says you should use the anneal_qubo or anneal_quso functions.

Example

Consider the example of finding the ground state of the 1D antiferromagnetic Ising chain of length 5.

>>> import qubovert as qv
>>>
>>> H = sum(qv.spin_var(i) * qv.spin_var(i+1) for i in range(4))
>>> anneal_res = qv.sim.anneal_puso(H, num_anneals=3)
>>>
>>> print(anneal_res.best.value)
-4
>>> print(anneal_res.best.state)
{0: 1, 1: -1, 2: 1, 3: -1, 4: 1}
>>> # now sort the results
>>> anneal_res.sort()
>>>
>>> # now iterate through all of the results in the sorted order
>>> for res in anneal_res:
>>>     print(res.value, res.state)
-4, {0: 1, 1: -1, 2: 1, 3: -1, 4: 1}
-4, {0: -1, 1: 1, 2: -1, 3: 1, 4: -1}
-4, {0: 1, 1: -1, 2: 1, 3: -1, 4: 1}

Anneal QUBO

qubovert.sim.anneal_qubo(Q, num_anneals=1, anneal_duration=1000, initial_state=None, temperature_range=None, schedule='geometric', in_order=True, seed=None)

anneal_qubo.

Run a simulated annealing algorithm to try to find the minimum of the QUBO given by Q. anneal_qubo converts Q to a QUSO and then uses qubovert.sim.anneal_quso. Please see all of the parameters for details.

Parameters
  • Q (dict, qubovert.utils.QUBOMatrix or qubovert.QUBO.) – Maps boolean labels to their values in the objective function. Please see the docstring of qubovert.QUBO for more info on how to format Q.

  • num_anneals (int >= 1 (optional, defaults to 1)) – The number of times to run the simulated annealing algorithm.

  • anneal_duration (int >= 1 (optional, defaults to 1000)) – The total number of updates to the simulation during the anneal. This is related to the amount of time we spend in the cooling schedule. If an explicit schedule is provided, then anneal_duration will be ignored.

  • initial_state (dict (optional, defaults to None)) – The initial state to start the anneal in. initial_state must map the spin label names to their values in {0, 1}. If initial_state is None, then a random state will be chosen to start each anneal. Otherwise, initial_state will be the starting state for all of the anneals.

  • temperature_range (tuple (optional, defaults to None)) – The temperature to start and end the anneal at. temperature = (T0, Tf). T0 must be >= Tf. To see more details on picking a temperature range, please see the function qubovert.sim.anneal_temperature_range. If temperature_range is None, then it will by default be set to T0, Tf = qubovert.sim.anneal_temperature_range(Q, spin=False).

  • schedule (str or iterable of tuple (optional, defaults to 'geometric')) – What type of cooling schedule to use. If schedule == 'linear', then the cooling schedule will be a linear interpolation between the values in temperature_range. If schedule == 'geometric', then the cooling schedule will be a geometric interpolation between the values in temperature_range. Otherwise, you can supply an explicit schedule. In this case, schedule should be an iterable of tuples, where each tuple is a (T, n) pair, where T denotes the temperature to update the simulation, and n denote the number of times to update the simulation at that temperature. This schedule will be sent directly into the qubovert.sim.PUBOSimulation.schedule_update method.

  • in_order (bool (optional, defaults to True)) – Whether to iterate through the variables in order or randomly during an update step. When in_order is False, the simulation is more physically realistic, but when using the simulation for annealing, often it is better to have in_order = True.

  • seed (number (optional, defaults to None)) – The number to seed Python’s builtin random module with. If seed is None, then random.seed will not be called.

Returns

resres contains information on the final states of the simulations. See Examples below for an example of how to read from res. See help(qubovert.sim.AnnealResults) for more info.

Return type

qubovert.sim.AnnealResults object.

Raises
  • ValueError – If the schedule argument provided is formatted incorrectly. See the Parameters section.

  • ValueError – If the initial temperature is less than the final temperature.

Warns

qubovert.utils.QUBOVertWarning – If both the temperature_range and explicit schedule arguments are provided.

Example

Consider the example of finding the ground state of the 1D antiferromagnetic Ising chain of length 5 in boolean form.

>>> import qubovert as qv
>>>
>>> H = sum(qv.spin_var(i) * qv.spin_var(i+1) for i in range(4))
>>> Q = H.to_qubo()
>>> anneal_res = qv.sim.anneal_qubo(Q, num_anneals=3)
>>>
>>> print(anneal_res.best.value)
-4
>>> print(anneal_res.best.state)
{0: 0, 1: 1, 2: 0, 3: 1, 4: 0}
>>> # now sort the results
>>> anneal_res.sort()
>>>
>>> # now iterate through all of the results in the sorted order
>>> for res in anneal_res:
>>>     print(res.value, res.state)
-4, {0: 0, 1: 1, 2: 0, 3: 1, 4: 0}
-4, {0: 1, 1: 0, 2: 1, 3: 0, 4: 1}
-4, {0: 0, 1: 1, 2: 0, 3: 1, 4: 0}

Anneal QUSO

qubovert.sim.anneal_quso(L, num_anneals=1, anneal_duration=1000, initial_state=None, temperature_range=None, schedule='geometric', in_order=True, seed=None)

anneal_quso.

Run a simulated annealing algorithm to try to find the minimum of the QUSO given by L. Please see all of the parameters for details.

Parameters
  • L (dict, qubovert.utils.QUSOMatrix or qubovert.QUSO.) – Maps spin labels to their values in the objective function. Please see the docstring of qubovert.QUSO for more info on how to format L.

  • num_anneals (int >= 1 (optional, defaults to 1)) – The number of times to run the simulated annealing algorithm.

  • anneal_duration (int >= 1 (optional, defaults to 1000)) – The total number of updates to the simulation during the anneal. This is related to the amount of time we spend in the cooling schedule. If an explicit schedule is provided, then anneal_duration will be ignored.

  • initial_state (dict (optional, defaults to None)) – The initial state to start the anneal in. initial_state must map the spin label names to their values in {1, -1}. If initial_state is None, then a random state will be chosen to start each anneal. Otherwise, initial_state will be the starting state for all of the anneals.

  • temperature_range (tuple (optional, defaults to None)) – The temperature to start and end the anneal at. temperature = (T0, Tf). T0 must be >= Tf. To see more details on picking a temperature range, please see the function qubovert.sim.anneal_temperature_range. If temperature_range is None, then it will by default be set to T0, Tf = qubovert.sim.anneal_temperature_range(L, spin=True).

  • schedule (str, or list of floats (optional, defaults to 'geometric').) – What type of cooling schedule to use. If schedule == 'linear', then the cooling schedule will be a linear interpolation between the values in temperature_range. If schedule == 'geometric', then the cooling schedule will be a geometric interpolation between the values in temperature_range. Otherwise, schedule must be an iterable of floats being the explicit temperature schedule for the anneal to follow.

  • in_order (bool (optional, defaults to True)) – Whether to iterate through the variables in order or randomly during an update step. When in_order is False, the simulation is more physically realistic, but when using the simulation for annealing, often it is better to have in_order = True.

  • seed (number (optional, defaults to None)) – The number to seed Python’s builtin random module with. If seed is None, then random.seed will not be called.

Returns

resres contains information on the final states of the simulations. See Examples below for an example of how to read from res. See help(qubovert.sim.AnnealResults) for more info.

Return type

qubovert.sim.AnnealResults object.

Raises
  • ValueError – If the schedule argument provided is formatted incorrectly. See the Parameters section.

  • ValueError – If the initial temperature is less than the final temperature.

  • ValueError – If L is not degree 2 or less.

Warns

qubovert.utils.QUBOVertWarning – If both the temperature_range and explicit schedule arguments are provided.

Example

Consider the example of finding the ground state of the 1D antiferromagnetic Ising chain of length 5.

>>> import qubovert as qv
>>>
>>> H = sum(qv.spin_var(i) * qv.spin_var(i+1) for i in range(4))
>>> anneal_res = qv.sim.anneal_quso(H, num_anneals=3)
>>>
>>> print(anneal_res.best.value)
-4
>>> print(anneal_res.best.state)
{0: 1, 1: -1, 2: 1, 3: -1, 4: 1}
>>> # now sort the results
>>> anneal_res.sort()
>>>
>>> # now iterate through all of the results in the sorted order
>>> for res in anneal_res:
>>>     print(res.value, res.state)
-4, {0: 1, 1: -1, 2: 1, 3: -1, 4: 1}
-4, {0: -1, 1: 1, 2: -1, 3: 1, 4: -1}
-4, {0: 1, 1: -1, 2: 1, 3: -1, 4: 1}

Anneal temperature range

The following function is used to determine the default annealing temperatures to start and stop at for the above anneal functions if the user does not supply a range themselves.

qubovert.sim.anneal_temperature_range(model, start_flip_prob=0.5, end_flip_prob=0.01, spin=False)

anneal_temperature_range.

Calculate the temperature to start and end an anneal of model, such that at the start of the anneal there is a start_flip_prob probability that a bit is flipped despite it being energetically unfavorable, and at the end of the anneal there is a end_flip_prob probability that a bit is flipped despite it being energetically unfavorable.

Parameters
  • model (dict, or any type in qubovert.SPIN_MODELS or BOOLEAN_MODELS) – Dictionary mapping tuples of binary labels to their values. See any of the docstrings of a type in qubovert.SPIN_MODELS or BOOLEAN_MODELS for more info.

  • start_flip_prob (float in [0, 1) (optional, defaults to 0.5)) – The desired probability that a bit flips despite it being energetically unfavorable at the start of the anneal. start_flip_prob must be greater than end_flip_prob.

  • end_flip_prob (float in [0, 1) (optional, defaults to 0.01)) – The desired probability that a bit flips despite it being energetically unfavorable at the end of the anneal. end_flip_prob must be less than start_flip_prob.

  • spin (bool (optional, default to False)) – spin should be True if model is a spin model (ie isinstance(model, qubovert.SPIN_MODELS)) and should be False if model is a boolean model (ie isinstance(model, qubovert.BOOLEAN_MODELS)).

Returns

temp_range – The hot temperature is the temperature to start the anneal at, and the cold temperature is the temperature to end the anneal at. Note that hot >= cold.

Return type

tuple (hot, cold)