From bfdc66494d66def7dbc3ff44f8584615b20a96ef Mon Sep 17 00:00:00 2001 From: Pete Shadbolt Date: Wed, 11 May 2016 12:35:26 +0100 Subject: [PATCH] Switch off some tests if not using legacy table --- abp/clifford.py | 46 ++++++++++++------------ tests/test_against_anders_and_briegel.py | 18 +++++++--- tests/test_against_circuit_model.py | 24 +++++-------- tests/test_cphase_against_anders.py | 15 ++------ 4 files changed, 47 insertions(+), 56 deletions(-) diff --git a/abp/clifford.py b/abp/clifford.py index 1ec65bd..1027cb0 100644 --- a/abp/clifford.py +++ b/abp/clifford.py @@ -1,18 +1,17 @@ -#!/usr/bin/python # -*- coding: utf-8 -*- """ -This program generates lookup tables +This program generates lookup tables and handles the Clifford group """ -import os, json +import os, json, tempfile, os, sys, json, string from functools import reduce import itertools as it -import qi import numpy as np -import tempfile from tqdm import tqdm -import os, sys, json, string +import argparse + +import qi decompositions = ("xxxx", "xx", "zzxx", "zz", "zxx", "z", "zzz", "xxz", "xzx", "xzxxx", "xzzzx", "xxxzx", "xzz", "zzx", "xxx", "x", @@ -32,7 +31,8 @@ def find_clifford(needle, haystack): return i raise IndexError -def find_cz(bond, c1, c2, commuters, state_table, ab_cz_table): + +def find_cz(bond, c1, c2, commuters, state_table): """ Find the output of a CZ operation """ # Figure out the target state target = qi.cz.dot(state_table[bond, c1, c2]) @@ -66,7 +66,7 @@ def get_unitaries(): def get_by_name(unitaries): """ Get a lookup table of cliffords by name """ a = {name: find_clifford(u, unitaries) - for name, u in qi.by_name.items()} + for name, u in qi.by_name.items()} b = {get_name(i): i for i in range(24)} a.update(b) return a @@ -106,7 +106,6 @@ def get_cz_table(unitaries): # Get a cached state table and a list of gates which commute with CZ commuters = get_commuters(unitaries) state_table = get_state_table(unitaries) - ab_cz_table = get_ab_cz_table() # And now build the CZ table cz_table = np.zeros((2, 24, 24, 3), dtype=int) @@ -115,36 +114,38 @@ def get_cz_table(unitaries): # CZ is symmetric so we only need combinations for bond, (c1, c2) in tqdm(rows, desc="Building CZ table"): newbond, c1p, c2p = find_cz( - bond, c1, c2, commuters, state_table, ab_cz_table) + bond, c1, c2, commuters, state_table) cz_table[bond, c1, c2] = [newbond, c1p, c2p] cz_table[bond, c2, c1] = [newbond, c2p, c1p] return cz_table -def get_ab_cz_table(): - """ Load anders and briegel's CZ table """ - filename = "anders_briegel/cphase.tbl" - filename = os.path.join(os.path.dirname(sys.path[0]), filename) - with open(filename) as f: - s = f.read().translate(string.maketrans("{}", "[]")) - return np.array(json.loads(s)) - - # First try to load tables from cache. If that fails, build them from -# scratch and store +# scratch and store in /tmp/ os.chdir(tempfile.gettempdir()) try: if __name__ == "__main__": raise IOError + + # Parse command line args + parser = argparse.ArgumentParser() + parser.add_argument("-l", "--legacy", help="Use legacy CZ table", action="store_true", default=False) + args = parser.parse_args() + legacy_cz = args.legacy + unitaries = np.load("unitaries.npy") conjugation_table = np.load("conjugation_table.npy") times_table = np.load("times_table.npy") - cz_table = np.load("cz_table.npy") - # cz_table = get_ab_cz_table() + if legacy_cz: + import anders_cz + cz_table = anders_cz.cz_table + else: + cz_table = np.load("cz_table.npy") with open("by_name.json") as f: by_name = json.load(f) + print "Loaded tables from cache" except IOError: # Spend time building the tables @@ -153,7 +154,6 @@ except IOError: conjugation_table = get_conjugation_table(unitaries) times_table = get_times_table(unitaries) cz_table = get_cz_table(unitaries) - #cz_table = get_ab_cz_table() # Write it all to disk np.save("unitaries.npy", unitaries) diff --git a/tests/test_against_anders_and_briegel.py b/tests/test_against_anders_and_briegel.py index 2ab9fc7..13ff708 100644 --- a/tests/test_against_anders_and_briegel.py +++ b/tests/test_against_anders_and_briegel.py @@ -1,5 +1,6 @@ from abp.graphstate import GraphState from anders_briegel import graphsim +from abp import clifford import random import difflib import re @@ -44,8 +45,13 @@ def test_local_rotations(): compare(a, b) -def test_cz_table(): +def test_cz_table(N=10): """ Test the CZ table """ + + # Don't test if we are using Pete's CZ table - doesn't make sense + if not clifford.legacy_cz: + return + for j in range(24): a = graphsim.GraphRegister(2) b = GraphState() @@ -65,9 +71,8 @@ def test_cz_table(): -def test_with_cphase_gates_hadamard_only(): +def test_with_cphase_gates_hadamard_only(N=10): """ Hadamrds and CPHASEs, deterministic """ - N=10 a = graphsim.GraphRegister(N) b = GraphState() @@ -84,9 +89,12 @@ def test_with_cphase_gates_hadamard_only(): compare(a, b) -def test_all(): +def test_all(N=10): """ Test all gates at random """ - N=10 + + # Don't test if we are using Pete's CZ table - doesn't make sense + if not clifford.legacy_cz: + return a = graphsim.GraphRegister(N) b = GraphState() diff --git a/tests/test_against_circuit_model.py b/tests/test_against_circuit_model.py index d2b1587..1a91ad5 100644 --- a/tests/test_against_circuit_model.py +++ b/tests/test_against_circuit_model.py @@ -9,7 +9,7 @@ REPEATS = 100 def test_single_qubit(n=1): """ A multi qubit test with Hadamards only""" - for repeat in tqdm(range(REPEATS), desc="Testing against circuit model") : + for repeat in tqdm(range(REPEATS), desc="Testing against circuit model"): g = GraphState([0]) c = CircuitModel(1) @@ -23,7 +23,7 @@ def test_single_qubit(n=1): def test_hadamard_only_multiqubit(n=6): """ A multi qubit test with Hadamards only""" - for repeat in tqdm(range(REPEATS), desc="Testing against circuit model") : + for repeat in tqdm(range(REPEATS), desc="Testing against circuit model"): g = GraphState(range(n)) c = CircuitModel(n) @@ -54,21 +54,15 @@ def test_all_multiqubit(n=4): assert g.to_state_vector() == c - for repeat in tqdm(range(REPEATS), desc="Testing against circuit model") : - a, b = np.random.randint(0, n-1, 2) + for repeat in tqdm(range(REPEATS), desc="Testing against circuit model"): + a, b = np.random.randint(0, n - 1, 2) if a != b: g.act_cz(a, b) c.act_cz(a, b) - assert np.allclose(np.sum(np.abs(c.state)**2), 1) - assert np.allclose(np.sum(np.abs(g.to_state_vector().state)**2), 1) - - if not g.to_state_vector() == c: - print g - print a, b - print "Circuit:" - print g.to_state_vector() - print "Graph:" - print c - raise ValueError + assert np.allclose(np.sum(np.abs(c.state) ** 2), 1) + assert np.allclose( + np.sum(np.abs(g.to_state_vector().state) ** 2), 1) + + assert g.to_state_vector() == c assert g.to_state_vector() == c diff --git a/tests/test_cphase_against_anders.py b/tests/test_cphase_against_anders.py index 6b6cc79..cf17754 100644 --- a/tests/test_cphase_against_anders.py +++ b/tests/test_cphase_against_anders.py @@ -1,26 +1,15 @@ import json import numpy as np -from abp import clifford, qi import sys import os import itertools as it from string import maketrans - - -def get_ab_cz_table(): - """ Load anders and briegel's CZ table """ - filename = "anders_briegel/cphase.tbl" - filename = os.path.join(os.path.dirname(sys.path[0]), filename) - with open(filename) as f: - s = f.read().translate(maketrans("{}", "[]")) - return np.array(json.loads(s)) - - +from abp import clifford, qi, anders_cz def test_cz_table(): """ Does our clifford code work with anders & briegel's table? """ state_table = clifford.get_state_table(clifford.unitaries) - ab_cz_table = get_ab_cz_table() + ab_cz_table = anders_cz.cz_table rows = it.product([0, 1], it.combinations_with_replacement(range(24), 2)) for bond, (c1, c2) in rows: