Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tfim simulation using 2 CNOT rather than 3 CNOT #94

Open
wants to merge 13 commits into
base: main
Choose a base branch
from
Open

Conversation

shangtai
Copy link
Contributor

This pull request is to address issue 70 where we consider the special TFIM model:

$$H^{(a)}=X_{a}X_{a+1}+B_{a}Z_{a}$$

where we can express the time evolution as

$$e^{-itH^{(a)}}=CNOT(a,a+1)e^{-it(X_a+B_aZ_a)}CNOT(a,a+1).$$

@shangtai shangtai linked an issue Oct 24, 2024 that may be closed by this pull request
@shangtai shangtai marked this pull request as draft October 24, 2024 17:06
@shangtai shangtai marked this pull request as ready for review October 29, 2024 19:40
steps: int = None
B_a: float = None

def circuit(self, a, t_duration, B_a, steps=None, order=None):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
def circuit(self, a, t_duration, B_a, steps=None, order=None):
def circuit(self, t_duration, steps=None, order=None):

This class must implement eo.circuit(0.1) without requiring other parameters.

What is a?

Copy link
Contributor Author

@shangtai shangtai Nov 5, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I use the notation in the paper where a is an index and B_a is another parameter.

$$H^{(a)}=X_{a}X_{a+1}+B_{a}Z_{a}$$


for _ in range(steps):
# Apply time evolution for X(a) + B_a * Z(a)
circuit += self._time_evolution_step(a, dt, B_a)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is commuting so it's equivalent to
circuit += self._time_evolution_step(a, t_duration, B_a)

Once you have for a in range(self.nqubits): (TFIM evolution oracle should be implemented for nqubits) then you need to do the CNOTs before every dt step here

Copy link
Contributor

@marekgluza marekgluza left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please provide test code demonstrating the functioning of this CNOT decomposition:

  • as the number of steps increase the comparison with H_TFIM_symbolic.exp(t) should be improving
  • in XXZ we used 2nd order, here we should do that too


# Time evolution under the transverse field Ising model Hamiltonian
# exp(-i t (X(a) + B_a * Z(a)))
dt = t_duration / steps # Divide the time duration for Trotterization if needed
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
dt = t_duration / steps # Divide the time duration for Trotterization if needed
dt = t_duration / steps # Divide the time duration for Trotterization if needed
for a in range(nqubits:
circuit.add(gates.CNOT(a, a + 1))
circuit += self._time_evolution_step(a, dt, B_a)
circuit.add(gates.CNOT(a, a + 1))

and then loop this over _ in range(steps)

Copy link
Contributor Author

@shangtai shangtai Nov 20, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

n_qubits = 3
h_coeff = 1
hamiltonian = SymbolicHamiltonian(nqubits=n_qubits)

oracle = TFIM_EvolutionOracle(h=hamiltonian, evolution_oracle_type="trotter", steps=1, B_a=0, order=2)

circuit = oracle.circuit(t_duration=1.0)

unitary = circuit.unitary()


from qibo import hamiltonians
from numpy.linalg import norm

def our_TFIM(nqubits, h: float = 0.0, dense: bool = True, backend=None):
        def multikron(matrix_list):
        """Calculates Kronecker product of a list of matrices."""
        return reduce(np.kron, matrix_list)

    from qibo.backends import matrices

    matrix = (
        - multikron([matrices.X, matrices.X]) - h * multikron([matrices.Z, matrices.I])
    )
    terms = [hamiltonians.terms.HamiltonianTerm(matrix, i, i + 1) for i in range(nqubits - 1)]
    terms.append(hamiltonians.terms.HamiltonianTerm(matrix, nqubits - 1, 0))
    ham = SymbolicHamiltonian(backend=backend)
    ham.terms = terms
    return ham

ham = our_TFIM(nqubits=n_qubits, h=h_coeff, dense=False)
truth = ham.exp(1)
verification_norm = []
for step in range(1, 21):
    oracle = TFIM_EvolutionOracle(h=hamiltonian, evolution_oracle_type="trotter", steps=step, B_a=h_coeff, order=2)
    circuit = oracle.circuit(t_duration=1.0)
    unitary = circuit.unitary()
    #print(norm(truth-unitary))
    verification_norm.append(norm(truth-unitary))

import matplotlib.pyplot as plt
x = np.array([i for i in range(1, 21)])
plt.plot(x, verification_norm, 'o')
plt.title("verification of TFIM 2 CNOT implementation")
plt.xlabel("steps")
plt.ylabel("norm of difference")

plt.show()

produces the following graph:

Screenshot 2024-11-20 at 3 19 27 PM

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

TFIM 2 CNOT not 3 CNOT compiling
2 participants