Skip to content

algos

This module contains Qiskit implementations of example algorithms to analyse the effects of isotropic errors.

isotropic.algos

grover

Grover's algorithm implementation and utilities for isotropic error analysis.

get_grover_answer(result)

Extract the measurement counts from the result of a Grover circuit execution.

Parameters:

Name Type Description Default
result PrimitiveResult

The result object returned by executing the Grover circuit.

required

Returns:

Type Description
tuple[dict, str]

A tuple containing the counts dictionary and the most probable search item.

Source code in src/isotropic/algos/grover.py
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
def get_grover_answer(result: PrimitiveResult) -> tuple[dict, str]:
    """
    Extract the measurement counts from the result of a Grover circuit execution.

    Parameters
    ----------
    result : PrimitiveResult
        The result object returned by executing the Grover circuit.

    Returns
    -------
    tuple[dict, str]
        A tuple containing the counts dictionary and the most probable search item.
    """
    if not isinstance(result, PrimitiveResult):
        raise TypeError("The result must be an instance of PrimitiveResult.")

    counts = result[0].data.c0.get_counts()
    grover_answer = max(counts, key=counts.get)

    return counts, grover_answer

get_grover_circuit(num_qubits, U_w, iterations)

Create a Grover circuit with the given number of qubits, oracle, and iterations.

Parameters:

Name Type Description Default
num_qubits int

The number of qubits used to encode the states.

required
U_w Operator

The oracle that marks the solution states.

required
iterations int

The number of Grover iterations to perform.

required

Returns:

Type Description
QuantumCircuit

The constructed Grover quantum circuit.

Source code in src/isotropic/algos/grover.py
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
def get_grover_circuit(
    num_qubits: int, U_w: Operator, iterations: int
) -> QuantumCircuit:
    """
    Create a Grover circuit with the given number of qubits, oracle, and iterations.

    Parameters
    ----------
    num_qubits : int
        The number of qubits used to encode the states.
    U_w : Operator
        The oracle that marks the solution states.
    iterations : int
        The number of Grover iterations to perform.

    Returns
    -------
    QuantumCircuit
        The constructed Grover quantum circuit.
    """

    if U_w.num_qubits != num_qubits:
        raise ValueError(
            "Oracle U_w must have the same number of qubits as num_qubits."
        )

    qr = QuantumRegister(num_qubits)
    cr = ClassicalRegister(num_qubits)
    qcirc = QuantumCircuit(qr, cr)

    # Initializing the circuit
    for i in range(num_qubits):
        qcirc.h(i)

    for i in range(iterations):
        qcirc.barrier()

        # Oracle to introduce negative phase (circuit of above matrix)
        qcirc.append(U_w, qr)

        qcirc.barrier()

        # Diffusion operator
        for qubit in range(num_qubits):
            qcirc.h(qubit)
        for qubit in range(num_qubits):
            qcirc.x(qubit)
        qcirc.h(num_qubits - 1)
        qcirc.mcx(list(range(num_qubits - 1)), num_qubits - 1)
        qcirc.h(num_qubits - 1)
        for qubit in range(num_qubits):
            qcirc.x(qubit)
        for qubit in range(num_qubits):
            qcirc.h(qubit)

    return qcirc

optimal_num_iterations(num_solutions, num_qubits)

Return the optimal number of iterations, if the number of solutions is known.

Parameters:

Name Type Description Default
num_solutions int

The number of solutions.

required
num_qubits int

The number of qubits used to encode the states.

required

Returns:

Type Description
int

The optimal number of iterations for Grover's algorithm to succeed.

Source code in src/isotropic/algos/grover.py
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
def optimal_num_iterations(num_solutions: int, num_qubits: int) -> int:
    """
    Return the optimal number of iterations, if the number of solutions is known.

    Parameters
    ----------
    num_solutions : int
        The number of solutions.
    num_qubits : int
        The number of qubits used to encode the states.

    Returns
    -------
    int
        The optimal number of iterations for Grover's algorithm to succeed.
    """
    amplitude = jnp.sqrt(num_solutions / 2**num_qubits)
    return round(jnp.arccos(amplitude) / (2 * jnp.arcsin(amplitude)))