Skip to content

Commit

Permalink
Merge pull request #56 from Cornell-QCA/fusion
Browse files Browse the repository at this point in the history
Fusion Touch Ups + Fusion Verification
  • Loading branch information
rbyrne299 authored Jun 22, 2024
2 parents 0582a98 + 2305250 commit 547e385
Show file tree
Hide file tree
Showing 12 changed files with 328 additions and 159 deletions.
6 changes: 6 additions & 0 deletions python/anyon_braiding_simulator/Model.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,12 @@ def __init__(self, model_type: AnyonModel, num_fusion_channels=5) -> None:

self._num_fusion_channels = num_fusion_channels

def get_model_type(self) -> AnyonModel:
"""
Provides the model type
"""
return self.model_type

def get_charges(self) -> set:
"""
Provide the charges that are defined in this model.
Expand Down
25 changes: 18 additions & 7 deletions python/anyon_braiding_simulator/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import subprocess
import sys

from anyon_braiding_simulator import Anyon, AnyonModel, IsingTopoCharge
from anyon_braiding_simulator import Anyon, AnyonModel, FibonacciTopoCharge, IsingTopoCharge, TopoCharge
from Braiding import Braid
from Model import Model
from Simulator import Simulator
Expand All @@ -23,11 +23,22 @@ def anyon(*args):
topological_charge = args[1]
position = ()

topo_charge = {
'psi': IsingTopoCharge.Psi,
'sigma': IsingTopoCharge.Sigma,
'vac': IsingTopoCharge.Vacuum,
}
topo_charge = {}
if sim.get_model().get_model_type() == AnyonModel.Ising:
topo_charge = {
'psi': IsingTopoCharge.Psi,
'sigma': IsingTopoCharge.Sigma,
'vac': IsingTopoCharge.Vacuum,
}
elif sim.get_model().get_model_type() == AnyonModel.Fibonacci:
topo_charge = {
'tau': FibonacciTopoCharge.Tau,
'Vacuum': FibonacciTopoCharge.Vacuum,
}
else:
print('Error: Model not set')
return

try:
topological_charge = topo_charge[args[1].lower()]
except KeyError:
Expand Down Expand Up @@ -67,7 +78,7 @@ def anyon(*args):
print('Error: position must be formatted as {x,y} where x and y are numbers')
return

new_anyon = Anyon(name, topological_charge, position)
new_anyon = Anyon(name, TopoCharge(topological_charge), position)
try:
sim.update_anyons(True, [new_anyon])
if len(args) == 2:
Expand Down
6 changes: 3 additions & 3 deletions python/tests/test_anyon.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import pytest
from anyon_braiding_simulator import Anyon, IsingTopoCharge
from anyon_braiding_simulator import Anyon, IsingTopoCharge, TopoCharge


@pytest.mark.anyon
def test_anyon():
anyon = Anyon('thisisatest', IsingTopoCharge.Psi, (1, 1))
anyon = Anyon('thisisatest', TopoCharge.from_ising(IsingTopoCharge.Psi), (1, 1))
assert anyon.name == 'thisisatest'
assert anyon.charge == IsingTopoCharge.Psi
assert anyon.charge.get_ising() == IsingTopoCharge.Psi
assert anyon.position == (1, 1)
12 changes: 6 additions & 6 deletions python/tests/test_braiding.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,16 @@

sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..', 'model')))

from anyon_braiding_simulator import Anyon, IsingTopoCharge
from anyon_braiding_simulator import Anyon, IsingTopoCharge, TopoCharge


@pytest.fixture
def setup_anyons():
return [
Anyon('A', IsingTopoCharge.Psi, (1, 1)),
Anyon('B', IsingTopoCharge.Psi, (2, 2)),
Anyon('C', IsingTopoCharge.Psi, (3, 3)),
Anyon('D', IsingTopoCharge.Psi, (4, 4)),
Anyon('A', TopoCharge.from_ising(IsingTopoCharge.Psi), (1, 1)),
Anyon('B', TopoCharge.from_ising(IsingTopoCharge.Psi), (2, 2)),
Anyon('C', TopoCharge.from_ising(IsingTopoCharge.Psi), (3, 3)),
Anyon('D', TopoCharge.from_ising(IsingTopoCharge.Psi), (4, 4)),
]


Expand All @@ -36,7 +36,7 @@ def test_braid_initialization(setup_anyons):

# Test with duplicate anyon names
duplicate_anyons = setup_anyons[:]
duplicate_anyons[3] = Anyon('A', IsingTopoCharge.Psi, (4, 4))
duplicate_anyons[3] = Anyon('A', TopoCharge.from_ising(IsingTopoCharge.Psi), (4, 4))
with pytest.raises(ValueError, match='Duplicate anyon names detected'):
Braid(duplicate_anyons)

Expand Down
30 changes: 22 additions & 8 deletions python/tests/test_fusion.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import pytest
from anyon_braiding_simulator import Anyon, Fusion, FusionPair, IsingTopoCharge, State
from anyon_braiding_simulator import Anyon, AnyonModel, Fusion, FusionPair, IsingTopoCharge, State, TopoCharge


@pytest.fixture
def state() -> State:
state = State()
for i in range(6):
state.add_anyon(Anyon(f'{i}', IsingTopoCharge.Sigma, (0, 0)))
state.add_anyon(Anyon(f'{i}', TopoCharge.from_ising(IsingTopoCharge.Sigma), (0, 0)))
return state


Expand All @@ -32,13 +32,13 @@ def test_apply_ising_fusion(state):
vacuum = [0, 1, 0]
sigma = [0, 0, 1]

assert fusion.apply_fusion(psi, psi) == vacuum
assert fusion.apply_fusion(vacuum, vacuum) == vacuum
assert fusion.apply_fusion(sigma, sigma) == [psi[i] + vacuum[i] for i in range(3)]
assert fusion.apply_fusion(psi, psi, AnyonModel.Ising) == vacuum
assert fusion.apply_fusion(vacuum, vacuum, AnyonModel.Ising) == vacuum
assert fusion.apply_fusion(sigma, sigma, AnyonModel.Ising) == [psi[i] + vacuum[i] for i in range(3)]

psi_sigma = [1, 0, 1]
assert fusion.apply_fusion(psi_sigma, psi_sigma) == [1, 2, 2]
assert not fusion.apply_fusion(psi_sigma, psi_sigma) == [2, 1, 2] # get owned rishi
assert fusion.apply_fusion(psi_sigma, psi_sigma, AnyonModel.Ising) == [1, 2, 2]
assert not fusion.apply_fusion(psi_sigma, psi_sigma, AnyonModel.Ising) == [2, 1, 2] # get owned rishi


@pytest.mark.fusion
Expand All @@ -52,4 +52,18 @@ def test_qubit_enc(state):
fusion = Fusion(state)
correct = [FusionPair(0, 1), FusionPair(2, 4), FusionPair(2, 3)]

assert set(map(str, fusion.qubit_enc())) == set(map(str, correct))
assert set(map(str, fusion.qubit_enc(AnyonModel.Ising))) == set(map(str, correct))


@pytest.mark.fusion
def test_verify_fusion_result(state):
fusion = Fusion(state)
assert not fusion.verify_fusion_result(TopoCharge.from_ising(IsingTopoCharge.Sigma), AnyonModel.Ising)
assert fusion.verify_fusion_result(TopoCharge.from_ising(IsingTopoCharge.Vacuum), AnyonModel.Ising)
assert fusion.verify_fusion_result(TopoCharge.from_ising(IsingTopoCharge.Psi), AnyonModel.Ising)

state.add_anyon(Anyon('7', TopoCharge.from_ising(IsingTopoCharge.Sigma), (0, 0)))
fusion = Fusion(state)
assert not fusion.verify_fusion_result(TopoCharge.from_ising(IsingTopoCharge.Vacuum), AnyonModel.Ising)
assert not fusion.verify_fusion_result(TopoCharge.from_ising(IsingTopoCharge.Psi), AnyonModel.Ising)
assert fusion.verify_fusion_result(TopoCharge.from_ising(IsingTopoCharge.Sigma), AnyonModel.Ising)
8 changes: 4 additions & 4 deletions python/tests/test_state.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import pytest
from anyon_braiding_simulator import Anyon, FusionPair, IsingTopoCharge, State
from anyon_braiding_simulator import Anyon, FusionPair, IsingTopoCharge, State, TopoCharge


@pytest.fixture
Expand All @@ -10,20 +10,20 @@ def state() -> State:
@pytest.mark.state
def test_add_anyon(state):
for i in range(100):
anyon = Anyon(f'{i}', IsingTopoCharge.Sigma, (0, 0))
anyon = Anyon(f'{i}', TopoCharge.from_ising(IsingTopoCharge.Sigma), (0, 0))
state.add_anyon(anyon)

for anyon in state.anyons:
assert anyon.name in [f'{i}' for i in range(100)]
assert anyon.charge == IsingTopoCharge.Sigma
assert anyon.charge.get_ising() == IsingTopoCharge.Sigma
assert anyon.position == (0, 0)

assert len(state.anyons) == 100


def test_add_operation(state):
for i in range(101):
anyon = Anyon(f'{i}', IsingTopoCharge.Sigma, (0, 0))
anyon = Anyon(f'{i}', TopoCharge.from_ising(IsingTopoCharge.Sigma), (0, 0))
state.add_anyon(anyon)

assert state.add_operation(1, FusionPair(0, 1))
Expand Down
Loading

0 comments on commit 547e385

Please sign in to comment.