Skip to content

CNOT with interacting qubits

Digital-analog quantum computing focuses on using single qubit digital gates combined with more complex and device-dependent analog interactions to represent quantum programs. This paradigm has been shown to be universal for quantum computation1. However, while this approach may have advantages when adapting quantum programs to real devices, known quantum algorithms are very often expressed in a fully digital paradigm. As such, it is also important to have concrete ways to transform from one paradigm to another.

This tutorial will exemplify the DAQC transformation starting with the representation of a simple digital CNOT using the universality of the Ising Hamiltonian2.

CNOT with CPHASE

Let's look at a single example of how the digital-analog transformation can be used to perform a CNOT on two qubits inside a register of globally interacting qubits.

First, note that the CNOT can be decomposed with two Hadamard and a CPHASE gate with \(\phi=\pi\):

import torch
from qadence import chain, sample, product_state

from qadence.draw import display
from qadence import X, I, Z, H, N, CPHASE, CNOT, HamEvo, PI

n_qubits = 2

# CNOT gate
cnot_gate = CNOT(0, 1)

# CNOT decomposed
phi = PI
cnot_decomp = chain(H(1), CPHASE(0, 1, phi), H(1))

init_state = product_state("10")
sample from CNOT gate and 100 shots = [Counter({'11': 100})]
sample from decomposed CNOT gate and 100 shots = [Counter({'11': 100})]

The CPHASE matrix is diagonal, and can be implemented by exponentiating an Ising-like Hamiltonian, or generator,

\[\text{CPHASE}(i,j,\phi)=\text{exp}\left(-i\phi \mathcal{H}_\text{CP}(i, j)\right)\]
\[\begin{aligned} \mathcal{H}_\text{CP}&=-\frac{1}{4}(I_i-Z_i)(I_j-Z_j)\\ &=-N_iN_j \end{aligned}\]

where the number operator \(N_i = \frac{1}{2}(I_i-Z_i)=\hat{n}_i\) is used, leading to an Ising-like interaction \(\hat{n}_i\hat{n}_j\) realisable in neutral-atom systems. Let's rebuild the CNOT using this evolution.

from qadence import kron, block_to_tensor

# Hamiltonian for the CPHASE gate
h_cphase = (-1.0) * kron(N(0), N(1))

# Exponentiating and time-evolving the Hamiltonian until t=phi.
cphase_evo = HamEvo(h_cphase, phi)

# Check that we have the CPHASE gate:
cphase_matrix = block_to_tensor(CPHASE(0, 1, phi))
cphase_evo_matrix = block_to_tensor(cphase_evo)
cphase_matrix == cphase_evo_matrix: True

Now that the CPHASE generator is checked, it can be applied to the CNOT:

# CNOT with Hamiltonian Evolution
cnot_evo = chain(
    H(1),
    cphase_evo,
    H(1)
)

# Initialize state to check CNOTs sample outcomes.
init_state = product_state("10")
sample cnot_gate = [Counter({'11': 100})]
sample cnot_evo = [Counter({'11': 100})]

Thus, a CNOT gate can be created by combining a few single-qubit gates together with a two-qubit Ising interaction between the control and the target qubit which is the essence of the Ising transform proposed in the seminal DAQC paper2 for \(ZZ\) interactions. In Qadence, both \(ZZ\) and \(NN\) interactions are supported.

CNOT in an interacting system of three qubits

Consider a simple experimental setup with \(n=3\) interacting qubits laid out in a triangular grid. For the sake of simplicity, all qubits interact with each other with an \(NN\)-Ising interaction of constant strength \(g_\text{int}\). The Hamiltonian for the system can be written by summing interaction terms over all pairs:

\[\mathcal{H}_\text{sys}=\sum_{i=0}^{n}\sum_{j=0}^{i-1}g_\text{int}N_iN_j,\]

which in this case leads to only three interaction terms,

\[\mathcal{H}_\text{sys}=g_\text{int}(N_0N_1+N_1N_2+N_0N_2)\]

This generator can be easily built in Qadence:

from qadence import add, kron
n_qubits = 3

# Interaction strength.
g_int = 1.0

# Build a list of interactions.
interaction_list = []
for i in range(n_qubits):
    for j in range(i):
        interaction_list.append(g_int * kron(N(i), N(j)))

h_sys = add(*interaction_list)
h_sys = AddBlock(0,1,2)
├── [mul: 1.00000000000000] 
│   └── KronBlock(0,1)
│       ├── N(1)
│       └── N(0)
├── [mul: 1.00000000000000] 
│   └── KronBlock(0,2)
│       ├── N(2)
│       └── N(0)
└── [mul: 1.00000000000000] 
    └── KronBlock(1,2)
        ├── N(2)
        └── N(1)

Now let's consider that the experimental system is fixed, and qubits can not be isolated one from another. The options are:

  • Turn on or off the global system Hamiltonian.
  • Perform local single-qubit rotations.

To perform a fully digital CNOT(0,1), the interacting control on qubit 0 and target on qubit 1 must be isolated from the third one to implement the gate directly. While this can be achieved for a three-qubit system, it becomes experimentally untractable when scaling the qubit count.

However, this is not the case within the digital-analog paradigm. In fact, the two qubit Ising interaction required for the CNOT can be represented with a combination of the global system Hamiltonian and a specific set of single-qubit rotations. Full details about this transformation are to be found in the DAQC paper2 but a more succint yet in-depth description takes place in the next section. It is conveniently available in Qadence by calling the daqc_transform function.

In the most general sense, the daqc_transform function will return a circuit that represents the evolution of a target Hamiltonian \(\mathcal{H}_\text{target}\) (here the unitary of the gate) until a specified time \(t_f\) by using only the evolution of a build Hamiltonian \(\mathcal{H}_\text{build}\) (here \(\mathcal{H}_\text{sys}\)) together with local \(X\)-gates. In Qadence, daqc_transform is applicable for \(\mathcal{H}_\text{target}\) and \(\mathcal{H}_\text{build}\) composed only of \(ZZ\)- or \(NN\)-interactions. These generators are parsed by the daqc_transform function and the appropriate type is automatically determined together with the appropriate single-qubit detunings and global phases.

Let's apply it for the CNOT implementation:

from qadence import daqc_transform, Strategy

# Settings for the target CNOT operation
i = 0  # Control qubit
j = 1  # Target qubit
k = 2  # The extra qubit

# Define the target CNOT operation
# by composing with identity on the extra qubit.
cnot_target = kron(CNOT(i, j), I(k))

# The two-qubit NN-Ising interaction term for the CPHASE
h_int = (-1.0) * kron(N(i), N(j))

# Transforming the two-qubit Ising interaction using only our system Hamiltonian
transformed_ising = daqc_transform(
    n_qubits=3,        # Total number of qubits in the transformation
    gen_target=h_int,  # The target Ising generator
    t_f=PI,            # The target evolution time
    gen_build=h_sys,   # The building block Ising generator to be used
    strategy=Strategy.SDAQC,   # Currently only sDAQC is implemented
    ignore_global_phases=False  # Global phases from mapping between Z and N
)

# display(transformed_ising)
%3 cluster_b1b0c63780884ce39c150db34a8cec3c cluster_b9de7238ff3046a8be84768bc7613706 cluster_10c11f4a7f0a48b6b743fea1c9ed518f cluster_7f7c95aa6b8444d597b53f6be1912207 cluster_8c4470169d6d4cac98e530c91c5ae8d7 cluster_c2659657e30043028ebfc69dd0a1250f cluster_dc15e917e1db49aeb017040a0493b530 fdc731fbbaa2455fabdd15ed49a9fa5e 0 c11df9201f5e4d92bbf246e815298dd7 HamEvo fdc731fbbaa2455fabdd15ed49a9fa5e--c11df9201f5e4d92bbf246e815298dd7 dd35438c0fab4003b1987e6840899bfd 1 edf60e58f1c44bccbf93dbaa2b94b146 HamEvo c11df9201f5e4d92bbf246e815298dd7--edf60e58f1c44bccbf93dbaa2b94b146 1bd299fee9e64ae5b8b8c6b0366c8b90 HamEvo edf60e58f1c44bccbf93dbaa2b94b146--1bd299fee9e64ae5b8b8c6b0366c8b90 9d672628646d4d9fb1d854a87cc6e262 X 1bd299fee9e64ae5b8b8c6b0366c8b90--9d672628646d4d9fb1d854a87cc6e262 8b599f37181b47e28e0d446ed0e65801 HamEvo 9d672628646d4d9fb1d854a87cc6e262--8b599f37181b47e28e0d446ed0e65801 7999c8ad58474eb0871a84ac75372b8c HamEvo 8b599f37181b47e28e0d446ed0e65801--7999c8ad58474eb0871a84ac75372b8c 0174956f34af49818362859fc3f80b6b X 7999c8ad58474eb0871a84ac75372b8c--0174956f34af49818362859fc3f80b6b 68e0a4ebb0c348b69c52f77595588ebe 0174956f34af49818362859fc3f80b6b--68e0a4ebb0c348b69c52f77595588ebe 826f6e1d54f44c8bae374a3c04e05bed HamEvo 68e0a4ebb0c348b69c52f77595588ebe--826f6e1d54f44c8bae374a3c04e05bed 326bfaefeeca4838bd4e918f3ce5038e HamEvo 826f6e1d54f44c8bae374a3c04e05bed--326bfaefeeca4838bd4e918f3ce5038e c704c83898dd4a729ee4e7b7f2ca1c1e 326bfaefeeca4838bd4e918f3ce5038e--c704c83898dd4a729ee4e7b7f2ca1c1e b25d684220564d4b84e1dadea5a5dc95 c704c83898dd4a729ee4e7b7f2ca1c1e--b25d684220564d4b84e1dadea5a5dc95 66e64a82b4204464954f004635bbaec3 a8e8191cde90474ea73b54df0472c40f t = -3.142 dd35438c0fab4003b1987e6840899bfd--a8e8191cde90474ea73b54df0472c40f d0b3ec80e3ce461eb64ee0be67890f7e 2 ec4650a2419148c9b75084e250860cae t = 3.142 a8e8191cde90474ea73b54df0472c40f--ec4650a2419148c9b75084e250860cae 169e1aedbf4d460f8136582135b7bbaf t = -3.142 ec4650a2419148c9b75084e250860cae--169e1aedbf4d460f8136582135b7bbaf b89085d90ffd4bcd948ed8736613babc 169e1aedbf4d460f8136582135b7bbaf--b89085d90ffd4bcd948ed8736613babc 4b7ce1ad23b74555ba512afccb91f3cf t = 1.571 b89085d90ffd4bcd948ed8736613babc--4b7ce1ad23b74555ba512afccb91f3cf eb3a61a5091040018eda8a5696525d70 t = 1.571 4b7ce1ad23b74555ba512afccb91f3cf--eb3a61a5091040018eda8a5696525d70 a8e146d6e3664a09bfd8cd061a8ec0d7 eb3a61a5091040018eda8a5696525d70--a8e146d6e3664a09bfd8cd061a8ec0d7 5c83d2168482480aab37ea4bccd8b1c0 X a8e146d6e3664a09bfd8cd061a8ec0d7--5c83d2168482480aab37ea4bccd8b1c0 8326811fb1264f4a9757656a73f1f3fb t = 1.571 5c83d2168482480aab37ea4bccd8b1c0--8326811fb1264f4a9757656a73f1f3fb 87063616b86949718f9c0dd4829e9599 t = 1.571 8326811fb1264f4a9757656a73f1f3fb--87063616b86949718f9c0dd4829e9599 b2ba016f6dc1473db6ae2b5064b1ee40 X 87063616b86949718f9c0dd4829e9599--b2ba016f6dc1473db6ae2b5064b1ee40 b2ba016f6dc1473db6ae2b5064b1ee40--66e64a82b4204464954f004635bbaec3 2627fe5fb5e144a09b943f526ae211bd 9fd41f4bfc274af8ab1c7902503ce804 d0b3ec80e3ce461eb64ee0be67890f7e--9fd41f4bfc274af8ab1c7902503ce804 fd910b7cdda14b769edc4af5f97092c8 9fd41f4bfc274af8ab1c7902503ce804--fd910b7cdda14b769edc4af5f97092c8 6ff21a8273514d1b9095166fb1c870e5 fd910b7cdda14b769edc4af5f97092c8--6ff21a8273514d1b9095166fb1c870e5 a704cb43d0484cfdb3f4b6d1a03fff54 X 6ff21a8273514d1b9095166fb1c870e5--a704cb43d0484cfdb3f4b6d1a03fff54 0941c401f60a4e60bbefb4e0d6f62422 a704cb43d0484cfdb3f4b6d1a03fff54--0941c401f60a4e60bbefb4e0d6f62422 3b3b8853ab3243a5920c321fa2feb482 0941c401f60a4e60bbefb4e0d6f62422--3b3b8853ab3243a5920c321fa2feb482 cf18f2cbdaf742a7a9242b61dfd67d8c X 3b3b8853ab3243a5920c321fa2feb482--cf18f2cbdaf742a7a9242b61dfd67d8c 79058d4115d44f2aa3157933b2a929f0 X cf18f2cbdaf742a7a9242b61dfd67d8c--79058d4115d44f2aa3157933b2a929f0 e4fd5b09a1aa432684e499764fe81827 79058d4115d44f2aa3157933b2a929f0--e4fd5b09a1aa432684e499764fe81827 8d11ab4667104abaab62e439d3b4e900 e4fd5b09a1aa432684e499764fe81827--8d11ab4667104abaab62e439d3b4e900 4c3935f8c79e414faeb3c6a4f6ac0bd9 X 8d11ab4667104abaab62e439d3b4e900--4c3935f8c79e414faeb3c6a4f6ac0bd9 4c3935f8c79e414faeb3c6a4f6ac0bd9--2627fe5fb5e144a09b943f526ae211bd

The output circuit displays three groups of system Hamiltonian evolutions which account for global-phases and single-qubit detunings related to the mapping between the \(Z\) and \(N\) operators. Optionally, global phases can be ignored.

In general, the mapping of a \(n\)-qubit Ising Hamiltonian to another will require at most \(n(n-1)\) evolutions. The transformed circuit performs these evolutions for specific times that are computed from the solution of a linear system of equations involving the set of interactions in the target and build Hamiltonians.

In this case, the mapping is exact when using the step-wise DAQC strategy (Strategy.SDAQC) available in Qadence. In banged DAQC (Strategy.BDAQC) the mapping is approximate, but easier to implement on a physical device with always-on interactions such as neutral-atom systems.

Just as before, the transformed Ising circuit can be checked to exactly recover the CPHASE gate:

# CPHASE on (i, j), Identity on third qubit:
cphase_matrix = block_to_tensor(kron(CPHASE(i, j, phi), I(k)))

# CPHASE using the transformed circuit:
cphase_evo_matrix = block_to_tensor(transformed_ising)

# Check that it implements the CPHASE.
# Will fail if global phases are ignored.
cphase_matrix == cphase_evo_matrix : True

The CNOT gate can now finally be built:

from qadence import equivalent_state, run, sample

cnot_daqc = chain(
    H(j),
    transformed_ising,
    H(j)
)

# And finally apply the CNOT on a specific 3-qubit initial state:
init_state = product_state("101")

# Check we get an equivalent wavefunction
wf_cnot = run(n_qubits, block=cnot_target, state=init_state)
wf_daqc = run(n_qubits, block=cnot_daqc, state=init_state)

# Visualize the CNOT bit-flip in samples.
wf_cnot == wf_dacq : True
sample cnot_target = [Counter({'111': 100})]
sample cnot_dacq = [Counter({'111': 100})]

As one can see, a CNOT operation has been succesfully implemented on the desired target qubits by using only the global system as the building block Hamiltonian and single-qubit rotations. Decomposing a single digital gate into an Ising Hamiltonian serves as a proof of principle for the potential of this technique to represent universal quantum computation.

Technical details on the DAQC transformation

  • The mapping between target generator and final circuit is performed by solving a linear system of size \(n(n-1)\) where \(n\) is the number of qubits, so it can be computed efficiently (i.e., with a polynomial cost in the number of qubits).
  • The linear system to be solved is actually not invertible for \(n=4\) qubits. This is very specific edge case requiring a workaround, that is currently not yet implemented.
  • As mentioned, the final circuit has at most \(n(n-1)\) slices, so there is at most a quadratic overhead in circuit depth.

Finally, and most important to its usage:

  • The target Hamiltonian should be sufficiently represented in the building block Hamiltonian.

To illustrate this point, consider the following target and build Hamiltonians:

# Interaction between qubits 0 and 1
gen_target = 1.0 * (Z(0) @ Z(1))

# Fixed interaction between qubits 1 and 2, and customizable between 0 and 1
def gen_build(g_int):
    return g_int * (Z(0) @ Z(1)) + 1.0 * (Z(1) @ Z(2))

And now we perform the DAQC transform by setting g_int=1.0, exactly matching the target Hamiltonian:

transformed_ising = daqc_transform(
    n_qubits=3,
    gen_target=gen_target,
    t_f=1.0,
    gen_build=gen_build(g_int=1.0),
)

# display(transformed_ising)
%3 cluster_eec7f5899c1a4f6f9519a77d8b095b50 cluster_5f10146429c24346bd35401f4fb1b99e 92bb0dbe362d4aff96a7d0c4305672aa 0 dc2c1f6672bf4cb99d2ec7905e390f8d X 92bb0dbe362d4aff96a7d0c4305672aa--dc2c1f6672bf4cb99d2ec7905e390f8d 0bde85751d664b34868bba62d02e33e5 1 b9580d5ecc054a28a336efd3bbf2619c HamEvo dc2c1f6672bf4cb99d2ec7905e390f8d--b9580d5ecc054a28a336efd3bbf2619c 4224e65b81d848c3a77d7e77b5c914fd X b9580d5ecc054a28a336efd3bbf2619c--4224e65b81d848c3a77d7e77b5c914fd 75cf661d89f24f52a8b0662fde92a841 4224e65b81d848c3a77d7e77b5c914fd--75cf661d89f24f52a8b0662fde92a841 22cb15f4796c49458100f1b730e3f463 HamEvo 75cf661d89f24f52a8b0662fde92a841--22cb15f4796c49458100f1b730e3f463 a3437d61e6c54730a588b23ed4f3fcf9 22cb15f4796c49458100f1b730e3f463--a3437d61e6c54730a588b23ed4f3fcf9 a6163ee7ecc64aeca735e5699490e03b a3437d61e6c54730a588b23ed4f3fcf9--a6163ee7ecc64aeca735e5699490e03b a40ca1f239fc4244b6e795e67c210bd7 fb6ab31a5a0349b7ab586ce10a2b4a98 0bde85751d664b34868bba62d02e33e5--fb6ab31a5a0349b7ab586ce10a2b4a98 f261cb1cff5644abb4579d085110f641 2 c52dea8c2a6146f19acf61a672de4103 t = -0.500 fb6ab31a5a0349b7ab586ce10a2b4a98--c52dea8c2a6146f19acf61a672de4103 e2bdd5c4786546278a6ffc8b9d801e98 c52dea8c2a6146f19acf61a672de4103--e2bdd5c4786546278a6ffc8b9d801e98 99a5c17f79c846dbaa98ab7760c22676 X e2bdd5c4786546278a6ffc8b9d801e98--99a5c17f79c846dbaa98ab7760c22676 1d8996c637554691b76f4e71a5ec2a98 t = -0.500 99a5c17f79c846dbaa98ab7760c22676--1d8996c637554691b76f4e71a5ec2a98 e130d28407f0430782a91699ca4c7b40 X 1d8996c637554691b76f4e71a5ec2a98--e130d28407f0430782a91699ca4c7b40 e130d28407f0430782a91699ca4c7b40--a40ca1f239fc4244b6e795e67c210bd7 621de07c6c30431c847196f3ec571801 b45217683a024b74804be78aa8777425 X f261cb1cff5644abb4579d085110f641--b45217683a024b74804be78aa8777425 8ebf2040339445a284e9941e720d2e1b b45217683a024b74804be78aa8777425--8ebf2040339445a284e9941e720d2e1b d4b9ef39ca754af8be71c17c73af76af X 8ebf2040339445a284e9941e720d2e1b--d4b9ef39ca754af8be71c17c73af76af c0a7f1ce4c8e4e70b483d636e9cb6b6b X d4b9ef39ca754af8be71c17c73af76af--c0a7f1ce4c8e4e70b483d636e9cb6b6b 858823c922224e8d898aec924422e504 c0a7f1ce4c8e4e70b483d636e9cb6b6b--858823c922224e8d898aec924422e504 04b4de1ea5074c6c923e6f2b113b81d5 X 858823c922224e8d898aec924422e504--04b4de1ea5074c6c923e6f2b113b81d5 04b4de1ea5074c6c923e6f2b113b81d5--621de07c6c30431c847196f3ec571801

Now, if the interaction between qubits 0 and 1 is weakened in the build Hamiltonian:

transformed_ising = daqc_transform(
    n_qubits=3,
    gen_target=gen_target,
    t_f=1.0,
    gen_build=gen_build(g_int=0.001),
)

# display(transformed_ising)
%3 cluster_007e3773471c4d79abc37ddd02091193 cluster_d78f1b6f96694ab38e46068cfc6d60c1 924337f9bf8a45fa8cbacd2240506cbe 0 6dcbe5ce880c42b08889594f08480318 X 924337f9bf8a45fa8cbacd2240506cbe--6dcbe5ce880c42b08889594f08480318 69fd345c8ac342368d34e35e713d26c1 1 73eaee3906cb43febee2ad6d0526ae53 HamEvo 6dcbe5ce880c42b08889594f08480318--73eaee3906cb43febee2ad6d0526ae53 c4edf6283203425e8d639a80030a73f2 X 73eaee3906cb43febee2ad6d0526ae53--c4edf6283203425e8d639a80030a73f2 88c9306312fc436baf1d5978dde9a29f c4edf6283203425e8d639a80030a73f2--88c9306312fc436baf1d5978dde9a29f aae31adce6954e408c8d7d0b1fe374d0 HamEvo 88c9306312fc436baf1d5978dde9a29f--aae31adce6954e408c8d7d0b1fe374d0 f04a3c8eec834b5fbbdb9f9802700994 aae31adce6954e408c8d7d0b1fe374d0--f04a3c8eec834b5fbbdb9f9802700994 81e97a9cbba94cc690a85980ffbbf730 f04a3c8eec834b5fbbdb9f9802700994--81e97a9cbba94cc690a85980ffbbf730 d6f60d281354405ca44ea8b80292453c 51704b0710b4471bb1a7ab233e711a8a 69fd345c8ac342368d34e35e713d26c1--51704b0710b4471bb1a7ab233e711a8a a3cdfab532ed469b8a567b86f2422945 2 03d2cd272777414a8f48634af9508cc4 t = -500.000000000000 51704b0710b4471bb1a7ab233e711a8a--03d2cd272777414a8f48634af9508cc4 aec886b2e5e847a886839408f947870a 03d2cd272777414a8f48634af9508cc4--aec886b2e5e847a886839408f947870a 6da7fb5bc0ae468b8d6eeead1a46ebf8 X aec886b2e5e847a886839408f947870a--6da7fb5bc0ae468b8d6eeead1a46ebf8 148d2687af5541219688be92cabf915d t = -500.000000000000 6da7fb5bc0ae468b8d6eeead1a46ebf8--148d2687af5541219688be92cabf915d d47a90daa1524113b55a94f954727792 X 148d2687af5541219688be92cabf915d--d47a90daa1524113b55a94f954727792 d47a90daa1524113b55a94f954727792--d6f60d281354405ca44ea8b80292453c 916eefa767a44b169455379dee6dacdf 283011f0f51949baa90d8b7a3b9b543f X a3cdfab532ed469b8a567b86f2422945--283011f0f51949baa90d8b7a3b9b543f bd74e8d35e734a0a9197e9bc3b9feb35 283011f0f51949baa90d8b7a3b9b543f--bd74e8d35e734a0a9197e9bc3b9feb35 a85f796199c7441490ead9a1f1318725 X bd74e8d35e734a0a9197e9bc3b9feb35--a85f796199c7441490ead9a1f1318725 ea7a32b59f484e4a9109647fc29920b7 X a85f796199c7441490ead9a1f1318725--ea7a32b59f484e4a9109647fc29920b7 2cde2afacfbe466eaa7dd0c91118de83 ea7a32b59f484e4a9109647fc29920b7--2cde2afacfbe466eaa7dd0c91118de83 ba305e9bada848edaf8f34cd6b314463 X 2cde2afacfbe466eaa7dd0c91118de83--ba305e9bada848edaf8f34cd6b314463 ba305e9bada848edaf8f34cd6b314463--916eefa767a44b169455379dee6dacdf

The times slices using the build Hamiltonian need now to evolve for much longer to represent the same interaction since it is not sufficiently represented in the building block Hamiltonian.

In the limit where that interaction is not present, the transform will not work:

try:
    transformed_ising = daqc_transform(
        n_qubits=3,
        gen_target=gen_target,
        t_f=1.0,
        gen_build=gen_build(g_int = 0.0),
    )
except ValueError as error:
    print("Error:", error)
Error: Incompatible interactions between target and build Hamiltonians.

References