Matrix Objects

The matrix objects are for dealing with PUBOs, PUSOs, QUBOs, and QUSOs that have integer labels. All the to_ methods return matrix objects. For example, PCBO.to_qubo returns a QUBOMatrix object.

Note that the utils module will not be imported with from qubovert import *. You must import qubovert.utils explicitly.

Accessed with qubovert.utils.matrix_name.

PUBOMatrix

class qubovert.utils.PUBOMatrix(*args, **kwargs)

PUBOMatrix.

PUBOMatrix inherits some methods from DictArithmetic, see help(qubovert.utils.DictArithmetic).

A class to handle PUBO matrices. It is the same thing as a dictionary with some methods modified. Note that each key must be a tuple of integers >= 0.

Note that below we only consider keys that are of length 1 or 2, but they can in general be arbitrarily long! See qubovert.utils.QUBOMatrix for an object that restricts the length to <= 2.

One method is that values will always default to 0. Consider the following example:

>>> d = PUBOMatrix()
>>> print(d[(0,)]) # will print 0
>>> d[(0,)] += 1
>>> print(d) # will print {(0,): 1}

Compared to an ordinary dictionary.

>>> g = dict()
>>> print(g[(0,)]) # will raise KeyError
>>> g[(0,)] += 1 # will raise KeyError, since (0,) was never set

One method of PUBOMatrix is that it will always keep the PUBO upper triangular! Consider the following example:

>>> d = PUBOMatrix()
>>> d[(1, 0)] += 2
>>> print(d)
>>> # will print {(0, 1): 2}

One method is that if we set an item to 0, it will be removed. Consider the following example:

>>> d = PUBOMatrix()
>>> d[(0,)] += 1
>>> d[(0,)] -= 1
>>> print(d) # will print {}

One method is that if we initialize PUBOMatrix with a previous dictionary it will be reinitialized to ensure that the PUBOMatrix is upper triangular and contains no zero values. Consider the following example:

>>> d = PUBOMatrix({(0, 0): 1, (1, 0): 2, (2, 0): 0, (2, 0, 1): 1})
>>> print(d) # will print {(0,): 1, (0, 1): 2, (0, 1, 2): 1}

We also change the update method so that it follows all the conventions.

>>> d = PUBOMatrix({(0, 0): 1, (0, 1): 2})
>>> d.update({(0,): 0, (1, 0): 1, (1, 2): -1})
>>> print(d)  # will print {(0, 1): 1, (1, 2): -1}

We also include arithmetic, addition, subtraction, scalar division, multiplication, and all those in place. For example,

>>> d = PUBOMatrix({(0, 0): 1, (0, 1): -2})
>>> g = d + {(0,): -1}
>>> print(g) # will print {(0, 1): -2}
>>> g *= 4
>>> print(g) # will print {(0, 1): -8}
>>> g -= {(0, 1): -8}
>>> print(g) # will print {}
>>> d = PUBOMatrix({(0, 0): 1, (0, 1): -1})
>>> g = {(0,): -1, (2,): 1}
>>> d *= g
>>> print(d)
{(0,): -1, (0, 2): 1, (0, 1): 1, (0, 1, 2): -1}
>>> d = PUBOMatrix({(0, 0): 1, (0, 1): -1})
>>> print(d ** 2 == d * d)
True

Adding or subtracting constants will update the () element of the dict.

>>> d = PUBOMatrix()
>>> d += 5
>>> print(d)
{(): 5}

Finally, if you try to access a key out of order, it will sort the key. Be careful with this, it can cause unexpected behavior if you don’t know it. For example,

>>> d = PUBOMatrix()
>>> d[(0, 1)] += 2
>>> print(d[(1, 0)])  # will print 2
>>> d = PUBOMatrix()
>>> d[(0, 0)] += 2
>>> print(d[(0,)])  # will print 2
>>> d = PUBOMatrix()
>>> d[(0, 0, 3, 2, 2)] += 2
>>> print(d)  # will print {(0, 2, 3): 2}
>>> print(d[(0, 3, 2)])  # will print 2

__init__.

This class deals with Binary Optimization matrices. See child classes or qubovert.utils.DictArithmetic for details on the inputs.

Parameters

arguments (parameters.) – Defined in child classes or in qubovert.utils.DictArithmetic.

clear()

clear.

For efficiency, the internal variables for degree, num_binary_variables, max_index are computed as the dictionary is being built (and in subclasses such as qubovert.PUBO, properties such as mapping and reverse_mapping). This can cause these values to be wrong for some specific situations. Thus, when we clear, we also need to reset all of these cached values. This function remove all the elments from self and resets the cached values.

copy()

copy.

Same as dict.copy, but we adjust the method so that it returns a DictArithmetic object, or whatever object is the subclass.

Returns

d – Same as self.__class__.

Return type

DictArithmetic object, or subclass of.

classmethod create_var(name)

create_var.

Create the variable with name name.

Parameters

name (hashable object allowed as a key.) – Name of the variable.

Returns

res – The model representing the variable with type cls.

Return type

cls object.

Examples

>>> from qubovert.utils import DictArithmetic
>>>
>>> x = DictArithmetic.create_var('x')
>>> x == DictArithmetic({('x',): 1})
True
>>> isinstance(x, DictArithmetic)
True
>>> x.name
'x'
>>> from qubovert import QUSO
>>>
>>> z = QUSO.create_var('z')
>>> print(z)
{('z',): 1}
>>> print(isinstance(z, QUSO))
True
>>> print(z.name)
'z'
property degree

degree.

Return the degree of the problem.

Returns

deg

Return type

int.

fromkeys(value=None, /)

Create a new dictionary with keys from iterable and values set to value.

get(key, default=None, /)

Return the value for key if key is in the dictionary, else default.

is_solution_valid(solution)

is_solution_valid.

Included for consistency with other problem classes. Always returns True since this is an unconstrainted problem.

Parameters

solution (iterable or dict.) –

Returns

valid – Always returns True.

Return type

bool.

items() a set-like object providing a view on D's items
keys() a set-like object providing a view on D's keys
property max_index

max_index.

Returns the maximum label index of the problem. If the problem is labeled with integers from 0 to n-1, then max_index will give the same result as num_binary_variables - 1.

Returns

n – Max label index of the problem dictionary. If the dict is empty, then this returns None.

Return type

int or None.

property name

name.

Return the name of the object.

Returns

name

Return type

object.

Example

>>> d = DictArithmetic()
>>> d.name
None
>>> d.name = 'd'
>>> d.name
'd'
normalize(value=1)

normalize.

Normalize the coefficients to a maximum magnitude.

Parameters

value (float (optional, defaults to 1)) – Every coefficient value will be normalized such that the coefficient with the maximum magnitude will be +/- 1.

Examples

>>> from qubovert.utils import DictArithmetic
>>> d = DictArithmetic({(0, 1): 1, (1, 2, 'x'): 4})
>>> d.normalize()
>>> print(d)
{(0, 1): 0.25, (1, 2, 'x'): 1}
>>> from qubovert.utils import DictArithmetic
>>> d = DictArithmetic({(0, 1): 1, (1, 2, 'x'): -4})
>>> d.normalize()
>>> print(d)
{(0, 1): 0.25, (1, 2, 'x'): -1}
>>> from qubovert import PUBO
>>> d = PUBO({(0, 1): 1, (1, 2, 'x'): 4})
>>> d.normalize()
>>> print(d)
{(0, 1): 0.25, (1, 2, 'x'): 1}
>>> from qubovert.utils import PUBO
>>> d = PUBO({(0, 1): 1, (1, 2, 'x'): -4})
>>> d.normalize()
>>> print(d)
{(0, 1): 0.25, (1, 2, 'x'): -1}
property num_binary_variables

num_binary_variables.

Return the number of binary variables in the problem.

Returns

n – Number of binary variables in the problem.

Return type

int.

property num_terms

num_terms.

Return the number of terms in the dictionary.

Returns

n – Number of terms in the dictionary.

Return type

int.

property offset

offset.

Get the part that does not depend on any variables. Ie the value corresponding to the () key.

Returns

offset

Return type

float.

pop(k[, d]) v, remove specified key and return the corresponding value.

If key is not found, d is returned if given, otherwise KeyError is raised

popitem()

Remove and return a (key, value) pair as a 2-tuple.

Pairs are returned in LIFO (last-in, first-out) order. Raises KeyError if the dict is empty.

pretty_str(var_prefix='x')

pretty_str.

Return a pretty string representation of the model.

Parameters

var_prefix (str (optional, defaults to 'x').) – The prefix for the variables.

Returns

res

Return type

str.

refresh()

refresh.

For efficiency, the internal variables for degree, num_binary_variables, max_index are computed as the dictionary is being built (and in subclasses such as qubovert.PUBO, properties such as mapping and reverse_mapping). This can cause these values to be wrong for some specific situations. Calling refresh will rebuild the dictionary, resetting all of the values.

Examples

>>> from qubovert.utils import PUBOMatrix
>>> P = PUBOMatrix()
>>> P[(0,)] += 1
>>> P, P.degree, P.num_binary_variables
{(0,): 1}, 1, 1
>>> P[(0,)] -= 1
>>> P, P.degree, P.num_binary_variables
{}, 1, 1
>>> P.refresh()
>>> P, P.degree, P.num_binary_variables
{}, 0, 0
>>> from qubovert import PUBO
>>> P = PUBO()
>>> P[('a',)] += 1
>>> P, P.mapping, P.reverse_mapping
{('a',): 1}, {'a': 0}, {0: 'a'}
>>> P[('a',)] -= 1
>>> P, P.mapping, P.reverse_mapping
{}, {'a': 0}, {0: 'a'}
>>> P.refresh()
>>> P, P.mapping, P.reverse_mapping
{}, {}, {}
setdefault(key, default=None, /)

Insert key with a value of default if key is not in the dictionary.

Return the value for key if key is in the dictionary, else default.

simplify()

simplify.

If self has any symbolic expressions, this will go through and simplify them. This will also make everything a float!

Returns

Return type

None. Updates it in place.

solve_bruteforce(all_solutions=False)

solve_bruteforce.

Solve the problem bruteforce. THIS SHOULD NOT BE USED FOR LARGE PROBLEMS! This is the exact same as calling ``qubovert.utils.solve_pubo_bruteforce(

self, all_solutions, self.is_solution_valid)[1]``.

Parameters

all_solutions (bool.) – See the description of the all_solutions parameter in qubovert.utils.solve_pubo_bruteforce.

Returns

resqubovert.utils.solve_pubo_bruteforce.

Return type

the second element of the two element tuple that is returned from

classmethod squash_key(key)

squash_key.

Will convert the input key into the standard form for PUBOMatrix / QUBOMatrix. It will get rid of duplicates and sort. This method will check to see if the input key is valid.

Parameters

key (tuple of integers.) –

Returns

k – A sorted and squashed version of key.

Return type

tuple of integers.

Raises

KeyError if the key is invalid.

Example

>>> squash_key((0, 4, 0, 3, 3, 2))
>>> (0, 2, 3, 4)
subgraph(nodes, connections=None)

subgraph.

Create the subgraph of self that only includes vertices in nodes, and external nodes are given the values in connections.

Parameters
  • nodes (set.) – Nodes of self to include in the subgraph.

  • connections (dict (optional, defaults to {})) – For each node in self that is not in nodes, we assign a value given by connections.get(node, 0).

Returns

D – The subgraph of self with nodes in nodes and the values of the nodes not included given by connections.

Return type

same as type(self)

Notes

Any offset value included in self (ie {(): 1}) will be ignored, however there may be an offset in the output D.

Examples

>>> G = DictArithmetic(
>>>     {(0, 1): -4, (0, 2): -1, (0,): 3, (1,): 2, (): 2}
>>> )
>>> D = G.subgraph({0, 2}, {1: 5})
>>> D
{(0,): -17, (0, 2): -1, (): 10}
>>> G = DictArithmetic(
>>>     {(0, 1): -4, (0, 2): -1, (0,): 3, (1,): 2, (): 2}
>>> )
>>> D = G.subgraph({0, 2})
>>> D
{(0, 2): -1, (0,): 3}
>>> G = DictArithmetic(
>>>     {(0, 1): -4, (0, 2): -1, (0,): 3, (1,): 2, (): 2}
>>> )
>>> D = G.subgraph({0, 1}, {2: -10})
>>> D
{(0, 1): -4, (0,): 13, (1,): 2}
>>> G = DictArithmetic(
>>>     {(0, 1): -4, (0, 2): -1, (0,): 3, (1,): 2, (): 2}
>>> )
>>> D = G.subgraph({0, 1})
>>> D
{(0, 1): -4, (0,): 3, (1,): 2}
subs(*args, **kwargs)

subs.

Replace any sympy symbols that are used in the dict with values. Please see help(sympy.Symbol.subs) for more info.

Parameters

arguments (substitutions.) – Same parameters as are inputted into sympy.Symbol.subs.

Returns

res – Same as self but with all the symbols replaced with values.

Return type

DictArithmetic object.

subvalue(values)

subvalue.

Replace each element in self with a value in values if it exists.

Parameters

values (dict.) – For each node v in self that is in values, we replace the node with values[v].

Returns

D

Return type

same as type(self)

Examples

>>> G = DictArithmetic(
>>>     {(0, 1): -4, (0, 2): -1, (0,): 3, (1,): 2, (): 2
>>> }
>>> D = G.subvalue({0: 2})
>>> D
{(1,): -6, (2,): -2, (): 8}
>>> G = DictArtihmetic(
>>>     {(0, 1): -4, (0, 2): -1, (0,): 3, (1,): 2, (): 2
>>> }
>>> D = G.subvalue({2: -3})
>>> D
{(0, 1): -4, (0,): 6, (1,): 2, (): 2}
>>> G = PUBO(
>>>     {(0, 1): -4, (0, 2): -1, (0,): 3, (1,): 2, (): 2
>>> }
>>> D = G.subvalue({2: -3})
>>> D
{(0, 1): -4, (0,): 6, (1,): 2, (): 2}
update(*args, **kwargs)

update.

Update the dictionary but following all the conventions of this class.

Parameters

arguments (defines a dictionary, ie d = dict(*args, **kwargs).) – Each element in d will be added in place to this instance following all the required convensions.

value(x)

value.

Find the value of \(\sum_{i,...,j} P_{i...j} x_{i} ... x_{j}\). Calling self.value(x) is the same as calling qubovert.utils.pubo_value(x, self).

Parameters

x (dict or iterable.) – Maps boolean variable indices to their boolean values, 0 or 1. Ie x[i] must be the boolean value of variable i.

Returns

value – The value of the PUBO with the given assignment x. Ie

Return type

float.

Example

>>> from qubovert.utils import QUBOMatrix, PUBOMatrix
>>> from qubovert import QUBO, PUBO
>>> P = PUBOMatrix({(0, 0): 1, (0, 1): -1})
>>> x = {0: 1, 1: 0}
>>> P.value(x)
1
>>> Q = QUBOMatrix({(0, 0): 1, (0, 1): -1})
>>> x = {0: 1, 1: 0}
>>> Q.value(x)
1
>>> P = PUBO({(0, 0): 1, (0, 1): -1})
>>> x = {0: 1, 1: 0}
>>> P.value(x)
1
>>> Q = QUBO({(0, 0): 1, (0, 1): -1})
>>> x = {0: 1, 1: 0}
>>> Q.value(x)
1
values() an object providing a view on D's values
property variables

variables.

Return a set of all the variables in the dict.

Returns

res

Return type

set.

PUSOMatrix

class qubovert.utils.PUSOMatrix(*args, **kwargs)

PUSOMatrix.

PUSOMatrix inherits some methods from DictArithmetic, see help(qubovert.utils.DictArithmetic).

PUSOMatrix inherits some methods from PUBOMatrix, see help(qubovert.utils.PUBOMatrix).

A class to handle PUSO matrices. It is the same thing as a dictionary with some methods modified. Note that each key must be a tuple of integers >= 0.

Note that below we only consider keys that are of length 1 or 2, but they can in general be arbitrarily long! See qubovert.utils.QUSOMatrix for an object that restricts the length to <= 2.

One method is that values will always default to 0. Consider the following example:

>>> d = PUSOMatrix()
>>> print(d[(0,)]) # will print 0
>>> d[(0,)] += 1
>>> print(d) # will print {(0,): 1}

One method of PUSOMatrix is that it will always keep the PUSO upper triangular! Consider the following example:

>>> d = PUSOMatrix()
>>> d[(1, 0)] += 2
>>> print(d)
>>> # will print {(0, 1): 2}

One method is that if we set an item to 0, it will be removed. Consider the following example:

>>> d = PUSOMatrix()
>>> d[(0,)] += 1
>>> d[(0,)] -= 1
>>> print(d) # will print {}

One method is that if we initialize PUSOMatrix with a previous dictionary it will be reinitialized to ensure that the PUSOMatrix is upper triangular and contains no zero values. Consider the following example:

>>> d = PUSOMatrix({(0,): 1, (1, 0): 2, (2, 0): 0, (2, 0, 1): 1})
>>> print(d) # will print {(0,): 1, (0, 1): 2, (0, 1, 2): 1}

We also change the update method so that it follows all the conventions.

>>> d = PUSOMatrix({(0,): 1, (0, 1): 2})
>>> d.update({(0,): 0, (1, 0): 1, (1, 2): -1})
>>> print(d)  # will print {(0, 1): 1, (1, 2): -1}

We also include arithmetic, addition, subtraction, scalar division, scalar multiplication, and all those in place. For example,

>>> d = PUSOMatrix((0,)=1, (0, 1)=-2)
>>> g = d + {(0,): -1}
>>> print(g) # will print {(0, 1): -2}
>>> g *= 4
>>> print(g) # will print {(0, 1): -8}
>>> g -= {(0, 1): -8}
>>> print(g) # will print {}
>>> d = PUSOMatrix({(0, 0): 1, (0, 1): -1})
>>> print(d)
{(): 1, (0, 1): -1}
>>> g = {(0,): -1, (1,): 1}
>>> d *= g
>>> print(d)
{(0,): -2, (1,): 2}
>>> d = PUSOMatrix({(0, 0): 1, (0, 1): -1})
>>> print(d ** 2 == d * d)
True

If we try to set a key with duplicated indices, it will squash the key into its equivalent form. For example (0, 1, 1, 2, 2, 2) is equivalent to (0, 2). Thus,

>>> d = PUSOMatrix()
>>> d[(0, 1, 1, 2, 2, 2)] += 1
>>> d[(0, 2)] += 2
>>> print(d)
{(0, 2): 3}

Adding or subtracting constants will update the () element of the dict.

>>> d = PUSOMatrix()
>>> d += 5
>>> print(d)
{(): 5}

Finally, if you try to access a key out of order, it will sort the key. Be careful with this, it can cause unexpected behavior if you don’t know it. For example,

>>> d = PUSOMatrix()
>>> d[(0, 1)] += 2
>>> print(d[(1, 0)])  # will print 2

__init__.

This class deals with Binary Optimization matrices. See child classes or qubovert.utils.DictArithmetic for details on the inputs.

Parameters

arguments (parameters.) – Defined in child classes or in qubovert.utils.DictArithmetic.

clear()

clear.

For efficiency, the internal variables for degree, num_binary_variables, max_index are computed as the dictionary is being built (and in subclasses such as qubovert.PUBO, properties such as mapping and reverse_mapping). This can cause these values to be wrong for some specific situations. Thus, when we clear, we also need to reset all of these cached values. This function remove all the elments from self and resets the cached values.

copy()

copy.

Same as dict.copy, but we adjust the method so that it returns a DictArithmetic object, or whatever object is the subclass.

Returns

d – Same as self.__class__.

Return type

DictArithmetic object, or subclass of.

classmethod create_var(name)

create_var.

Create the variable with name name.

Parameters

name (hashable object allowed as a key.) – Name of the variable.

Returns

res – The model representing the variable with type cls.

Return type

cls object.

Examples

>>> from qubovert.utils import DictArithmetic
>>>
>>> x = DictArithmetic.create_var('x')
>>> x == DictArithmetic({('x',): 1})
True
>>> isinstance(x, DictArithmetic)
True
>>> x.name
'x'
>>> from qubovert import QUSO
>>>
>>> z = QUSO.create_var('z')
>>> print(z)
{('z',): 1}
>>> print(isinstance(z, QUSO))
True
>>> print(z.name)
'z'
property degree

degree.

Return the degree of the problem.

Returns

deg

Return type

int.

fromkeys(value=None, /)

Create a new dictionary with keys from iterable and values set to value.

get(key, default=None, /)

Return the value for key if key is in the dictionary, else default.

is_solution_valid(solution)

is_solution_valid.

Included for consistency with other problem classes. Always returns True since this is an unconstrainted problem.

Parameters

solution (iterable or dict.) –

Returns

valid – Always returns True.

Return type

bool.

items() a set-like object providing a view on D's items
keys() a set-like object providing a view on D's keys
property max_index

max_index.

Returns the maximum label index of the problem. If the problem is labeled with integers from 0 to n-1, then max_index will give the same result as num_binary_variables - 1.

Returns

n – Max label index of the problem dictionary. If the dict is empty, then this returns None.

Return type

int or None.

property name

name.

Return the name of the object.

Returns

name

Return type

object.

Example

>>> d = DictArithmetic()
>>> d.name
None
>>> d.name = 'd'
>>> d.name
'd'
normalize(value=1)

normalize.

Normalize the coefficients to a maximum magnitude.

Parameters

value (float (optional, defaults to 1)) – Every coefficient value will be normalized such that the coefficient with the maximum magnitude will be +/- 1.

Examples

>>> from qubovert.utils import DictArithmetic
>>> d = DictArithmetic({(0, 1): 1, (1, 2, 'x'): 4})
>>> d.normalize()
>>> print(d)
{(0, 1): 0.25, (1, 2, 'x'): 1}
>>> from qubovert.utils import DictArithmetic
>>> d = DictArithmetic({(0, 1): 1, (1, 2, 'x'): -4})
>>> d.normalize()
>>> print(d)
{(0, 1): 0.25, (1, 2, 'x'): -1}
>>> from qubovert import PUBO
>>> d = PUBO({(0, 1): 1, (1, 2, 'x'): 4})
>>> d.normalize()
>>> print(d)
{(0, 1): 0.25, (1, 2, 'x'): 1}
>>> from qubovert.utils import PUBO
>>> d = PUBO({(0, 1): 1, (1, 2, 'x'): -4})
>>> d.normalize()
>>> print(d)
{(0, 1): 0.25, (1, 2, 'x'): -1}
property num_binary_variables

num_binary_variables.

Return the number of binary variables in the problem.

Returns

n – Number of binary variables in the problem.

Return type

int.

property num_terms

num_terms.

Return the number of terms in the dictionary.

Returns

n – Number of terms in the dictionary.

Return type

int.

property offset

offset.

Get the part that does not depend on any variables. Ie the value corresponding to the () key.

Returns

offset

Return type

float.

pop(k[, d]) v, remove specified key and return the corresponding value.

If key is not found, d is returned if given, otherwise KeyError is raised

popitem()

Remove and return a (key, value) pair as a 2-tuple.

Pairs are returned in LIFO (last-in, first-out) order. Raises KeyError if the dict is empty.

pretty_str(var_prefix='z')

pretty_str.

Return a pretty string representation of the model.

Parameters

var_prefix (str (optional, defaults to 'z').) – The prefix for the variables.

Returns

res

Return type

str.

refresh()

refresh.

For efficiency, the internal variables for degree, num_binary_variables, max_index are computed as the dictionary is being built (and in subclasses such as qubovert.PUBO, properties such as mapping and reverse_mapping). This can cause these values to be wrong for some specific situations. Calling refresh will rebuild the dictionary, resetting all of the values.

Examples

>>> from qubovert.utils import PUBOMatrix
>>> P = PUBOMatrix()
>>> P[(0,)] += 1
>>> P, P.degree, P.num_binary_variables
{(0,): 1}, 1, 1
>>> P[(0,)] -= 1
>>> P, P.degree, P.num_binary_variables
{}, 1, 1
>>> P.refresh()
>>> P, P.degree, P.num_binary_variables
{}, 0, 0
>>> from qubovert import PUBO
>>> P = PUBO()
>>> P[('a',)] += 1
>>> P, P.mapping, P.reverse_mapping
{('a',): 1}, {'a': 0}, {0: 'a'}
>>> P[('a',)] -= 1
>>> P, P.mapping, P.reverse_mapping
{}, {'a': 0}, {0: 'a'}
>>> P.refresh()
>>> P, P.mapping, P.reverse_mapping
{}, {}, {}
setdefault(key, default=None, /)

Insert key with a value of default if key is not in the dictionary.

Return the value for key if key is in the dictionary, else default.

simplify()

simplify.

If self has any symbolic expressions, this will go through and simplify them. This will also make everything a float!

Returns

Return type

None. Updates it in place.

solve_bruteforce(all_solutions=False)

solve_bruteforce.

Solve the problem bruteforce. THIS SHOULD NOT BE USED FOR LARGE PROBLEMS! This is the exact same as calling ``qubovert.utils.solve_puso_bruteforce(

self, all_solutions, self.is_solution_valid)[1]``.

Parameters

all_solutions (bool.) – See the description of the all_solutions parameter in qubovert.utils.solve_puso_bruteforce.

Returns

resqubovert.utils.solve_puso_bruteforce.

Return type

the second element of the two element tuple that is returned from

classmethod squash_key(key)

squash_key.

Will convert the input key into the standard form for PUSOMatrix / QUSOMatrix. It will get rid of pairs of duplicates and sort. This method will check to see if the input key is valid.

Parameters

key (tuple of integers.) –

Returns

k – A sorted and squashed version of key.

Return type

tuple of integers.

Example

>>> squash_key((0, 4, 0, 3, 3, 2, 3))
>>> (2, 3, 4)
subgraph(nodes, connections=None)

subgraph.

Create the subgraph of self that only includes vertices in nodes, and external nodes are given the values in connections.

Parameters
  • nodes (set.) – Nodes of self to include in the subgraph.

  • connections (dict (optional, defaults to {})) – For each node in self that is not in nodes, we assign a value given by connections.get(node, 0).

Returns

D – The subgraph of self with nodes in nodes and the values of the nodes not included given by connections.

Return type

same as type(self)

Notes

Any offset value included in self (ie {(): 1}) will be ignored, however there may be an offset in the output D.

Examples

>>> G = DictArithmetic(
>>>     {(0, 1): -4, (0, 2): -1, (0,): 3, (1,): 2, (): 2}
>>> )
>>> D = G.subgraph({0, 2}, {1: 5})
>>> D
{(0,): -17, (0, 2): -1, (): 10}
>>> G = DictArithmetic(
>>>     {(0, 1): -4, (0, 2): -1, (0,): 3, (1,): 2, (): 2}
>>> )
>>> D = G.subgraph({0, 2})
>>> D
{(0, 2): -1, (0,): 3}
>>> G = DictArithmetic(
>>>     {(0, 1): -4, (0, 2): -1, (0,): 3, (1,): 2, (): 2}
>>> )
>>> D = G.subgraph({0, 1}, {2: -10})
>>> D
{(0, 1): -4, (0,): 13, (1,): 2}
>>> G = DictArithmetic(
>>>     {(0, 1): -4, (0, 2): -1, (0,): 3, (1,): 2, (): 2}
>>> )
>>> D = G.subgraph({0, 1})
>>> D
{(0, 1): -4, (0,): 3, (1,): 2}
subs(*args, **kwargs)

subs.

Replace any sympy symbols that are used in the dict with values. Please see help(sympy.Symbol.subs) for more info.

Parameters

arguments (substitutions.) – Same parameters as are inputted into sympy.Symbol.subs.

Returns

res – Same as self but with all the symbols replaced with values.

Return type

DictArithmetic object.

subvalue(values)

subvalue.

Replace each element in self with a value in values if it exists.

Parameters

values (dict.) – For each node v in self that is in values, we replace the node with values[v].

Returns

D

Return type

same as type(self)

Examples

>>> G = DictArithmetic(
>>>     {(0, 1): -4, (0, 2): -1, (0,): 3, (1,): 2, (): 2
>>> }
>>> D = G.subvalue({0: 2})
>>> D
{(1,): -6, (2,): -2, (): 8}
>>> G = DictArtihmetic(
>>>     {(0, 1): -4, (0, 2): -1, (0,): 3, (1,): 2, (): 2
>>> }
>>> D = G.subvalue({2: -3})
>>> D
{(0, 1): -4, (0,): 6, (1,): 2, (): 2}
>>> G = PUBO(
>>>     {(0, 1): -4, (0, 2): -1, (0,): 3, (1,): 2, (): 2
>>> }
>>> D = G.subvalue({2: -3})
>>> D
{(0, 1): -4, (0,): 6, (1,): 2, (): 2}
update(*args, **kwargs)

update.

Update the dictionary but following all the conventions of this class.

Parameters

arguments (defines a dictionary, ie d = dict(*args, **kwargs).) – Each element in d will be added in place to this instance following all the required convensions.

value(z)

value.

Find the value of

\(\sum_{i,...,j} H_{i...j} z_{i} ... z_{j}\). Calling self.value(z) is the same as calling qubovert.utils.puso_value(z, self).

Parameters

z (dict or iterable.) – Maps variable labels to their values, -1 or 1. Ie z[i] must be the value of variable i.

Returns

value – The value of the PUSO/QUSO with the given assignment z.

Return type

float.

Example

>>> from qubovert.utils import QUSOMatrix, PUSOMatrix
>>> from qubovert import QUSO, PUSO
>>> H = PUSOMatrix({(0, 1): -1, (0,): 1})
>>> z = {0: -1, 1: 1}
>>> H.value(z)
0
>>> H = PUSO({(0, 1): -1, (0,): 1})
>>> z = {0: -1, 1: 1}
>>> H.value(z)
0
>>> L = QUSOMatrix({(0, 1): -1, (0,): 1})
>>> z = {0: -1, 1: 1}
>>> L.value(z)
0
>>> L = QUSO({(0, 1): -1, (0,): 1})
>>> z = {0: -1, 1: 1}
>>> L.value(z)
0
values() an object providing a view on D's values
property variables

variables.

Return a set of all the variables in the dict.

Returns

res

Return type

set.

QUBOMatrix

class qubovert.utils.QUBOMatrix(*args, **kwargs)

QUBOMatrix.

QUBOMatrix inherits some methods from PUBOMatrix, see help(qubovert.utils.PUBOMattrix).

A class to handle QUBO matrices. It is the same thing as a dictionary with some methods modified. Note that each key must be a tuple of two integers >= 0.

One method is that values will always default to 0. Consider the following example:

>>> d = QUBOMatrix()
>>> print(d[(0,)]) # will print 0
>>> d[(0,)] += 1
>>> print(d) # will print {(0,): 1}

Compared to an ordinary dictionary.

>>> g = dict()
>>> print(g[(0,)]) # will raise KeyError
>>> g[(0,)] += 1 # will raise KeyError, since (0,) was never set

One method of QUBOMatrix is that it will always keep the QUBO upper triangular! Consider the following example:

>>> d = QUBOMatrix()
>>> d[(1, 0)] += 2
>>> print(d)
>>> # will print {(0, 1): 2}

One method is that if we set an item to 0, it will be removed. Consider the following example:

>>> d = QUBOMatrix()
>>> d[(0,)] += 1
>>> d[(0,)] -= 1
>>> print(d) # will print {}

One method is that if we initialize QUBOMatrix with a previous dictionary it will be reinitialized to ensure that the QUBOMatrix is upper triangular and contains no zero values. Consider the following example:

>>> d = QUBOMatrix({(0, 0): 1, (1, 0): 2, (2, 0): 0})
>>> print(d) # will print {(0, 0): 1, (0, 1): 2}

We also change the update method so that it follows all the conventions.

>>> d = QUBOMatrix({(0, 0): 1, (0, 1): 2})
>>> d.update({(0, 0): 0, (1, 0): 1, (1, 1): -1})
>>> print(d)  # will print {(0, 1): 1, (1,): -1}

We also include arithmetic, addition, subtraction, scalar division, multiplication, and all those in place. For example,

>>> d = QUBOMatrix((0, 0)=1, (0, 1)=-2)
>>> g = d + {(0, 0): -1}
>>> print(g) # will print {(0, 1): -2}
>>> g *= 4
>>> print(g) # will print {(0, 1): -8}
>>> g -= {(0, 1): -8}
>>> print(g) # will print {}
>>> d = QUBOMatrix({(0, 0): 1, (0, 1): -1})
>>> g = {(0,): -1, (1,): 1}
>>> d *= g
>>> print(d)
{(0,): -1, (0, 1): 1}
>>> d = QUBOMatrix({(0, 0): 1, (0, 1): -1})
>>> print(d ** 2 == d * d)
True

Adding or subtracting constants will update the () element of the dict.

>>> d = QUBOMatrix()
>>> d += 5
>>> print(d)
{(): 5}

Finally, if you try to access a key out of order, it will sort and squash the key. Be careful with this, it can cause unexpected behavior if you don’t know it. For example,

>>> d = QUBOMatrix()
>>> d[(0, 1)] += 2
>>> print(d[(1, 0)])  # will print 2
>>> d = QUBOMatrix()
>>> d[(0, 0)] += 2
>>> print(d[(0,)])  # will print 2
>>> print(d[(0, 0)])  # will print 2
>>> print(d)  # will print {(0,): 2}

__init__.

This class deals with Binary Optimization matrices. See child classes or qubovert.utils.DictArithmetic for details on the inputs.

Parameters

arguments (parameters.) – Defined in child classes or in qubovert.utils.DictArithmetic.

property Q

Return a plain dictionary representing the QUBO. Each key is a tuple of two integers, ie (1, 1) corresponds to (1,). Note that the offset in the QUBOMatrix is ignored (ie the value corresponding to the key ()). See the offset property to access it.

Returns

Q – Plain dictionary representing the QUBO in standard form.

Return type

dict.

clear()

clear.

For efficiency, the internal variables for degree, num_binary_variables, max_index are computed as the dictionary is being built (and in subclasses such as qubovert.PUBO, properties such as mapping and reverse_mapping). This can cause these values to be wrong for some specific situations. Thus, when we clear, we also need to reset all of these cached values. This function remove all the elments from self and resets the cached values.

copy()

copy.

Same as dict.copy, but we adjust the method so that it returns a DictArithmetic object, or whatever object is the subclass.

Returns

d – Same as self.__class__.

Return type

DictArithmetic object, or subclass of.

classmethod create_var(name)

create_var.

Create the variable with name name.

Parameters

name (hashable object allowed as a key.) – Name of the variable.

Returns

res – The model representing the variable with type cls.

Return type

cls object.

Examples

>>> from qubovert.utils import DictArithmetic
>>>
>>> x = DictArithmetic.create_var('x')
>>> x == DictArithmetic({('x',): 1})
True
>>> isinstance(x, DictArithmetic)
True
>>> x.name
'x'
>>> from qubovert import QUSO
>>>
>>> z = QUSO.create_var('z')
>>> print(z)
{('z',): 1}
>>> print(isinstance(z, QUSO))
True
>>> print(z.name)
'z'
property degree

degree.

Return the degree of the problem.

Returns

deg

Return type

int.

fromkeys(value=None, /)

Create a new dictionary with keys from iterable and values set to value.

get(key, default=None, /)

Return the value for key if key is in the dictionary, else default.

is_solution_valid(solution)

is_solution_valid.

Included for consistency with other problem classes. Always returns True since this is an unconstrainted problem.

Parameters

solution (iterable or dict.) –

Returns

valid – Always returns True.

Return type

bool.

items() a set-like object providing a view on D's items
keys() a set-like object providing a view on D's keys
property max_index

max_index.

Returns the maximum label index of the problem. If the problem is labeled with integers from 0 to n-1, then max_index will give the same result as num_binary_variables - 1.

Returns

n – Max label index of the problem dictionary. If the dict is empty, then this returns None.

Return type

int or None.

property name

name.

Return the name of the object.

Returns

name

Return type

object.

Example

>>> d = DictArithmetic()
>>> d.name
None
>>> d.name = 'd'
>>> d.name
'd'
normalize(value=1)

normalize.

Normalize the coefficients to a maximum magnitude.

Parameters

value (float (optional, defaults to 1)) – Every coefficient value will be normalized such that the coefficient with the maximum magnitude will be +/- 1.

Examples

>>> from qubovert.utils import DictArithmetic
>>> d = DictArithmetic({(0, 1): 1, (1, 2, 'x'): 4})
>>> d.normalize()
>>> print(d)
{(0, 1): 0.25, (1, 2, 'x'): 1}
>>> from qubovert.utils import DictArithmetic
>>> d = DictArithmetic({(0, 1): 1, (1, 2, 'x'): -4})
>>> d.normalize()
>>> print(d)
{(0, 1): 0.25, (1, 2, 'x'): -1}
>>> from qubovert import PUBO
>>> d = PUBO({(0, 1): 1, (1, 2, 'x'): 4})
>>> d.normalize()
>>> print(d)
{(0, 1): 0.25, (1, 2, 'x'): 1}
>>> from qubovert.utils import PUBO
>>> d = PUBO({(0, 1): 1, (1, 2, 'x'): -4})
>>> d.normalize()
>>> print(d)
{(0, 1): 0.25, (1, 2, 'x'): -1}
property num_binary_variables

num_binary_variables.

Return the number of binary variables in the problem.

Returns

n – Number of binary variables in the problem.

Return type

int.

property num_terms

num_terms.

Return the number of terms in the dictionary.

Returns

n – Number of terms in the dictionary.

Return type

int.

property offset

offset.

Get the part that does not depend on any variables. Ie the value corresponding to the () key.

Returns

offset

Return type

float.

pop(k[, d]) v, remove specified key and return the corresponding value.

If key is not found, d is returned if given, otherwise KeyError is raised

popitem()

Remove and return a (key, value) pair as a 2-tuple.

Pairs are returned in LIFO (last-in, first-out) order. Raises KeyError if the dict is empty.

pretty_str(var_prefix='x')

pretty_str.

Return a pretty string representation of the model.

Parameters

var_prefix (str (optional, defaults to 'x').) – The prefix for the variables.

Returns

res

Return type

str.

refresh()

refresh.

For efficiency, the internal variables for degree, num_binary_variables, max_index are computed as the dictionary is being built (and in subclasses such as qubovert.PUBO, properties such as mapping and reverse_mapping). This can cause these values to be wrong for some specific situations. Calling refresh will rebuild the dictionary, resetting all of the values.

Examples

>>> from qubovert.utils import PUBOMatrix
>>> P = PUBOMatrix()
>>> P[(0,)] += 1
>>> P, P.degree, P.num_binary_variables
{(0,): 1}, 1, 1
>>> P[(0,)] -= 1
>>> P, P.degree, P.num_binary_variables
{}, 1, 1
>>> P.refresh()
>>> P, P.degree, P.num_binary_variables
{}, 0, 0
>>> from qubovert import PUBO
>>> P = PUBO()
>>> P[('a',)] += 1
>>> P, P.mapping, P.reverse_mapping
{('a',): 1}, {'a': 0}, {0: 'a'}
>>> P[('a',)] -= 1
>>> P, P.mapping, P.reverse_mapping
{}, {'a': 0}, {0: 'a'}
>>> P.refresh()
>>> P, P.mapping, P.reverse_mapping
{}, {}, {}
setdefault(key, default=None, /)

Insert key with a value of default if key is not in the dictionary.

Return the value for key if key is in the dictionary, else default.

simplify()

simplify.

If self has any symbolic expressions, this will go through and simplify them. This will also make everything a float!

Returns

Return type

None. Updates it in place.

solve_bruteforce(all_solutions=False)

solve_bruteforce.

Solve the problem bruteforce. THIS SHOULD NOT BE USED FOR LARGE PROBLEMS! This is the exact same as calling ``qubovert.utils.solve_qubo_bruteforce(

self, all_solutions, self.is_solution_valid)[1]``.

Parameters

all_solutions (bool.) – See the description of the all_solutions parameter in qubovert.utils.solve_qubo_bruteforce.

Returns

resqubovert.utils.solve_qubo_bruteforce.

Return type

the second element of the two element tuple that is returned from

classmethod squash_key(key)

squash_key.

Will convert the input key into the standard form for PUBOMatrix / QUBOMatrix. It will get rid of duplicates and sort. This method will check to see if the input key is valid.

Parameters

key (tuple of integers.) –

Returns

k – A sorted and squashed version of key.

Return type

tuple of integers.

Raises

KeyError if the key is invalid.

Example

>>> squash_key((0, 4, 0, 3, 3, 2))
>>> (0, 2, 3, 4)
subgraph(nodes, connections=None)

subgraph.

Create the subgraph of self that only includes vertices in nodes, and external nodes are given the values in connections.

Parameters
  • nodes (set.) – Nodes of self to include in the subgraph.

  • connections (dict (optional, defaults to {})) – For each node in self that is not in nodes, we assign a value given by connections.get(node, 0).

Returns

D – The subgraph of self with nodes in nodes and the values of the nodes not included given by connections.

Return type

same as type(self)

Notes

Any offset value included in self (ie {(): 1}) will be ignored, however there may be an offset in the output D.

Examples

>>> G = DictArithmetic(
>>>     {(0, 1): -4, (0, 2): -1, (0,): 3, (1,): 2, (): 2}
>>> )
>>> D = G.subgraph({0, 2}, {1: 5})
>>> D
{(0,): -17, (0, 2): -1, (): 10}
>>> G = DictArithmetic(
>>>     {(0, 1): -4, (0, 2): -1, (0,): 3, (1,): 2, (): 2}
>>> )
>>> D = G.subgraph({0, 2})
>>> D
{(0, 2): -1, (0,): 3}
>>> G = DictArithmetic(
>>>     {(0, 1): -4, (0, 2): -1, (0,): 3, (1,): 2, (): 2}
>>> )
>>> D = G.subgraph({0, 1}, {2: -10})
>>> D
{(0, 1): -4, (0,): 13, (1,): 2}
>>> G = DictArithmetic(
>>>     {(0, 1): -4, (0, 2): -1, (0,): 3, (1,): 2, (): 2}
>>> )
>>> D = G.subgraph({0, 1})
>>> D
{(0, 1): -4, (0,): 3, (1,): 2}
subs(*args, **kwargs)

subs.

Replace any sympy symbols that are used in the dict with values. Please see help(sympy.Symbol.subs) for more info.

Parameters

arguments (substitutions.) – Same parameters as are inputted into sympy.Symbol.subs.

Returns

res – Same as self but with all the symbols replaced with values.

Return type

DictArithmetic object.

subvalue(values)

subvalue.

Replace each element in self with a value in values if it exists.

Parameters

values (dict.) – For each node v in self that is in values, we replace the node with values[v].

Returns

D

Return type

same as type(self)

Examples

>>> G = DictArithmetic(
>>>     {(0, 1): -4, (0, 2): -1, (0,): 3, (1,): 2, (): 2
>>> }
>>> D = G.subvalue({0: 2})
>>> D
{(1,): -6, (2,): -2, (): 8}
>>> G = DictArtihmetic(
>>>     {(0, 1): -4, (0, 2): -1, (0,): 3, (1,): 2, (): 2
>>> }
>>> D = G.subvalue({2: -3})
>>> D
{(0, 1): -4, (0,): 6, (1,): 2, (): 2}
>>> G = PUBO(
>>>     {(0, 1): -4, (0, 2): -1, (0,): 3, (1,): 2, (): 2
>>> }
>>> D = G.subvalue({2: -3})
>>> D
{(0, 1): -4, (0,): 6, (1,): 2, (): 2}
update(*args, **kwargs)

update.

Update the dictionary but following all the conventions of this class.

Parameters

arguments (defines a dictionary, ie d = dict(*args, **kwargs).) – Each element in d will be added in place to this instance following all the required convensions.

value(x)

value.

Find the value of the QUBO. Calling self.value(x) is the same as calling qubovert.utils.qubo_value(x, self).

Parameters

x (dict or iterable.) – Maps boolean variable indices to their boolean values, 0 or 1. Ie x[i] must be the boolean value of variable i.

Returns

value – The value of the QUBO with the given assignment x. Ie

Return type

float.

Example

>>> from qubovert.utils import QUBOMatrix, PUBOMatrix
>>> from qubovert import QUBO, PUBO
>>> P = PUBOMatrix({(0, 0): 1, (0, 1): -1})
>>> x = {0: 1, 1: 0}
>>> P.value(x)
1
>>> Q = QUBOMatrix({(0, 0): 1, (0, 1): -1})
>>> x = {0: 1, 1: 0}
>>> Q.value(x)
1
>>> P = PUBO({(0, 0): 1, (0, 1): -1})
>>> x = {0: 1, 1: 0}
>>> P.value(x)
1
>>> Q = QUBO({(0, 0): 1, (0, 1): -1})
>>> x = {0: 1, 1: 0}
>>> Q.value(x)
1
values() an object providing a view on D's values
property variables

variables.

Return a set of all the variables in the dict.

Returns

res

Return type

set.

QUSOMatrix

class qubovert.utils.QUSOMatrix(*args, **kwargs)

QUSOMatrix.

QUSOMatrix inherits some methods from PUSOMatrix, see help(qubovert.utils.PUSOMatrix).

A class to handle QUSO matrices. It is the same thing as a dictionary with some methods modified. Note that each key must be a tuple integers >= 0.

One method is that values will always default to 0. Consider the following example:

>>> d = QUSOMatrix()
>>> print(d[(0,)]) # will print 0
>>> d[(0,)] += 1
>>> print(d) # will print {(0,): 1}

One method of QUSOMatrix is that it will always keep the QUSO upper triangular! Consider the following example:

>>> d = QUSOMatrix()
>>> d[(1, 0)] += 2
>>> print(d)
>>> # will print {(0, 1): 2}

One method is that if we set an item to 0, it will be removed. Consider the following example:

>>> d = QUSOMatrix()
>>> d[(0, 1)] += 1
>>> d[(0, 1)] -= 1
>>> print(d) # will print {}

One method is that if we initialize QUSOMatrix with a previous dictionary it will be reinitialized to ensure that the QUSOMatrix is upper triangular and contains no zero values. Consider the following example:

>>> d = QUSOMatrix({(0,): 1, (1, 0): 2, (2, 0): 0})
>>> print(d) # will print {(0,): 1, (0, 1): 2}

We also change the update method so that it follows all the conventions.

>>> d = Isingatrix({(0,): 1, (0, 1): 2})
>>> d.update({(0,): 0, (1, 0): 1, (1,): -1})
>>> print(d)  # will print {(0, 1): 1, (1,): -1}

We also include arithmetic, addition, subtraction, scalar division, multiplication, and all those in place. For example,

>>> d = QUSOMatrix((0,)=1, (0, 1)=-2)
>>> g = d + {(0,): -1}
>>> print(g) # will print {(0, 1): -2}
>>> g *= 4
>>> print(g) # will print {(0, 1): -8}
>>> g -= {(0, 1): -8}
>>> print(g) # will print {}
>>> d = QUSOMatrix({(0, 0): 1, (0, 1): -1})
>>> print(d)
{(): 1, (0, 1): -1}
>>> g = {(0,): -1, (1,): 1}
>>> d *= g
>>> print(d)
{(0,): -2, (1,): 2}
>>> d = QUSOMatrix({(0, 0): 1, (0, 1): -1})
>>> print(d ** 2 == d * d)
True

Adding or subtracting constants will update the () element of the dict.

>>> d = QUSOMatrix()
>>> d += 5
>>> print(d)
{(): 5}

Finally, if you try to access a key out of order, it will sort the key. Be careful with this, it can cause unexpected behavior if you don’t know it. For example,

>>> d = QUSOMatrix()
>>> d[(0, 1)] += 2
>>> print(d[(1, 0)])  # will print 2

__init__.

This class deals with Binary Optimization matrices. See child classes or qubovert.utils.DictArithmetic for details on the inputs.

Parameters

arguments (parameters.) – Defined in child classes or in qubovert.utils.DictArithmetic.

property J

Return a plain dictionary representing the QUSO coupling values. Each key is an integer.

Returns

J – Plain dictionary representing the QUSO coupling values.

Return type

dict.

clear()

clear.

For efficiency, the internal variables for degree, num_binary_variables, max_index are computed as the dictionary is being built (and in subclasses such as qubovert.PUBO, properties such as mapping and reverse_mapping). This can cause these values to be wrong for some specific situations. Thus, when we clear, we also need to reset all of these cached values. This function remove all the elments from self and resets the cached values.

copy()

copy.

Same as dict.copy, but we adjust the method so that it returns a DictArithmetic object, or whatever object is the subclass.

Returns

d – Same as self.__class__.

Return type

DictArithmetic object, or subclass of.

classmethod create_var(name)

create_var.

Create the variable with name name.

Parameters

name (hashable object allowed as a key.) – Name of the variable.

Returns

res – The model representing the variable with type cls.

Return type

cls object.

Examples

>>> from qubovert.utils import DictArithmetic
>>>
>>> x = DictArithmetic.create_var('x')
>>> x == DictArithmetic({('x',): 1})
True
>>> isinstance(x, DictArithmetic)
True
>>> x.name
'x'
>>> from qubovert import QUSO
>>>
>>> z = QUSO.create_var('z')
>>> print(z)
{('z',): 1}
>>> print(isinstance(z, QUSO))
True
>>> print(z.name)
'z'
property degree

degree.

Return the degree of the problem.

Returns

deg

Return type

int.

fromkeys(value=None, /)

Create a new dictionary with keys from iterable and values set to value.

get(key, default=None, /)

Return the value for key if key is in the dictionary, else default.

property h

Return a plain dictionary representing the QUSO field values. Each key is an integer.

Returns

h – Plain dictionary representing the QUSO field values.

Return type

dict.

is_solution_valid(solution)

is_solution_valid.

Included for consistency with other problem classes. Always returns True since this is an unconstrainted problem.

Parameters

solution (iterable or dict.) –

Returns

valid – Always returns True.

Return type

bool.

items() a set-like object providing a view on D's items
keys() a set-like object providing a view on D's keys
property max_index

max_index.

Returns the maximum label index of the problem. If the problem is labeled with integers from 0 to n-1, then max_index will give the same result as num_binary_variables - 1.

Returns

n – Max label index of the problem dictionary. If the dict is empty, then this returns None.

Return type

int or None.

property name

name.

Return the name of the object.

Returns

name

Return type

object.

Example

>>> d = DictArithmetic()
>>> d.name
None
>>> d.name = 'd'
>>> d.name
'd'
normalize(value=1)

normalize.

Normalize the coefficients to a maximum magnitude.

Parameters

value (float (optional, defaults to 1)) – Every coefficient value will be normalized such that the coefficient with the maximum magnitude will be +/- 1.

Examples

>>> from qubovert.utils import DictArithmetic
>>> d = DictArithmetic({(0, 1): 1, (1, 2, 'x'): 4})
>>> d.normalize()
>>> print(d)
{(0, 1): 0.25, (1, 2, 'x'): 1}
>>> from qubovert.utils import DictArithmetic
>>> d = DictArithmetic({(0, 1): 1, (1, 2, 'x'): -4})
>>> d.normalize()
>>> print(d)
{(0, 1): 0.25, (1, 2, 'x'): -1}
>>> from qubovert import PUBO
>>> d = PUBO({(0, 1): 1, (1, 2, 'x'): 4})
>>> d.normalize()
>>> print(d)
{(0, 1): 0.25, (1, 2, 'x'): 1}
>>> from qubovert.utils import PUBO
>>> d = PUBO({(0, 1): 1, (1, 2, 'x'): -4})
>>> d.normalize()
>>> print(d)
{(0, 1): 0.25, (1, 2, 'x'): -1}
property num_binary_variables

num_binary_variables.

Return the number of binary variables in the problem.

Returns

n – Number of binary variables in the problem.

Return type

int.

property num_terms

num_terms.

Return the number of terms in the dictionary.

Returns

n – Number of terms in the dictionary.

Return type

int.

property offset

offset.

Get the part that does not depend on any variables. Ie the value corresponding to the () key.

Returns

offset

Return type

float.

pop(k[, d]) v, remove specified key and return the corresponding value.

If key is not found, d is returned if given, otherwise KeyError is raised

popitem()

Remove and return a (key, value) pair as a 2-tuple.

Pairs are returned in LIFO (last-in, first-out) order. Raises KeyError if the dict is empty.

pretty_str(var_prefix='z')

pretty_str.

Return a pretty string representation of the model.

Parameters

var_prefix (str (optional, defaults to 'z').) – The prefix for the variables.

Returns

res

Return type

str.

refresh()

refresh.

For efficiency, the internal variables for degree, num_binary_variables, max_index are computed as the dictionary is being built (and in subclasses such as qubovert.PUBO, properties such as mapping and reverse_mapping). This can cause these values to be wrong for some specific situations. Calling refresh will rebuild the dictionary, resetting all of the values.

Examples

>>> from qubovert.utils import PUBOMatrix
>>> P = PUBOMatrix()
>>> P[(0,)] += 1
>>> P, P.degree, P.num_binary_variables
{(0,): 1}, 1, 1
>>> P[(0,)] -= 1
>>> P, P.degree, P.num_binary_variables
{}, 1, 1
>>> P.refresh()
>>> P, P.degree, P.num_binary_variables
{}, 0, 0
>>> from qubovert import PUBO
>>> P = PUBO()
>>> P[('a',)] += 1
>>> P, P.mapping, P.reverse_mapping
{('a',): 1}, {'a': 0}, {0: 'a'}
>>> P[('a',)] -= 1
>>> P, P.mapping, P.reverse_mapping
{}, {'a': 0}, {0: 'a'}
>>> P.refresh()
>>> P, P.mapping, P.reverse_mapping
{}, {}, {}
setdefault(key, default=None, /)

Insert key with a value of default if key is not in the dictionary.

Return the value for key if key is in the dictionary, else default.

simplify()

simplify.

If self has any symbolic expressions, this will go through and simplify them. This will also make everything a float!

Returns

Return type

None. Updates it in place.

solve_bruteforce(all_solutions=False)

solve_bruteforce.

Solve the problem bruteforce. THIS SHOULD NOT BE USED FOR LARGE PROBLEMS! This is the exact same as calling ``qubovert.utils.solve_quso_bruteforce(

self, all_solutions, self.is_solution_valid)[1]``.

Parameters

all_solutions (bool.) – See the description of the all_solutions parameter in qubovert.utils.solve_quso_bruteforce.

Returns

resqubovert.utils.solve_quso_bruteforce.

Return type

the second element of the two element tuple that is returned from

classmethod squash_key(key)

squash_key.

Will convert the input key into the standard form for PUSOMatrix / QUSOMatrix. It will get rid of pairs of duplicates and sort. This method will check to see if the input key is valid.

Parameters

key (tuple of integers.) –

Returns

k – A sorted and squashed version of key.

Return type

tuple of integers.

Example

>>> squash_key((0, 4, 0, 3, 3, 2, 3))
>>> (2, 3, 4)
subgraph(nodes, connections=None)

subgraph.

Create the subgraph of self that only includes vertices in nodes, and external nodes are given the values in connections.

Parameters
  • nodes (set.) – Nodes of self to include in the subgraph.

  • connections (dict (optional, defaults to {})) – For each node in self that is not in nodes, we assign a value given by connections.get(node, 0).

Returns

D – The subgraph of self with nodes in nodes and the values of the nodes not included given by connections.

Return type

same as type(self)

Notes

Any offset value included in self (ie {(): 1}) will be ignored, however there may be an offset in the output D.

Examples

>>> G = DictArithmetic(
>>>     {(0, 1): -4, (0, 2): -1, (0,): 3, (1,): 2, (): 2}
>>> )
>>> D = G.subgraph({0, 2}, {1: 5})
>>> D
{(0,): -17, (0, 2): -1, (): 10}
>>> G = DictArithmetic(
>>>     {(0, 1): -4, (0, 2): -1, (0,): 3, (1,): 2, (): 2}
>>> )
>>> D = G.subgraph({0, 2})
>>> D
{(0, 2): -1, (0,): 3}
>>> G = DictArithmetic(
>>>     {(0, 1): -4, (0, 2): -1, (0,): 3, (1,): 2, (): 2}
>>> )
>>> D = G.subgraph({0, 1}, {2: -10})
>>> D
{(0, 1): -4, (0,): 13, (1,): 2}
>>> G = DictArithmetic(
>>>     {(0, 1): -4, (0, 2): -1, (0,): 3, (1,): 2, (): 2}
>>> )
>>> D = G.subgraph({0, 1})
>>> D
{(0, 1): -4, (0,): 3, (1,): 2}
subs(*args, **kwargs)

subs.

Replace any sympy symbols that are used in the dict with values. Please see help(sympy.Symbol.subs) for more info.

Parameters

arguments (substitutions.) – Same parameters as are inputted into sympy.Symbol.subs.

Returns

res – Same as self but with all the symbols replaced with values.

Return type

DictArithmetic object.

subvalue(values)

subvalue.

Replace each element in self with a value in values if it exists.

Parameters

values (dict.) – For each node v in self that is in values, we replace the node with values[v].

Returns

D

Return type

same as type(self)

Examples

>>> G = DictArithmetic(
>>>     {(0, 1): -4, (0, 2): -1, (0,): 3, (1,): 2, (): 2
>>> }
>>> D = G.subvalue({0: 2})
>>> D
{(1,): -6, (2,): -2, (): 8}
>>> G = DictArtihmetic(
>>>     {(0, 1): -4, (0, 2): -1, (0,): 3, (1,): 2, (): 2
>>> }
>>> D = G.subvalue({2: -3})
>>> D
{(0, 1): -4, (0,): 6, (1,): 2, (): 2}
>>> G = PUBO(
>>>     {(0, 1): -4, (0, 2): -1, (0,): 3, (1,): 2, (): 2
>>> }
>>> D = G.subvalue({2: -3})
>>> D
{(0, 1): -4, (0,): 6, (1,): 2, (): 2}
update(*args, **kwargs)

update.

Update the dictionary but following all the conventions of this class.

Parameters

arguments (defines a dictionary, ie d = dict(*args, **kwargs).) – Each element in d will be added in place to this instance following all the required convensions.

value(z)

value.

Find the value of the QUSO. Calling

self.value(z) is the same as calling qubovert.utils.quso_value(z, self).

Parameters

z (dict or iterable.) – Maps variable labels to their values, -1 or 1. Ie z[i] must be the value of variable i.

Returns

value – The value of the QUSO with the given assignment z.

Return type

float.

Example

>>> from qubovert.utils import QUSOMatrix, PUSOMatrix
>>> from qubovert import QUSO, PUSO
>>> H = PUSOMatrix({(0, 1): -1, (0,): 1})
>>> z = {0: -1, 1: 1}
>>> H.value(z)
0
>>> H = PUSO({(0, 1): -1, (0,): 1})
>>> z = {0: -1, 1: 1}
>>> H.value(z)
0
>>> L = QUSOMatrix({(0, 1): -1, (0,): 1})
>>> z = {0: -1, 1: 1}
>>> L.value(z)
0
>>> L = QUSO({(0, 1): -1, (0,): 1})
>>> z = {0: -1, 1: 1}
>>> L.value(z)
0
values() an object providing a view on D's values
property variables

variables.

Return a set of all the variables in the dict.

Returns

res

Return type

set.