def test_copy(self):
     g = Graph()
     v1, v2 = g.add_vertices(2)
     g.add_edge((v1, v2), 2)
     g2 = g.copy()
     self.assertEqual(g.num_vertices(), g2.num_vertices())
     self.assertEqual(g.num_edges(), g2.num_edges())
     v1, v2 = list(g2.vertices())
     self.assertEqual(g.edge_type(g.edge(v1, v2)), 2)
Exemple #2
0
 def test_id_graph(self):
     g = Graph()
     i = g.add_vertex(0, 0, 0)
     o = g.add_vertex(0, 0, 1)
     g.inputs.append(i)
     g.outputs.append(o)
     g.add_edge((i, o))
     t = tensorfy(g)
     id_array = np.array([[1, 0], [0, 1]])
     self.assertTrue(np.allclose(t, id_array))
     self.assertTrue(compare_tensors(t, id_array))
Exemple #3
0
class TestGraphCircuitMethods(unittest.TestCase):

    def setUp(self):
        """Sets up a two qubit circuit containing a single CNOT with some phases."""
        self.graph = Graph()
        g = self.graph
        i1 = g.add_vertex(0,0,0) #add_vertex(type,qubit_index,row_index,phase=0)
        i2 = g.add_vertex(0,1,0)
        g.inputs = [i1,i2]
        v = g.add_vertex(1,0,1,Fraction(1,2))
        w = g.add_vertex(2,1,1,Fraction(1,1))
        o1 = g.add_vertex(0,0,2)
        o2 = g.add_vertex(0,1,2)
        g.outputs = [o1, o2]
        g.add_edges([(i1,v),(i2,w),(v,w),(v,o1),(w,o2)])
        self.i1, self.i2, self.v, self.w, self.o1, self.o2 = i1, i2, v, w, o1, o2

    def test_qubit_index_and_depth(self):
        g = self.graph
        self.assertEqual(g.depth(),2)
        self.assertEqual(g.qubit_count(),2)

    def test_adjoint(self):
        g = self.graph
        adj = g.adjoint()
        self.assertEqual(g.num_vertices(),adj.num_vertices())
        self.assertEqual(g.num_edges(),adj.num_edges())
        self.assertEqual(g.depth(), adj.depth())
        self.assertEqual(g.qubit_count(), adj.qubit_count())

        v = [i for i in g.vertices() if g.type(i)==1][0]
        w = [i for i in adj.vertices() if adj.type(i)==1][0]
        self.assertEqual(g.phase(v),(-adj.phase(v))%2)
        self.assertEqual(g.vertex_degree(v),adj.vertex_degree(w))

    def test_compose_basic(self):
        g = self.graph.copy()
        g.compose(g)
        self.assertEqual(g.num_vertices(), self.graph.num_vertices()+2)
        self.assertEqual((len(g.inputs),len(g.outputs)),(2,2))

    def test_compose_handling_hadamards(self):
        g = self.graph
        g.set_edge_type(g.edge(self.v,self.o1),2)
        g2 = g.copy()
        g2.compose(g)
        num_hadamards = len([e for e in g2.edges() if g2.edge_type(e)==2])
        self.assertEqual(num_hadamards, 2)
        g2 = g.copy()
        g2.compose(g.adjoint())
        num_hadamards = len([e for e in g2.edges() if g2.edge_type(e)==2])
        self.assertEqual(num_hadamards, 0)
Exemple #4
0
 def test_equality_of_id_zx_graph_to_id(self):
     g = Graph()
     i = g.add_vertex(0,0,0)
     o = g.add_vertex(0,0,2)
     g.set_inputs((i,))
     g.set_outputs((o,))
     g2 = g.copy()
     g.add_edge((i,o))
     v = g2.add_vertex(1,0,1)
     g2.add_edges([(i,v),(v,o)])
     tensor1 = tensorfy(g)
     tensor2 = tensorfy(g2)
     self.assertTrue(compare_tensors(tensor1,tensor2))
Exemple #5
0
 def setUp(self):
     """Sets up a two qubit circuit containing a single CNOT with some phases."""
     self.graph = Graph()
     g = self.graph
     i1 = g.add_vertex(0,0,0) #add_vertex(type,qubit_index,row_index,phase=0)
     i2 = g.add_vertex(0,1,0)
     g.inputs = [i1,i2]
     v = g.add_vertex(1,0,1,Fraction(1,2))
     w = g.add_vertex(2,1,1,Fraction(1,1))
     o1 = g.add_vertex(0,0,2)
     o2 = g.add_vertex(0,1,2)
     g.outputs = [o1, o2]
     g.add_edges([(i1,v),(i2,w),(v,w),(v,o1),(w,o2)])
     self.i1, self.i2, self.v, self.w, self.o1, self.o2 = i1, i2, v, w, o1, o2
 def test_supplementarity_simp(self):
     g = Graph()
     v = g.add_vertex(1,0,0,phase=Fraction(1,4))
     w = g.add_vertex(1,1,0,phase=Fraction(7,4))
     g.add_edge((v,w),2)
     vs = []
     for i in range(3):
         h = g.add_vertex(1,i,2,Fraction(1))
         vs.append(h)
         g.add_edges([(v,h),(w,h)],2)
     t = g.to_tensor()
     i = supplementarity_simp(g,quiet=True)
     self.assertEqual(i,1)
     self.assertTrue(compare_tensors(t,g.to_tensor()))
Exemple #7
0
 def test_three_cnots_is_swap(self):
     g = Graph()
     i1 = g.add_vertex(0,0,0)
     i2 = g.add_vertex(0,1,0)
     o1 = g.add_vertex(0,0,1)
     o2 = g.add_vertex(0,1,1)
     g.set_inputs((i1, i2))
     g.set_outputs((o1, o2))
     g.add_edges([(i1,o2),(i2,o1)])
     swap = tensorfy(g)
     c = Circuit(2)
     c.add_gate("CNOT",0,1)
     c.add_gate("CNOT",1,0)
     c.add_gate("CNOT",0,1)
     three_cnots = tensorfy(c.to_graph())
     self.assertTrue(compare_tensors(swap,three_cnots))
Exemple #8
0
 def test_inequality_id_and_swap(self):
     g = Graph()
     i1 = g.add_vertex(0, 0, 0)
     i2 = g.add_vertex(0, 1, 0)
     o1 = g.add_vertex(0, 0, 1)
     o2 = g.add_vertex(0, 1, 1)
     g.inputs = [i1, i2]
     g.outputs = [o1, o2]
     g2 = g.copy()
     g.add_edges([(i1, o2), (i2, o1)])
     g2.add_edges([(i1, o1), (i2, o2)])
     id_id = tensorfy(g2)
     swap = tensorfy(g)
     self.assertFalse(compare_tensors(id_id, swap))
 def test_remove_isolated_vertex_preserves_semantics(self):
     g = Graph()
     v = g.add_vertex(1, 0, 0)
     g2 = g.copy()
     g2.remove_isolated_vertices()
     self.assertTrue(compare_tensors(g, g2))
     self.assertEqual(g2.scalar.to_number(), 2)
     g.set_phase(v, Fraction(1))
     g2 = g.copy()
     g2.remove_isolated_vertices()
     self.assertTrue(compare_tensors(g, g2))
     self.assertAlmostEqual(g2.scalar.to_number(), 0)
Exemple #10
0
 def test_scalar(self):
     g = Graph()
     x = g.add_vertex(VertexType.Z, row = 0, phase = 1 / 2)
     y = g.add_vertex(VertexType.Z, row = 1, phase = 1 / 4)
     g.add_edge(g.edge(x, y), edgetype = EdgeType.SIMPLE)
     
     full_reduce(g)
     val = to_quimb_tensor(g).contract(output_inds = ())
     expected_val = 1 + np.exp(1j * np.pi * 3 / 4)
     self.assertTrue(abs(val - expected_val) < 1e-9)
Exemple #11
0
class TestGraphCircuitMethods(unittest.TestCase):
    def setUp(self):
        """Sets up a two qubit circuit containing a single CNOT with some phases."""
        self.graph = Graph()
        g = self.graph
        i1 = g.add_vertex(VertexType.BOUNDARY, 0,
                          0)  #add_vertex(type,qubit_index,row_index,phase=0)
        i2 = g.add_vertex(VertexType.BOUNDARY, 1, 0)
        g.inputs = [i1, i2]
        v = g.add_vertex(VertexType.Z, 0, 1, Fraction(1, 2))
        w = g.add_vertex(VertexType.X, 1, 1, Fraction(1, 1))
        o1 = g.add_vertex(VertexType.BOUNDARY, 0, 2)
        o2 = g.add_vertex(VertexType.BOUNDARY, 1, 2)
        g.outputs = [o1, o2]
        g.add_edges([(i1, v), (i2, w), (v, w), (v, o1), (w, o2)])
        self.i1, self.i2, self.v, self.w, self.o1, self.o2 = i1, i2, v, w, o1, o2

    def test_qubit_index_and_depth(self):
        g = self.graph
        self.assertEqual(g.depth(), 2)
        self.assertEqual(g.qubit_count(), 2)

    def test_adjoint(self):
        g = self.graph
        adj = g.adjoint()
        self.assertEqual(g.num_vertices(), adj.num_vertices())
        self.assertEqual(g.num_edges(), adj.num_edges())
        self.assertEqual(g.depth(), adj.depth())
        self.assertEqual(g.qubit_count(), adj.qubit_count())

        v = [i for i in g.vertices() if g.type(i) == VertexType.Z][0]
        w = [i for i in adj.vertices() if adj.type(i) == VertexType.Z][0]
        self.assertEqual(g.phase(v), (-adj.phase(v)) % 2)
        self.assertEqual(g.vertex_degree(v), adj.vertex_degree(w))

    def test_compose_basic(self):
        g = self.graph.copy()
        g.compose(g)
        self.assertEqual((len(g.inputs), len(g.outputs)), (2, 2))

    @unittest.skipUnless(np, "numpy needs to be installed for this to run")
    def test_compose_unitary(self):
        g = self.graph
        g.set_edge_type(g.edge(self.v, self.o1), EdgeType.HADAMARD)
        g2 = g.adjoint()
        g2.compose(g)
        self.assertTrue(compare_tensors(g2, identity(2), False))
 def test_remove_isolated_pair_preserves_semantics(self):
     for i, j, k in itertools.product([1, 2], repeat=3):
         for phase1, phase2 in itertools.product([0, 1, 2], [0, 4, 5]):
             with self.subTest(i=i, j=j, k=k, phase1=phase1, phase2=phase2):
                 g = Graph()
                 v = g.add_vertex(i, 0, 0, phase=phase1)
                 w = g.add_vertex(j, 1, 0, phase=phase2)
                 g.add_edge((v, w), k)
                 g2 = g.copy()
                 g2.remove_isolated_vertices()
                 self.assertEqual(g2.num_vertices(), 0)
                 self.assertTrue(compare_tensors(g, g2))
Exemple #13
0
 def test_hadamard_tensor(self):
     g = Graph()
     x = g.add_vertex(VertexType.BOUNDARY)
     y = g.add_vertex(VertexType.BOUNDARY)
     g.add_edge(g.edge(x, y), edgetype = EdgeType.HADAMARD)
     
     tn = to_quimb_tensor(g)
     self.assertTrue(abs((tn & qtn.Tensor(data = [1, 0], inds = ("0",)) 
                         & qtn.Tensor(data = [1 / np.sqrt(2), 1 / np.sqrt(2)], inds = ("1",)))
                     .contract(output_inds = ()) - 1) < 1e-9)
     self.assertTrue(abs((tn & qtn.Tensor(data = [0, 1], inds = ("0",)) 
                         & qtn.Tensor(data = [1 / np.sqrt(2), -1 / np.sqrt(2)], inds = ("1",)))
                     .contract(output_inds = ()) - 1) < 1e-9)
Exemple #14
0
 def test_id_tensor(self):
     g = Graph()
     x = g.add_vertex(VertexType.BOUNDARY)
     y = g.add_vertex(VertexType.BOUNDARY)
     g.add_edge(g.edge(x, y), edgetype = EdgeType.SIMPLE)
     
     tn = to_quimb_tensor(g)
     self.assertTrue((tn & qtn.Tensor(data = [0, 1], inds = ("0",)) 
                         & qtn.Tensor(data = [0, 1], inds = ("1",)))
                     .contract(output_inds = ()) == 1)
     self.assertTrue((tn & qtn.Tensor(data = [1, 0], inds = ("0",)) 
                         & qtn.Tensor(data = [1, 0], inds = ("1",)))
                     .contract(output_inds = ()) == 1)
Exemple #15
0
 def test_set_attributes(self):
     g = Graph()
     v = g.add_vertex()
     self.assertEqual(g.phase(v),0)
     g.set_phase(v,1)
     self.assertEqual(g.phase(v),1)
     self.assertEqual(g.type(v),VertexType.BOUNDARY)
     g.set_type(v,VertexType.X)
     self.assertEqual(g.type(v),VertexType.X)
     self.assertFalse(g.is_ground(v))
     g.set_ground(v)
     self.assertTrue(g.is_ground(v))
     g.set_row(v,3)
     self.assertEqual(g.row(v),3)
     g.set_qubit(v,2)
     self.assertEqual(g.qubit(v),2)
 def test_add_edge_table_different_type(self):
     g = Graph()
     v1, v2 = g.add_vertices(2)
     g.set_type(v1, 1)
     g.set_type(v2, 2)
     etab = {(v1, v2): [0, 2]}
     g.add_edge_table(etab)
     self.assertTrue(g.connected(v1, v2))
     self.assertEqual((g.phase(v1), g.phase(v2)), (0, 0))
     g.remove_edge(g.edge(v1, v2))
     self.assertFalse(g.connected(v1, v2))
     etab = {(v1, v2): [2, 0]}
     g.add_edge_table(etab)
     self.assertFalse(g.connected(v1, v2))
     etab = {(v1, v2): [1, 1]}
     g.add_edge_table(etab)
     self.assertEqual(g.edge_type(g.edge(v1, v2)), 2)
     self.assertTrue((g.phase(v1) == 1 and g.phase(v2) == 0)
                     or (g.phase(v1) == 0 and g.phase(v2) == 1))
 def test_set_attributes(self):
     g = Graph()
     v = g.add_vertex()
     g.set_phase(v, 1)
     self.assertEqual(g.phase(v), 1)
     g.set_type(v, 2)
     self.assertEqual(g.type(v), 2)
     g.set_row(v, 3)
     self.assertEqual(g.row(v), 3)
     g.set_qubit(v, 2)
     self.assertEqual(g.qubit(v), 2)
 def test_edges(self):
     g = Graph()
     v1, v2, v3 = g.add_vertices(3)
     g.add_edge((v1, v2))
     self.assertEqual(g.num_edges(), 1)
     self.assertTrue(g.connected(v1, v2))
     self.assertTrue(v2 in g.neighbours(v1))
     self.assertEqual(g.vertex_degree(v1), 1)
     self.assertFalse(g.connected(v1, v3))
     e = g.edge(v1, v2)
     self.assertEqual(g.edge_type(e), 1)
     g.set_edge_type(e, 2)
     self.assertEqual(g.edge_type(e), 2)
     g.remove_edge(e)
     self.assertEqual(g.num_edges(), 0)
     self.assertFalse(g.connected(v1, v2))
 def test_empty_graph(self):
     g = Graph()
     self.assertEqual(g.num_vertices(), 0)
     self.assertEqual(g.num_edges(), 0)
Exemple #20
0
    def test_xor_tensor(self):
        g = Graph()
        x = g.add_vertex(VertexType.BOUNDARY)
        y = g.add_vertex(VertexType.BOUNDARY)
        v = g.add_vertex(VertexType.Z)
        z = g.add_vertex(VertexType.BOUNDARY)

        g.add_edge(g.edge(x, v), edgetype = EdgeType.HADAMARD)
        g.add_edge(g.edge(y, v), edgetype = EdgeType.HADAMARD)
        g.add_edge(g.edge(v, z), edgetype = EdgeType.HADAMARD)
        tn = to_quimb_tensor(g)
        
        for x in range(2):
            for y in range(2):
                for z in range(2):
                    self.assertTrue(abs((tn &
                            qtn.Tensor(data = [1 - x, x], inds = ("0",)) &
                            qtn.Tensor(data = [1 - y, y], inds = ("1",)) &
                            qtn.Tensor(data = [1 - z, z], inds = ("3",))).contract(output_inds = ()) - 
                            ((x ^ y) == z) / np.sqrt(2)) < 1e-9)
Exemple #21
0
 def test_phases_tensor(self):
     # This diagram represents a 1-input 1-output Z-spider of phase pi/2,
     # but written using two Z-spiders of phases pi/6 and pi/3 that are
     # connected by a simple edge.
     g = Graph()
     x = g.add_vertex(VertexType.BOUNDARY)
     v = g.add_vertex(VertexType.Z, phase = 1. / 6.)
     w = g.add_vertex(VertexType.Z, phase = 1. / 3.)
     y = g.add_vertex(VertexType.BOUNDARY)
     
     g.add_edge(g.edge(x, v), edgetype = EdgeType.SIMPLE)
     g.add_edge(g.edge(v, w), edgetype = EdgeType.SIMPLE)
     g.add_edge(g.edge(w, y), edgetype = EdgeType.SIMPLE)
     tn = to_quimb_tensor(g)
     
     self.assertTrue(abs((tn & qtn.Tensor(data = [1, 0], inds = ("0",)) 
                         & qtn.Tensor(data = [1, 0], inds = ("3",)))
                     .contract(output_inds = ()) - 1) < 1e-9)
     self.assertTrue(abs((tn & qtn.Tensor(data = [0, 1], inds = ("0",)) 
                         & qtn.Tensor(data = [0, 1j], inds = ("3",)))
                     .contract(output_inds = ()) + 1) < 1e-9)
Exemple #22
0
 def test_add_edge_table_same_type(self):
     g = Graph()
     v1, v2 = g.add_vertices(2)
     g.set_type(v1, VertexType.Z)
     g.set_type(v2, VertexType.Z)
     etab = {(v1, v2): [2, 0]}
     g.add_edge_table(etab)
     self.assertTrue(g.connected(v1, v2))
     self.assertEqual((g.phase(v1), g.phase(v2)), (0, 0))
     g.remove_edge(g.edge(v1, v2))
     self.assertFalse(g.connected(v1, v2))
     etab = {(v1, v2): [0, 2]}
     g.add_edge_table(etab)
     self.assertFalse(g.connected(v1, v2))
     etab = {(v1, v2): [1, 1]}
     g.add_edge_table(etab)
     self.assertEqual(g.edge_type(g.edge(v1, v2)), EdgeType.SIMPLE)
     self.assertTrue((g.phase(v1) == 1 and g.phase(v2) == 0)
                     or (g.phase(v1) == 0 and g.phase(v2) == 1))
Exemple #23
0
 def test_load_tikz(self):
     js = json.dumps(test_graph)
     g = Graph.from_json(js)
     tikz = g.to_tikz()
     g2 = Graph.from_tikz(tikz, warn_overlap=False)
Exemple #24
0
 def test_load_json(self):
     js = json.dumps(test_graph)
     g = Graph.from_json(js)
     js2 = g.to_json()