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

n_qubits = 2

# CNOT gate
cnot_gate = CNOT(0, 1)

# CNOT decomposed
phi = torch.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=torch.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_a75401db31974620bcfbdb555ac4a8bf cluster_9a9137334b234c9aa6b68b21ceac8864 cluster_e4318ce4994c471bb18dda46e22b30d1 cluster_d3d34691220646acb545a669d5a98939 cluster_e5cffd5dbb1b47f4935e5e0453726183 cluster_243ac2d8e71a492d9c10c7e1e0206a92 cluster_fffa306b2afc4a5ba7fe3fa1af600279 d924c6f92a2d4023b3ce5dfaf9c02a7c 0 f3be571ae71e46ebbfc0994c8306a477 HamEvo d924c6f92a2d4023b3ce5dfaf9c02a7c--f3be571ae71e46ebbfc0994c8306a477 24091013c7934a938880fc256b8fbbb9 1 9994ef93aa234a02abe6a8de842d5b44 HamEvo f3be571ae71e46ebbfc0994c8306a477--9994ef93aa234a02abe6a8de842d5b44 37b9b78582344297873de57384464904 HamEvo 9994ef93aa234a02abe6a8de842d5b44--37b9b78582344297873de57384464904 b5ac4daf2f894102986c968b0a8d709d X 37b9b78582344297873de57384464904--b5ac4daf2f894102986c968b0a8d709d 9edfd1fa4052465690f3a0aabd45fee5 HamEvo b5ac4daf2f894102986c968b0a8d709d--9edfd1fa4052465690f3a0aabd45fee5 3241668fb0f4401092cd228371a87670 HamEvo 9edfd1fa4052465690f3a0aabd45fee5--3241668fb0f4401092cd228371a87670 e5d95fac4d274edf8c6f4a1ea2109b25 X 3241668fb0f4401092cd228371a87670--e5d95fac4d274edf8c6f4a1ea2109b25 37a95baf38564d9b9f8659b2ac616128 e5d95fac4d274edf8c6f4a1ea2109b25--37a95baf38564d9b9f8659b2ac616128 70906854e88a4eddbbc7b09887420a68 HamEvo 37a95baf38564d9b9f8659b2ac616128--70906854e88a4eddbbc7b09887420a68 f7eba2f499104852bbfc42652e04fdad HamEvo 70906854e88a4eddbbc7b09887420a68--f7eba2f499104852bbfc42652e04fdad 489c96b0a42b449e8373c31b8579e217 f7eba2f499104852bbfc42652e04fdad--489c96b0a42b449e8373c31b8579e217 ee05741839e74185b95a0fe0a66cc82f 489c96b0a42b449e8373c31b8579e217--ee05741839e74185b95a0fe0a66cc82f b019c398a589496ab521abce6ad8cb8d a3f4e91f333f48da810cbaf87cd035fa t = -3.142 24091013c7934a938880fc256b8fbbb9--a3f4e91f333f48da810cbaf87cd035fa 3cb327dd9ea547e4a800a9d67fc8a1fa 2 eea0b44634814ce9b72b12847473a431 t = 3.142 a3f4e91f333f48da810cbaf87cd035fa--eea0b44634814ce9b72b12847473a431 88140b8f7ec34c3d827c4dd510d0482b t = -3.142 eea0b44634814ce9b72b12847473a431--88140b8f7ec34c3d827c4dd510d0482b 697711fb10444db493330cbbdc07b81e 88140b8f7ec34c3d827c4dd510d0482b--697711fb10444db493330cbbdc07b81e 0388281dfb1d42aa9a91467dd374b1c5 t = 1.571 697711fb10444db493330cbbdc07b81e--0388281dfb1d42aa9a91467dd374b1c5 d6380ecf61f04f6b920e946a2bdbbef1 t = 1.571 0388281dfb1d42aa9a91467dd374b1c5--d6380ecf61f04f6b920e946a2bdbbef1 50958be4471948029d79b696c7ff911c d6380ecf61f04f6b920e946a2bdbbef1--50958be4471948029d79b696c7ff911c 6e6673fa84364d81b8ef77f025c24029 X 50958be4471948029d79b696c7ff911c--6e6673fa84364d81b8ef77f025c24029 88f45dd544e74fd5ab180ad94f503e27 t = 1.571 6e6673fa84364d81b8ef77f025c24029--88f45dd544e74fd5ab180ad94f503e27 c599f12a9efe4bca8d0d6065982443ab t = 1.571 88f45dd544e74fd5ab180ad94f503e27--c599f12a9efe4bca8d0d6065982443ab b34f636897d3466992973eb2556aaee3 X c599f12a9efe4bca8d0d6065982443ab--b34f636897d3466992973eb2556aaee3 b34f636897d3466992973eb2556aaee3--b019c398a589496ab521abce6ad8cb8d 0f6a81c05fc84092994577e992c5378b 6b662854b6bc4ee0b3e89853b32f53af 3cb327dd9ea547e4a800a9d67fc8a1fa--6b662854b6bc4ee0b3e89853b32f53af a898394b46a741b788e3bb72a3d0f00f 6b662854b6bc4ee0b3e89853b32f53af--a898394b46a741b788e3bb72a3d0f00f bb7a6bf407fa4489acdd4cc3dd2529ed a898394b46a741b788e3bb72a3d0f00f--bb7a6bf407fa4489acdd4cc3dd2529ed 1cbc805b8a9d46e19f8dc90b33bc39ce X bb7a6bf407fa4489acdd4cc3dd2529ed--1cbc805b8a9d46e19f8dc90b33bc39ce 2fcc4d83701f47468cc2876a682adae5 1cbc805b8a9d46e19f8dc90b33bc39ce--2fcc4d83701f47468cc2876a682adae5 a3b34fe09acf4b6094be749cbb4a1bef 2fcc4d83701f47468cc2876a682adae5--a3b34fe09acf4b6094be749cbb4a1bef d4c2c1a8d72043f7a56f57e6f699ca24 X a3b34fe09acf4b6094be749cbb4a1bef--d4c2c1a8d72043f7a56f57e6f699ca24 808e8e1700d44478890e234d2ef2e3ed X d4c2c1a8d72043f7a56f57e6f699ca24--808e8e1700d44478890e234d2ef2e3ed fcc91dc15d554edf9df1528460dd1cb7 808e8e1700d44478890e234d2ef2e3ed--fcc91dc15d554edf9df1528460dd1cb7 f7369e8c641a460088cb596d15a3cf31 fcc91dc15d554edf9df1528460dd1cb7--f7369e8c641a460088cb596d15a3cf31 316b1a88d7da45cf8a476818c76f8026 X f7369e8c641a460088cb596d15a3cf31--316b1a88d7da45cf8a476818c76f8026 316b1a88d7da45cf8a476818c76f8026--0f6a81c05fc84092994577e992c5378b

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_bd2bcca0448d493bb977ce02b9fb4842 cluster_4f755638f30347eb9532972edbbabdfc 8c881aefdc984baea1ea31d6d3976e07 0 1f7c22962d8c4687ac09a04352957f0a X 8c881aefdc984baea1ea31d6d3976e07--1f7c22962d8c4687ac09a04352957f0a b4ae9549659e42bfa5b51a1e2c4c95f8 1 a4689b12adcc4f9ab9ef69f253473743 HamEvo 1f7c22962d8c4687ac09a04352957f0a--a4689b12adcc4f9ab9ef69f253473743 34830cd5786543b9a9bcb6be6b129511 X a4689b12adcc4f9ab9ef69f253473743--34830cd5786543b9a9bcb6be6b129511 ac9691fc6975454d917791ed281a09b3 34830cd5786543b9a9bcb6be6b129511--ac9691fc6975454d917791ed281a09b3 ae9ea1a404a640538f48db8172a41f19 HamEvo ac9691fc6975454d917791ed281a09b3--ae9ea1a404a640538f48db8172a41f19 af82f062779e4fc7a66aeafc6d7c4756 ae9ea1a404a640538f48db8172a41f19--af82f062779e4fc7a66aeafc6d7c4756 e6907ef01f6e410aa9134eb4490a38d3 af82f062779e4fc7a66aeafc6d7c4756--e6907ef01f6e410aa9134eb4490a38d3 0f5a02b7fd8a41cfb0ab142da6ca632e eada3e9bc7734265a701929e585ccdde b4ae9549659e42bfa5b51a1e2c4c95f8--eada3e9bc7734265a701929e585ccdde 01506b4db71d4d28814fc22ec6dc332b 2 77e0ca51dbf347598cba00045c9015e8 t = -0.500 eada3e9bc7734265a701929e585ccdde--77e0ca51dbf347598cba00045c9015e8 872c7aed69e74ec8941f0d0bf0c3dd9a 77e0ca51dbf347598cba00045c9015e8--872c7aed69e74ec8941f0d0bf0c3dd9a 5299c9d78f3548e295e7d9c532e75b5a X 872c7aed69e74ec8941f0d0bf0c3dd9a--5299c9d78f3548e295e7d9c532e75b5a 20cc01b21aa94bb1980f0dd21f57ec28 t = -0.500 5299c9d78f3548e295e7d9c532e75b5a--20cc01b21aa94bb1980f0dd21f57ec28 45fb5981c8c24f1f98ebc34e407fe00a X 20cc01b21aa94bb1980f0dd21f57ec28--45fb5981c8c24f1f98ebc34e407fe00a 45fb5981c8c24f1f98ebc34e407fe00a--0f5a02b7fd8a41cfb0ab142da6ca632e 3d54a2a31e524dffa01fdc37ae18a9e8 139fb60127394289bcb6e4e9fec2f64a X 01506b4db71d4d28814fc22ec6dc332b--139fb60127394289bcb6e4e9fec2f64a c1bda9a4716f4780b79504c1fa364ebb 139fb60127394289bcb6e4e9fec2f64a--c1bda9a4716f4780b79504c1fa364ebb 35fb1109dbdc4762a7beb8d6b18d7422 X c1bda9a4716f4780b79504c1fa364ebb--35fb1109dbdc4762a7beb8d6b18d7422 5b09166935da4da69e398a931044d988 X 35fb1109dbdc4762a7beb8d6b18d7422--5b09166935da4da69e398a931044d988 160c7f86df8e4515963298ef8b726902 5b09166935da4da69e398a931044d988--160c7f86df8e4515963298ef8b726902 c476b488e58043fab11343ebe0c0371f X 160c7f86df8e4515963298ef8b726902--c476b488e58043fab11343ebe0c0371f c476b488e58043fab11343ebe0c0371f--3d54a2a31e524dffa01fdc37ae18a9e8

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_14cff56cad574c10879e626353506441 cluster_e316de09bf05423f98e632301fcf8e01 05b6805da48442699aa148ae81a5ddb0 0 eef0b17598384779ab71a3f193f6787f X 05b6805da48442699aa148ae81a5ddb0--eef0b17598384779ab71a3f193f6787f e17a5d2c4a70463d9a9798d0ca9cb0d7 1 21a7f6fd284b4680b13cd126590c4e45 HamEvo eef0b17598384779ab71a3f193f6787f--21a7f6fd284b4680b13cd126590c4e45 ef5b17d5101a4d7cb7e59776f9b6f94e X 21a7f6fd284b4680b13cd126590c4e45--ef5b17d5101a4d7cb7e59776f9b6f94e 4ef1696b50d84382a6d90090aab4d483 ef5b17d5101a4d7cb7e59776f9b6f94e--4ef1696b50d84382a6d90090aab4d483 57a1f0fc33534fe0b880a129a92d7484 HamEvo 4ef1696b50d84382a6d90090aab4d483--57a1f0fc33534fe0b880a129a92d7484 e85f48aa42f94ef9afc7b35ac228447a 57a1f0fc33534fe0b880a129a92d7484--e85f48aa42f94ef9afc7b35ac228447a 2aa1b1647fc34d8f84e7048c5b5909de e85f48aa42f94ef9afc7b35ac228447a--2aa1b1647fc34d8f84e7048c5b5909de 2a3baf89ce92446180f93e50fe2b0326 03568d45a3ec4a5b9c605a03d91e2479 e17a5d2c4a70463d9a9798d0ca9cb0d7--03568d45a3ec4a5b9c605a03d91e2479 cc7e3aa63445471f91c0e03f9a5c6f28 2 4481d25d3ffc49faa0d14603d7cef3c6 t = -500.000000000000 03568d45a3ec4a5b9c605a03d91e2479--4481d25d3ffc49faa0d14603d7cef3c6 dedba35791fe4392882bcbdfbc3b70f9 4481d25d3ffc49faa0d14603d7cef3c6--dedba35791fe4392882bcbdfbc3b70f9 11912f4d65d045d29320bc5a5b53f1aa X dedba35791fe4392882bcbdfbc3b70f9--11912f4d65d045d29320bc5a5b53f1aa cb9cda844fb146faaabca9eddd9165c1 t = -500.000000000000 11912f4d65d045d29320bc5a5b53f1aa--cb9cda844fb146faaabca9eddd9165c1 01f679ce727b48f5a2f5cad11802e083 X cb9cda844fb146faaabca9eddd9165c1--01f679ce727b48f5a2f5cad11802e083 01f679ce727b48f5a2f5cad11802e083--2a3baf89ce92446180f93e50fe2b0326 9672a0c5801d4809a7ec8f08dabd7b29 e40efc3a7d484573910ea1f86c9180d5 X cc7e3aa63445471f91c0e03f9a5c6f28--e40efc3a7d484573910ea1f86c9180d5 dcbd1cb5b98548f583b2548f486faad2 e40efc3a7d484573910ea1f86c9180d5--dcbd1cb5b98548f583b2548f486faad2 f3c9f79d6e88470f9c75940d59c8ea2a X dcbd1cb5b98548f583b2548f486faad2--f3c9f79d6e88470f9c75940d59c8ea2a 36c223e3d2df450ab7837d83824a57cf X f3c9f79d6e88470f9c75940d59c8ea2a--36c223e3d2df450ab7837d83824a57cf d69bc1460dca4094850ff84ebc363ea7 36c223e3d2df450ab7837d83824a57cf--d69bc1460dca4094850ff84ebc363ea7 9aa7c35660d44b418271691c00c651fa X d69bc1460dca4094850ff84ebc363ea7--9aa7c35660d44b418271691c00c651fa 9aa7c35660d44b418271691c00c651fa--9672a0c5801d4809a7ec8f08dabd7b29

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