Skip to main contentIBM Quantum Documentation
Important

IBM Quantum Platform is moving and this version will be sunset on July 1. To get started on the new platform, read the migration guide.

Ansatz generation

qiskit_addon_aqc_tensor.ansatz_generation

Tools for generating ansatz circuits.

AnsatzBlockAnsatz block.
OneQubitAnsatzBlockOne-qubit ansatz block.
TwoQubitAnsatzBlockTwo-qubit ansatz block.
ZXZOne-qubit ansatz block based on the ZXZ decomposition.
KAKTwo-qubit ansatz block based on the KAK decomposition.

generate_ansatz_from_circuit

generate_ansatz_from_circuit(qc, /, *, qubits_initially_zero=False, parameter_name='theta')

GitHub

Generate an ansatz from the two-qubit connectivity structure of a circuit.

See the explanatatory material for motivation.

Parameters

  • qc (QuantumCircuit) – A circuit, which is assumed to be unitary. Barriers are ignored.
  • qubits_initially_zero (bool) – If True, the first Z rotation on each qubit is fixed to zero because such a rotation has no effect on the state 0|0\rangle.
  • parameter_name (str) – Name for the ParameterVector representing the free parameters in the returned ansatz circuit.

Return type

tuple[QuantumCircuit, list[float]]

Returns

(ansatz, parameter_values) such that ansatz.assign_parameters(parameter_values) is equivalent to qc up to a global phase.

Example:

Consider the following circuit as an example:

from qiskit import QuantumCircuit
 
qc = QuantumCircuit(6)
qc.rx(0.4, 0)
qc.ryy(0.2, 2, 3)
qc.h(2)
qc.rz(0.1, 2)
qc.rxx(0.3, 0, 1)
qc.rzz(0.3, 0, 1)
qc.cx(2, 1)
qc.s(1)
qc.h(4)
qc.draw("mpl")
Circuit diagram output by the previous code.

If the above circuit is passed to generate_ansatz_from_circuit(), it will return an ansatz with parametrized two-qubit KAK rotations in the same locations as the input:

from qiskit_addon_aqc_tensor import generate_ansatz_from_circuit
 
ansatz, initial_params = generate_ansatz_from_circuit(
    qc, qubits_initially_zero=True, parameter_name="x"
)
ansatz.draw("mpl")
Circuit diagram output by the previous code.

Note that in the generated ansatz, all consecutive single-qubit gates are collapsed into the same ZXZ block, and all consecutive two-qubit gates are collapsed into a single KAK block, up to single-qubit rotations.

Further, the generate_ansatz_from_circuit() function provides parameters which, when bound to the ansatz, will result in a circuit equivalent to the original one, up to a global phase:

ansatz.assign_parameters(initial_params).draw("mpl")
Circuit diagram output by the previous code.

A 1D Trotter circuit leads to a similar result, with its characteristic brickwork structure:

from rustworkx.generators import path_graph
from qiskit.synthesis import SuzukiTrotter
from qiskit_addon_utils.problem_generators import generate_time_evolution_circuit, generate_xyz_hamiltonian
 
hamiltonian = generate_xyz_hamiltonian(
    path_graph(6),
    coupling_constants=(0.0, 0.0, 1.0),
    ext_magnetic_field=(0.4, 0.0, 0.0),
)
 
good_circuit = generate_time_evolution_circuit(
    hamiltonian,
    synthesis=SuzukiTrotter(reps=2),
    time=1.0,
)
 
good_circuit.draw("mpl", initial_state=True)
Circuit diagram output by the previous code.
from qiskit_addon_aqc_tensor import generate_ansatz_from_circuit
 
ansatz, initial_params = generate_ansatz_from_circuit(
    good_circuit, qubits_initially_zero=True, parameter_name="x"
)
ansatz.assign_parameters(initial_params).draw("mpl", initial_state=True)
Circuit diagram output by the previous code.

parametrize_circuit

parametrize_circuit(qc, /, *, parameter_name='theta')

GitHub

Create a parametrized version of a circuit.

Given a quantum circuit, constructs another quantum circuit which is identical except that any gates with numerical parameters are replaced by gates (of the same type) with free parameters. The new circuit is returned along with a list containing the original values of the parameters.

Parameters

  • qc (QuantumCircuit) – The quantum circuit to parametrize.
  • parameter_name (str) – Name for the ParameterVector representing the free parameters in the returned ansatz circuit.

Return type

tuple[QuantumCircuit, list[float | None]]

Returns

(ansatz, parameter_values) such that ansatz.assign_parameters(parameter_values) is identical to qc as long as qc did not already contain parameters. If qc already had parameters, then parameter_values will contain None at the entries corresponding to those parameters.

Example:

Consider the following circuit as an example:

from qiskit import QuantumCircuit
 
qc = QuantumCircuit(6)
qc.rx(0.4, 0)
qc.ryy(0.2, 2, 3)
qc.h(2)
qc.rz(0.1, 2)
qc.rxx(0.3, 0, 1)
qc.rzz(0.3, 0, 1)
qc.cx(2, 1)
qc.s(1)
qc.h(4)
qc.draw("mpl")
Circuit diagram output by the previous code.

If the above circuit is passed to parametrize_circuit(), it will return an ansatz obtained from this circuit by replacing numerical parameters with free parameters:

from qiskit_addon_aqc_tensor import parametrize_circuit
 
ansatz, initial_params = parametrize_circuit(qc)
ansatz.draw("mpl")
Circuit diagram output by the previous code.

Further, the parametrize_circuit() function provides parameters which, when bound to the ansatz, will result in a circuit identical to the original one:

ansatz.assign_parameters(initial_params).draw("mpl")
Circuit diagram output by the previous code.

If the original circuit already contained parameters, then the returned parameter values will contain None at the entries corresponding to those parameters, and the preceding code will not work. The following example shows how to recover the original circuit in this case.

from qiskit.circuit import Parameter
 
qc = QuantumCircuit(3)
alpha1 = Parameter("alpha1")
alpha2 = Parameter("alpha2")
qc.ry(alpha1, [0])
qc.rz(0.1, [0])
qc.ry(alpha2, [1])
qc.rz(alpha1, [1])
qc.ry(0.2, [2])
qc.rz(0.3, [2])
ansatz, initial_params = parametrize_circuit(qc)
ansatz.assign_parameters(
    {
        param: val
        for param, val in zip(ansatz.parameters, initial_params)
        if val is not None
    },
    inplace=True,
)
ansatz.draw("mpl")
Circuit diagram output by the previous code.
Was this page helpful?
Report a bug or request content on GitHub.