From 1415670666c0eb809ba65cefaaebf58392118000 Mon Sep 17 00:00:00 2001 From: shangtai Date: Thu, 24 Oct 2024 02:32:09 +0800 Subject: [PATCH 01/13] added tfim_EvolutionOracle --- .../dbi/double_bracket_evolution_oracles.py | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/src/boostvqe/models/dbi/double_bracket_evolution_oracles.py b/src/boostvqe/models/dbi/double_bracket_evolution_oracles.py index 7740df6..83a2a90 100644 --- a/src/boostvqe/models/dbi/double_bracket_evolution_oracles.py +++ b/src/boostvqe/models/dbi/double_bracket_evolution_oracles.py @@ -307,3 +307,43 @@ def circuit(self, t_duration, steps=None, order=None): steps=steps, order=order, ) + + +@dataclass +class tfim_EvolutionOracle(EvolutionOracle): + steps: int = None + B_a: float = None + + def circuit(self, a, t_duration, steps=None, order=None): + if steps is None: + steps = self.steps + + circuit = Circuit(self.h.nqubits) # Initialize the circuit with the number of qubits + + # Add CNOT(a, a+1) + circuit.add(gates.CNOT(a, a + 1)) + + # 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 + + for _ in range(steps): + # Apply time evolution for X(a) + B_a * Z(a) + circuit += self._time_evolution_step(a, dt) + + # Add second CNOT(a, a+1) + circuit.add(gates.CNOT(a, a + 1)) + + return circuit + + def _time_evolution_step(self, a: int, dt: float, B_a: float): + """Apply a single Trotter step of the time evolution operator exp(-i dt (X(a) + B_a Z(a))).""" + step_circuit = Circuit(self.h.nqubits) + + # Time evolution for X(a) + step_circuit.add(gates.RX(a, theta=-2 * dt)) # Apply exp(-i dt X(a)) + + # Time evolution for Z(a) + step_circuit.add(gates.RZ(a, theta=-2 * dt * B_a)) # Apply exp(-i dt B_a Z(a)) + + return step_circuit \ No newline at end of file From 9c729bf2d4fae8d49eb96f7f34e512b55e78e36a Mon Sep 17 00:00:00 2001 From: shangtai Date: Thu, 24 Oct 2024 02:55:07 +0800 Subject: [PATCH 02/13] added tfim_EvolutionOracle --- src/boostvqe/models/dbi/double_bracket_evolution_oracles.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/boostvqe/models/dbi/double_bracket_evolution_oracles.py b/src/boostvqe/models/dbi/double_bracket_evolution_oracles.py index 83a2a90..6f2efc6 100644 --- a/src/boostvqe/models/dbi/double_bracket_evolution_oracles.py +++ b/src/boostvqe/models/dbi/double_bracket_evolution_oracles.py @@ -314,7 +314,7 @@ class tfim_EvolutionOracle(EvolutionOracle): steps: int = None B_a: float = None - def circuit(self, a, t_duration, steps=None, order=None): + def circuit(self, a, t_duration, B_a, steps=None, order=None): if steps is None: steps = self.steps @@ -329,7 +329,7 @@ def circuit(self, a, t_duration, steps=None, order=None): for _ in range(steps): # Apply time evolution for X(a) + B_a * Z(a) - circuit += self._time_evolution_step(a, dt) + circuit += self._time_evolution_step(a, dt, B_a) # Add second CNOT(a, a+1) circuit.add(gates.CNOT(a, a + 1)) From 7ad8b90367fc111d58ce929cbe7ff2f40278520b Mon Sep 17 00:00:00 2001 From: shangtai Date: Wed, 6 Nov 2024 00:09:45 +0800 Subject: [PATCH 03/13] Update src/boostvqe/models/dbi/double_bracket_evolution_oracles.py Co-authored-by: Marek Gluza --- src/boostvqe/models/dbi/double_bracket_evolution_oracles.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/boostvqe/models/dbi/double_bracket_evolution_oracles.py b/src/boostvqe/models/dbi/double_bracket_evolution_oracles.py index 6f2efc6..e01ff44 100644 --- a/src/boostvqe/models/dbi/double_bracket_evolution_oracles.py +++ b/src/boostvqe/models/dbi/double_bracket_evolution_oracles.py @@ -310,7 +310,7 @@ def circuit(self, t_duration, steps=None, order=None): @dataclass -class tfim_EvolutionOracle(EvolutionOracle): +class TFIM_EvolutionOracle(EvolutionOracle): steps: int = None B_a: float = None From 7a54540c1af8311a03904e22166dc1242adcf08f Mon Sep 17 00:00:00 2001 From: shangtai Date: Mon, 11 Nov 2024 03:56:36 +0800 Subject: [PATCH 04/13] yet to be done, make a over all qubits and load B_a. Currently made use of commutivity. --- .../dbi/double_bracket_evolution_oracles.py | 25 +++++++++++++------ 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/src/boostvqe/models/dbi/double_bracket_evolution_oracles.py b/src/boostvqe/models/dbi/double_bracket_evolution_oracles.py index e01ff44..9a53047 100644 --- a/src/boostvqe/models/dbi/double_bracket_evolution_oracles.py +++ b/src/boostvqe/models/dbi/double_bracket_evolution_oracles.py @@ -4,8 +4,8 @@ from functools import cached_property, reduce from typing import Union -import hyperopt -import matplotlib.pyplot as plt +#import hyperopt +#import matplotlib.pyplot as plt import numpy as np from qibo import Circuit, gates, symbols from qibo.config import raise_error @@ -314,7 +314,7 @@ class TFIM_EvolutionOracle(EvolutionOracle): steps: int = None B_a: float = None - def circuit(self, a, t_duration, B_a, steps=None, order=None): + def circuit(self, t_duration, steps=None, order=None): if steps is None: steps = self.steps @@ -325,11 +325,8 @@ def circuit(self, a, t_duration, B_a, steps=None, order=None): # 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 - for _ in range(steps): - # Apply time evolution for X(a) + B_a * Z(a) - circuit += self._time_evolution_step(a, dt, B_a) + circuit += self._time_evolution_step(a, t_duration, B_a) # Add second CNOT(a, a+1) circuit.add(gates.CNOT(a, a + 1)) @@ -346,4 +343,16 @@ def _time_evolution_step(self, a: int, dt: float, B_a: float): # Time evolution for Z(a) step_circuit.add(gates.RZ(a, theta=-2 * dt * B_a)) # Apply exp(-i dt B_a Z(a)) - return step_circuit \ No newline at end of file + return step_circuit + + +hamiltonian = SymbolicHamiltonian(nqubits=3) + +# Instantiate the oracle with 10 Trotter steps +oracle = TFIM_EvolutionOracle(h=hamiltonian, steps=10, evolution_oracle_type="trotter") + +# Example: Run the circuit for qubit a=0, B_a=0.8, and t_duration=1.0 +circuit = oracle.circuit(a=0, t_duration=1.0, B_a=0.8) + +# Print the resulting circuit to visualize it +print(circuit.summary()) From 1032637e6561f17de950416ab8759a45e7b24dc7 Mon Sep 17 00:00:00 2001 From: shangtai Date: Wed, 13 Nov 2024 03:57:41 +0800 Subject: [PATCH 05/13] Use commutivity to get rid of a for loop in steps. Thanks. Also, worked on the looping at the boundary condition for TFIM model. --- .../dbi/double_bracket_evolution_oracles.py | 34 +++++++------------ 1 file changed, 13 insertions(+), 21 deletions(-) diff --git a/src/boostvqe/models/dbi/double_bracket_evolution_oracles.py b/src/boostvqe/models/dbi/double_bracket_evolution_oracles.py index 9a53047..4f6116d 100644 --- a/src/boostvqe/models/dbi/double_bracket_evolution_oracles.py +++ b/src/boostvqe/models/dbi/double_bracket_evolution_oracles.py @@ -314,26 +314,21 @@ class TFIM_EvolutionOracle(EvolutionOracle): steps: int = None B_a: float = None - def circuit(self, t_duration, steps=None, order=None): - if steps is None: - steps = self.steps - + def circuit(self, t_duration): circuit = Circuit(self.h.nqubits) # Initialize the circuit with the number of qubits + for a in range(self.h.nqubits): + # Add CNOT(a, a+1) + circuit.add(gates.CNOT(a, (a + 1)%self.h.nqubits)) - # Add CNOT(a, a+1) - circuit.add(gates.CNOT(a, a + 1)) - - # Time evolution under the transverse field Ising model Hamiltonian - # exp(-i t (X(a) + B_a * Z(a))) - - circuit += self._time_evolution_step(a, t_duration, B_a) - - # Add second CNOT(a, a+1) - circuit.add(gates.CNOT(a, a + 1)) + # Time evolution under the transverse field Ising model Hamiltonian + # exp(-i t (X(a) + B_a * Z(a))) + circuit += self._time_evolution_step(a, t_duration) + # Add second CNOT(a, a+1) + circuit.add(gates.CNOT(a, (a + 1)%self.h.nqubits)) return circuit - def _time_evolution_step(self, a: int, dt: float, B_a: float): + def _time_evolution_step(self, a: int, dt: float): """Apply a single Trotter step of the time evolution operator exp(-i dt (X(a) + B_a Z(a))).""" step_circuit = Circuit(self.h.nqubits) @@ -341,18 +336,15 @@ def _time_evolution_step(self, a: int, dt: float, B_a: float): step_circuit.add(gates.RX(a, theta=-2 * dt)) # Apply exp(-i dt X(a)) # Time evolution for Z(a) - step_circuit.add(gates.RZ(a, theta=-2 * dt * B_a)) # Apply exp(-i dt B_a Z(a)) + step_circuit.add(gates.RZ(a, theta=-2 * dt * self.B_a)) # Apply exp(-i dt B_a Z(a)) return step_circuit hamiltonian = SymbolicHamiltonian(nqubits=3) - # Instantiate the oracle with 10 Trotter steps -oracle = TFIM_EvolutionOracle(h=hamiltonian, steps=10, evolution_oracle_type="trotter") - +oracle = TFIM_EvolutionOracle(h=hamiltonian, evolution_oracle_type="trotter", steps=1, B_a=0.8) # Example: Run the circuit for qubit a=0, B_a=0.8, and t_duration=1.0 -circuit = oracle.circuit(a=0, t_duration=1.0, B_a=0.8) - +circuit = oracle.circuit(t_duration=1.0) # Print the resulting circuit to visualize it print(circuit.summary()) From c0a0f618c8421edc69892614de6b9e3a2ca9ebc4 Mon Sep 17 00:00:00 2001 From: shangtai Date: Wed, 13 Nov 2024 13:22:28 +0800 Subject: [PATCH 06/13] introduce steps in loop --- .../dbi/double_bracket_evolution_oracles.py | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/boostvqe/models/dbi/double_bracket_evolution_oracles.py b/src/boostvqe/models/dbi/double_bracket_evolution_oracles.py index 4f6116d..73ea0ca 100644 --- a/src/boostvqe/models/dbi/double_bracket_evolution_oracles.py +++ b/src/boostvqe/models/dbi/double_bracket_evolution_oracles.py @@ -316,16 +316,17 @@ class TFIM_EvolutionOracle(EvolutionOracle): def circuit(self, t_duration): circuit = Circuit(self.h.nqubits) # Initialize the circuit with the number of qubits - for a in range(self.h.nqubits): - # Add CNOT(a, a+1) - circuit.add(gates.CNOT(a, (a + 1)%self.h.nqubits)) + for _ in range(self.steps): + for a in range(self.h.nqubits): + # Add CNOT(a, a+1) + circuit.add(gates.CNOT(a, (a + 1)%self.h.nqubits)) - # Time evolution under the transverse field Ising model Hamiltonian - # exp(-i t (X(a) + B_a * Z(a))) - circuit += self._time_evolution_step(a, t_duration) + # Time evolution under the transverse field Ising model Hamiltonian + # exp(-i t (X(a) + B_a * Z(a))) + circuit += self._time_evolution_step(a, t_duration) - # Add second CNOT(a, a+1) - circuit.add(gates.CNOT(a, (a + 1)%self.h.nqubits)) + # Add second CNOT(a, a+1) + circuit.add(gates.CNOT(a, (a + 1)%self.h.nqubits)) return circuit def _time_evolution_step(self, a: int, dt: float): From 6f2854a43d9419e9ce5fbc72a0f65a29bbb38018 Mon Sep 17 00:00:00 2001 From: shangtai Date: Fri, 15 Nov 2024 04:30:19 +0800 Subject: [PATCH 07/13] apply product formula for TFIM --- .../dbi/double_bracket_evolution_oracles.py | 28 +++++++++++++------ 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/src/boostvqe/models/dbi/double_bracket_evolution_oracles.py b/src/boostvqe/models/dbi/double_bracket_evolution_oracles.py index 73ea0ca..eb01b13 100644 --- a/src/boostvqe/models/dbi/double_bracket_evolution_oracles.py +++ b/src/boostvqe/models/dbi/double_bracket_evolution_oracles.py @@ -313,20 +313,32 @@ def circuit(self, t_duration, steps=None, order=None): class TFIM_EvolutionOracle(EvolutionOracle): steps: int = None B_a: float = None + order: int = None def circuit(self, t_duration): circuit = Circuit(self.h.nqubits) # Initialize the circuit with the number of qubits - for _ in range(self.steps): - for a in range(self.h.nqubits): - # Add CNOT(a, a+1) - circuit.add(gates.CNOT(a, (a + 1)%self.h.nqubits)) - + def routine(tmp_circuit, enum_list, routine_t): + for a in enum_list: + tmp_circuit.add(gates.CNOT(a, (a + 1) % self.h.nqubits)) # Time evolution under the transverse field Ising model Hamiltonian # exp(-i t (X(a) + B_a * Z(a))) - circuit += self._time_evolution_step(a, t_duration) + tmp_circuit += self._time_evolution_step(a, routine_t) # Add second CNOT(a, a+1) - circuit.add(gates.CNOT(a, (a + 1)%self.h.nqubits)) + tmp_circuit.add(gates.CNOT(a, (a + 1) % self.h.nqubits)) + if self.order is None: + for _ in range(self.steps): + routine(circuit, range(self.h.nqubits), t_duration) + elif self.order == 1: + routine(circuit, range(self.steps, 2), t_duration) + routine(circuit, range(1, self.steps, 2), t_duration) + + elif self.order == 2: + routine(circuit, range(1, self.steps, 2), t_duration/2) + routine(circuit, range(self.steps, 2), t_duration) + routine(circuit, range(1, self.steps, 2), t_duration / 2) + else: + print("order must be either 0, 1, 2") return circuit def _time_evolution_step(self, a: int, dt: float): @@ -344,7 +356,7 @@ def _time_evolution_step(self, a: int, dt: float): hamiltonian = SymbolicHamiltonian(nqubits=3) # Instantiate the oracle with 10 Trotter steps -oracle = TFIM_EvolutionOracle(h=hamiltonian, evolution_oracle_type="trotter", steps=1, B_a=0.8) +oracle = TFIM_EvolutionOracle(h=hamiltonian, evolution_oracle_type="trotter", steps=1, B_a=0.8, order=2) # Example: Run the circuit for qubit a=0, B_a=0.8, and t_duration=1.0 circuit = oracle.circuit(t_duration=1.0) # Print the resulting circuit to visualize it From 18a950be3ad8aedc3c27f32ffba1a40969baa6e7 Mon Sep 17 00:00:00 2001 From: shangtai Date: Fri, 15 Nov 2024 15:29:55 +0800 Subject: [PATCH 08/13] fixing bug of RX not appearing in the circuit --- .../dbi/double_bracket_evolution_oracles.py | 37 +++++++++++-------- 1 file changed, 21 insertions(+), 16 deletions(-) diff --git a/src/boostvqe/models/dbi/double_bracket_evolution_oracles.py b/src/boostvqe/models/dbi/double_bracket_evolution_oracles.py index eb01b13..e464060 100644 --- a/src/boostvqe/models/dbi/double_bracket_evolution_oracles.py +++ b/src/boostvqe/models/dbi/double_bracket_evolution_oracles.py @@ -316,48 +316,53 @@ class TFIM_EvolutionOracle(EvolutionOracle): order: int = None def circuit(self, t_duration): - circuit = Circuit(self.h.nqubits) # Initialize the circuit with the number of qubits + circuit_v = Circuit(self.h.nqubits) # Initialize the circuit with the number of qubits def routine(tmp_circuit, enum_list, routine_t): + print(enum_list) for a in enum_list: + print(a) tmp_circuit.add(gates.CNOT(a, (a + 1) % self.h.nqubits)) # Time evolution under the transverse field Ising model Hamiltonian # exp(-i t (X(a) + B_a * Z(a))) - tmp_circuit += self._time_evolution_step(a, routine_t) + self._time_evolution_step(tmp_circuit, a, routine_t) # Add second CNOT(a, a+1) tmp_circuit.add(gates.CNOT(a, (a + 1) % self.h.nqubits)) if self.order is None: for _ in range(self.steps): - routine(circuit, range(self.h.nqubits), t_duration) + routine(circuit_v, range(self.h.nqubits), t_duration) elif self.order == 1: - routine(circuit, range(self.steps, 2), t_duration) - routine(circuit, range(1, self.steps, 2), t_duration) + routine(circuit_v, range(0, self.h.nqubits, 2), t_duration) + routine(circuit_v, range(1, self.h.nqubits, 2), t_duration) elif self.order == 2: - routine(circuit, range(1, self.steps, 2), t_duration/2) - routine(circuit, range(self.steps, 2), t_duration) - routine(circuit, range(1, self.steps, 2), t_duration / 2) + routine(circuit_v, range(1, self.h.nqubits, 2), t_duration/2) + print(circuit_v.draw()) + routine(circuit_v, range(0, self.h.nqubits, 2), t_duration) + print(circuit_v.draw()) + routine(circuit_v, range(1, self.h.nqubits, 2), t_duration / 2) + print(circuit_v.draw()) else: print("order must be either 0, 1, 2") - return circuit + return circuit_v - def _time_evolution_step(self, a: int, dt: float): + def _time_evolution_step(self, tmp_circuit: Circuit, a: int, dt: float): """Apply a single Trotter step of the time evolution operator exp(-i dt (X(a) + B_a Z(a))).""" - step_circuit = Circuit(self.h.nqubits) # Time evolution for X(a) - step_circuit.add(gates.RX(a, theta=-2 * dt)) # Apply exp(-i dt X(a)) + tmp_circuit.add(gates.RX(a, theta=-2 * dt)) # Apply exp(-i dt X(a)) # Time evolution for Z(a) - step_circuit.add(gates.RZ(a, theta=-2 * dt * self.B_a)) # Apply exp(-i dt B_a Z(a)) + tmp_circuit.add(gates.RZ(a, theta=-2 * dt * self.B_a)) # Apply exp(-i dt B_a Z(a)) - return step_circuit + return tmp_circuit -hamiltonian = SymbolicHamiltonian(nqubits=3) +hamiltonian = SymbolicHamiltonian(nqubits=5) # Instantiate the oracle with 10 Trotter steps -oracle = TFIM_EvolutionOracle(h=hamiltonian, evolution_oracle_type="trotter", steps=1, B_a=0.8, order=2) +oracle = TFIM_EvolutionOracle(h=hamiltonian, evolution_oracle_type="trotter", steps=3, B_a=0.8, order=2) # Example: Run the circuit for qubit a=0, B_a=0.8, and t_duration=1.0 circuit = oracle.circuit(t_duration=1.0) # Print the resulting circuit to visualize it print(circuit.summary()) +print(circuit.draw()) From bbd692828e1576f81912c4778bf4f77c49066422 Mon Sep 17 00:00:00 2001 From: shangtai Date: Wed, 20 Nov 2024 03:58:52 +0800 Subject: [PATCH 09/13] still debugging. --- .../dbi/double_bracket_evolution_oracles.py | 62 +++++++++++++++---- 1 file changed, 50 insertions(+), 12 deletions(-) diff --git a/src/boostvqe/models/dbi/double_bracket_evolution_oracles.py b/src/boostvqe/models/dbi/double_bracket_evolution_oracles.py index e464060..a9ff9ca 100644 --- a/src/boostvqe/models/dbi/double_bracket_evolution_oracles.py +++ b/src/boostvqe/models/dbi/double_bracket_evolution_oracles.py @@ -4,6 +4,7 @@ from functools import cached_property, reduce from typing import Union + #import hyperopt #import matplotlib.pyplot as plt import numpy as np @@ -318,9 +319,7 @@ class TFIM_EvolutionOracle(EvolutionOracle): def circuit(self, t_duration): circuit_v = Circuit(self.h.nqubits) # Initialize the circuit with the number of qubits def routine(tmp_circuit, enum_list, routine_t): - print(enum_list) for a in enum_list: - print(a) tmp_circuit.add(gates.CNOT(a, (a + 1) % self.h.nqubits)) # Time evolution under the transverse field Ising model Hamiltonian # exp(-i t (X(a) + B_a * Z(a))) @@ -332,16 +331,15 @@ def routine(tmp_circuit, enum_list, routine_t): for _ in range(self.steps): routine(circuit_v, range(self.h.nqubits), t_duration) elif self.order == 1: - routine(circuit_v, range(0, self.h.nqubits, 2), t_duration) - routine(circuit_v, range(1, self.h.nqubits, 2), t_duration) + for _ in range(self.steps): + routine(circuit_v, range(0, self.h.nqubits, 2), t_duration) + routine(circuit_v, range(1, self.h.nqubits, 2), t_duration) elif self.order == 2: - routine(circuit_v, range(1, self.h.nqubits, 2), t_duration/2) - print(circuit_v.draw()) - routine(circuit_v, range(0, self.h.nqubits, 2), t_duration) - print(circuit_v.draw()) - routine(circuit_v, range(1, self.h.nqubits, 2), t_duration / 2) - print(circuit_v.draw()) + for _ in range(self.steps): + routine(circuit_v, range(1, self.h.nqubits, 2), t_duration/2) + routine(circuit_v, range(0, self.h.nqubits, 2), t_duration) + routine(circuit_v, range(1, self.h.nqubits, 2), t_duration / 2) else: print("order must be either 0, 1, 2") return circuit_v @@ -358,11 +356,51 @@ def _time_evolution_step(self, tmp_circuit: Circuit, a: int, dt: float): return tmp_circuit -hamiltonian = SymbolicHamiltonian(nqubits=5) +hamiltonian = SymbolicHamiltonian(nqubits=3) # Instantiate the oracle with 10 Trotter steps -oracle = TFIM_EvolutionOracle(h=hamiltonian, evolution_oracle_type="trotter", steps=3, B_a=0.8, order=2) +oracle = TFIM_EvolutionOracle(h=hamiltonian, evolution_oracle_type="trotter", steps=1, B_a=0.8, order=1) # Example: Run the circuit for qubit a=0, B_a=0.8, and t_duration=1.0 circuit = oracle.circuit(t_duration=1.0) # Print the resulting circuit to visualize it print(circuit.summary()) print(circuit.draw()) +oracle = TFIM_EvolutionOracle(h=hamiltonian, evolution_oracle_type="trotter", steps=1, B_a=0, order=2) +# Example: Run the circuit for qubit a=0, B_a=0.8, and t_duration=1.0 +circuit = oracle.circuit(t_duration=1.0) +# Print the resulting circuit to visualize it +#print(circuit.summary()) +#print(circuit.draw()) +unitary = circuit.unitary() + + +from qibo import hamiltonians +from numpy.linalg import norm +from qibo.backends import matrices + +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) + + # Example usage + 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=3, dense=False) +truth = ham.exp(1) +for step in range(1, 10): + oracle = TFIM_EvolutionOracle(h=hamiltonian, evolution_oracle_type="trotter", steps=step, B_a=0, order=2) + circuit = oracle.circuit(t_duration=1.0) + # Print the resulting circuit to visualize it + # print(circuit.summary()) + # print(circuit.draw()) + unitary = circuit.unitary() + print(norm(truth-unitary)) From 109286b915a851618a54aab6dae5428cc857a3aa Mon Sep 17 00:00:00 2001 From: shangtai Date: Wed, 20 Nov 2024 04:06:26 +0800 Subject: [PATCH 10/13] still debugging. --- src/boostvqe/models/dbi/double_bracket_evolution_oracles.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/boostvqe/models/dbi/double_bracket_evolution_oracles.py b/src/boostvqe/models/dbi/double_bracket_evolution_oracles.py index a9ff9ca..6b94bef 100644 --- a/src/boostvqe/models/dbi/double_bracket_evolution_oracles.py +++ b/src/boostvqe/models/dbi/double_bracket_evolution_oracles.py @@ -348,10 +348,10 @@ def _time_evolution_step(self, tmp_circuit: Circuit, a: int, dt: float): """Apply a single Trotter step of the time evolution operator exp(-i dt (X(a) + B_a Z(a))).""" # Time evolution for X(a) - tmp_circuit.add(gates.RX(a, theta=-2 * dt)) # Apply exp(-i dt X(a)) + tmp_circuit.add(gates.RX(a, theta=2 * dt)) # Apply exp(-i dt X(a)) # Time evolution for Z(a) - tmp_circuit.add(gates.RZ(a, theta=-2 * dt * self.B_a)) # Apply exp(-i dt B_a Z(a)) + tmp_circuit.add(gates.RZ(a, theta=2 * dt * self.B_a)) # Apply exp(-i dt B_a Z(a)) return tmp_circuit From a1369913b5abe27bffb8d98f5a04d8dd0c215bad Mon Sep 17 00:00:00 2001 From: shangtai Date: Wed, 20 Nov 2024 15:22:45 +0800 Subject: [PATCH 11/13] removed comments. --- .../dbi/double_bracket_evolution_oracles.py | 54 ++----------------- 1 file changed, 3 insertions(+), 51 deletions(-) diff --git a/src/boostvqe/models/dbi/double_bracket_evolution_oracles.py b/src/boostvqe/models/dbi/double_bracket_evolution_oracles.py index 6b94bef..0245e1a 100644 --- a/src/boostvqe/models/dbi/double_bracket_evolution_oracles.py +++ b/src/boostvqe/models/dbi/double_bracket_evolution_oracles.py @@ -318,6 +318,7 @@ class TFIM_EvolutionOracle(EvolutionOracle): def circuit(self, t_duration): circuit_v = Circuit(self.h.nqubits) # Initialize the circuit with the number of qubits + t_duration /= self.steps def routine(tmp_circuit, enum_list, routine_t): for a in enum_list: tmp_circuit.add(gates.CNOT(a, (a + 1) % self.h.nqubits)) @@ -348,59 +349,10 @@ def _time_evolution_step(self, tmp_circuit: Circuit, a: int, dt: float): """Apply a single Trotter step of the time evolution operator exp(-i dt (X(a) + B_a Z(a))).""" # Time evolution for X(a) - tmp_circuit.add(gates.RX(a, theta=2 * dt)) # Apply exp(-i dt X(a)) + tmp_circuit.add(gates.RX(a, theta=-2*dt)) # Apply exp(-i dt X(a)) # Time evolution for Z(a) - tmp_circuit.add(gates.RZ(a, theta=2 * dt * self.B_a)) # Apply exp(-i dt B_a Z(a)) + tmp_circuit.add(gates.RZ(a, theta=-2*dt * self.B_a)) # Apply exp(-i dt B_a Z(a)) return tmp_circuit - -hamiltonian = SymbolicHamiltonian(nqubits=3) -# Instantiate the oracle with 10 Trotter steps -oracle = TFIM_EvolutionOracle(h=hamiltonian, evolution_oracle_type="trotter", steps=1, B_a=0.8, order=1) -# Example: Run the circuit for qubit a=0, B_a=0.8, and t_duration=1.0 -circuit = oracle.circuit(t_duration=1.0) -# Print the resulting circuit to visualize it -print(circuit.summary()) -print(circuit.draw()) -oracle = TFIM_EvolutionOracle(h=hamiltonian, evolution_oracle_type="trotter", steps=1, B_a=0, order=2) -# Example: Run the circuit for qubit a=0, B_a=0.8, and t_duration=1.0 -circuit = oracle.circuit(t_duration=1.0) -# Print the resulting circuit to visualize it -#print(circuit.summary()) -#print(circuit.draw()) -unitary = circuit.unitary() - - -from qibo import hamiltonians -from numpy.linalg import norm -from qibo.backends import matrices - -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) - - # Example usage - 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=3, dense=False) -truth = ham.exp(1) -for step in range(1, 10): - oracle = TFIM_EvolutionOracle(h=hamiltonian, evolution_oracle_type="trotter", steps=step, B_a=0, order=2) - circuit = oracle.circuit(t_duration=1.0) - # Print the resulting circuit to visualize it - # print(circuit.summary()) - # print(circuit.draw()) - unitary = circuit.unitary() - print(norm(truth-unitary)) From a6aa3079d9983508a2d9ce0ea05c88590a8ef0a5 Mon Sep 17 00:00:00 2001 From: shangtai Date: Wed, 20 Nov 2024 15:35:13 +0800 Subject: [PATCH 12/13] removed comments. --- src/boostvqe/models/dbi/double_bracket_evolution_oracles.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/boostvqe/models/dbi/double_bracket_evolution_oracles.py b/src/boostvqe/models/dbi/double_bracket_evolution_oracles.py index 0245e1a..0946b51 100644 --- a/src/boostvqe/models/dbi/double_bracket_evolution_oracles.py +++ b/src/boostvqe/models/dbi/double_bracket_evolution_oracles.py @@ -342,7 +342,7 @@ def routine(tmp_circuit, enum_list, routine_t): routine(circuit_v, range(0, self.h.nqubits, 2), t_duration) routine(circuit_v, range(1, self.h.nqubits, 2), t_duration / 2) else: - print("order must be either 0, 1, 2") + print("order must be either 1 or 2") return circuit_v def _time_evolution_step(self, tmp_circuit: Circuit, a: int, dt: float): From 43531994311835ddfd9dc5b7c3770eef76b4658b Mon Sep 17 00:00:00 2001 From: shangtai Date: Sat, 23 Nov 2024 01:06:21 +0800 Subject: [PATCH 13/13] added tfim_2cnot_test.py --- notebooks/tfim_2cnot_test.py | 62 ++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 notebooks/tfim_2cnot_test.py diff --git a/notebooks/tfim_2cnot_test.py b/notebooks/tfim_2cnot_test.py new file mode 100644 index 0000000..7f13cc4 --- /dev/null +++ b/notebooks/tfim_2cnot_test.py @@ -0,0 +1,62 @@ +from qibo.hamiltonians import SymbolicHamiltonian +from boostvqe.models.dbi.double_bracket_evolution_oracles import * +from functools import reduce +import numpy as np +from qibo import hamiltonians +import matplotlib.pyplot as plt + +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() +def multikron(matrix_list): + """Calculates Kronecker product of a list of matrices. + + Args: + matrix_list (list): List of matrices as ``ndarray``. + + Returns: + ndarray: Kronecker product of all matrices in ``matrix_list``. + """ + return reduce(np.kron, matrix_list) + +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() + verification_norm.append(norm(truth-unitary)) + + +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() \ No newline at end of file