def test_postselect(): """Test if the function ``strawberryfields.apps.sample.postselect`` correctly postselects on minimum number of photons or clicks.""" counts_pnr = [ [0, 0, 0, 0], [1, 1, 0, 2], [1, 1, 1, 0], [1, 2, 1, 0], [1, 0, 0, 1], [5, 0, 0, 0], [1, 2, 1, 2], ] counts_pnr_ps_4_5 = [[1, 1, 0, 2], [1, 2, 1, 0], [5, 0, 0, 0]] counts_threshold = [ [0, 0, 0, 0], [1, 1, 0, 1], [1, 1, 1, 0], [1, 1, 1, 0], [1, 0, 0, 1], [1, 1, 1, 1], ] counts_threshold_ps_3_3 = [[1, 1, 0, 1], [1, 1, 1, 0], [1, 1, 1, 0]] assert sample.postselect(counts_pnr, 4, 5) == counts_pnr_ps_4_5 assert sample.postselect(counts_threshold, 3, 3) == counts_threshold_ps_3_3
maximal_clique = [4, 11, 12, 18] maximal_fig = plot.graph(TA_graph, maximal_clique) plotly.offline.plot(maximal_fig, filename="maximal_clique.html") ############################################################################## # .. raw:: html # :file: ../../examples_apps/maximal_clique.html ############################################################################## # We'll now use the :mod:`~.apps.clique` module to find larger cliques in the graph. We can make # use of the pre-generated samples from the TACE-AS graph in the :mod:`~.apps.data` module and # post-select samples with a specific number of clicks. Here we'll look at samples with eight # clicks, of which there are a total of 1,984: postselected = sample.postselect(TA, 8, 8) samples = sample.to_subgraphs(postselected, TA_graph) print(len(samples)) ############################################################################## # GBS produces samples that correspond to subgraphs of high density. For fun, let's confirm this # by comparing the average subgraph density in the GBS samples to uniformly generated samples: GBS_dens = [] u_dens = [] for s in samples: uniform = list(np.random.choice(24, 8, replace=False)) # generates uniform sample GBS_dens.append(nx.density(TA_graph.subgraph(s))) u_dens.append(nx.density(TA_graph.subgraph(uniform)))
############################################################################## # In this tutorial, we'll study a 30-node graph with a planted 10-node graph, as considered in # :cite:`arrazola2018using`. The graph is generated by joining two Erdős–Rényi random graphs. The # first graph of 20 nodes is created with edge probability of 0.5. The second planted # graph is generated with edge probability of 0.875. The planted nodes are the last ten nodes in the # graph. The two graphs are joined by selecting 8 nodes at random from both graphs and adding an # edge between them. This graph has the sneaky property that even though the planted subgraph is the # densest of its size, its nodes have a lower average degree than the nodes in the rest of the # graph. # # The :mod:`~.apps.data` module has pre-generated GBS samples from this graph. Let's load them, # postselect on samples with a large number of clicks, and convert them to subgraphs: planted = data.Planted() postselected = sample.postselect(planted, 16, 30) pl_graph = nx.to_networkx_graph(planted.adj) samples = sample.to_subgraphs(postselected, pl_graph) print(len(samples)) ############################################################################## # Not bad! We have more than 2000 samples to play with 😎. The planted subgraph is actually easy to # identify; it even appears clearly from the force-directed Kamada-Kawai algorithm that is used to # plot graphs in Strawberry Fields: sub = list(range(20, 30)) plot_graph = plot.graph(pl_graph, sub) plotly.offline.plot(plot_graph, filename="planted.html") ############################################################################## # .. raw:: html # :file: ../../examples_apps/planted.html
############################################################################## # Each sample in ``s`` is a list of modes with ``1``'s for nodes that have clicked and ``0``'s # for nodes that haven't. We want to convert a sample to another representation where the result # is a list of modes that have clicked. This list of modes can be used to select a subgraph. # For example, if ``[0, 1, 0, 1, 1, 0]`` is a sample from GBS then ``[1, 3, 4]`` are # the selected nodes of the corresponding subgraph. # # However, the number of clicks in GBS is a random variable and we are not always guaranteed to # have enough clicks in a sample for the resultant subgraph to be of interest. We can filter out # the uninteresting samples using the :func:`~.apps.sample.postselect` function: min_clicks = 3 max_clicks = 4 s = sample.postselect(s, min_clicks, max_clicks) print(len(s)) s.append([0, 1, 0, 1, 1, 0]) ############################################################################## # As expected, we have fewer samples than before. The number of samples that survive this # postselection is determined by the mean photon number in GBS. We have also added in our example # sample ``[0, 1, 0, 1, 1, 0]`` to ensure that there is at least one for the following. # # Let's convert our postselected samples to subgraphs: subgraphs = sample.to_subgraphs(s, graph) print(subgraphs)