Document feedback

Question document fragment

When a question document fragment contains a formula, it is displayed as a space.

Submission type
issue

It's a little complicated...

I'd like to ask someone.

Please select the submission type

Problem type
Specifications and Common Mistakes

- Specifications and Common Mistakes:

- Misspellings or punctuation mistakes,incorrect formulas, abnormal display.

- Incorrect links, empty cells, or wrong formats.

- Chinese characters in English context.

- Minor inconsistencies between the UI and descriptions.

- Low writing fluency that does not affect understanding.

- Incorrect version numbers, including software package names and version numbers on the UI.

Usability

- Usability:

- Incorrect or missing key steps.

- Missing main function descriptions, keyword explanation, necessary prerequisites, or precautions.

- Ambiguous descriptions, unclear reference, or contradictory context.

- Unclear logic, such as missing classifications, items, and steps.

Correctness

- Correctness:

- Technical principles, function descriptions, supported platforms, parameter types, or exceptions inconsistent with that of software implementation.

- Incorrect schematic or architecture diagrams.

- Incorrect commands or command parameters.

- Incorrect code.

- Commands inconsistent with the functions.

- Wrong screenshots.

- Sample code running error, or running results inconsistent with the expectation.

Risk Warnings

- Risk Warnings:

- Lack of risk warnings for operations that may damage the system or important data.

Content Compliance

- Content Compliance:

- Contents that may violate applicable laws and regulations or geo-cultural context-sensitive words and expressions.

- Copyright infringement.

Please select the type of question

Problem description

Describe the bug so that we can quickly locate the problem.

Advanced Operations of Quantum Circuit

Download NotebookDownload CodeView source on GiteeRun in ModelArts

In previous tutorial we introduced the basic usage of quantum circuit. In this tutorial, we will introduce how to operator the circuit in high level.

mindquantum.core.circuit.controlled

The controlled method is used to add control qubits (which can be multiple) to any quantum circuit or quantum operator.

For example, let’s build a quantum circuit containing only two qubits and add a control qubit - q2 to it by a controlled method:

[1]:
from mindquantum.algorithm.library import qft
from mindquantum.core.circuit import controlled

u1 = qft(range(2))  # Build the quantum circuit
u1.svg()
[1]:
../_images/beginner_advanced_operations_of_quantum_circuit_1_0.svg
[2]:
u2 = controlled(u1)(2)  # Add control qubit q2 to the circuit, returning a new circuit
u2.svg()
[2]:
../_images/beginner_advanced_operations_of_quantum_circuit_2_0.svg

Actually, controlled() returns a function. E.g:

[3]:
u3 = controlled(u1)

We can add control qubits to the initial circuit u1 by calling u3, which has the same effect as above:

[4]:
u4 = u3(2)
u4.svg()
[4]:
../_images/beginner_advanced_operations_of_quantum_circuit_6_0.svg

Note: The added control qubit cannot be the target qubit of a gate that already exists in the circuit, otherwise an error will be reported!

In addition, we can batch add control qubits to the quantum circuit. For example, in the following example we add control qubits - q2 and q3 to q0 and q1 respectively:

[5]:
u = controlled(qft)
u = u([2, 3], [0, 1])  # Bulk add control qubits
u.svg()
[5]:
../_images/beginner_advanced_operations_of_quantum_circuit_8_0.svg

mindquantum.core.circuit.dagger

The dagger method is used to find the Hermitian conjugates of quantum circuits or quantum operators.

The following examples provide two ways of doing dagger operations:

[6]:
from mindquantum.core.circuit import dagger

u1 = qft(range(3))
u1.svg()
[6]:
../_images/beginner_advanced_operations_of_quantum_circuit_10_0.svg
[7]:
u2 = dagger(u1)
u2.svg()
[7]:
../_images/beginner_advanced_operations_of_quantum_circuit_11_0.svg
[8]:
u3 = dagger(qft)
u4 = u3(range(3))
u4.svg()
[8]:
../_images/beginner_advanced_operations_of_quantum_circuit_12_0.svg

It can be seen that the circuits obtained by the two methods are the same.

mindquantum.core.circuit.apply

The apply method is used to apply a quantum circuit or quantum operator to the specified qubits (which can be multiple).

[9]:
from mindquantum.core.circuit import apply

u1 = qft([0, 1])
circuit1 = apply(u1, [1, 0])  # Apply quantum circuit u1 to qubits q1, q0
circuit1.svg()
[9]:
../_images/beginner_advanced_operations_of_quantum_circuit_14_0.svg
[10]:
u2 = apply(qft, [1, 0])  # Apply qft to qubits q0, q1
circuit2 = u2([0, 1])
circuit2.svg()
[10]:
../_images/beginner_advanced_operations_of_quantum_circuit_15_0.svg

mindquantum.core.circuit.add_prefix

The add_prefix method is used to prefix the parameter names of parameterized quantum circuits or parameterized quantum operators. This is useful in neural network layering, for example:

[11]:
from mindquantum.core.circuit import add_prefix, Circuit
from mindquantum.core.gates import RX, H

circ = Circuit().rx("theta", 0)
circ.svg()
[11]:
../_images/beginner_advanced_operations_of_quantum_circuit_17_0.svg
[12]:
# After adding, the parameter "theta" becomes "l0_theta"
circ = add_prefix(circ, 'l0')
circ.svg()
[12]:
../_images/beginner_advanced_operations_of_quantum_circuit_18_0.svg

We can prefix the parameter name of a parameterized qubit after it acts on a specific qubit, or we can add it when it has not yet been applied to the qubit. E.g:

[13]:
u = lambda qubit: Circuit([H.on(0), RX('a').on(qubit)])

u1 = u(0)
u1 = add_prefix(u1, 'ansatz')
u1.svg()
[13]:
../_images/beginner_advanced_operations_of_quantum_circuit_20_0.svg
[14]:

u2 = add_prefix(u, 'ansatz') u2 = u2(0) u2.svg()
[14]:
../_images/beginner_advanced_operations_of_quantum_circuit_21_0.svg

mindquantum.core.circuit.change_param_name

The change_param_name method is used to modify the parameter name of a parameterized quantum circuit or a parameterized quantum operator.

[15]:
from mindquantum.core.circuit import change_param_name, Circuit
from mindquantum.core.gates import RX, H

u = lambda qubit: Circuit([H.on(0), RX('a').on(qubit)])

u1 = u(0)
u1 = change_param_name(u1, {'a': 'b'})
u1.svg()
[15]:
../_images/beginner_advanced_operations_of_quantum_circuit_23_0.svg
[16]:
u2 = change_param_name(u, {'a': 'b'})
u2 = u2(0)
u2.svg()
[16]:
../_images/beginner_advanced_operations_of_quantum_circuit_24_0.svg

mindquantum.core.circuit.UN

The UN module is used to actuate quantum gates on different target qubits and control qubits.

The general format is as follows: mindquantum.circuit.UN(gate, maps_obj, maps_ctrl=None), the parameter gate is the gate to be executed, maps_obj is the target qubit to be executed, and maps_Ctrl is the control qubit (None if there are no control qubits). If each qubit implements the same quantum gate without parameters, UN(gate, N) can be used directly, where N represents the number of qubits.

Here is a simple example where we apply an H-gate to each qubit in the circuit we build:

[17]:
from mindquantum.core.circuit import change_param_name, Circuit, UN
from mindquantum.core.gates import X, H, SWAP

circuit1 = Circuit()
circuit1 += UN(H, 4)  # Apply the H gate to each qubit
circuit1.svg()
[17]:
../_images/beginner_advanced_operations_of_quantum_circuit_26_0.svg

In the following example, we add a CNOT gate to the qubits q2 and q0, q3 and q1 respectively, where q2 is the control bit, q0 is the target bit; q3 is the control bit , q1 is the target bit:

[18]:
circuit2 = UN(X, maps_obj=[0, 1], maps_ctrl=[2, 3])
circuit2.svg()
[18]:
../_images/beginner_advanced_operations_of_quantum_circuit_28_0.svg

For SWAP gate

[19]:
circuit3 = UN(SWAP, maps_obj=[[0, 1], [2, 3]]).x(2, 1)
circuit3.svg()
[19]:
../_images/beginner_advanced_operations_of_quantum_circuit_30_0.svg

mindquantum.core.circuit.shift

The shift method is used to modify the qubit range of a given circuit, and the parameter is the step size to be shifted. Note that the step size cannot be negative. Moreover, it can only move to the last qubit, and cannot cycle to q0 (the first qubit).

[20]:
from mindquantum.core.circuit import shift, Circuit
from mindquantum.core.gates import X

circ = Circuit().x(1, 0)
circ.svg()
[20]:
../_images/beginner_advanced_operations_of_quantum_circuit_32_0.svg
[21]:
circ = shift(circ, 1)
circ.svg()  # The qubit acting on the circuit changes from q0, q1 to q1, q2
[21]:
../_images/beginner_advanced_operations_of_quantum_circuit_33_0.svg

Case - Iris Classification: Building Encoder

The above examples of higher-order operations show the applicability and convenience of higher-order operations in quantum circuits. What magic will happen if we further combine them to build quantum circuits?

Next we will start with Classification of irises by quantum neural network. Build the Encoder part as an example, build the quantum circuit shown in the figure below:

encoder classification of iris by qnn

[22]:
from mindquantum.core.circuit import shift, add_prefix, Circuit, UN
from mindquantum.core.gates import RZ, X, H

template = Circuit([X.on(1, 0), RZ('alpha').on(1), X.on(1, 0)])
encoder = UN(H, 4) + (RZ(f'{i}_alpha').on(i) for i in range(4)) + sum(add_prefix(shift(template, i), f'{i+4}') for i in range(3))
encoder.summary()
                                    Circuit Summary                                     
╭──────────────────────┬───────────────────────────────────────────────────────────────╮
│ Info                  value                                                         │
├──────────────────────┼───────────────────────────────────────────────────────────────┤
│ Number of qubit      │ 4                                                             │
├──────────────────────┼───────────────────────────────────────────────────────────────┤
│ Total number of gate │ 17                                                            │
│ Barrier              │ 0                                                             │
│ Noise Channel        │ 0                                                             │
│ Measurement          │ 0                                                             │
├──────────────────────┼───────────────────────────────────────────────────────────────┤
│ Parameter gate       │ 7                                                             │
│ 7 ansatz parameters  │ 0_alpha, 1_alpha, 2_alpha, 3_alpha, 4_alpha, 5_alpha, 6_alpha │
╰──────────────────────┴───────────────────────────────────────────────────────────────╯
[23]:
encoder.svg()
[23]:
../_images/beginner_advanced_operations_of_quantum_circuit_36_0.svg

In the above code, we use the UN module to apply the parameter-free H gate to the target qubits q0~q3, and then apply the RZ(i_alpha) gate to the i-th qubit. Next, it is observed that there are three identical modules in the circuit, and they are all composed of a controlled X gate, a RZ gate and a controlled X gate. Therefore, we construct the corresponding template template, which is controlled by q0, an X gate acting on q1, an RZ gate acting on q1, and an X gate controlled by q0 acting on q1 are formed. Then we use shift(template, i) to change the qubit range that the template acts on, and build three modules with the same structure but the qubit range differs by 1. The qubit ranges involved are q0 and q1, q1 and q2, q2 and q3. Finally, we use the add_prefix method to prefix the parameter names of all parameter quantum gates constructed by shift with a number.

So far, through these advanced operations of quantum circuit provided by MindSpore Quantum, we have built the required Encoder with only two lines of code!

[24]:
from mindquantum.utils.show_info import InfoTable

InfoTable('mindquantum', 'scipy', 'numpy')
[24]:
Software Version
mindquantum0.9.11
scipy1.10.1
numpy1.24.4
System Info
Python3.8.17
OSLinux x86_64
Memory16.62 GB
CPU Max Thread16
DateTue Jan 2 14:38:22 2024