Skip to content

Fock backend of localsimulator and thewalrus decomposition not giving the desirable result #742

@minseok1999

Description

@minseok1999

Before posting a bug report

  • I have searched exisisting GitHub issues to make sure the issue does not already exist.

Expected behavior

I wanted to follow the full steps of encoding an adjacency matrix of a graph into an interferometric setup and single mode squeezed states for Gaussian boson sampling experiment. To do this, I first used thewalrus library to decompose the adjacency matrix using Takagi decomposition. After I have decomposed the matrix, I have then used rectangular_phase_end from the strawberry fields library to convert my unitary gate into a set of beam splitters. Finally, I have used the Fock backend of the local simulator engine and fed in the squeezing parameters and Beam splitter setup I have generated to get the photo count result corresponding to my specific adjacency matrix.

I expected the photocount pattern of [111100] to appear for the largest number of times since that pattern corresponds to the 4 dimensional subgraph choice of maximum Hafnium value to my 6 dimensional adjacency matrix. (Hafnium value of 3, Hafnium squared value of 9 whereas other choices such as [110011] only has single perfect matching) I have tested my graph using hafnium_sample_graph from thewalrus library as well, and I got 231 samples of [111100] among 10000 samples, which is quite desirable.

Actual behavior

What I got after postselecting only those with ones and zeros (subspace used for the estimation of hafnian) was something like this,
[1 1 1 0 0 1]
[1 0 0 1 1 1]
[1 0 1 0 1 1]
[0 1 1 1 0 1]
[1 1 0 1 1 0]
[1 1 1 0 1 0]
[0 0 1 1 1 1]
[1 1 1 0 0 1]

only 8 cases out of 1000 samples and I could not see the answer case,i.e, [111100] ,to the maximum hafnian problem at all.

What's more, mean photon number at the output was around 0.97 whereas I aimed it at 4 to best see the 4 dimensional subgraph among my 6 dimensional adjacency matrix.

Reproduces how often

Reproduces nearly every time.

System information

Strawberry Fields: a Python library for continuous-variable quantum circuits.
Copyright 2018-2020 Xanadu Quantum Technologies Inc.

Python version:            3.10.9
Platform info:             macOS-13.4.1-arm64-arm-64bit
Installation path:         /Users/ryuminseok/anaconda3/lib/python3.10/site-packages/strawberryfields
Strawberry Fields version: 0.23.0
Numpy version:             1.23.5
Scipy version:             1.10.0
SymPy version:             1.12
NetworkX version:          3.1
The Walrus version:        0.20.0
Blackbird version:         0.5.0
XCC version:               0.3.0
TensorFlow version:        None

Source code


import numpy as np

matrix = np.array(
[[1,1,1,1,0,0],
[1,1,1,1,0,0],
[1,1,1,1,0,1],
[1,1,1,1,0,0],
[0,0,0,0,1,1],
[0,0,1,0,1,1]]
)-np.eye(6)
print(matrix)

import matplotlib.pyplot as plt
import networkx as nx
# Create the entire graph
gr = nx.Graph(matrix)

default_edge_color = 'gray'

edge_colors = {edge: default_edge_color for edge in gr.edges()}

node_color = 'orange'
nx.draw(gr, node_size=500,node_color=node_color, edge_color=[edge_colors[edge] for edge in gr.edges()],with_labels=True)

# Display the graph
plt.show()

import strawberryfields as sf

dim=np.shape(matrix)
print(dim[0])
"write the mean photon number you want to give at the output"
meanphoton=4
meanphotonpermode=meanphoton/dim[0]
print(meanphotonpermode)
result=sf.decompositions.graph_embed(matrix,meanphotonpermode)
squeeze=result[0]
uni=result[1]

setup=sf.decompositions.rectangular_phase_end(uni)
newt=setup[0]
"Print out the beam splitters"
print(np.round(newt,2))
ss=np.shape(newt)[0]

from strawberryfields import ops

nr_modes=dim[0]
prog = sf.Program(nr_modes)

with prog.context as q:
    for i in range(dim[0]) :
        ops.Sgate(squeeze[i]) |(q[i])
    for j in range(ss) :
        ops.BSgate(np.round(newt[j][2],2),np.round(newt[j][3],2)) |(q[newt[j][0]],q[newt[j][1]])

    ops.MeasureFock() | q


from strawberryfields import LocalEngine

eng = sf.Engine("fock", backend_options={"cutoff_dim": 4})
"Check if circuit is working as desired"
eng.run(prog)
eng.print_applied()

from pytictoc import TicToc

t=TicToc()
t.tic()

sample_array = []  # Array to store the samples
"Type in How many samples you want to put"
num=1000
for _ in range(num):
    results = eng.run(prog)
    sample=results.samples
    sample_array.append(sample)  # Add the results to the array

t.toc()

sample_array = np.array(sample_array)

peeled_array = np.array(sample_array)[:, 0]

mean_count = np.mean(peeled_array.sum(axis=1))
"What is the mean photon number of the entire output?"
print(mean_count)

concatenated_array = np.concatenate(sample_array, axis=0)
"Postselect only those with 0 or 1"
filtered_array = [arr for arr in concatenated_array if all(elem in {0, 1} for elem in arr)]
"Postselect 4 dim subgraph"
postselected_array = [arr for arr in filtered_array if np.sum(arr) == 4]

for arr in postselected_array:
    print(arr)

"Count the number of answer samples to MaxHaf problem"
target_sequence = np.array([1, 1, 1, 1, 0, 0])
count = 0

for arr in postselected_array:
    if np.array_equal(arr, target_sequence):
        count += 1

print(count) 

Tracebacks

No response

Additional information

I add information of Hafnian value of every 4 dimensional subgraph to my specific graph
 
Submatrix:

i)Perfect matching

ii) (prob)∝|HafA_s |^2


0123  (a case)

i) 3

ii) 9

xxx5  (10 cases)

i) 1

ii) 1

xxx4  (4 cases)

i) 0

ii) 0

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions