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 = [OrderedCounter({'11': 100})]
sample from decomposed CNOT gate and 100 shots = [OrderedCounter({'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 = [OrderedCounter({'11': 100})]
sample cnot_evo = [OrderedCounter({'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.000] 
│   └── KronBlock(0,1)
│       ├── N(1)
│       └── N(0)
├── [mul: 1.000] 
│   └── KronBlock(0,2)
│       ├── N(2)
│       └── N(0)
└── [mul: 1.000] 
    └── 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_e6fe5176211c48eb8f9492863b2c9a7e cluster_f563e4c8b70e4cf5a9bd2768366ff14b cluster_41dd41e51b4a4d778199951d24b67e36 cluster_b34014a7c4bc4fe59eb441742d00f1e7 cluster_12800a3f77444403a04049aa2b5c76d1 cluster_c5208013923d4f8fa29307443a9ffd8c cluster_8609da6a2efc41c89a9092c3720bc31e 058d277bf64a49bba4b59bdf7bae4810 0 f555bb4343424fb9b6a50e564059a366 HamEvo 058d277bf64a49bba4b59bdf7bae4810--f555bb4343424fb9b6a50e564059a366 f1d8c4cb00984fdca1dea3d209be4275 1 f202680e42074b70afc7d00aea4fa477 HamEvo f555bb4343424fb9b6a50e564059a366--f202680e42074b70afc7d00aea4fa477 a6c7c86e8d8c4079889ad1a76999a744 HamEvo f202680e42074b70afc7d00aea4fa477--a6c7c86e8d8c4079889ad1a76999a744 74c3f587d72a46eba491ef5f0734f30f X a6c7c86e8d8c4079889ad1a76999a744--74c3f587d72a46eba491ef5f0734f30f 17df9b8692fa4ec9a903a4aed8bf7962 HamEvo 74c3f587d72a46eba491ef5f0734f30f--17df9b8692fa4ec9a903a4aed8bf7962 1970cbbc32954a8cbe5ac9ba5a0a8675 HamEvo 17df9b8692fa4ec9a903a4aed8bf7962--1970cbbc32954a8cbe5ac9ba5a0a8675 da5754075c0b4085a868206e34e19603 X 1970cbbc32954a8cbe5ac9ba5a0a8675--da5754075c0b4085a868206e34e19603 3f72be2600ca4545ba70b47de99f8af3 da5754075c0b4085a868206e34e19603--3f72be2600ca4545ba70b47de99f8af3 6a8d2bd0b03d43ecbf150272b64ee8b1 HamEvo 3f72be2600ca4545ba70b47de99f8af3--6a8d2bd0b03d43ecbf150272b64ee8b1 04f70744eed946f4b1b1b09d4e7362fb HamEvo 6a8d2bd0b03d43ecbf150272b64ee8b1--04f70744eed946f4b1b1b09d4e7362fb ac73ca4b39c54b5ba71edcf6bd8d57e2 04f70744eed946f4b1b1b09d4e7362fb--ac73ca4b39c54b5ba71edcf6bd8d57e2 56897fe97b51444daa79ffeecb307176 ac73ca4b39c54b5ba71edcf6bd8d57e2--56897fe97b51444daa79ffeecb307176 60fa56e916be4a08acebfb6334cee831 d53690ca6fe74caca83b33d79b0d1124 t = -3.14 f1d8c4cb00984fdca1dea3d209be4275--d53690ca6fe74caca83b33d79b0d1124 60b01ae85c4544b4a31d48a630d23c5a 2 03ace017719241afa7176116059db1fb t = 3.142 d53690ca6fe74caca83b33d79b0d1124--03ace017719241afa7176116059db1fb 36bfa0a07a8e4a28bddf8f6bed203163 t = -3.14 03ace017719241afa7176116059db1fb--36bfa0a07a8e4a28bddf8f6bed203163 e7d3650d05f8492584432e1db9f91da5 36bfa0a07a8e4a28bddf8f6bed203163--e7d3650d05f8492584432e1db9f91da5 54383d3dc50a4a2b9fde9d4ff455466c t = 1.571 e7d3650d05f8492584432e1db9f91da5--54383d3dc50a4a2b9fde9d4ff455466c d9a4ad71bb1a412d8f650a20a73f8757 t = 1.571 54383d3dc50a4a2b9fde9d4ff455466c--d9a4ad71bb1a412d8f650a20a73f8757 2993526caf1943a68ba6bb7ff33576b9 d9a4ad71bb1a412d8f650a20a73f8757--2993526caf1943a68ba6bb7ff33576b9 0e1740ea08a44ea1a0e60fb4357fb6cc X 2993526caf1943a68ba6bb7ff33576b9--0e1740ea08a44ea1a0e60fb4357fb6cc 3eb58ca3da8f4c948de3f6d5dcbacaf1 t = 1.571 0e1740ea08a44ea1a0e60fb4357fb6cc--3eb58ca3da8f4c948de3f6d5dcbacaf1 f74840fc395546429f3e1e83a34c57e1 t = 1.571 3eb58ca3da8f4c948de3f6d5dcbacaf1--f74840fc395546429f3e1e83a34c57e1 5737fd6870f94d28a68609c32f35522c X f74840fc395546429f3e1e83a34c57e1--5737fd6870f94d28a68609c32f35522c 5737fd6870f94d28a68609c32f35522c--60fa56e916be4a08acebfb6334cee831 3d4830628dc14e258296735dbc48e4c4 b1fe8b5e4ebe4b16afb4fb524a1f4b04 60b01ae85c4544b4a31d48a630d23c5a--b1fe8b5e4ebe4b16afb4fb524a1f4b04 9231e09079b444179982f08ac23a81d9 b1fe8b5e4ebe4b16afb4fb524a1f4b04--9231e09079b444179982f08ac23a81d9 46b4601c78e343d9bd76a2363d4f92dc 9231e09079b444179982f08ac23a81d9--46b4601c78e343d9bd76a2363d4f92dc a604f2a23b264a3cb79ed0ea08844558 X 46b4601c78e343d9bd76a2363d4f92dc--a604f2a23b264a3cb79ed0ea08844558 e2154665b05a47829678e1b36cac9441 a604f2a23b264a3cb79ed0ea08844558--e2154665b05a47829678e1b36cac9441 031fc3a375c64eb4a4e5fc8a7637290c e2154665b05a47829678e1b36cac9441--031fc3a375c64eb4a4e5fc8a7637290c bfcb43327d2241a782b5fb6a3f1c167b X 031fc3a375c64eb4a4e5fc8a7637290c--bfcb43327d2241a782b5fb6a3f1c167b 6ac94980c7074ed5b2f941bbd0e52e91 X bfcb43327d2241a782b5fb6a3f1c167b--6ac94980c7074ed5b2f941bbd0e52e91 c976c9404e8142a0bf722a4e431c13b3 6ac94980c7074ed5b2f941bbd0e52e91--c976c9404e8142a0bf722a4e431c13b3 0cb34614486440099236474909a47be9 c976c9404e8142a0bf722a4e431c13b3--0cb34614486440099236474909a47be9 2b8da87f8a254f43ab9d8e458647da20 X 0cb34614486440099236474909a47be9--2b8da87f8a254f43ab9d8e458647da20 2b8da87f8a254f43ab9d8e458647da20--3d4830628dc14e258296735dbc48e4c4

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 = [OrderedCounter({'111': 100})]
sample cnot_dacq = [OrderedCounter({'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_28c74b24ad6d40f2b2b6c32df4935814 cluster_811bea47f89e417ab8aaad13f0e48d64 3ed3da2d64904fb3afbf8cca844b85ad 0 1f8f82b344b24bfc9aefa24cfe694416 X 3ed3da2d64904fb3afbf8cca844b85ad--1f8f82b344b24bfc9aefa24cfe694416 bcf7d4c77f0d4e16ad5990f9600f1a84 1 436caba861574467bcac47996ea0ccf9 HamEvo 1f8f82b344b24bfc9aefa24cfe694416--436caba861574467bcac47996ea0ccf9 9de1d6e969a547099f01cab9683f97ca X 436caba861574467bcac47996ea0ccf9--9de1d6e969a547099f01cab9683f97ca 17cc77856ef846ae82270faa6734d95e 9de1d6e969a547099f01cab9683f97ca--17cc77856ef846ae82270faa6734d95e 1ba784213fd649aea217747e3b823e28 HamEvo 17cc77856ef846ae82270faa6734d95e--1ba784213fd649aea217747e3b823e28 6a1dc4d7045d4af8ad5f58685955cc43 1ba784213fd649aea217747e3b823e28--6a1dc4d7045d4af8ad5f58685955cc43 01a14d54c1dd4b91bbdb6e5a738be694 6a1dc4d7045d4af8ad5f58685955cc43--01a14d54c1dd4b91bbdb6e5a738be694 8a01b694abee48848aab6194460e458b 3330d1db5d114bf89147d63e5dda5003 bcf7d4c77f0d4e16ad5990f9600f1a84--3330d1db5d114bf89147d63e5dda5003 e4a4450d9a6e48bca7334e41fea98760 2 5bd8cd067cf44639a9e760eaf43ef2db t = -0.50 3330d1db5d114bf89147d63e5dda5003--5bd8cd067cf44639a9e760eaf43ef2db e4448ada30444feb8bfc1bceafed047a 5bd8cd067cf44639a9e760eaf43ef2db--e4448ada30444feb8bfc1bceafed047a 9e9157afa7c1489c8330c3ec5bc5811b X e4448ada30444feb8bfc1bceafed047a--9e9157afa7c1489c8330c3ec5bc5811b b32281fcae304410bb621a2967daddc9 t = -0.50 9e9157afa7c1489c8330c3ec5bc5811b--b32281fcae304410bb621a2967daddc9 4d2a86deaef24e38b7672a348658d0e4 X b32281fcae304410bb621a2967daddc9--4d2a86deaef24e38b7672a348658d0e4 4d2a86deaef24e38b7672a348658d0e4--8a01b694abee48848aab6194460e458b 0a31815ca4f3492e8eaab58a5a7275d5 4215c2974d534716a6f7ca91c586e178 X e4a4450d9a6e48bca7334e41fea98760--4215c2974d534716a6f7ca91c586e178 493137b093114ffca1f98bcbc8eeca4f 4215c2974d534716a6f7ca91c586e178--493137b093114ffca1f98bcbc8eeca4f 75b124bec3434f0c849fc2c23e10b4af X 493137b093114ffca1f98bcbc8eeca4f--75b124bec3434f0c849fc2c23e10b4af 1ce5fc323739419bb42f5faaaf4839cb X 75b124bec3434f0c849fc2c23e10b4af--1ce5fc323739419bb42f5faaaf4839cb 6279c931363e4769a1e7273de8e55df9 1ce5fc323739419bb42f5faaaf4839cb--6279c931363e4769a1e7273de8e55df9 13e5878d69ef446dbc3d548991f35826 X 6279c931363e4769a1e7273de8e55df9--13e5878d69ef446dbc3d548991f35826 13e5878d69ef446dbc3d548991f35826--0a31815ca4f3492e8eaab58a5a7275d5

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_1fa657278a894a428aa88bb5d56554b7 cluster_58ae80d5d6834388a92834e1b1a6cfe1 e71937cd3bbf4491b02f126b84aede6f 0 08a7245d87e0449f89b59b68357611ae X e71937cd3bbf4491b02f126b84aede6f--08a7245d87e0449f89b59b68357611ae 44201cb17c7f40529af08414ba3e0725 1 740d3a7b03de430c977121575eb8bf51 HamEvo 08a7245d87e0449f89b59b68357611ae--740d3a7b03de430c977121575eb8bf51 4cdf0410d13a417dbd6ff401ac40b44b X 740d3a7b03de430c977121575eb8bf51--4cdf0410d13a417dbd6ff401ac40b44b 0a4e241a6d3d44a7bc47f19cd6a2847e 4cdf0410d13a417dbd6ff401ac40b44b--0a4e241a6d3d44a7bc47f19cd6a2847e 41fb11b315414fc8bbde038809b5a6fb HamEvo 0a4e241a6d3d44a7bc47f19cd6a2847e--41fb11b315414fc8bbde038809b5a6fb e6d7f527358649618d8ee8f4b8d7d417 41fb11b315414fc8bbde038809b5a6fb--e6d7f527358649618d8ee8f4b8d7d417 603e05b34da54a45a73a0ddab003a07a e6d7f527358649618d8ee8f4b8d7d417--603e05b34da54a45a73a0ddab003a07a 7f44807baaf0469b92cda1bbd185cb7d 46e3479e3cbf48d580e0fe52d76fac53 44201cb17c7f40529af08414ba3e0725--46e3479e3cbf48d580e0fe52d76fac53 cd0478dfa306401085b4dacd3e05956a 2 3382c7cfbd664d97b74f58f59f09bc01 t = -500. 46e3479e3cbf48d580e0fe52d76fac53--3382c7cfbd664d97b74f58f59f09bc01 02861cb653534a0288d55dfe292c8b74 3382c7cfbd664d97b74f58f59f09bc01--02861cb653534a0288d55dfe292c8b74 64ca7565d7a749e6800683348992bc6e X 02861cb653534a0288d55dfe292c8b74--64ca7565d7a749e6800683348992bc6e 030d7e03859f463dab197202152ffc1f t = -500. 64ca7565d7a749e6800683348992bc6e--030d7e03859f463dab197202152ffc1f 5fcd9ede5ce24f74b1906942a2eb4bb4 X 030d7e03859f463dab197202152ffc1f--5fcd9ede5ce24f74b1906942a2eb4bb4 5fcd9ede5ce24f74b1906942a2eb4bb4--7f44807baaf0469b92cda1bbd185cb7d cce0010b2ac24e289241de7b3fe80ece 538a96aead934674bbbde3fa13d5ddf8 X cd0478dfa306401085b4dacd3e05956a--538a96aead934674bbbde3fa13d5ddf8 062859609e7d4ba1a79a18113948dee7 538a96aead934674bbbde3fa13d5ddf8--062859609e7d4ba1a79a18113948dee7 cf0db7413c3c4ca4bb81c98265d0b22c X 062859609e7d4ba1a79a18113948dee7--cf0db7413c3c4ca4bb81c98265d0b22c fbdc5c9df6df4985b5ea416a67868376 X cf0db7413c3c4ca4bb81c98265d0b22c--fbdc5c9df6df4985b5ea416a67868376 07734a9891df405bb1421611ca58eb23 fbdc5c9df6df4985b5ea416a67868376--07734a9891df405bb1421611ca58eb23 77bcaed3780c4149b5f326274a09a994 X 07734a9891df405bb1421611ca58eb23--77bcaed3780c4149b5f326274a09a994 77bcaed3780c4149b5f326274a09a994--cce0010b2ac24e289241de7b3fe80ece

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