Skip to content

Commit

Permalink
Merge branch 'dev' into feature/json-standard-output
Browse files Browse the repository at this point in the history
  • Loading branch information
JonhasSC committed Mar 19, 2024
2 parents 1e198bf + 1e9778b commit 0a8a634
Show file tree
Hide file tree
Showing 6 changed files with 341 additions and 0 deletions.
20 changes: 20 additions & 0 deletions .github/workflows/mypy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
name: Mypy

on: [push]

jobs:
build:
runs-on: ubuntu-latest
name: Mypy
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: 3.11
- name: Install Dependencies
run: |
pip install mypy
- name: mypy
run: |
mypy .
23 changes: 23 additions & 0 deletions .github/workflows/pylint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
name: Pylint

on: [push]

jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.11"]
steps:
- uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install pylint
- name: Analysing the code with pylint
run: |
pylint $(git ls-files '*.py')
8 changes: 8 additions & 0 deletions .github/workflows/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
cirq == 1.3.0.dev20231102230836,
matplotlib,
networkx,
numpy,
openfermion,
openfermionpyscf,
pandas,
pyLIQTR ==1.0.0
24 changes: 24 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
name: Tests

on: [push]

jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.11"]
steps:
- uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install pytest
pip install .
- name: Run Tests
run: |
python -m pytest --import-mode=append tests/
208 changes: 208 additions & 0 deletions tests/hamiltonian_utils_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,208 @@
import unittest
from pyLIQTR.utils.Hamiltonian import Hamiltonian as pyH
from networkx.generators.lattice import hexagonal_lattice_graph
from qca.utils.hamiltonian_utils import (
nx_triangle_lattice,
assign_hexagon_labels,
generate_two_orbital_nx,
generate_square_hamiltonian,
nx_to_two_orbital_hamiltonian,
assign_directional_triangular_labels,
pyliqtr_hamiltonian_to_openfermion_qubit_operator
)


class HamiltonianUtilsTest(unittest.TestCase):
def test_triangle_hamiltonian_generation(self):
graph_triangle = nx_triangle_lattice(lattice_size=2)
assign_directional_triangular_labels(graph_triangle, 2)
edge_labels = dict([((n1, n2), d['label']) for n1, n2, d in graph_triangle.edges(data=True)])
correct_labels = {((0,0), (1,0)): 'Z',
((0,0), (0,1)): 'X',
((0,0), (1, 1)): 'Y',
((0, 1), (1, 1)): 'Z',
((1, 0), (1, 1)): 'X'}
for edge, label in edge_labels.items():
self.assertTrue(edge in correct_labels.keys())
self.assertEqual(label, correct_labels[edge])

def test_hexagonal_labels(self):
hexagon_graph = hexagonal_lattice_graph(1,1)
assign_hexagon_labels(hexagon_graph, 'X', 'Y', 'Z')
edge_labels = dict([((n1, n2), d['label']) for n1, n2, d in hexagon_graph.edges(data=True)])
correct_labels = {((0, 0), (0,1)): 'Y',
((0, 0), (1, 0)): 'Z',
((0, 1), (0, 2)): 'X',
((0, 2), (1, 2)): 'Z',
((1, 0), (1, 1)): 'X',
((1, 1), (1, 2)): 'Y'}
for edge, label in edge_labels.items():
self.assertTrue(edge in correct_labels.keys())
self.assertEqual(label, correct_labels[edge])

def test_grabbing_transverse_ising_terms(self):
transverse_test = generate_square_hamiltonian(lattice_size=2, dim=2)[0]
transverse_hamiltonian = ['XIII', 'IXII', 'IIXI', 'IIIX']
self.assertEqual(len(transverse_test), len(transverse_hamiltonian))
for idx, transverse_term in enumerate(transverse_test):
correct_hamiltonian = transverse_hamiltonian[idx]
self.assertEqual(transverse_term[0], correct_hamiltonian)

def test_grabbing_longitudinal_ising_terms(self):
longitudinal_test = generate_square_hamiltonian(lattice_size=2, dim=2)[1]
longitudinal_hamiltonian = ['ZIZI', 'ZZII', 'IZIZ', 'IIZZ']
self.assertEqual(len(longitudinal_hamiltonian), len(longitudinal_test))
for idx, longitudinal_term in enumerate(longitudinal_test):
correct_hamiltonian = longitudinal_hamiltonian[idx]
self.assertEqual(longitudinal_term[0], correct_hamiltonian)

def test_pyliqtr_hamiltonian_to_qubit_op(self):
square_hamiltonian = generate_square_hamiltonian(lattice_size=2, dim=2)
H_square = pyH(square_hamiltonian[0]+square_hamiltonian[1])
openfermion_hamiltonian_square = pyliqtr_hamiltonian_to_openfermion_qubit_operator(H_square)
correct_ops = ['X0', 'X1', 'X2', 'X3', 'Z0Z2', 'Z0Z1', 'Z1Z3', 'Z2Z3']
for idx, op in enumerate(openfermion_hamiltonian_square):
qubit_op = ''
for term in op.terms:
for ops in term:
qubit_op += f'{ops[1]}{ops[0]}'
self.assertEqual(qubit_op, correct_ops[idx])

def test_two_orbital_gen_test(self):
two_orbital = generate_two_orbital_nx(2, 2)
edge_labels = dict([((n1, n2), d['label'])
for n1, n2, d in two_orbital.edges(data=True)])
correct_labels = {((0, 0, 0, 0), (0, 1, 0, 0)): '-t3',
((0, 0, 0, 0), (1, 0, 0, 0)): '-t3',
((0, 0, 0, 0), (1, 1, 0, 0)): '-t3',
((0, 0, 0, 0), (1, 1, 1, 0)): '+t4',
((0, 0, 0, 1), (0, 1, 0, 1)): '-t3',
((0, 0, 0, 1), (1, 0, 0, 1)): '-t3',
((0, 0, 0, 1), (1, 1, 0, 1)): '-t3',
((0, 0, 0, 1), (1, 1, 1, 1)): '+t4',
((0, 0, 1, 0), (1, 0, 1, 0)): '-t3',
((0, 0, 1, 0), (0, 1, 1, 0)): '-t3',
((0, 0, 1, 0), (1, 1, 1, 0)): '-t3',
((0, 0, 1, 0), (1, 1, 0, 0)): '+t4',
((0, 0, 1, 1), (1, 0, 1, 1)): '-t3',
((0, 0, 1, 1), (0, 1, 1, 1)): '-t3',
((0, 0, 1, 1), (1, 1, 1, 1)): '-t3',
((0, 0, 1, 1), (1, 1, 0, 1)): '+t4',
((0, 1, 0, 0), (1, 1, 0, 0)): '-t3',
((0, 1, 0, 0), (1, 0, 0, 0)): '-t3',
((0, 1, 0, 0), (1, 0, 1, 0)): '-t4',
((0, 1, 0, 1), (1, 1, 0, 1)): '-t3',
((0, 1, 0, 1), (1, 0, 0, 1)): '-t3',
((0, 1, 0, 1), (1, 0, 1, 1)): '-t4',
((0, 1, 1, 0), (1, 1, 1, 0)): '-t3',
((0, 1, 1, 0), (1, 0, 1, 0)): '-t3',
((0, 1, 1, 0), (1, 0, 0, 0)): '-t4',
((0, 1, 1, 1), (1, 1, 1, 1)): '-t3',
((0, 1, 1, 1), (1, 0, 1, 1)): '-t3',
((0, 1, 1, 1), (1, 0, 0, 1)): '-t4',
((1, 0, 0, 0), (1, 1, 0, 0)): '-t3',
((1, 0, 0, 1), (1, 1, 0, 1)): '-t3',
((1, 0, 1, 0), (1, 1, 1, 0)): '-t3',
((1, 0, 1, 1), (1, 1, 1, 1)): '-t3'}
for edge, label in edge_labels.items():
self.assertTrue(edge in correct_labels.keys())
self.assertEqual(label, correct_labels[edge])

def test_nx_to_two_orbital_hamiltonian(self):
two_orbital = generate_two_orbital_nx(2, 2)
fermionic_two_orbital = nx_to_two_orbital_hamiltonian(
two_orbital,
-1,
1.3,
0.85,
0.85,
1
)
edge_labels = dict([((n1, n2), d['label']) for n1, n2, d in two_orbital.edges(data=True)]);
correct_fermionic_terms = {((0, 1), (4, 0)): -0.85,
((4, 1), (0, 0)): -0.85,
((0, 1), (8, 0)): -0.85,
((8, 1), (0, 0)): -0.85,
((0, 1), (12, 0)): -0.85,
((12, 1), (0, 0)): -0.85,
((0, 1), (14, 0)): 0.85,
((14, 1), (0, 0)): 0.85,
((1, 1), (5, 0)): -0.85,
((5, 1), (1, 0)): -0.85,
((1, 1), (9, 0)): -0.85,
((9, 1), (1, 0)): -0.85,
((1, 1), (13, 0)): -0.85,
((13, 1), (1, 0)): -0.85,
((1, 1), (15, 0)): 0.85,
((15, 1), (1, 0)): 0.85,
((2, 1), (10, 0)): -0.85,
((10, 1), (2, 0)): -0.85,
((2, 1), (6, 0)): -0.85,
((6, 1), (2, 0)): -0.85,
((2, 1), (14, 0)): -0.85,
((14, 1), (2, 0)): -0.85,
((2, 1), (12, 0)): 0.85,
((12, 1), (2, 0)): 0.85,
((3, 1), (11, 0)): -0.85,
((11, 1), (3, 0)): -0.85,
((3, 1), (7, 0)): -0.85,
((7, 1), (3, 0)): -0.85,
((3, 1), (15, 0)): -0.85,
((15, 1), (3, 0)): -0.85,
((3, 1), (13, 0)): 0.85,
((13, 1), (3, 0)): 0.85,
((4, 1), (12, 0)): -0.85,
((12, 1), (4, 0)): -0.85,
((4, 1), (8, 0)): -0.85,
((8, 1), (4, 0)): -0.85,
((4, 1), (10, 0)): -0.85,
((10, 1), (4, 0)): -0.85,
((5, 1), (13, 0)): -0.85,
((13, 1), (5, 0)): -0.85,
((5, 1), (9, 0)): -0.85,
((9, 1), (5, 0)): -0.85,
((5, 1), (11, 0)): -0.85,
((11, 1), (5, 0)): -0.85,
((6, 1), (14, 0)): -0.85,
((14, 1), (6, 0)): -0.85,
((6, 1), (10, 0)): -0.85,
((10, 1), (6, 0)): -0.85,
((6, 1), (8, 0)): -0.85,
((8, 1), (6, 0)): -0.85,
((7, 1), (15, 0)): -0.85,
((15, 1), (7, 0)): -0.85,
((7, 1), (11, 0)): -0.85,
((11, 1), (7, 0)): -0.85,
((7, 1), (9, 0)): -0.85,
((9, 1), (7, 0)): -0.85,
((8, 1), (12, 0)): -0.85,
((12, 1), (8, 0)): -0.85,
((9, 1), (13, 0)): -0.85,
((13, 1), (9, 0)): -0.85,
((10, 1), (14, 0)): -0.85,
((14, 1), (10, 0)): -0.85,
((11, 1), (15, 0)): -0.85,
((15, 1), (11, 0)): -0.85,
((0, 1), (0, 0)): -1.0,
((1, 1), (1, 0)): -1.0,
((2, 1), (2, 0)): -1.0,
((3, 1), (3, 0)): -1.0,
((4, 1), (4, 0)): -1.0,
((5, 1), (5, 0)): -1.0,
((6, 1), (6, 0)): -1.0,
((7, 1), (7, 0)): -1.0,
((8, 1), (8, 0)): -1.0,
((9, 1), (9, 0)): -1.0,
((10, 1), (10, 0)): -1.0,
((11, 1), (11, 0)): -1.0,
((12, 1), (12, 0)): -1.0,
((13, 1), (13, 0)): -1.0,
((14, 1), (14, 0)): -1.0,
((15, 1), (15, 0)): -1.0}
for edge, label in correct_fermionic_terms.items():
self.assertTrue(edge in fermionic_two_orbital.terms)
self.assertEqual(label, fermionic_two_orbital.terms[edge])


if __name__ == '__main__':
unittest.main()
58 changes: 58 additions & 0 deletions tests/utils_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import cirq
import unittest
import numpy as np
from qca.utils.utils import count_gates, count_T_gates, get_T_depth, get_T_depth_wire
from pyLIQTR.gate_decomp.cirq_transforms import clifford_plus_t_direct_transform

class UtilsTest(unittest.TestCase):
def test_count_gates(self):
qubits = [cirq.LineQubit(i) for i in range(4)]

layer_rz = [cirq.Rz(rads = np.pi/4).on(qubit) for qubit in qubits]
layer_rx = [cirq.Rx(rads = np.pi/4).on(qubit) for qubit in qubits]
layer_measurement = [cirq.measure(qubit) for qubit in qubits]
circuit = cirq.Circuit()
circuit.append(layer_rz)
circuit.append(layer_rx)
circuit.append(layer_measurement)
self.assertEqual(count_gates(circuit), 12)

def test_T_gate_info(self):
qubits = [cirq.LineQubit(i) for i in range(4)]

layer_rz = [cirq.Rz(rads = np.pi/4).on(qubit) for qubit in qubits]
layer_rx = [cirq.Rx(rads = np.pi/4).on(qubit) for qubit in qubits]
layer_measurement = [cirq.measure(qubit) for qubit in qubits]
circuit = cirq.Circuit()
circuit.append(layer_rz)
circuit.append(layer_rx)
circuit.append(layer_measurement)
circ_cpt = clifford_plus_t_direct_transform(circuit)

self.assertEqual(count_T_gates(circ_cpt), 8)
self.assertEqual(get_T_depth(circ_cpt), 2)
self.assertEqual(get_T_depth_wire(circ_cpt), 2)


def test_clifford_info(self):
qubits = [cirq.LineQubit(i) for i in range(4)]

layer_rz = [cirq.Rz(rads = np.pi/4).on(qubit) for qubit in qubits]
layer_rx = [cirq.Rx(rads = np.pi/4).on(qubit) for qubit in qubits]
layer_measurement = [cirq.measure(qubit) for qubit in qubits]
circuit = cirq.Circuit()
circuit.append(layer_rz)
circuit.append(layer_rx)
circuit.append(layer_measurement)
circ_cpt = clifford_plus_t_direct_transform(circuit)

gate_count = count_gates(circ_cpt)
t_count = count_T_gates(circ_cpt)
clifford_count = gate_count - t_count
circ_depth = len(circ_cpt)
self.assertEqual(circ_depth, 5)
self.assertEqual(clifford_count, 12)


if __name__ == '__main__':
unittest.main()

0 comments on commit 0a8a634

Please sign in to comment.