Example #1
0
 def test_local_complementation(self):
     # first test with known examples
     test_graph = gg.Graph(N=3, E=[(0, 1), (0, 2)])
     test_result = gg.local_complementation(n=0, graph=test_graph)
     known_result = gg.Graph(N=3, E=[(0, 1), (0, 2), (1, 2)])
     self.assertEqual(test_result, known_result)
     test_graph = gg.Graph(N=6,
                           E=[(0, 1), (1, 2), (0, 3), (1, 4), (2, 5),
                              (3, 4), (4, 5)])  # butterfly graph
     test_result = gg.local_complementation(n=1, graph=test_graph)
     known_result = gg.Graph(
         N=6,
         E=[
             (0, 1),
             (1, 2),
             (0, 3),
             (1, 4),
             (2, 5),
             (3, 4),
             (4, 5),
             (0, 4),
             (2, 4),
             (0, 2),
         ],
     )
     self.assertEqual(test_result, known_result)
     # test with random graphs and stupid verification function
     for _ in range(10):
         num_vertices = 10
         test_graph = random_graph(num_vertices)
         for lc_vertex in range(
                 num_vertices):  # try all possible complementations
             complemented_graph = gg.local_complementation(n=lc_vertex,
                                                           graph=test_graph)
             # now do the verification
             for i in range(num_vertices):
                 for j in range(i + 1, num_vertices):
                     if (
                             test_graph.adj[j, lc_vertex]
                             and test_graph.adj[i, lc_vertex]
                     ):  # i and j are both in the neighborhood of lc_vertex
                         self.assertEqual(
                             complemented_graph.adj[i, j],
                             (test_graph.adj[i, j] + 1) % 2,
                         )
                     else:
                         self.assertEqual(complemented_graph.adj[i, j],
                                          test_graph.adj[i, j])
Example #2
0
 def test_ynoise(self):
     # only reproducibility test because this function is just a definition
     test_rho = np.array([0.93, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01])
     test_graph = gg.Graph(N=3, E=[(0, 1), (0, 2)])  # GHZ graph
     test_result = gg.ynoise(rho=test_rho,
                             qubit_index=1,
                             p=0.98,
                             graph=test_graph)
     self.assertTrue(
         np.allclose(
             test_result,
             np.array([0.9116, 0.01, 0.01, 0.01, 0.01, 0.01, 0.0284, 0.01]),
         ))
     # now try different noise on all qubits
     ps = [0.7, 0.93, 0.98]
     test_result = test_rho
     for idx, p in enumerate(ps):
         test_result = gg.ynoise(rho=test_result,
                                 qubit_index=idx,
                                 p=p,
                                 graph=test_graph)
     self.assertTrue(
         np.allclose(
             test_result,
             np.array([
                 0.5969416,
                 0.0289336,
                 0.0151336,
                 0.0109016,
                 0.0103864,
                 0.0219784,
                 0.0541784,
                 0.2615464,
             ]),
         ))
Example #3
0
def random_graph(num_vertices, p=0.5):
    """Generate random gg.Graph.

    Graph with `num_vertices` vertices. Each edge exists with probability `p`.
    """
    edges = []
    for i in range(num_vertices):
        for j in range(i + 1, num_vertices):
            if np.random.random() < p:
                edges += [(i, j)]
    return gg.Graph(N=num_vertices, E=edges)
Example #4
0
 def test_noise_global(self):
     # again, this function is just following the definition
     test_rho = np.array([0.91, 0.02, 0.01, 0.01, 0.01, 0.01, 0.01, 0.02])
     test_graph = gg.Graph(N=3, E=[(0, 1), (0, 2)])  # GHZ graph
     p = 0.98
     test_result = gg.noise_global(rho=test_rho, p=p, graph=test_graph)
     self.assertTrue(
         np.allclose(
             test_result,
             np.array([
                 0.8943, 0.0221, 0.0123, 0.0123, 0.0123, 0.0123, 0.0123,
                 0.0221
             ]),
         ))
Example #5
0
 def test_wnoise_all(self):
     # again, this function is just writing down a definition
     test_rho = np.array([0.93, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01])
     test_graph = gg.Graph(N=3, E=[(0, 1), (0, 2)])  # GHZ graph
     p = 0.98
     test_result = gg.wnoise_all(rho=test_rho, p=p, graph=test_graph)
     self.assertTrue(
         np.allclose(
             test_result,
             np.array([
                 0.88928632,
                 0.014554,
                 0.014554,
                 0.014554,
                 0.02338968,
                 0.014554,
                 0.014554,
                 0.014554,
             ]),
         ))
Example #6
0
 def test_equivalence(self):
     # test that equivalent graphs are considered equal
     test_graph = gg.Graph(N=5, E=[(0, 1), (0, 2), (2, 3), (3, 4)])
     # other number of vertices
     graph1 = gg.Graph(N=6, E=[(0, 1), (0, 2), (2, 3), (3, 4)])
     self.assertNotEqual(graph1, test_graph)
     self.assertNotEqual(hash(graph1), hash(test_graph))
     # order of nodes in edges
     graph2 = gg.Graph(N=5, E=[(1, 0), (0, 2), (3, 2), (4, 3)])
     self.assertEqual(graph2, test_graph)
     self.assertEqual(hash(graph2), hash(test_graph))
     # order of edges should not matter
     graph3 = gg.Graph(N=5, E=[(0, 1), (3, 4), (0, 2), (2, 3)])
     self.assertEqual(graph3, test_graph)
     self.assertEqual(hash(graph3), hash(test_graph))
     # different sets are not equivalent
     test_graph1 = gg.Graph(N=5,
                            E=[(0, 1), (0, 2), (2, 3), (3, 4)],
                            sets=[[0, 3], [1, 2, 4]])
     self.assertNotEqual(test_graph1, test_graph)
     self.assertNotEqual(hash(test_graph1), hash(test_graph))
     graph4 = gg.Graph(N=5,
                       E=[(0, 1), (0, 2), (2, 3), (3, 4)],
                       sets=[[0], [1, 2, 4], [3]])
     self.assertNotEqual(graph4, test_graph1)
     self.assertNotEqual(hash(graph4), hash(test_graph1))
     # order within sets should not matter
     graph5 = gg.Graph(N=5,
                       E=[(0, 1), (0, 2), (2, 3), (3, 4)],
                       sets=[[3, 0], [1, 4, 2]])
     self.assertEqual(graph5, test_graph1)
     self.assertEqual(hash(graph5), hash(test_graph1))
     # but order of sets matters
     graph6 = gg.Graph(N=5,
                       E=[(0, 1), (0, 2), (2, 3), (3, 4)],
                       sets=[[1, 2, 4], [0, 3]])
     self.assertNotEqual(graph6, test_graph1)
     self.assertNotEqual(hash(graph6), hash(test_graph1))
Example #7
0
 def test_mask_b(self):
     for _ in range(10):
         num_vertices = 10
         test_graph = random_graph(num_vertices)
         # randomly split in two sets - actual colorability doesn't matter for this test
         first_set = sorted(
             np.random.choice(
                 np.arange(num_vertices, dtype=int),
                 size=np.random.randint(num_vertices),
                 replace=False,
             ))
         second_set = [i for i in range(num_vertices) if i not in first_set]
         test_graph = gg.Graph(N=test_graph.N,
                               E=test_graph.E,
                               sets=[first_set, second_set])
         for short_bit_string in range(2**len(test_graph.b)):
             long_bit_string = _mask_b(j=short_bit_string, graph=test_graph)
             short_string = format(short_bit_string,
                                   "0" + str(len(test_graph.b)) + "b")
             long_string = format(long_bit_string,
                                  "0" + str(test_graph.N) + "b")
             for bit, idx in zip(short_string, test_graph.b):
                 self.assertEqual(bit, long_string[idx])
Example #8
0
 def test_immutableish(self):
     # test that all the properties are read only
     test_graph = gg.Graph(N=5,
                           E=[(0, 1), (1, 2), (2, 0), (3, 4)],
                           sets=[[0, 3], [1, 4], [2]])
     with self.assertRaises(AttributeError):
         test_graph.N = 3
     with self.assertRaises(AttributeError):
         test_graph.E = ((1, 2), )
     with self.assertRaises(TypeError):
         E = test_graph.E
         E[0] = (0, 1)
     with self.assertRaises(AttributeError):
         test_graph.sets = ((1, 2), (0, 3))
     with self.assertRaises(TypeError):
         sets = test_graph.sets
         sets[0] = (0, 2, 4)
     with self.assertRaises(AttributeError):
         test_graph.adj = np.array([[0, 1], [1, 0]], dtype=int)
     adj = test_graph.adj
     adj[0, 0] = 1
     adj[1, 0] = 0
     self.assertFalse(np.all(adj == test_graph.adj))
Example #9
0
 def test_wnoise(self):
     # only reproducibility test because this function is just a definition
     test_rho = np.array([0.93, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01])
     test_graph = gg.Graph(N=3, E=[(0, 1), (0, 2)])  # GHZ graph
     test_result = gg.wnoise(rho=test_rho,
                             qubit_index=1,
                             p=0.98,
                             graph=test_graph)
     self.assertTrue(
         np.allclose(
             test_result,
             np.array(
                 [0.9162, 0.01, 0.0146, 0.01, 0.0146, 0.01, 0.0146, 0.01]),
         ))
     # now try different noise on all qubits
     ps = [0.7, 0.93, 0.98]
     test_result = test_rho
     for idx, p in enumerate(ps):
         test_result = gg.wnoise(rho=test_result,
                                 qubit_index=idx,
                                 p=p,
                                 graph=test_graph)
     self.assertTrue(
         np.allclose(
             test_result,
             np.array([
                 0.6770368,
                 0.016164,
                 0.024214,
                 0.076056,
                 0.0900952,
                 0.016164,
                 0.024214,
                 0.076056,
             ]),
         ))
Example #10
0
 def test_p2(self):
     test_graph = gg.Graph(N=4,
                           E=((0, 1), (0, 2), (0, 3)),
                           sets=[[0],
                                 [1, 2,
                                  3]])  # 4 qubit GHZ graph; two-colorable
     test_rho = np.array([
         0.70,
         0.01,
         0.02,
         0.00,
         0.00,
         0.02,
         0.00,
         0.01,
         0.00,
         0.05,
         0.00,
         0.04,
         0.14,
         0.01,
         0.00,
         0.00,
     ])
     test_result = gg.p2(rho=test_rho, graph=test_graph)
     self.assertTrue(
         np.allclose(
             test_result,
             np.array([
                 9.49244479e-01,
                 5.03680744e-03,
                 7.74893452e-04,
                 3.09957381e-03,
                 3.79697792e-02,
                 9.68616815e-04,
                 0.00000000e00,
                 1.93723363e-04,
                 0.00000000e00,
                 1.93723363e-03,
                 0.00000000e00,
                 0.00000000e00,
                 0.00000000e00,
                 7.74893452e-04,
                 0.00000000e00,
                 0.00000000e00,
             ]),
         ))
     test_graph = gg.Graph(N=5,
                           E=((0, 1), (1, 2), (2, 3), (3, 4)),
                           sets=[[0, 2, 4],
                                 [1, 3]])  # 5 qubit linear cluster state
     test_rho = np.zeros(2**5, dtype=np.float)
     test_rho[0] = 1.0
     test_rho = gg.wnoise_all(rho=test_rho, p=0.99, graph=test_graph)
     test_result = gg.p2(rho=test_rho, graph=test_graph)
     self.assertTrue(
         np.allclose(
             test_result,
             np.array([
                 9.74888853e-01,
                 4.94873525e-03,
                 3.73657691e-05,
                 2.51192019e-05,
                 4.98572109e-03,
                 4.94873525e-03,
                 1.28738842e-05,
                 2.51192019e-05,
                 3.73657691e-05,
                 3.79924263e-07,
                 1.25002804e-05,
                 2.53094747e-07,
                 1.28738842e-05,
                 3.79924263e-07,
                 1.24996619e-05,
                 2.53094747e-07,
                 4.94873525e-03,
                 5.01102580e-05,
                 3.79924263e-07,
                 3.79299534e-07,
                 4.94873525e-03,
                 5.01102580e-05,
                 3.79924263e-07,
                 3.79299534e-07,
                 2.51192019e-05,
                 3.79299534e-07,
                 2.53094747e-07,
                 1.29395220e-07,
                 2.51192019e-05,
                 3.79299534e-07,
                 2.53094747e-07,
                 1.29395220e-07,
             ]),
         ))
Example #11
0
 def test_p1(self):
     # only reproducibility tests for now - an alternative implementation with density matrices would be ideal
     test_graph = gg.Graph(N=4,
                           E=((0, 1), (0, 2), (0, 3)),
                           sets=[[0],
                                 [1, 2,
                                  3]])  # 4 qubit GHZ graph; two-colorable
     test_rho = np.array([
         0.70,
         0.01,
         0.02,
         0.00,
         0.00,
         0.02,
         0.00,
         0.01,
         0.00,
         0.05,
         0.00,
         0.04,
         0.14,
         0.01,
         0.00,
         0.00,
     ])
     test_result = gg.p1(rho=test_rho, graph=test_graph)
     self.assertTrue(
         np.allclose(
             test_result,
             np.array([
                 7.72984887e-01,
                 2.20403023e-02,
                 4.47103275e-02,
                 6.29722922e-04,
                 6.29722922e-04,
                 4.47103275e-02,
                 3.14861461e-04,
                 2.32997481e-02,
                 3.74685139e-02,
                 4.40806045e-03,
                 6.29722922e-03,
                 0.00000000e00,
                 1.57430730e-03,
                 2.20403023e-02,
                 1.25944584e-03,
                 1.76322418e-02,
             ]),
         ))
     test_graph = gg.Graph(N=5,
                           E=((0, 1), (1, 2), (2, 3), (3, 4)),
                           sets=[[0, 2, 4],
                                 [1, 3]])  # 5 qubit linear cluster state
     test_rho = np.zeros(2**5, dtype=np.float)
     test_rho[0] = 1.0
     test_rho = gg.wnoise_all(rho=test_rho, p=0.99, graph=test_graph)
     test_result = gg.p1(rho=test_rho, graph=test_graph)
     self.assertTrue(
         np.allclose(
             test_result,
             np.array([
                 9.75112509e-01,
                 1.25003027e-05,
                 9.87411374e-03,
                 1.25003027e-05,
                 1.25028117e-05,
                 1.25003027e-05,
                 3.76852011e-07,
                 1.25003027e-05,
                 9.87411374e-03,
                 2.51861704e-07,
                 5.01148266e-03,
                 2.51861704e-07,
                 3.76852011e-07,
                 2.51861704e-07,
                 1.25021931e-05,
                 2.51861704e-07,
                 1.25003027e-05,
                 6.43999920e-10,
                 2.51861704e-07,
                 6.43999920e-10,
                 1.25003027e-05,
                 6.43999920e-10,
                 2.51861704e-07,
                 6.43999920e-10,
                 1.25003027e-05,
                 6.43999920e-10,
                 2.51861704e-07,
                 6.43999920e-10,
                 1.25003027e-05,
                 6.43999920e-10,
                 2.51861704e-07,
                 6.43999920e-10,
             ]),
         ))
Example #12
0
 def test_p2_var(self):
     # assert that calling it with rho=sigma is equivalent to p2
     test_graph = gg.Graph(N=4,
                           E=((0, 1), (0, 2), (0, 3)),
                           sets=[[0],
                                 [1, 2,
                                  3]])  # 4 qubit GHZ graph; two-colorable
     test_rho = np.random.random(2**4)
     test_rho = test_rho / np.sum(test_rho)
     test_result1 = gg.p2(rho=test_rho, graph=test_graph)
     test_result2 = gg.p2_var(rho=test_rho,
                              sigma=test_rho,
                              graph=test_graph)
     self.assertTrue(np.allclose(test_result1, test_result2))
     # also small reproducibility test
     test_rho = np.array([
         0.70,
         0.01,
         0.02,
         0.00,
         0.00,
         0.02,
         0.00,
         0.01,
         0.00,
         0.05,
         0.00,
         0.04,
         0.14,
         0.01,
         0.00,
         0.00,
     ])
     test_sigma = np.array([
         0.84,
         0.01,
         0.00,
         0.01,
         0.00,
         0.02,
         0.00,
         0.01,
         0.00,
         0.00,
         0.05,
         0.02,
         0.03,
         0.01,
         0.00,
         0.00,
     ])
     test_result = gg.p2_var(rho=test_rho,
                             sigma=test_sigma,
                             graph=test_graph)
     self.assertTrue(
         np.allclose(
             test_result,
             np.array([
                 9.86577181e-01,
                 1.67785235e-04,
                 0.00000000e00,
                 1.34228188e-03,
                 7.04697987e-03,
                 8.38926174e-04,
                 0.00000000e00,
                 1.67785235e-04,
                 0.00000000e00,
                 8.38926174e-04,
                 1.67785235e-03,
                 6.71140940e-04,
                 0.00000000e00,
                 6.71140940e-04,
                 0.00000000e00,
                 0.00000000e00,
             ]),
         ))
Example #13
0
 def test_noise_pattern(self):
     # first compare to other functions
     test_rho = np.random.random(16)
     test_rho[0] += 16
     test_rho = test_rho / np.sum(test_rho)
     test_graph = random_graph(num_vertices=4, p=0.9)
     px = 0.5 + np.random.random() * 0.5
     known_result = gg.xnoise(rho=test_rho,
                              qubit_index=2,
                              p=px,
                              graph=test_graph)
     test_result = gg.noise_pattern(rho=test_rho,
                                    qubit_index=2,
                                    ps=[px, 1 - px, 0, 0],
                                    graph=test_graph)
     self.assertTrue(np.allclose(test_result, known_result))
     py = 0.5 + np.random.random() * 0.5
     known_result = gg.ynoise(rho=test_rho,
                              qubit_index=2,
                              p=py,
                              graph=test_graph)
     test_result = gg.noise_pattern(rho=test_rho,
                                    qubit_index=2,
                                    ps=[py, 0, 1 - py, 0],
                                    graph=test_graph)
     self.assertTrue(np.allclose(test_result, known_result))
     pz = 0.5 + np.random.random() * 0.5
     known_result = gg.znoise(rho=test_rho,
                              qubit_index=2,
                              p=pz,
                              graph=test_graph)
     test_result = gg.noise_pattern(rho=test_rho,
                                    qubit_index=2,
                                    ps=[pz, 0, 0, 1 - pz],
                                    graph=test_graph)
     self.assertTrue(np.allclose(test_result, known_result))
     pw = 0.5 + np.random.random() * 0.5
     known_result = gg.wnoise(rho=test_rho,
                              qubit_index=2,
                              p=pw,
                              graph=test_graph)
     test_result = gg.noise_pattern(
         rho=test_rho,
         qubit_index=2,
         ps=[pw + (1 - pw) / 4, (1 - pw) / 4, (1 - pw) / 4, (1 - pw) / 4],
         graph=test_graph,
     )
     self.assertTrue(np.allclose(test_result, known_result))
     # and reproducibility
     test_rho = np.array([
         0.85,
         0.01,
         0.01,
         0.01,
         0.01,
         0.01,
         0.01,
         0.01,
         0.01,
         0.01,
         0.01,
         0.01,
         0.01,
         0.01,
         0.01,
         0.01,
     ])
     test_graph = gg.Graph(N=4, E=[(0, 1), (1, 2), (2, 3), (3, 0)])
     ps = [0.8, 0.1, 0.07, 0.03]
     test_result = gg.noise_pattern(rho=test_rho,
                                    qubit_index=2,
                                    ps=ps,
                                    graph=test_graph)
     self.assertTrue(
         np.allclose(
             test_result,
             np.array([
                 0.682,
                 0.01,
                 0.0352,
                 0.01,
                 0.01,
                 0.094,
                 0.01,
                 0.0688,
                 0.01,
                 0.01,
                 0.01,
                 0.01,
                 0.01,
                 0.01,
                 0.01,
                 0.01,
             ]),
         ))
Example #14
0
 def test_pk(self):
     # assert that for a two-colorables state with graph1 == graph2 and
     # appropriate subset, this is equivalent to p1_var or p2_var
     test_graph = gg.Graph(N=4,
                           E=((0, 1), (0, 2), (0, 3)),
                           sets=[[0],
                                 [1, 2,
                                  3]])  # 4 qubit GHZ graph; two-colorable
     for _ in range(10):
         test_rho = np.random.random(2**4)
         test_rho = test_rho / np.sum(test_rho)
         test_sigma = np.random.random(2**4)
         test_sigma = test_sigma / np.sum(test_sigma)
         test_result1 = gg.pk(
             rho=test_rho,
             sigma=test_sigma,
             graph1=test_graph,
             graph2=test_graph,
             subset=test_graph.a,
         )
         test_result2 = gg.pk(
             rho=test_rho,
             sigma=test_sigma,
             graph1=test_graph,
             graph2=test_graph,
             subset=test_graph.b,
         )
         known_result1 = gg.p1_var(rho=test_rho,
                                   sigma=test_sigma,
                                   graph=test_graph)
         known_result2 = gg.p2_var(rho=test_rho,
                                   sigma=test_sigma,
                                   graph=test_graph)
         self.assertTrue(np.allclose(test_result1, known_result1))
         self.assertTrue(np.allclose(test_result2, known_result2))
     # small reproducibility test
     test_graph = gg.Graph(
         N=4, E=((0, 1), (1, 2), (2, 0), (2, 3)), sets=[[0, 3], [1], [2]]
     )  # small graph that is actually not two-colorable, we choose a coloring with 3 colors
     subgraph0 = gg.Graph(N=4,
                          E=((0, 1), (2, 0), (2, 3)),
                          sets=[[0, 3], [1, 2]])
     subgraph1 = gg.Graph(N=4, E=((0, 1), (1, 2)), sets=[[1], [0, 2, 3]])
     subgraph2 = gg.Graph(N=4,
                          E=((1, 2), (2, 0), (2, 3)),
                          sets=[[2], [0, 1, 3]])
     test_rho = np.array([
         0.70,
         0.01,
         0.02,
         0.00,
         0.00,
         0.02,
         0.00,
         0.01,
         0.00,
         0.05,
         0.00,
         0.04,
         0.14,
         0.01,
         0.00,
         0.00,
     ])
     test_sigma = np.array([
         0.84,
         0.01,
         0.00,
         0.01,
         0.00,
         0.02,
         0.00,
         0.01,
         0.00,
         0.00,
         0.05,
         0.02,
         0.03,
         0.01,
         0.00,
         0.00,
     ])
     test_result0 = gg.pk(
         rho=test_rho,
         sigma=test_sigma,
         graph1=test_graph,
         graph2=subgraph0,
         subset=test_graph.sets[0],
     )
     self.assertTrue(
         np.allclose(
             test_result0,
             np.array([
                 9.46859903e-01,
                 9.66183575e-04,
                 2.70531401e-02,
                 8.05152979e-04,
                 0.00000000e00,
                 8.05152979e-04,
                 0.00000000e00,
                 6.44122383e-04,
                 6.76328502e-03,
                 1.44927536e-03,
                 0.00000000e00,
                 1.61030596e-03,
                 0.00000000e00,
                 8.05152979e-04,
                 1.12721417e-02,
                 9.66183575e-04,
             ]),
         ))
     test_result1 = gg.pk(
         rho=test_rho,
         sigma=test_sigma,
         graph1=test_graph,
         graph2=subgraph1,
         subset=test_graph.sets[1],
     )
     self.assertTrue(
         np.allclose(
             test_result1,
             np.array([
                 7.59674923e-01,
                 2.27038184e-02,
                 2.30908153e-02,
                 1.25128999e-02,
                 6.19195046e-03,
                 2.19298246e-03,
                 5.15995872e-04,
                 0.00000000e00,
                 2.45098039e-03,
                 5.46955624e-02,
                 4.65686275e-02,
                 6.20485036e-02,
                 5.15995872e-04,
                 4.38596491e-03,
                 2.57997936e-04,
                 2.19298246e-03,
             ]),
         ))
     test_result2 = gg.pk(
         rho=test_rho,
         sigma=test_sigma,
         graph1=test_graph,
         graph2=subgraph2,
         subset=test_graph.sets[2],
     )
     self.assertTrue(
         np.allclose(
             test_result2,
             np.array([
                 6.95285011e-01,
                 2.00562984e-02,
                 1.05559465e-03,
                 2.58034248e-03,
                 1.05559465e-03,
                 3.78841192e-02,
                 1.17288295e-04,
                 2.34576589e-04,
                 1.05559465e-03,
                 5.32488858e-02,
                 1.64203612e-03,
                 4.69153179e-04,
                 1.63969036e-01,
                 2.00562984e-02,
                 7.03729768e-04,
                 5.86441473e-04,
             ]),
         ))
Example #15
0
 def test_p1_var(self):
     # assert that calling it with rho=sigma is equivalent to p1
     test_graph = gg.Graph(N=4,
                           E=((0, 1), (0, 2), (0, 3)),
                           sets=[[0],
                                 [1, 2,
                                  3]])  # 4 qubit GHZ graph; two-colorable
     test_rho = np.random.random(2**4)
     test_rho = test_rho / np.sum(test_rho)
     test_result1 = gg.p1(rho=test_rho, graph=test_graph)
     test_result2 = gg.p1_var(rho=test_rho,
                              sigma=test_rho,
                              graph=test_graph)
     self.assertTrue(np.allclose(test_result1, test_result2))
     # also small reproducibility test
     test_rho = np.array([
         0.70,
         0.01,
         0.02,
         0.00,
         0.00,
         0.02,
         0.00,
         0.01,
         0.00,
         0.05,
         0.00,
         0.04,
         0.14,
         0.01,
         0.00,
         0.00,
     ])
     test_sigma = np.array([
         0.84,
         0.01,
         0.00,
         0.01,
         0.00,
         0.02,
         0.00,
         0.01,
         0.00,
         0.00,
         0.05,
         0.02,
         0.03,
         0.01,
         0.00,
         0.00,
     ])
     test_result = gg.p1_var(rho=test_rho,
                             sigma=test_sigma,
                             graph=test_graph)
     self.assertTrue(
         np.allclose(
             test_result,
             np.array([
                 8.37507114e-01,
                 2.21969266e-02,
                 2.46158224e-02,
                 1.02447353e-02,
                 7.11439954e-04,
                 4.41092772e-02,
                 5.69151964e-04,
                 2.24815026e-02,
                 7.25668754e-03,
                 5.26465566e-03,
                 1.42287991e-03,
                 3.55719977e-03,
                 7.11439954e-04,
                 2.13431986e-03,
                 1.08138873e-02,
                 6.40295959e-03,
             ]),
         ))
Example #16
0
"""Find the fixed point of an EPP with noisy CNOT gates."""
import graphepp as gg
import numpy as np

# CNOT gate is modelled as local white noise acting on both of the qubits
# followed by the perfect operation
noise_param = 0.98
ghz5_graph = gg.Graph(N=5,
                      E=((0, i) for i in range(1, 5)),
                      sets=[(0, ),
                            (i for i in range(1, 5))])  # 5-qubit GHZ state

print("Noisy fixed point of the P1-P2 protocol for the 5-qubit GHZ state.")
print(
    f"CNOTs are noisy with local depolarizing noise with error parameter p={noise_param:.2f}"
)

rho = np.zeros(2**ghz5_graph.N, dtype=np.float)
rho[0] = 1.0  # perfect state

for i in range(
        100
):  # 100 iterations are more than enough to reach the fixed point with numerical precision
    rho = gg.wnoise_all(
        rho=rho, p=noise_param, graph=ghz5_graph
    )  # a noisy CNOT is acting on each of the qubits to perform the protocol
    rho = gg.p1(rho=rho, graph=ghz5_graph)
    rho = gg.wnoise_all(rho=rho, p=noise_param, graph=ghz5_graph)
    rho = gg.p2(rho=rho, graph=ghz5_graph)
    fixed_point_fidelity_p2 = rho[0]  # fidelity when ending with p2
rho = gg.wnoise_all(
"""Perform the entanglement purification protocol for arbitrary graph states.

Here we look at an example for a 6-qubit graph state that is three-colorable.
"""
import graphepp as gg
import numpy as np

# as main graph we use this 6-qubit state that is linked to a
# universal quantum error correction code
# For visualization of this particular coloring and the auxiliary graphs
# see Fig.9 and Fig. 20 in https://arxiv.org/abs/1609.05754
main_graph = gg.Graph(
    N=6,
    E=[(0, 1), (0, 4), (0, 5), (1, 2), (1, 3), (2, 3), (2, 5), (3, 4), (4, 5)],
    sets=[[0, 2], [1, 4], [3, 5]],
)
aux_graph1 = gg.Graph(N=6, E=[(0, 1), (0, 4), (0, 5), (1, 2), (2, 3), (2, 5)])
aux_graph2 = gg.Graph(N=6, E=[(0, 1), (0, 4), (1, 2), (1, 3), (3, 4), (4, 5)])
aux_graph3 = gg.Graph(N=6, E=[(0, 5), (1, 3), (2, 3), (2, 5), (3, 4), (4, 5)])

# assume we have all these states available, with the same noise per qubit
rho = np.zeros(2 ** main_graph.N, dtype=np.float)
rho[0] = 1.0  # perfect graph state
rho = gg.wnoise_all(rho=rho, p=0.98, graph=main_graph)

mu1 = np.zeros(2 ** aux_graph1.N, dtype=np.float)
mu1[0] = 1.0
mu1 = gg.wnoise_all(rho=mu1, p=0.98, graph=aux_graph1)

mu2 = np.zeros(2 ** aux_graph2.N, dtype=np.float)
mu2[0] = 1.0