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.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_235f68e2a35b42bdb0b9514d2bcc6170 cluster_d94fa179ad0c46628b336746498db747 cluster_f7582a21d26b4aa3b9c91103c16f9bdd cluster_6fc34f76a9854825975c5f7b2d834da6 cluster_b5b9ab39ac394b2dafbfb876a25f2370 cluster_de3bff0bbf3c472aba51a8b77ec017f8 cluster_cd4c1d6191e4415f91c2c4eef8856416 585e7a28cdaf4d02b301600f656c1b21 0 b113ab1eee924f59ae0331f1d863d884 HamEvo 585e7a28cdaf4d02b301600f656c1b21--b113ab1eee924f59ae0331f1d863d884 70cb85358a574c7da128eeacfe98b388 1 d14d9916a7b542b1923d5e321f7539d5 HamEvo b113ab1eee924f59ae0331f1d863d884--d14d9916a7b542b1923d5e321f7539d5 e797cd7aff994a28bcc4891f5076b54b HamEvo d14d9916a7b542b1923d5e321f7539d5--e797cd7aff994a28bcc4891f5076b54b 90817f975149439c8bef05bc8e80e095 X e797cd7aff994a28bcc4891f5076b54b--90817f975149439c8bef05bc8e80e095 9601efd105a04fc78e4f27cd5e933030 HamEvo 90817f975149439c8bef05bc8e80e095--9601efd105a04fc78e4f27cd5e933030 a8e0af9a835b41638b9f1c969e4cbeb5 HamEvo 9601efd105a04fc78e4f27cd5e933030--a8e0af9a835b41638b9f1c969e4cbeb5 6ad02c279528444e92e44e7718548d99 X a8e0af9a835b41638b9f1c969e4cbeb5--6ad02c279528444e92e44e7718548d99 6c607f15b8fd4f83b46dc2234eaa7914 6ad02c279528444e92e44e7718548d99--6c607f15b8fd4f83b46dc2234eaa7914 7d9c96207b904e8796c552fab9d36400 HamEvo 6c607f15b8fd4f83b46dc2234eaa7914--7d9c96207b904e8796c552fab9d36400 c7a9747852704c4b8e1f9d4aaf545f07 HamEvo 7d9c96207b904e8796c552fab9d36400--c7a9747852704c4b8e1f9d4aaf545f07 a2d369d63cf04272a453224f38049fba c7a9747852704c4b8e1f9d4aaf545f07--a2d369d63cf04272a453224f38049fba b642b07dbaa745a7b4591c8e60492394 a2d369d63cf04272a453224f38049fba--b642b07dbaa745a7b4591c8e60492394 3fbef1bf1c444237b88f138877b267e5 2f94b1cef5d6438da15b453ed69f1119 t = -3.14 70cb85358a574c7da128eeacfe98b388--2f94b1cef5d6438da15b453ed69f1119 76b0decbbd784fb3a160fb1caed67bb6 2 8d9882a7424948ef990e87cb90dc7e31 t = 3.142 2f94b1cef5d6438da15b453ed69f1119--8d9882a7424948ef990e87cb90dc7e31 3d3f5ced3cbc4a75a0c9d7e1fe6396f7 t = -3.14 8d9882a7424948ef990e87cb90dc7e31--3d3f5ced3cbc4a75a0c9d7e1fe6396f7 be351e38e87d447f9ac0200b01b985ac 3d3f5ced3cbc4a75a0c9d7e1fe6396f7--be351e38e87d447f9ac0200b01b985ac 32dd542e85f840bfb1e7365b03446050 t = 1.571 be351e38e87d447f9ac0200b01b985ac--32dd542e85f840bfb1e7365b03446050 490146ff5e12492388dfe1524d098487 t = 1.571 32dd542e85f840bfb1e7365b03446050--490146ff5e12492388dfe1524d098487 ce544f5e3068458f8c569fef71e73220 490146ff5e12492388dfe1524d098487--ce544f5e3068458f8c569fef71e73220 cb69bcdf4e0349c8a48a13d7c073b01d X ce544f5e3068458f8c569fef71e73220--cb69bcdf4e0349c8a48a13d7c073b01d 7c5c27e296204f398feb5ed9779cdd7e t = 1.571 cb69bcdf4e0349c8a48a13d7c073b01d--7c5c27e296204f398feb5ed9779cdd7e 5c9e1ff55d154d25b7afd1294da98fde t = 1.571 7c5c27e296204f398feb5ed9779cdd7e--5c9e1ff55d154d25b7afd1294da98fde 9536c4c17f25476fa4b410efc35a7e66 X 5c9e1ff55d154d25b7afd1294da98fde--9536c4c17f25476fa4b410efc35a7e66 9536c4c17f25476fa4b410efc35a7e66--3fbef1bf1c444237b88f138877b267e5 070c8737d3794d3ea9ec673c388884ca 2916bf898c1d4c74adc101b421855ce0 76b0decbbd784fb3a160fb1caed67bb6--2916bf898c1d4c74adc101b421855ce0 30e3406a929341c69bff47e5767fc225 2916bf898c1d4c74adc101b421855ce0--30e3406a929341c69bff47e5767fc225 bcacbc2dbbb14f33b455ea128026b8ac 30e3406a929341c69bff47e5767fc225--bcacbc2dbbb14f33b455ea128026b8ac 1a86b9ab0e524d5f96ebf2f9a4c0a65b X bcacbc2dbbb14f33b455ea128026b8ac--1a86b9ab0e524d5f96ebf2f9a4c0a65b c20747696352499bbafb84befb1c97a5 1a86b9ab0e524d5f96ebf2f9a4c0a65b--c20747696352499bbafb84befb1c97a5 ef0ef6e6671e43bd9cfd7bf1756af9c3 c20747696352499bbafb84befb1c97a5--ef0ef6e6671e43bd9cfd7bf1756af9c3 4f8489522e3c430699725aed946aa13b X ef0ef6e6671e43bd9cfd7bf1756af9c3--4f8489522e3c430699725aed946aa13b a03b514a7d6e4290a33bfb5393cde4c1 X 4f8489522e3c430699725aed946aa13b--a03b514a7d6e4290a33bfb5393cde4c1 43bde57dafd74a1685bcc5ac0d882d60 a03b514a7d6e4290a33bfb5393cde4c1--43bde57dafd74a1685bcc5ac0d882d60 e7114aec304b456888716dbbaf7901d2 43bde57dafd74a1685bcc5ac0d882d60--e7114aec304b456888716dbbaf7901d2 7bb93c8834554508a072f5cf31af6fc8 X e7114aec304b456888716dbbaf7901d2--7bb93c8834554508a072f5cf31af6fc8 7bb93c8834554508a072f5cf31af6fc8--070c8737d3794d3ea9ec673c388884ca

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_619348b7dc6b4fae94e2168a5b669294 cluster_59ad3a184d1c4b3eba7ecfe96cd1cd81 f2655db5b83e4ccc99fec53acab96d09 0 b4fe12715fd24804b35acfb88e40fb31 X f2655db5b83e4ccc99fec53acab96d09--b4fe12715fd24804b35acfb88e40fb31 643ad7b54f8344258b17395ec150cf4f 1 631b317524064ed18b7dc1f2515d14ad HamEvo b4fe12715fd24804b35acfb88e40fb31--631b317524064ed18b7dc1f2515d14ad 3b2a1baeb53642c28484d58e9502d935 X 631b317524064ed18b7dc1f2515d14ad--3b2a1baeb53642c28484d58e9502d935 d0c8042307174cfa98b2ddea5c999da8 3b2a1baeb53642c28484d58e9502d935--d0c8042307174cfa98b2ddea5c999da8 8e38dc82bc584ebcaebc95282fe88664 HamEvo d0c8042307174cfa98b2ddea5c999da8--8e38dc82bc584ebcaebc95282fe88664 058e62b2ebf54b28899253f56a95d71c 8e38dc82bc584ebcaebc95282fe88664--058e62b2ebf54b28899253f56a95d71c a50ffe75fcbf4d4781aafaaa4a59da48 058e62b2ebf54b28899253f56a95d71c--a50ffe75fcbf4d4781aafaaa4a59da48 4c367ecfa617428a8cba824f9cf14bec 7205c4d09772438f893b690156867832 643ad7b54f8344258b17395ec150cf4f--7205c4d09772438f893b690156867832 f329fbed9cd9424dabaa579d8141f0af 2 223aa262d4564ed296092aab83ca83f0 t = -0.50 7205c4d09772438f893b690156867832--223aa262d4564ed296092aab83ca83f0 0129932d1acb4dc79cfa9f15c03781b0 223aa262d4564ed296092aab83ca83f0--0129932d1acb4dc79cfa9f15c03781b0 f7d4f2dea4bd4771813b19573c5e522f X 0129932d1acb4dc79cfa9f15c03781b0--f7d4f2dea4bd4771813b19573c5e522f cf2beae31d3943b0951f0887ea0dbcd7 t = -0.50 f7d4f2dea4bd4771813b19573c5e522f--cf2beae31d3943b0951f0887ea0dbcd7 d85c795329aa4e4fa98aea6419b682ad X cf2beae31d3943b0951f0887ea0dbcd7--d85c795329aa4e4fa98aea6419b682ad d85c795329aa4e4fa98aea6419b682ad--4c367ecfa617428a8cba824f9cf14bec 8c410e99808040f89f0f2fba94d81a14 dfdeb7bf5deb495f890e8030f009dc90 X f329fbed9cd9424dabaa579d8141f0af--dfdeb7bf5deb495f890e8030f009dc90 1e0fc157ca5b467d9a55605061c15742 dfdeb7bf5deb495f890e8030f009dc90--1e0fc157ca5b467d9a55605061c15742 bb5e7c1539e34aa686451772800e8dd9 X 1e0fc157ca5b467d9a55605061c15742--bb5e7c1539e34aa686451772800e8dd9 66ff50b566db4a75b35d42e2a5f8dd50 X bb5e7c1539e34aa686451772800e8dd9--66ff50b566db4a75b35d42e2a5f8dd50 af2777bd88c04e5d8538dd0c4535c244 66ff50b566db4a75b35d42e2a5f8dd50--af2777bd88c04e5d8538dd0c4535c244 67544e4105514e4fbdefbeb69eb002d5 X af2777bd88c04e5d8538dd0c4535c244--67544e4105514e4fbdefbeb69eb002d5 67544e4105514e4fbdefbeb69eb002d5--8c410e99808040f89f0f2fba94d81a14

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_97fa4018e82044a5895ba067c92dd871 cluster_4d086af3002d4eb9a7eaf047168a033f c8978ac675e349419694fd2a6f6b2131 0 b657dd74d7dc443783992798c12eee66 X c8978ac675e349419694fd2a6f6b2131--b657dd74d7dc443783992798c12eee66 457ed8e68f754511a0376c9da9fa2b4a 1 38d37cc9e4f54069a112ef45dd7ed5f4 HamEvo b657dd74d7dc443783992798c12eee66--38d37cc9e4f54069a112ef45dd7ed5f4 4064e9d46d8e45d785ce3b3f320eb10c X 38d37cc9e4f54069a112ef45dd7ed5f4--4064e9d46d8e45d785ce3b3f320eb10c a6c7b25c05664e93b22aedf6e712eb58 4064e9d46d8e45d785ce3b3f320eb10c--a6c7b25c05664e93b22aedf6e712eb58 f267f903c9614b96b8b8c21b8e4a8a8b HamEvo a6c7b25c05664e93b22aedf6e712eb58--f267f903c9614b96b8b8c21b8e4a8a8b 566565c5577b43749c438625a4a29dfb f267f903c9614b96b8b8c21b8e4a8a8b--566565c5577b43749c438625a4a29dfb 53522004939e4690abde83da1e04063f 566565c5577b43749c438625a4a29dfb--53522004939e4690abde83da1e04063f 6add66c078e54a5db146542ec180e579 9c9b856502404550b7d70851e7a23aee 457ed8e68f754511a0376c9da9fa2b4a--9c9b856502404550b7d70851e7a23aee b366a2a7a00548b88ce5143f78be2014 2 00a742282d6c4c35b75051fe35920089 t = -500. 9c9b856502404550b7d70851e7a23aee--00a742282d6c4c35b75051fe35920089 6129434ce3c841aea49085dc3519dacd 00a742282d6c4c35b75051fe35920089--6129434ce3c841aea49085dc3519dacd 2301a7396aba47989e3b823af203cd24 X 6129434ce3c841aea49085dc3519dacd--2301a7396aba47989e3b823af203cd24 358974e680c54f58b6b0c6fcea35d064 t = -500. 2301a7396aba47989e3b823af203cd24--358974e680c54f58b6b0c6fcea35d064 3553e8404feb48a78a525827fb1b2363 X 358974e680c54f58b6b0c6fcea35d064--3553e8404feb48a78a525827fb1b2363 3553e8404feb48a78a525827fb1b2363--6add66c078e54a5db146542ec180e579 a477bc494214453f9017a56096142ddb 99045c8142cb4884af401c5bf445b1c7 X b366a2a7a00548b88ce5143f78be2014--99045c8142cb4884af401c5bf445b1c7 c2691ac2781c4aaf895b620dfa9fa7ea 99045c8142cb4884af401c5bf445b1c7--c2691ac2781c4aaf895b620dfa9fa7ea 1d16e8741abf4b60ba337afc271ee8e4 X c2691ac2781c4aaf895b620dfa9fa7ea--1d16e8741abf4b60ba337afc271ee8e4 9ee7f4b99a124bd5b96bd42055b560a1 X 1d16e8741abf4b60ba337afc271ee8e4--9ee7f4b99a124bd5b96bd42055b560a1 a784dcc53a8b48d9b89135a60bf61f4c 9ee7f4b99a124bd5b96bd42055b560a1--a784dcc53a8b48d9b89135a60bf61f4c ae2f6e35b485407fb7af7e0c764ca8ab X a784dcc53a8b48d9b89135a60bf61f4c--ae2f6e35b485407fb7af7e0c764ca8ab ae2f6e35b485407fb7af7e0c764ca8ab--a477bc494214453f9017a56096142ddb

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