From 3e2823d7b54e041eea8b4c7968fbc576d36053d1 Mon Sep 17 00:00:00 2001 From: Pete Shadbolt Date: Sat, 23 Jul 2016 18:13:11 +0100 Subject: [PATCH] Remove old debug code --- abp/graphstate_with_debug_statements.py | 279 ------------------------ setup.py | 4 +- 2 files changed, 3 insertions(+), 280 deletions(-) delete mode 100644 abp/graphstate_with_debug_statements.py diff --git a/abp/graphstate_with_debug_statements.py b/abp/graphstate_with_debug_statements.py deleted file mode 100644 index a09eec3..0000000 --- a/abp/graphstate_with_debug_statements.py +++ /dev/null @@ -1,279 +0,0 @@ -""" -Provides an extremely basic graph structure, based on neighbour lists -""" - -import itertools as it -import json -import qi, clifford, util -import random - -output = open("debug_pete.txt", "w") -def debug(x): - output.write(str(x)+"\n") - -class GraphState(object): - - def __init__(self, nodes=[]): - self.adj, self.node = {}, {} - self.add_nodes(nodes) - - def add_node(self, v, **kwargs): - """ Add a node """ - assert not v in self.node - self.adj[v] = {} - self.node[v] = {"vop": clifford.by_name["hadamard"]} - self.node[v].update(kwargs) - - def add_nodes(self, nodes): - """ Add a buncha nodes """ - for n in nodes: - self.add_node(n) - - def add_edge(self, v1, v2, data = {}): - """ Add an edge between two vertices in the self """ - assert v1 != v2 - self.adj[v1][v2] = data - self.adj[v2][v1] = data - - def add_edges(self, edges): - """ Add a buncha edges """ - for (v1, v2) in edges: - self.add_edge(v1, v2) - - def del_edge(self, v1, v2): - """ Delete an edge between two vertices in the self """ - debug("deling edge") - del self.adj[v1][v2] - del self.adj[v2][v1] - - def has_edge(self, v1, v2): - """ Test existence of an edge between two vertices in the self """ - return v2 in self.adj[v1] - - def toggle_edge(self, v1, v2): - """ Toggle an edge between two vertices in the self """ - if self.has_edge(v1, v2): - self.del_edge(v1, v2) - else: - self.add_edge(v1, v2) - - def edgelist(self): - """ Describe a graph as an edgelist """ - # TODO: inefficient - edges = set(tuple(sorted((i, n))) - for i, v in self.adj.items() - for n in v) - return tuple(edges) - - def remove_vop(self, a, avoid): - """ Reduces VOP[a] to the identity """ - # TODO: sucks! - others = set(self.adj[a]) - {avoid} - swap_qubit = others.pop() if others else avoid - - debug("remove_byprod_op called: (v, avoid, vb):") - self.print_adj_list_line(a) - self.print_adj_list_line(avoid) - self.print_adj_list_line(swap_qubit) - converted = clifford.decompositions[self.node[a]["vop"]] - converted = "".join("U" if x == "x" else "V" for x in converted) - debug("using {}".format(converted)) - - for v in reversed(clifford.decompositions[self.node[a]["vop"]]): - if v == "x": - self.local_complementation(a, "U ->") - else: - self.local_complementation(swap_qubit, "V ->") - - assert self.node[a]["vop"]==0 - - debug("remove_byprod_op: after (v, avoid, vb):") - self.print_adj_list_line(a) - self.print_adj_list_line(avoid) - self.print_adj_list_line(swap_qubit) - - assert self.node[a]["vop"] == 0 - - def local_complementation(self, v, prefix = ""): - """ As defined in LISTING 1 of Anders & Briegel """ - debug("{}Inverting about {}".format(prefix, self.get_adj_list_line(v))) - for i, j in it.combinations(self.adj[v], 2): - self.toggle_edge(i, j) - - msqx_h = clifford.conjugation_table[clifford.by_name["msqx"]] - sqz_h = clifford.conjugation_table[clifford.by_name["sqz"]] - self.node[v]["vop"] = clifford.times_table[self.node[v]["vop"], msqx_h] - for i in self.adj[v]: - self.node[i]["vop"] = clifford.times_table[self.node[i]["vop"], sqz_h] - - def act_local_rotation(self, v, op): - """ Act a local rotation """ - rotation = clifford.by_name[str(op)] - self.node[v]["vop"] = clifford.times_table[rotation, self.node[v]["vop"]] - - def act_hadamard(self, qubit): - """ Shorthand """ - self.act_local_rotation(qubit, 10) - - def act_cz(self, a, b): - """ Act a controlled-phase gate on two qubits """ - debug("before cphase between {} and {}".format(a, b)) - self.print_adj_list_line(a) - self.print_adj_list_line(b) - - ci = self.get_connection_info(a, b) - if ci["non1"]: - debug("cphase: left vertex has NONs -> putting it to Id") - self.remove_vop(a, b) - - ci = self.get_connection_info(a, b) - if ci["non2"]: - debug("cphase: right vertex has NONs -> putting it to Id") - self.remove_vop(b, a) - - ci = self.get_connection_info(a, b) - if ci["non1"] and not clifford.is_diagonal(self.node[a]["vop"]): - debug("cphase: left one needs treatment again -> putting it to Id") - self.remove_vop(a, b) - - self.cz_with_table(a, b) - - def get_connection_info(self, a, b): - if self.has_edge(a, b): - return {"was_edge": True, - "non1": len(self.adj.get(a)) > 1, - "non2": len(self.adj.get(b)) > 1} - else: - return {"was_edge": False, - "non1": len(self.adj.get(a)) > 0, - "non2": len(self.adj.get(b)) > 0} - - def cz_with_table(self, a, b): - """ Run the table """ - debug("cphase_with_table called on:") - self.print_adj_list_line(a) - self.print_adj_list_line(b) - - ci = self.get_connection_info(a, b) - try: - assert ci["non1"]==False or clifford.is_diagonal(self.node[a]["vop"]) - assert ci["non2"]==False or clifford.is_diagonal(self.node[b]["vop"]) - except AssertionError: - debug(ci) - debug(self.node[a]["vop"]) - debug(self.node[b]["vop"]) - - edge = self.has_edge(a, b) - new_edge, self.node[a]["vop"], self.node[ - b]["vop"] = clifford.cz_table[edge, self.node[a]["vop"], self.node[b]["vop"]] - if new_edge != edge: - self.toggle_edge(a, b) - - debug("cphase_with_table: after") - self.print_adj_list_line(a) - self.print_adj_list_line(b) - - ci = self.get_connection_info(a, b) - assert ci["non1"]==False or clifford.is_diagonal(self.node[a]["vop"]) - assert ci["non2"]==False or clifford.is_diagonal(self.node[b]["vop"]) - - def measure_z(self, node, force=None): - """ Measure the graph in the Z-basis """ - res = force if force!=None else random.choice([0, 1]) - - # Disconnect - for neighbour in self.adj[node]: - self.del_edge(node, neighbour) - if res: - self.act_local_rotation(neighbour, "pz") - - # Rotate - if res: - self.act_local_rotation(node, "px") - self.act_local_rotation(node, "hadamard") - else: - self.act_local_rotation(node, "hadamard") - - return res - - def measure_x(self, i): - """ Measure the graph in the X-basis """ - # TODO - pass - - def measure_y(self, i): - """ Measure the graph in the Y-basis """ - # TODO - pass - - def order(self): - """ Get the number of qubits """ - return len(self.node) - - def __str__(self): - """ Represent as a string for quick debugging """ - node = {key: clifford.get_name(value["vop"]) - for key, value in self.node.items()} - nbstr = str(self.adj) - return "graph:\n node: {}\n adj: {}\n".format(node, nbstr) - - def to_json(self): - """ Convert the graph to JSON form """ - return {"node": self.node, "adj": self.adj} - - def from_json(self, data): - """ Reconstruct from JSON """ - self.__init__([]) - #TODO - - def to_state_vector(self): - """ Get the full state vector """ - if len(self.node) > 15: - raise ValueError("Cannot build state vector: too many qubits") - state = qi.CircuitModel(len(self.node)) - for i in range(len(self.node)): - state.act_hadamard(i) - for i, j in self.edgelist(): - state.act_cz(i, j) - for i, n in self.node.items(): - state.act_local_rotation(i, clifford.unitaries[n["vop"]]) - return state - - def to_stabilizer(self): - """ Get the stabilizer of this graph """ - output = {a:{} for a in self.node} - for a, b in it.product(self.node, self.node): - if a == b: - output[a][b] = "X" - elif a in self.adj[b]: - output[a][b] = "Z" - else: - output[a][b] = "I" - return output - - def adj_list(self): - """ For comparison with Anders and Briegel's C++ implementation """ - rows = [] - for key, node in self.node.items(): - adj = " ".join(map(str, sorted(self.adj[key]))) - vop = clifford.get_name(node["vop"]) - s = "Vertex {}: VOp {}, neighbors {}".format(key, vop, adj) - rows.append(s) - return " \n".join(rows) + " \n" - - def get_adj_list_line(self, key): - """ TODO: delete """ - node = self.node[key] - adj = " ".join(map(str, sorted(self.adj[key]))) - vop = clifford.get_name(node["vop"]) - s = "Vertex {}: VOp {}, neighbors {}".format(key, vop, adj) - return s - - def print_adj_list_line(self, key): - debug(self.get_adj_list_line(key)) - - - def __eq__(self, other): - """ Check equality between graphs """ - return self.adj == other.adj and self.node == other.node - diff --git a/setup.py b/setup.py index 7ba75bb..084b1b2 100755 --- a/setup.py +++ b/setup.py @@ -9,10 +9,12 @@ print appdata setup( name = "abp", - version = "0.3", + version = "0.4", packages = find_packages(), test_suite = "tests", author = "Pete Shadbolt", + author_email = "hello@peteshadbolt.co.uk", + url = "https://github.com/peteshadbolt/abp", description = "Port of C++ due to Simon Anders and Hans J Briegel", keywords = "quantum", setup_requires = ["numpy"],