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

Fusion Touch Ups + Fusion Verification #56

Merged
merged 9 commits into from
Jun 22, 2024
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
8 changes: 8 additions & 0 deletions python/anyon_braiding_simulator/Simulator.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,14 @@ def set_model(self, model: Model) -> None:
"""
self._model = model

def get_model(self) -> Model:
"""
Get the model for the simulator.
"""
if self._model is None:
raise ValueError('Model has not been set')
return self._model

def list_anyons(self) -> list:
"""
List the anyons currently in the simulator.
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