<jupyter_start><jupyter_text>QNLP exampleThis notebook runs an example encoding of **"John rests inside, Mary walks outside"**. We initially define mappings for each of these tokens to a pre-defined set of basis tokens. These tokens are next represented as binary integers, and encoded using the QNLP runtime.A test pattern is then constructed using **"adults stand inside"**, and the encoded patterns are queried and sampled to determine the closest encoded data, as learned from the given sentences.The basis tokens are defined as:$$\begin{equation*}\begin{array}{c|c|c}\mathbf{Dataset} & \mathbf{Word} & \mathbf{Bin.~Index} \\\hline{n_s} & \mathrm{adult} & 00 \\{n_s} & \mathrm{child} & 11 \\{n_s} & \mathrm{smith} & 10 \\{n_s} & \mathrm{surgeon} & 01 \\\\{v} & \mathrm{stand} & 00 \\{v} & \mathrm{move} & 01 \\{v} & \mathrm{sit} & 11 \\{v} & \mathrm{sleep} & 10 \\\\{n_o} & \mathrm{inside} & 0 \\{n_o} & \mathrm{outside} & 1 \\\end{array}\end{equation*}$$We define the mapping of *"John rests inside, Mary walks outside"* to this basis as:$$\begin{equation*}\begin{array}{c|c|c}\mathbf{Dataset} & \mathbf{Word} & \mathbf{State} \\\hline{n_s} & \mathrm{John} & (\vert 00 \rangle + \vert 10 \rangle)/\sqrt{2} \\{n_s} & \mathrm{Mary} & (\vert 01 \rangle + \vert 11 \rangle)/\sqrt{2} \\{v} & \mathrm{walk} & (\vert 00 \rangle + \vert 01 \rangle)/\sqrt{2} \\{v} & \mathrm{rest} & (\vert 10 \rangle + \vert 11 \rangle)/\sqrt{2} \\{n_o} & \mathrm{inside} & \vert 0 \rangle  \\{n_o} & \mathrm{outside} & \vert 1 \rangle  \\\end{array}\end{equation*}$$Lastly, our test pattern is mapped onto the basis as **"adults stand inside"** $\rightarrow |00000\rangle$. The remainder of the notebook will encode the data using the given basis, encode the test pattern, and query the resulting register state using the Hamming distance to determine closeness.<jupyter_code>import os
os.environ["OMP_NUM_THREADS"] = "4"
%matplotlib inline
from matplotlib import rc
rc('text', usetex=True)
import matplotlib.pyplot as plt<jupyter_output><empty_output><jupyter_text>Import the C++ backed simulator package and the preprocessing Python package<jupyter_code>from PyQNLPSimulator import PyQNLPSimulator as p
import QNLP as q
import numpy as np
from itertools import product
from tqdm import tqdm<jupyter_output><empty_output><jupyter_text>Predefine necessary data for encoding and calculate resources requirements<jupyter_code># Define basis tokens encoding and decoding dicts
encoding_dict = {"ns" : { "adult":0b00, "child":0b11, "smith":0b10, "surgeon":0b01 },
                 "v"  : { "stand":0b00, "move":0b01, "sit":0b11, "sleep":0b10 },
                 "no" : { "inside":0b0,"outside":0b1 }
                }

decoding_dict = {"ns" : { 0b00:"adult", 0b11:"child", 0b10:"smith", 0b01:"surgeon"},
                 "v"  : { 0b00:"stand", 0b01:"move", 0b11:"sit", 0b10:"sleep"},
                 "no" : { 0b0:"inside", 0b1:"outside"}
                }
len_reg_memory = 5
len_reg_auxiliary = len_reg_memory + 2
num_qubits = len_reg_memory + len_reg_auxiliary
num_bin_pattern = 8

test_pattern = 0<jupyter_output><empty_output><jupyter_text>Create simulator object<jupyter_code>use_fusion = False
sim = p(num_qubits, use_fusion)
num_exps = 5000
normalise = True
# Set up registers to store indices
reg_memory = [0]*len_reg_memory;
for i in range(len_reg_memory):
    reg_memory[i] = i + len_reg_auxiliary

reg_auxiliary = [0]*len_reg_auxiliary
for i in range(len_reg_auxiliary-2):
    reg_auxiliary[i] = i + 2
reg_auxiliary[-2] = 0
reg_auxiliary[-2] = 1
# data for encoding using the given basis
"John rests outside, Mary walks inside"
sentences = [
    [{"john" :   [encoding_dict["ns"]["adult"], encoding_dict["ns"]["smith"]]},
    {"rest" :    [encoding_dict["v"]["sit"], encoding_dict["v"]["sleep"]]},
    {"inside" :  [encoding_dict["no"]["inside"]] }],

    [{"mary" :   [encoding_dict["ns"]["child"], encoding_dict["ns"]["surgeon"]]},
    {"walk" :    [encoding_dict["v"]["stand"],  encoding_dict["v"]["move"]]},
    {"outside" :[encoding_dict["no"]["outside"]] }],
]
sentences
# Parse the sentences and generate the required bit-patterns
superpos_patterns = [list(sentences[0][i].values())[0] for i in range(3)]

#Create list for the patterns to be encoded
vec_to_encode = []

# Generate bit-patterns from sentences and store in vec_to_encode
for idx,sentence in enumerate(sentences):
    superpos_patterns = list( product( list(sentence[0].values())[0], list(sentence[1].values())[0], list(sentence[2].values())[0] ) )
    # Generate all combinations of the bit-patterns for superpos states
    for patt in superpos_patterns: 
        num = q.utils.encode_binary_pattern_direct(patt, encoding_dict)
        vec_to_encode.extend([num])
        
vec_to_encode
for i in [12, 8, 14, 10, 19, 23, 17, 21]:
    print(q.utils.decode_binary_pattern(i,decoding_dict))
# Init result counter
count_even = {}
for i in vec_to_encode:
    count_even.update({i : 0})
%%time
# Test of equally encoded bit patterns
for exp in tqdm(range(num_exps)):

    sim.initRegister()

    # Encode
    sim.encodeBinToSuperpos_unique(reg_memory, reg_auxiliary, vec_to_encode, len_reg_memory)
    
    val = sim.applyMeasurementToRegister(reg_memory, normalise)
    count_even[val] += 1;

# Test value to compare
test_pattern = 0; # 00000 ->  adult, stand, inside

# Init result counter
count = {}
for i in vec_to_encode:
    count.update({i : 0})
# Repeated shots of experiment
for exp in tqdm(range(num_exps)):

    sim.initRegister()

    # Encode
    sim.encodeBinToSuperpos_unique(reg_memory, reg_auxiliary, vec_to_encode, len_reg_memory)

    # Compute Hamming distance between test pattern and encoded patterns
    sim.applyHammingDistanceRotY(test_pattern, reg_memory, reg_auxiliary, len_reg_memory)

    # Measure
    sim.collapseToBasisZ(reg_auxiliary[len_reg_auxiliary-2], 1)
    
    val = sim.applyMeasurementToRegister(reg_memory, normalise)
    count[val] += 1;

xlab_str = [",".join(q.utils.decode_binary_pattern(i, decoding_dict))  for i in list(count.keys())]
xlab_bin = ["{0:0{num_bits}b}".format(i, num_bits=len_reg_memory) for i in list(count.keys())]
[i[0]+"\n"+i[1] for i in zip(xlab_str,xlab_bin)]

# Sort histograms by P
hist_list_even = list(zip(
    [i[0]+r" $\vert$"+i[1]+r"$\rangle$" for i in zip(xlab_str,xlab_bin)],
    [i/np.sum(list(count_even.values())) for i in list(count_even.values())]
))
hist_list = list(zip(
    [i[0]+r" $\vert$"+i[1]+r"$\rangle$" for i in zip(xlab_str,xlab_bin)],
    [i/np.sum(list(count.values())) for i in list(count.values())]
))
#hist_list = sorted(hist_list, key=lambda pr: pr[1], reverse=True)
labels = [x[0] for x in hist_list_even]
even_vals = [y[1] for y in hist_list_even]
post_vals = [y[1] for y in hist_list]

x = np.arange(len(labels))  # the label locations
width = 0.35  # the width of the bars

fig, ax = plt.subplots()

rects1 = ax.bar(x - width/2, even_vals, width, label='Even superposition measurement')
rects2 = ax.bar(x + width/2, post_vals, width, label='Post-selection measurement')

# Add some text for labels, title and custom x-axis tick labels, etc.
ax.set_ylabel(r"$P(\textrm{{{}}})$".format("adult, sleep, outside"),fontsize=24)
ax.set_xticks(x)
ax.tick_params(axis='both', which='major', labelsize=16)
ax.set_xticklabels(labels, rotation=-30, ha="left",fontsize=16)
ax.legend(fontsize=16)

plt.axhline(y=1.0/len(count), color='crimson', linestyle="--")
plt.text(len(count)-0.1, 1.0/(len(count)), '$1/\sqrt{n}$', horizontalalignment='left', verticalalignment='center', fontsize=16)
plt.tight_layout()
fig.set_size_inches(20, 12, forward=True)
#plt.savefig("qnlp_vector_measurement.pdf")<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.15644572025052192, 'fraction_numerical': 0.0255741127348643, 'mean_word_length': 4.7936507936507935, 'pattern_counts': {'":': 10, '<': 17, '<?xml version=': 0, '>': 18, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 1, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '4', 'dir': 'jupyter-structured-clean-dedup', 'id': '393249', 'license': 'Apache-2.0', 'n_tokens_mistral': 2850, 'n_tokens_neox': 2685, 'n_words': 681, 'path': 'modules/py/nb/QNLP_Python.ipynb', 'repo_name': 'ICHEC/QNLP', 'size': '7664'}