Tools
Some additional tools are provided with our library. Even though most of them are geared at internal usage, they are all presented here. Amongst them, the ones most probable of being of use for you are in the Useful Maths Operations section, presenting mathematical tools for linear algebra, functions generalized to more data types, etc…
Useful Maths Operations
from mpqp.tools.maths import *
Mathematical tools for linear algebra, functions generalized to more data types, etc…
- cos(angle)[source]
Generalization of the cosine function, to take as input either
sympy
’s expressions or floating numbers.- Parameters
angle (Expr | Real) – The angle considered.
- Returns
Cosine of the given
angle
.- Return type
sp.Expr | float
- exp(angle)[source]
Generalization of the exponential function, to take as input either
sympy
’s expressions or floating numbers.- Parameters
angle (Expr | Complex) – The angle considered.
- Returns
Exponential of the given
angle
.- Return type
sp.Expr | complex
- is_hermitian(matrix)[source]
Checks whether the matrix in parameter is hermitian.
- Parameters
matrix (Matrix) – matrix for which we want to know if it is hermitian.
- Returns
True
if the matrix in parameter is Hermitian.- Return type
bool
Examples
>>> m1 = np.array([[1,2j,3j],[-2j,4,5j],[-3j,-5j,6]]) >>> is_hermitian(m1) True >>> m2 = np.diag([1,2,3,4]) >>> is_hermitian(m2) True >>> m3 = np.array([[1,2,3],[2,4,5],[3,5,6]]) >>> is_hermitian(m3) True >>> m4 = np.array([[1,2,3],[4,5,6],[7,8,9]]) >>> is_hermitian(m4) False >>> x = symbols("x", real=True) >>> m5 = np.diag([1,x]) >>> is_hermitian(m5) True >>> m6 = np.array([[1,x],[-x,2]]) >>> is_hermitian(m6) False
- is_unitary(matrix)[source]
Checks whether the matrix in parameter is unitary.
- Parameters
matrix (Matrix) – Matrix for which we want to know if it is unitary.
- Returns
True
if the matrix in parameter is Unitary.- Return type
bool
Example
>>> a = np.array([[1,1],[1,-1]]) >>> is_unitary(a) False >>> is_unitary(a/np.sqrt(2)) True
- matrix_eq(lhs, rhs, atol=1e-08, rtol=1e-05)[source]
Checks whether two matrix (including vectors) are element-wise equal, within a tolerance.
For respectively each elements \(a\) and \(b\) of both inputs, we check this specific condition: \(|a - b| \leq (atol + rtol * |b|)\).
- Parameters
lhs (Matrix) – Left-hand side matrix of the equality.
rhs (Matrix) – Right-hand side matrix of the equality.
atol (float) –
rtol (float) –
- Returns
True
if the two matrix are equal (according to the definition above).- Return type
bool
- normalize(v)[source]
Normalizes an array representing the amplitudes of the state.
- Parameters
v (ndarray[Any, dtype[complex64]]) – The vector to be normalized.
- Returns
The normalized vector.
- Return type
ndarray[Any, dtype[complex64]]
Examples
>>> vector = np.array([1,0,0,1]) >>> normalize(vector) array([0.70710678, 0. , 0. , 0.70710678]) >>> vector = np.array([0,0,0,0]) >>> normalize(vector) array([0, 0, 0, 0])
- rand_clifford_matrix(nb_qubits)[source]
Generate a random Clifford matrix.
- Parameters
size – Size (number of columns) of the square matrix to generate.
nb_qubits (int) –
- Returns
A random Clifford matrix.
- Return type
ndarray[Any, dtype[complex64]]
Examples
>>> rand_clifford_matrix(2) array([[ 0.5+0.j, -0.5+0.j, 0.5+0.j, -0.5+0.j], [-0.5+0.j, 0.5+0.j, 0.5+0.j, -0.5+0.j], [ 0.5+0.j, 0.5+0.j, 0.5+0.j, 0.5+0.j], [-0.5+0.j, -0.5+0.j, 0.5+0.j, 0.5+0.j]])
- rand_hermitian_matrix(size)[source]
Generate a random Hermitian matrix.
- Parameters
size (int) – Size (number of columns) of the square matrix to generate.
- Returns
A random Hermitian Matrix.
- Return type
ndarray[Any, dtype[complex64]]
Example
>>> rand_hermitian_matrix(2) array([[1.4488624 +0.j, 0.20804943+0.j], [0.20804943+0.j, 0.7826408 +0.j]], dtype=complex64)
- rand_orthogonal_matrix(size, seed=None)[source]
Generate a random orthogonal matrix optionally with a given seed.
- Parameters
size (int) – Size (number of columns) of the square matrix to generate.
seed (Optional[int]) – Seed used to control the random generation of the matrix.
- Returns
A random orthogonal matrix.
- Return type
ndarray[Any, dtype[complex64]]
Examples
>>> rand_orthogonal_matrix(3) array([[ 0.94569439, 0.2903415 , 0.14616405], [-0.32503798, 0.83976928, 0.43489984], [ 0.0035254 , -0.45879121, 0.88853711]])
>>> rand_orthogonal_matrix(3, seed=42) array([[ 0.21667149, 0.1867762 , 0.95821089], [ 0.9608116 , 0.13303749, -0.24319148], [-0.17290035, 0.9733528 , -0.15063131]])
- rand_product_local_unitaries(nb_qubits)[source]
Generate a pseudo random matrix, resulting from a tensor product of random unitary matrices.
- Parameters
nb_qubits (int) – Number of qubits on which the product of unitaries will act.
- Returns
A tensor product of random unitary matrices.
- Return type
ndarray[Any, dtype[complex64]]
Example
>>> rand_product_local_unitaries(2) array([[-0.39648015+0.j , 0.49842218-0.16609181j, 0.39826454-0.21692223j, -0.40979321+0.43953607j], [-0.49842218+0.16609181j, 0.14052896-0.37073997j, 0.40979321-0.43953607j, 0.06167784+0.44929471j], [-0.39826454+0.21692223j, 0.40979321-0.43953607j, 0.16112375-0.36226461j, -0.05079312+0.52290651j], [-0.40979321+0.43953607j, -0.06167784-0.44929471j, 0.05079312-0.52290651j, 0.28163685+0.27906487j]])
- rand_unitary_2x2_matrix()[source]
Generate a random one-qubit unitary matrix.
- Parameters
size – Size (number of columns) of the square matrix to generate.
- Returns
A random Clifford matrix.
- Return type
ndarray[Any, dtype[complex64]]
Examples
>>> rand_unitary_2x2_matrix() array([[ 0.86889957+0.j , 0.44138577+0.22403602j], [-0.44138577-0.22403602j, -0.72981565-0.47154594j]])
- sin(angle)[source]
Generalization of the sine function, to take as input either
sympy
’s expressions or floating numbers.- Parameters
angle (Expr | Real) – The angle considered.
- Returns
Sine of the given
angle
.- Return type
sp.Expr | float
- atol = 1e-08
The absolute tolerance parameter.
- rtol = 1e-05
The relative tolerance parameter.
Generics
from mpqp.tools.generics import *
This module contains a collection of generic types and functions needed across the library.
Type aliases Matrix
, OneOrMany
and ArbitraryNestedSequence
are used across the library. In particular, ArbitraryNestedSequence
is
used in cases the nesting of the sequence is unknown; and in these cases you
might want to flatten the list using flatten()
.
On occasion, there is also a need to “flatten” the string representation of an
object i.e. to display it on one line. In this case one_line_repr()
is
your friend.
Lastly, we find the default list search mechanism in python a bit too
restrictive. find()
allow us a much more versatile search using an
oracle
.
- class MessageEnum(value=<no_arg>, names=None, module=None, qualname=None, type=None, start=1, boundary=None)[source]
Bases:
Enum
Enum subclass allowing you to access the docstring of the members of your enum through the
message
property.Example
>>> class A(MessageEnum): ... '''an enum''' ... VALUE1 = auto() ... '''member VALUE1''' ... VALUE2 = auto() ... '''member VALUE2''' >>> A.VALUE1.message 'member VALUE1'
Warning
This implementation is not very robust, in particular, in case some members are not documented, it will mess things up. In addition, this can only work for code in file, and will not work in the interpreter.
- message: str
Each of the members of the eum will have the
message
attribute.
- class SimpleClassReprABC[source]
Bases:
object
This class is the equivalent of ABC (it signifies that it’s subclass isn’t meant to be instantiated directly), but it adds the small feature of setting the
repr
to be the class name, which is for instance useful for gates.
- class SimpleClassReprABCMeta(name, bases, namespace, **kwargs)[source]
Bases:
SimpleClassReprMeta
,ABCMeta
- class SimpleClassReprMeta[source]
Bases:
type
Metaclass used to change the repr of the class (not the instances) to display the name of the class only (instead of the usual <class mpqp.path.ClassName>)
- class classproperty(func)[source]
Bases:
object
Decorator yo unite the
classmethod
andproperty
decorators.- Parameters
func (Callable[..., Any]) –
- clean_array(array)[source]
Cleans and formats elements of an array. This function rounds the real parts of complex numbers in the array to 7 decimal places and formats them as integers if they are whole numbers. It returns a string representation of the cleaned array without parentheses.
- Parameters
array (list[complex] | numpy.ndarray[Any, numpy.dtype[numpy.complex64 | numpy.float32]]) – An array containing numeric elements, possibly including complex numbers.
- Returns
A string representation of the cleaned array without parentheses.
- Return type
str
Example
>>> clean_array([1.234567895546, 2.3456789645645, 3.45678945645]) '[1.2345679, 2.345679, 3.4567895]' >>> clean_array([1+2j, 3+4j, 5+6j]) '[1+2j, 3+4j, 5+6j]' >>> clean_array([1+0j, 0+0j, 5.]) '[1, 0, 5]' >>> clean_array([1.0, 2.0, 3.0]) '[1, 2, 3]'
- clean_matrix(matrix)[source]
Cleans and formats elements of a matrix. This function cleans and formats the elements of a matrix. It rounds the real parts of complex numbers in the matrix to 7 decimal places and formats them as integers if they are whole numbers. It returns a string representation of the cleaned matrix without parentheses.
- Parameters
matrix (Matrix) – A matrix containing numeric elements, possibly including complex numbers.
- Returns
A string representation of the cleaned matrix without parentheses.
- Return type
str
Examples
>>> print(clean_matrix([[1.234567895546, 2.3456789645645, 3.45678945645], ... [1+0j, 0+0j, 5.], ... [1.0, 2.0, 3.0]])) [[1.2345679, 2.345679, 3.4567895], [1, 0, 5], [1, 2, 3]]
- find(iterable, oracle)[source]
Finds the first element in the iterable that satisfies the given oracle.
- Parameters
iterable (Iterable[T]) – The iterable to search for the element.
oracle (Callable[[T], bool]) – A callable function that takes an element and returns
True
if the element satisfies the condition.
- Returns
The first element in the iterable that satisfies the oracle.
- Raises
ValueError – If no element in the iterable satisfies the given oracle.
- Return type
T
Example
>>> numbers = [1, 2, 3, 4, 5] >>> is_even = lambda x: x % 2 == 0 >>> find(numbers, is_even) 2
- flatten(lst)[source]
Flattens an arbitrarily nested Sequence.
This is a wrapper around
flatten_generator()
.- Parameters
lst (Union[Sequence[ArbitraryNestedSequence[T]], T]) – The nested sequence, to be flattened.
- Returns
A flattened list containing all elements from the input list.
- Return type
list[~T]
Example
>>> nested_list = [[1, 2, [3, 4]], [5, [6, 7]], 8] >>> flatten(nested_list) [1, 2, 3, 4, 5, 6, 7, 8]
- flatten_generator(lst)[source]
Helper generator function for flattening an arbitrarily nested list.
- Parameters
lst (Union[Sequence[ArbitraryNestedSequence[T]], T]) – The list, or nested list, to be flattened.
- Yields
Elements from the input list in a flattened order.
- Return type
Iterator[T]
- one_lined_repr(obj)[source]
One-liner returning a representation of the given object by removing extra whitespace.
- Parameters
obj (object) – The object for which a representation is desired.
- ArbitraryNestedSequence
This type alias allows us to define heterogeneously nested Sequences of
T
.Examples
>>> l: ArbitraryNestedSequence[int] >>> l = [[0,1],0,[[0,2],3]] >>> l = 1 >>> l = [2,1,3]
alias of
Union
[Sequence
[ArbitraryNestedSequence[T]
],T
]
- Matrix
Type alias denoting all the matrices we consider (either matrices of complex or of
sympy
expressions, given tonumpy
as objects)alias of
Union
[ndarray
[Any
,dtype
[complex64
]],ndarray
[Any
,dtype
[object_
]]]
- T
A generic type.
alias of TypeVar(‘T’)
Errors
from mpqp.tools.errors import *
You will find here the custom exceptions we created in order to provide clearer errors. When relevant, we also append the trace of the error raised by a provider’s SDK.
- exception AWSBraketRemoteExecutionError[source]
Bases:
RemoteExecutionError
Raised when an error occurred during the remote execution process of job(s) on the remote Amazon Braket.
- exception AdditionalGateNoiseWarning[source]
Bases:
UserWarning
Warning for additional noise on native gate used in the decomposition of noisy gate.
- exception DeviceJobIncompatibleError[source]
Bases:
ValueError
Raised when one tries to run a job with a JobType that is not suitable for the selected device (for example SAMPLE job on a statevector simulator).
- exception IBMRemoteExecutionError[source]
Bases:
RemoteExecutionError
Raised when an error occurred during the remote execution process of job(s) on an IBM device.
- exception InstructionParsingError[source]
Bases:
ValueError
Raised when an QASM instruction encountered by the parser is malformed.
- exception NumberQubitsError[source]
Bases:
ValueError
Raised when the number of qubits defining an instruction, a gate, or a measurement, is not coherent with the related objects (circuit, matrix, observable, etc…).
- exception OpenQASMTranslationWarning[source]
Bases:
UserWarning
Warning for potential translation error when exporting to OpenQASM.
- exception QLMRemoteExecutionError[source]
Bases:
RemoteExecutionError
Raised when an error occurred during the remote execution process of job(s) on the remote QLM.
- exception RemoteExecutionError[source]
Bases:
ConnectionError
Raised when an error occurred during a remote connection, submission or execution.
Choice Tree
from mpqp.tools.choice_tree import *
This module provides functionalities for working with decision trees, allowing for seamless navigation and interaction within a tree structure.
You can define a QuestionNode
, containing your question and options.
Each option (AnswerNode
) contains the description of the option
together with optional actions and follow up question.
To run your choice tree, just run run_choice_tree()
on your root question.
- class AnswerNode(label, action, next_question=None)[source]
Bases:
object
Represents a node in a decision tree corresponding to an answer to a question. An answer can lead to an action, or to another question.
- Parameters
label (str) – See attribute description.
action (Callable[[...], tuple[str, Iterable[Any]]]) – See attribute description.
next_question (Optional[QuestionNode]) – See attribute description.
- action: Callable[[...], tuple[str, Iterable[Any]]]
A callable representing an action function linked to an answer. The return value of the action is composed of the text to display after it ran (something like “Success”, “Failure”, or “You’re a wonderful human being”), and the parameters to pass to the next action to be executed. These parameters to be passed between actions are useful to keep memory of the previous actions for instance.
- label: str
The label or text associated with the answer.
- next_question: Optional[QuestionNode] = None
An optional reference to the next question node.
- class QuestionNode(label, answers)[source]
Bases:
object
Represents a node in a decision tree corresponding to a question.
- Parameters
label (str) – See attribute description.
answers (list[mpqp.tools.choice_tree.AnswerNode]) – See attribute description.
- answers: list[mpqp.tools.choice_tree.AnswerNode]
List of possible answers to this question.
- label: str
The label or text associated with the question.
- run_choice_tree(question)[source]
Execute the choice tree by starting with the question node in parameter.
- Parameters
question (QuestionNode) – Root question from which the choice tree will start
Example
def tea_picker(*_):
name = input("What's your favorite tea brand?\n\t")
return f"Very good choice, I love {name}!", [name]
choice_tree = QuestionNode(
"Hey, what's your favorite beverage?",
[
AnswerNode(
"Tea",
tea_picker,
QuestionNode(
"Do you want to come at my place to drink some",
[
AnswerNode(
"Yes", lambda n: (f"Cool, let's go for this cup of {n} :D", [])
),
AnswerNode("Can't :(", lambda n: ("No worries, another time!", [])),
],
),
),
AnswerNode(
"Coffee",
lambda: ("I get it, you gotta do what you gotta do to stay awake", []),
QuestionNode(
"And how do you like it?",
[
AnswerNode(
"American style",
lambda: (
"Hydrating is important, but I'm not sure this counts as coffee",
[],
),
),
AnswerNode("Italian", lambda: ("The only right way!", [])),
],
),
),
],
)
assert choice_tree.answers[-1].next_question is not None
choice_tree.answers[-1].next_question.answers[0].next_question = choice_tree
run_choice_tree(choice_tree)