Contents¶

Section 1. Text of the blogpost¶

section 2. Python code supporting the blog post¶

The HTML for this notebook can be found at https://robhendrik.github.io/Popescu-Rohrlich-photons/

For the Jupyter notebook check: https://github.com/robhendrik/Popescu-Rohrlich-photons

Popescu-Rohrlich photons¶

In quantum mechanics, entangled photons show correlations, which can only be explained by what Einstein called 'Spooky action at a distance.' Entanglement was 'discovered' in the 1930s and first experimentally demonstrated for photons in the 1950s [1]. In the early days, a debate raged in science about whether one could explain these correlations through 'local hidden variables' or whether one needed to accept non-locality (i.e., the instantaneous effect of a measurement result at one place on the probability distribution for a measurement at another location). This debate was concluded in the 1980s when Alain Aspect provided experimental evidence for the non-locality of quantum mechanics [2].

Around the time that Alain Aspect published his results proving non-locality, Boris Tsirelson published his work on the limitations of non-locality in quantum mechanics [3]. Tsirelson stated that the non-local correlations in quantum mechanics could not exceed a specific value, known as the Tsirelson bound. Initially, scientists suspected that the Tsirelson bound was linked to the theory of relativity. Relativity theory states that information can not travel faster than the speed of light; potentially, that would also limit non-local correlations.

Sandu Popescu and Daniel Rohrlich demonstrated in 1994 that relativity theory could not explain the Tsirelson bound [4]. They showed that we can conceive non-locality beyond quantum mechanics (i.e., with correlation beyond the Tsirelson bound) that are all perfectly compatible with relativity theory. This triggers the question of why quantum mechanics limits non-locality. What would go wrong if Nature exceeds the Tsirelson bound? What would be the 'implausible consequences of superstrong non-locality' [5]?

This post builds on the ideas launched by Sandu Popescu and Daniel Rohrlich. We will modify the entanglement between photons to show 'superquantum' behavior. In reality, we cannot create 'superentangled' photons, but we will model their behavior in Python. We use the FockStateCircuit package developed to model quantum optical experiments (like quantum teleportation or the original Alain Aspect experiments) [6].

Entangled photons¶

The toy model used when studying non-locality consists of two photons entangled in their polarization state. Any polarization measurement on one of the photons gives a totally random result. Still, once one photon is measured, we know the probability of detecting the second photon for a given polarization direction.

The function P(β|α) is the probability of detecting the second photon at a polarization angle β, given that we detected the first photon at a polarization angle α. P(β|α) = cos(α-β)² for quantum mechanics. Note that the probability only depends on the difference between the angles.

The correlation used is the CHSH correlation [7], which cannot exceed 2√2 for quantum mechanics.

-2√2 ≤ <SS> + <ST> + <TS> - <TT> ≤ 2√2

Here, S and T represent measurements on the first and second photons. The correlation <ST> follows from the P(β|α) if measurement S is at polarization angle α for photon one and T at polarization angle β for photon two.

<ST> = 2P(β|α) - 1

If P(β|α) = 1, we always detect photon two in polarization β after detecting photon one in polarization α, and the correlation <ST> is 1. If P(β|α) = 0, we never see the second photon in polarization β after seeing photon one in polarization α, and the correlation <ST> is -1. If P(β|α) = 50%, the measurement of the second photon in polarization direction β is fully random, and <ST> is 0.

The EPR experiment¶

We must select specific angles α and β to demonstrate non-locality with two entangled photons. In a previous post, we calculated these angles (also those used for the Alain Aspect experiments).

For the first photon of the entangled pair, we take T to be horizontal polarization (α = 0 degrees) and S diagonal (α = 45 degrees). For the second photon, we take β = 22.5 degrees for S and β = 67.5 degrees for T. With these choices,

  • For SS, TS, and ST, we find |α-β| equal to 22.5 degrees; P(β|α) equals (2+√2)/4 ≈ 85%, and <SS>, <TS>, and <ST> are equal to ½√2.
  • For TT, |α-β| is equal to 67.5 degrees; P(β|α) equals (2-√2)/4 ≈ 15%, and <TT> is equal to -½√2.

For the CHSH correlation, we find a value precisely at the Tsirelson bound for the specific polarization angles we selected.

CHSH = <SS> + <ST> + <TS> - <TT> = 2√2

In this graph, the probability distribution P(β|α) is plotted as a function of the difference in detection angleα-β between the photons. The green dotted line shows the angle difference for correlations SS, TS, and TT, while the orange dotted line shows the angle difference for correlation ST.

image.png

Superentangled photons¶

The insight from Popescu and Rohrlich was that we can assume another probability distribution leading to higher correlations. Specifically, they proposed a probability distribution where P(β|α) = 1 if α-β ≤ 22.5 degrees and 0 if P(β|α) = 0 if α-β ≥ 67.5 degrees.

The graph below shows the probability distribution from quantum mechanics next to the distribution taken by Popescu and Rohrlich.

image-2.png

For the CHSH, the Popescu-Rohrlich correlation leads to remarkable results.

  • For SS, TS, and ST, we find |α-β| equal to 22.5 degrees; P(β|α) = 100%, and <SS>, <TS>, and <ST> are equal to 1
  • For TT, |α-β| is equal to 67.5 degrees; P(β|α) = 0%, and <TT> is equal to -1

The CHSH correlation for this probability distribution is equal to the maximum conceivable value of four, which is well above the Tsirelson bound.

CHSH = <SS> + <ST> + <TS> - <TT> = 4

The Popescu-Rohrlich photons show 'superquantum' behavior. Note that individually, these photons still behave as 'normal' photons. The only change we made is in their entanglement properties.

Superquantumness as a parameter¶

Popescu and Rohrlich propose one probability distribution leading to the maximum non-locality conceivable. We can also consider a gradual transition from quantum mechanics into superquantum correlations. We introduce a 'superquantumness' parameter q, which can take a value of 1 or higher. For q=1, the entanglement is quantum mechanical, and for the limit q to infinity, we obtain the Popescu-Rohrlich correlation. The probability distribution we take to achieve this is based on higher-order roots.

$$ \Large \begin{array}{lcll} P(\beta|\alpha) &= & \frac{1}{2}(1+\sqrt[q]{|\cos(2(α-β))|}) &\text{If: } \cos(2|\alpha - \beta|) \geq 0 \\[10pt] & & \frac{1}{2}(1-\sqrt[q]{|\cos(2(α-β))|}) &\text{If: } \cos(2|\alpha - \beta|) < 0 \\ \end{array} $$

When we plot the probability distribution for different values of q, we see the gradual transition from the quantum domain to the Popescu-Rohrlich correlation with increasing q.

image-3.png

Optical experiments with 'superentangled' photons¶

We have generalized the Popescu-Rohrlich concept for superentangled photons. By varying the 'superquantumness' parameter q, we can tune from regular quantum behavior at the Tsirelson bound to the highest conceivable correlations expected for Popescu-Rohrlich photons. We run these experiments using the FockStateCircuit package in Python [6].

We will first run two photon pairs through a simple optical set-up with half-wave plates. One pair will have a q-value of 1, and the other will have a q-value of 5. After the wave plates, we detect the photons to determine the correlation. We score '1' if we detect both photons with the same polarization and '-1' if we see them with orthogonal polarization. This picture summarizes the setup.

image-4.png

What do we expect to find?

  1. If the half-wave plates are aligned, we expect perfect correlation, and if the wave plates are at an angle of 45 degrees, perfect anti-correlation. At 22.5 degrees between the wave plates, we expect no correlation. These conditions should hold for all q-values.
  2. We expect that the shape of the correlation curve changes for different q-values, reflecting the 'superquantum' entanglement.
  3. We expect that if we change the detection for the first photon (by rotating the half-wave plate for that photon), we will also see a shift for the second photon.

image-5.png image-6.png

These graphs above show in blue the correlation for the photon pair with regular entanglement and in orange the correlation for the 'superentangled' pair. If we change the half-wave plate for the first photon, we see the expected behavior, including the shift in probability distribution for the second photon. In the model, we used regular optical components so the superentangled photons individually behave exactly as a photon; the only difference is in their entanglement.

As the next step, we will use superentanglement in the EPR/Alain Aspect experiment. We create a photon pair and send the photons to two observers. They can do a T or an S measurement. For the entangled photons, S and T correspond to polarization detection at 45 degrees and 0 degrees for the first photon and 22.5 degrees and 67.5 degrees for the second photon. The CHSH value will be the correlation <SS> + <ST> + <TS> - <TT>. For regular photons, this CHSH value cannot exceed 2√2, for 'superentangled photons', we expect to see CHSH correlation up to a value of four.

We use the same EPR optical circuit as in the FockStateCircuit tutorial [8]. The change we made is that we added 'no-signaling boxes' as input states, replacing the regular entangled state. On the output side, we need to evaluate the result with a dedicated function to capture the result. The code snippet below shows how these functions are called (for the complete code, see GitHub for the Jupyter Notebook belonging to this post).

CodeSnapPRgate.png

We see that, as expected, the CHSH correlation approaches the maximum value of four for increasing q-values. So, our photons show correlations well above the highest value possible in quantum mechanics when measured on the same optical setup used for regular photons.

image-7.png

Why is Nature not superquantum?¶

In this post, we discussed Sandu Popescu and Daniel Rohrlich's work. They conceived photons showing 'superentanglement'. These photons will break the Tsirelson bound for CHSH correlation, so they are not possible in quantum mechanics as we know it.

Popescu and Rohrlich showed that relativity theory does not lead to the Tsirelson bound. The 'superentangled' photons do not require faster-than-light communication. The same non-locality that is needed for regular entanglement could also enable superentanglement. This post showed that 'super entangled' photons can still behave as photons. They have the same behavior for optical components like beamsplitters or wave plates. So, in principle, superentanglement is possible. So, why does quantum mechanics limit non-locality? What would go wrong if Nature exceeded the Tsirelson bound?

The following posts will address this question from another perspective and explore what happens if we use superentangled particles as a resource for communication and information processing. Finding a structural difference between regular and super-entanglement for communication and information processing can shed new light on the upper limit for quantum correlations. Potentially, we can use information-theoretical arguments as a physical principle.


[1] C. S. Wu and I. Shaknov, "The angular correlation of scattered annihilation radiation," Phys. Rev. 77, 136 (1950).

[2] A. Aspect, P. Grangier and G. Roger, "Experimental Realization of Einstein-Podolsky-Rosen-Bohm Gedankenexperiment: A New Violation of Bell's Inequalities," Phys. Rev. Lett. 49, 91 (1982).

[3] B. Tsirelson, "Quantum generalizations of Bell's inequality," Letters in Mathematical Physics 4, 93, (1980).

[4] S. Popescu and D. Rohrlich, "Quantum Nonlocality as an Axiom," Foundations of Physics 24, 397 (1994).

[5] W. van Dam, "Implausible consequences of superstrong nonlocality," Nat Comput 12, 9–12 (2013).

[6] https://github.com/robhendrik/FockStateCircuit

[7] J. F. Clauser, M. A. Horne, A. Shimony, and B. A. Holt, "Proposed Experiment to Test Local Hidden-Variable Theories" Phys. Rev. Lett. 23, 880 (1969).

[8] See the notebook fock_state_circuit_tutorial.ipynb on Github (https://github.com/robhendrik/FockStateCircuit/tree/main/docs)

Python code supporting the blog post¶

In [ ]:
# Generic imports
import importlib
import math
import numpy as np
%matplotlib inline
import matplotlib.pyplot as plt
import matplotlib.lines
import matplotlib.colors
In [ ]:
# Install the package via: pip install FockStateCircuit
# See https://github.com/robhendrik/FockStateCircuit
import fock_state_circuit as fsc
In [ ]:
def superquantum_vs_angle(poincare_angle: float = 0, quantumness_value: float = 1) -> float:
    ''' Return the probability to detect the same result for both photons, so this 
        is the probability to get the same outcome behind two detectors.
        (or, the probability for both to pass through a polarizer, or both absorbed
        in the polarizer). Probability is calculated as a function of the angle
        between the stokes vectors for both photons on the Poincare sphere. 

        The model used is that the probability_amplitude scales as cos(angle)**(1/k)
        The probability is then (1/2)*(probability_amplitude + 1)

        Note1: The angle is the angle on the Poincare sphere, which is 2x the angle
        between linear polarization directions. For orthogonal polarization the angle
        on the Poincare sphere is 180 degrees.

        Note2: The probability to actually detect two photons is half this value, as 
        there is 50% to detect no photon behind either polarizer and 50% to actually 
        detect two photons.
    '''
    vector1 = [1,0,0]
    vector2 = [np.cos(poincare_angle),np.sin(poincare_angle),0]
    return fsc._probability_from_stokes_vectors(vector1, vector2, quantumness_value=quantumness_value)

def PopescuRohrlich_vs_angle(poincare_angle: float = 0) -> float:
    ''' Return the probability to detect the same result for both photons, so this 
    is the probability to get the same outcome behind two detectors.
    (or, the probability for both to pass through a polarizer, or both absorbed
    in the polarizer). Probability is calculated as a function of the angle
    between the stokes vectors for both photons on the Poincare sphere. 

    The model used is that from Popescu Rohrlich (1994)

    Note1: The angle is the angle on the Poincare sphere, which is 2x the angle
    between linear polarization directions. For orthogonal polarization the angle
    on the Poincare sphere is 180 degrees.

    Note2: The probability to actually detect two photons is half this value, as 
    there is 50% to detect no photon behind either polarizer and 50% to actually 
    detect two photons.
    '''
    while poincare_angle > 2*np.pi:
        poincare_angle = poincare_angle - 2*np.pi
    while poincare_angle < 0:
        poincare_angle = poincare_angle + 2*np.pi

    if poincare_angle <= np.pi/4 or poincare_angle >= (7/4)*np.pi:
        return 1
    if poincare_angle >= np.pi*3/4 and poincare_angle <= (5/4)*np.pi:
        return 0
    if poincare_angle > np.pi/4 and poincare_angle < (3/4)*np.pi:
        return ((3/4)*np.pi - poincare_angle)/(np.pi/2)
    if poincare_angle > np.pi*5/4 and poincare_angle < (7/4)*np.pi:
        return (poincare_angle - np.pi*5/4)/(np.pi/2)
In [ ]:
def draw_the_curve(fullcurve):
    # Create the x-axis for the curves and initialize the graph
    N = 600
    angles = [(a)*(np.pi/N) for a in range(N)] # range from 0 to pi in N steps
    fig, ax = plt.subplots(figsize=(15,8))
        
    # Draw the quantum curve
    quantum_probability = [superquantum_vs_angle(poincare_angle=2*angle,quantumness_value=1) for angle in angles]
    ax.plot(angles,quantum_probability, color = 'blue')
    ax.set_title('Probability for detecting the second photon after detecting the first one as function of angle between polarization directions')
    ax.set_xlabel('Angle between detection orientation for first and second photon,' + r'$|\alpha - \beta|$' + ' (radians)')
    ax.set_ylabel('Probability for detecting the 2nd photon at angle '+ r'$\beta$' + 'after detecting the 1st at angle '+ r'$\alpha$')

    # Add the annotation for the quantum curve
    angle = 2
    value = superquantum_vs_angle(poincare_angle=2*angle,quantumness_value=1)
    ax.annotate('Probability curve for \nquantum mechanics', xy=(angle,value), xytext=(1.4, 0.3),
                arrowprops=dict(facecolor='blue', shrink=0.05))

    if fullcurve == True:
        # Draw the Popescu-Rohrlich curve
        N = 600
        PR_distribution = [PopescuRohrlich_vs_angle(poincare_angle=2*angle) for angle in angles]
        ax.plot(angles,PR_distribution, color = 'purple')

        # Add the annotation for the Popescu-Rohrlich curve
        angle = 2.6
        value = PopescuRohrlich_vs_angle(poincare_angle=2*angle)
        ax.annotate('Probability curve for \nPopescu-Rohrlich', xy=(angle,value), xytext=(2, 0.8),
                    arrowprops=dict(facecolor='purple', shrink=0.05))

    # SS, TS and ST orientation
    angle = 22.5 * np.pi/180
    value = (2 + np.sqrt(2))/4
    ax.plot([angle,angle],[0,1], color = 'green', linestyle = ':')
    ax.plot([angle],[value], color = 'green', linestyle = 'none', marker = 'o')
    ax.text(angle-0.05,value, "85% at 22.5 degrees\nfor QM", horizontalalignment='right',verticalalignment='top',)
    if fullcurve == True:
        value = 1
        ax.plot([angle],[value], color = 'green', linestyle = 'none', marker = 'o')
        ax.text(angle+0.05,value, "100% at 22.5 degrees\nfor PR", horizontalalignment='left',verticalalignment='top')

    # TT orientation
    angle = 67.5 * np.pi/180
    value = (2 - np.sqrt(2))/4
    ax.plot([angle,angle],[0,1], color = 'orange', linestyle = ':')
    ax.plot([angle],[value], color = 'orange', linestyle = 'none', marker = 'o')
    ax.text(angle+0.05,value, "15% at 67.5 degrees\nfor QM")
    if fullcurve == True:
        value = 0
        ax.plot([angle],[value], color = 'orange', linestyle = 'none', marker = 'o')
        ax.text(angle-0.05,value, "0% at 67.5 degrees\nfor PR", horizontalalignment='right',verticalalignment='bottom')

    plt.show()
In [ ]:
draw_the_curve(False)
No description has been provided for this image
In [ ]:
draw_the_curve(True)
No description has been provided for this image
In [ ]:
N = 600
fig, ax = plt.subplots(figsize=(15,8))
q_values = [1,2,4,8,16,32]

# # Draw the curves for 'superentanglement'
for q in q_values:
    angles = [(a)*(np.pi/N) for a in range(N)]
    quantum_probability = [superquantum_vs_angle(poincare_angle=2*angle,quantumness_value=q) for angle in angles]
    ax.plot(angles,quantum_probability)
ax.set_title('Superquantum probability for q = [1,2,4,8,16,32]')
ax.set_xlabel('Angle between detection orientation for first and second photon,' + r'$|\alpha - \beta|$' + ' (radians)')
ax.set_ylabel('Probability for detecting the 2nd photon at angle '+ r'$\beta$' + 'after detecting the 1st at angle '+ r'$\alpha$')

# SS, TS and ST orientation
angle = 22.5 * np.pi/180
value = superquantum_vs_angle(poincare_angle=2*angle,quantumness_value=max(q_values))
ax.plot([angle,angle],[0,1], color = 'green', linestyle = ':')
ax.plot([angle],[value], color = 'green', linestyle = 'none', marker = 'o')
text = str(int(value*100))+"% at 22.5 degrees\nfor q=" + str(int(max(q_values)))
ax.annotate(text, xy=(angle,value), xytext=(0.9, 0.9), arrowprops={'arrowstyle': '->', 'shrinkA' : 10, 'shrinkB' : 10}, va='center')

# ST orientation
angle = 67.5 * np.pi/180
value = superquantum_vs_angle(poincare_angle=2*angle,quantumness_value=max(q_values))
ax.plot([angle,angle],[0,1], color = 'orange', linestyle = ':')
ax.plot([angle],[value], color = 'orange', linestyle = 'none', marker = 'o')
text = str(int(value*100))+"% at 67.5 degrees\nfor q=" + str(int(max(q_values)))
ax.annotate(text, xy=(angle,value), xytext=(1.4, 0.05), arrowprops={'arrowstyle': '->', 'shrinkA' : 10, 'shrinkB' : 10}, va='center')

# SS, TS and ST orientation
angle = 22.5 * np.pi/180
value = (2 + np.sqrt(2))/4
ax.plot([angle,angle],[0,1], color = 'green', linestyle = ':')
ax.plot([angle],[value], color = 'green', linestyle = 'none', marker = 'o')
ax.text(angle-0.05,value, "85% at 22.5 degrees\nfor QM", horizontalalignment='right',verticalalignment='top',)

# TT orientation
angle = 67.5 * np.pi/180
value = (2 - np.sqrt(2))/4
ax.plot([angle,angle],[0,1], color = 'orange', linestyle = ':')
ax.plot([angle],[value], color = 'orange', linestyle = 'none', marker = 'o')
ax.text(angle+0.05,value, "15% at 67.5 degrees\nfor QM")

# Add the annotation for the quantum curve
angle = 2.5
value = superquantum_vs_angle(poincare_angle=2*angle,quantumness_value=1)
ax.annotate('Probability curve for \nquantum mechanics (q=1)', xy=(angle,value), xytext=(2.6, 0.5),
            arrowprops=dict(facecolor='blue', shrink=0.05))

# Add the annotation for the Popescu-Rohrlich curve
angle = (3/4)*np.pi+0.01
value = superquantum_vs_angle(poincare_angle=2*angle,quantumness_value=max(q_values))
ax.annotate('Probability curve for q='+str(int(max(q_values))), xy=(angle,value), xytext=(1.5, 0.8),
            arrowprops=dict(facecolor='purple', shrink=0.05))

plt.show()
No description has been provided for this image
In [ ]:
# draw the circuit with the Popescu-Rohrlich gate which creates the right correlation
# for visualization the classical channels are removed
popescu_rohrlich_correlations = [{'channels_Ah_Av_Bh_Bv':[0,1,2,3],'quantumness_indicator':1},
                                {'channels_Ah_Av_Bh_Bv':[4,5,6,7],'quantumness_indicator':5}]
angle_first = 0
circuit = fsc.FockStateCircuit(length_of_fock_state=3,no_of_optical_channels=8,no_of_classical_channels=0,circuit_name ="Circuit with Popescu-Rohrlich gate.")
circuit.popescu_rohrlich_correlation_gate(pr_correlation=popescu_rohrlich_correlations)
circuit.half_wave_plate(channel_horizontal=2,channel_vertical=3,angle=angle)
circuit.half_wave_plate(channel_horizontal=6,channel_vertical=7,angle=angle)
circuit.half_wave_plate(channel_horizontal=0,channel_vertical=1,angle=angle_first)
circuit.half_wave_plate(channel_horizontal=4,channel_vertical=5,angle=angle_first)
circuit.draw()
No description has been provided for this image
In [ ]:
N = 20
angles = [0,np.pi/3]

popescu_rohrlich_correlations = [{'channels_Ah_Av_Bh_Bv':[0,1,2,3],'quantumness_indicator':1},
            {'channels_Ah_Av_Bh_Bv':[4,5,6,7],'quantumness_indicator':5}]
for angle_first in angles:
    dict_for_plotting = dict([])
    for angle in [(a/N)*np.pi/2 for a in range(N)]:
        circuit = fsc.FockStateCircuit(length_of_fock_state=3,no_of_optical_channels=8,no_of_classical_channels=8)
        circuit.popescu_rohrlich_correlation_gate(pr_correlation=popescu_rohrlich_correlations)
        circuit.half_wave_plate(channel_horizontal=2,channel_vertical=3,angle=angle)
        circuit.half_wave_plate(channel_horizontal=6,channel_vertical=7,angle=angle)
        circuit.half_wave_plate(channel_horizontal=0,channel_vertical=1,angle=angle_first)
        circuit.half_wave_plate(channel_horizontal=4,channel_vertical=5,angle=angle_first)
        circuit.measure_optical_to_classical(optical_channels_to_be_measured=[n for n in range(8)],classical_channels_to_be_written=[n for n in range(8)])

        collection = fsc.CollectionOfStates(fock_state_circuit=circuit,input_collection_as_a_dict=dict([]))
        state = fsc.State(collection_of_states=collection)
        state.initial_state = 'pr_correlations'
        collection.add_state(state)
        output_collection = circuit.evaluate_circuit(collection_of_states_input=collection)

        channel_combis_for_correlation = [(0,2),(4,6)]
        label_for_channel_combinations = ['first pair, q = 1','second pair, q = 5']

        correlations = output_collection.plot_correlations(channel_combis_for_correlation=channel_combis_for_correlation,
                                                           correlation_output_instead_of_plot=True)['pr_correlations']
        lst = []
        lst.append({'output_state': 'first pair, q = 1', 'probability': correlations[0]})
        lst.append({'output_state': 'second pair, q = 5', 'probability': correlations[1]})
        dict_for_plotting.update({str(np.round(angle/np.pi,3)) + ' pi': lst})

    fsc.plot_correlations_from_dict(dict_for_plotting)
No description has been provided for this image
No description has been provided for this image
In [ ]:
aspect_EPR_circuit = fsc.FockStateCircuit(length_of_fock_state = 3, 
                                no_of_optical_channels = 4,
                                no_of_classical_channels=4,
                                circuit_name='aspect_EPR_circuit'
                                )

popescu_rohrlich_correlations = [{'channels_Ah_Av_Bh_Bv':[0,1,2,3], 'quantumness_indicator': 1 }]

aspect_EPR_circuit.popescu_rohrlich_correlation_gate(pr_correlation=popescu_rohrlich_correlations)

aspect_EPR_circuit.wave_plate_classical_control(optical_channel_horizontal=0,
                                     optical_channel_vertical=1,
                                     classical_channel_for_orientation=0,
                                     classical_channel_for_phase_shift=2)
aspect_EPR_circuit.wave_plate_classical_control(optical_channel_horizontal=2,
                                     optical_channel_vertical=3,
                                     classical_channel_for_orientation=1,
                                     classical_channel_for_phase_shift=3)

aspect_EPR_circuit.measure_optical_to_classical(optical_channels_to_be_measured=[0,1,2,3],
                                                    classical_channels_to_be_written=[0,1,2,3]
                                                    )
aspect_EPR_circuit.draw()
No description has been provided for this image
In [ ]:
def correlation_to_CHSH(correlation):
    return correlation['AB'] - correlation['Ab'] + correlation['aB'] + correlation['ab']

measurements = {
                'AB': [0, np.pi/16,np.pi,np.pi], 
                'Ab': [0, np.pi/16 +  np.pi/8 ,np.pi,np.pi], 
                'aB': [np.pi/8, np.pi/16,np.pi,np.pi], 
                'ab': [np.pi/8, np.pi/16+np.pi/8,np.pi,np.pi]
                }

CHSHs = []
q_values = [n/5 for n in range(5,100)]
for quantumness in q_values:   

    CHSH_components = dict([])
    for label, measurement in measurements.items():
      
        popescu_rohrlich_correlations= [{
                            'channels_Ah_Av_Bh_Bv':[0,1,2,3],
                            'quantumness_indicator':quantumness
                            }]
        
        aspect_EPR_circuit = fsc.FockStateCircuit(
                            length_of_fock_state = 3, 
                            no_of_optical_channels = 4,
                            no_of_classical_channels=4,
                            circuit_name='aspect_EPR_circuit'
                            )
        aspect_EPR_circuit.popescu_rohrlich_correlation_gate(
                            pr_correlation=popescu_rohrlich_correlations
                            )

        aspect_EPR_circuit.wave_plate_classical_control(optical_channel_horizontal=0,
                                     optical_channel_vertical=1,
                                     classical_channel_for_orientation=0,
                                     classical_channel_for_phase_shift=2)
        aspect_EPR_circuit.wave_plate_classical_control(optical_channel_horizontal=2,
                                     optical_channel_vertical=3,
                                     classical_channel_for_orientation=1,
                                     classical_channel_for_phase_shift=3)

        aspect_EPR_circuit.measure_optical_to_classical(optical_channels_to_be_measured=[0,1,2,3],
                                                    classical_channels_to_be_written=[0,1,2,3]
                                                    )
        
        initial_collection_of_states = fsc.CollectionOfStates(fock_state_circuit=aspect_EPR_circuit, 
                                                        input_collection_as_a_dict=dict([]))
        state = fsc.State(collection_of_states=initial_collection_of_states)
        state.classical_channel_values = measurement
        state.initial_state = 'pr_correlations'
        initial_collection_of_states.add_state(state)
        result = aspect_EPR_circuit.evaluate_circuit(
            collection_of_states_input=initial_collection_of_states)
        
        channel_combis_for_correlation = [(0,2)]
        
        correlations = result.plot_correlations(channel_combis_for_correlation=channel_combis_for_correlation,
                                                           correlation_output_instead_of_plot=True)['pr_correlations']
        CHSH_components.update({label:correlations[0]})
    CHSHs.append(correlation_to_CHSH(CHSH_components))
fig, ax = plt.subplots()
ax.set(xlabel='Quantumness of the entanglement (q)', ylabel='CHSH value',
       title='CHSH value for superquantum entanglement')
ax.plot(q_values,CHSHs)
plt.show()
No description has been provided for this image

Erroneous function for proability¶

In a previous version we used $$ \Large \begin{array}{lcll} P(\beta|\alpha) &= & \frac{1}{2} \sqrt[q]{|\cos(|\alpha - \beta|)|} &\text{If: } \cos(|\alpha - \beta|) \geq 0 \\[10pt] & & -\frac{1}{2} \sqrt[q]{|\cos(|\alpha - \beta|)|}&\text{If: } \cos(|\alpha - \beta|) < 0 \\ \end{array} $$

Where the correct value (i.e., what is implemented in the code is) $$ \Large \begin{array}{lcll} P(\beta|\alpha) &= & \frac{1}{2}(1+\sqrt[q]{|\cos(2(α-β))|}) &\text{If: } \cos(2|\alpha - \beta|) \geq 0 \\[10pt] & & \frac{1}{2}(1-\sqrt[q]{|\cos(2(α-β))|}) &\text{If: } \cos(2|\alpha - \beta|) < 0 \\ \end{array} $$

In [ ]:
quantumness = 20
wrong_ps = []
correct_ps = []
coded_ps = []
for delta in [np.pi*n/200 for n in range(201)]:
    if np.cos(delta) >= 0:
        Perror = (1/2) * np.power(np.cos(delta),1/quantumness)
    else:
        Perror = -1*(1/2) * np.power(np.abs(np.cos(delta)),1/quantumness)
    wrong_ps.append(Perror)
    if np.cos(2*delta) >= 0:
        Pcorrect = (1/2) * (1 + np.power(np.cos(2*delta),1/quantumness))
    else:
        Pcorrect = (1/2) * (1 - np.power(np.abs(np.cos(2*delta)),1/quantumness))
    correct_ps.append(Pcorrect)
    P_code = superquantum_vs_angle(2*delta,quantumness_value=quantumness)
    coded_ps.append(P_code)

fig, ax = plt.subplots()

ax.plot([np.pi*n/200 for n in range(201)], wrong_ps, label = 'Probabilities with wrong formula', linestyle = 'solid', marker = 'none', color='red')
ax.plot([np.pi*n/200 for n in range(201)], correct_ps, label = 'Probabilities with correct formula', linestyle = 'solid', marker = 'none', color='green')
ax.plot([np.pi*n/200 for n in range(201)], coded_ps, label = 'Probabilities used in code', linestyle = 'none', marker = 'x', color='black')
ax.legend()


plt.show()
No description has been provided for this image
In [ ]:
fsc.about()
FockStateCircuit: Quantum Optics with Fock States for Python
Copyright (c) 2023 and later.
Rob Hendriks

FockStateCircuit:            1.0.5
CollectionOfStates:          1.0.1
State:                       1.0.1
ColumnOfStates:              1.0.0
InterferenceGroup:           1.0.0
CollectionOfStateColumns:    1.0.0
OpticalNodes:                1.0.0
BridgeNodes:                 1.0.0
CustomNodes:                 1.0.0
ControlledNodes:             1.0.0
MeasurementNodes:            1.0.0
ClassicalNodes:              1.0.0
SpectralNodes:               1.0.0
QuantumOperatorNodes:        1.0.0
temporal_functions:          1.0.0
Numpy Version:               1.26.4
Matplotlib version:          3.8.4