Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
NVIDIA
GitHub Repository: NVIDIA/cuda-q-academic
Path: blob/main/quick-start-to-quantum/interactive_widget/borns_rule.py
1127 views
1
def create_borns_rule_widget():
2
# Clear any existing widgets
3
import IPython.display
4
IPython.display.clear_output()
5
# Widget to visualize Born's Rule for the state |ψ⟩ = cos(θ/2)|0⟩ + sin(θ/2)e^{iφ}|1⟩ along with its Bloch sphere representation
6
import cudaq
7
import ipywidgets as widgets
8
from ipywidgets import interactive_output, HBox, VBox
9
from IPython.display import display, clear_output
10
import numpy as np
11
import matplotlib.pyplot as plt
12
13
# Kernel to initialize a qubit and set it to the state |ψ⟩ = cos(θ/2)|0⟩ + sin(θ/2)e^{iφ}|1⟩
14
@cudaq.kernel
15
def state_kernel(theta: float, phi: float):
16
qubit = cudaq.qubit()
17
ry(theta, qubit)
18
rz(phi, qubit)
19
20
# Function to update the Bloch sphere plot based on the slider values
21
def update_bloch_sphere(theta, phi):
22
with output_bloch:
23
clear_output(wait=True) # Clear previous output
24
state = cudaq.get_state(state_kernel, theta, phi)
25
bloch_sphere = cudaq.add_to_bloch_sphere(state)
26
cudaq.show(bloch_sphere)
27
28
# Function to update the probability amplitude bar chart
29
def update_prob_chart(theta, phi):
30
with output_prob:
31
clear_output(wait=True) # Clear previous output
32
alpha_squared = np.cos(theta/2)**2
33
beta_squared = np.sin(theta/2)**2
34
35
plt.figure(figsize=(4,4)) # Make the figure square and smaller
36
plt.bar(['0', '1'], [alpha_squared, beta_squared], color=['#76b900', '#76b900']) # NVIDIA green
37
plt.ylim(0, 1)
38
plt.ylabel('Probability')
39
plt.title('Measurement Probability Distribution')
40
plt.show()
41
42
# Function to display the state in plain text with rounded angles
43
def update_state_output(theta, phi):
44
with output_state:
45
clear_output(wait=True) # Clear previous output
46
theta_half = round(theta / 2, 3)
47
phi = round(phi, 3)
48
expression = f"|ψ⟩ = cos({theta_half})|0⟩ + sin({theta_half})e^(i{phi})|1⟩"
49
print('|ψ⟩ = cos(θ/2)|0⟩ + sin(θ/2)e^(iφ)|1⟩ = α|0⟩ + β|1⟩')
50
print(expression)
51
alpha = np.cos(theta_half)
52
beta = np.sin(theta_half) * np.exp(1j * phi)
53
alpha_squared = np.abs(alpha)**2
54
beta_squared = np.abs(beta)**2
55
print(f"|α|^2: {alpha_squared:.3f}")
56
print(f"|β|^2: {beta_squared:.3f}")
57
58
# Create interactive sliders for angles
59
slider_theta = widgets.FloatSlider(min=0, max=2*np.pi, step=0.01, value=0, description='θ:', continuous_update=False)
60
slider_phi = widgets.FloatSlider(min=0, max=2*np.pi, step=0.01, value=0, description='φ:', continuous_update=False)
61
62
# Add a new title to the widget
63
title = widgets.HTML(value="<h3>Visualize Born's Rule for the State |ψ⟩ with Varying Angles θ and φ (in radians)</h3>")
64
65
# Create output widgets
66
output_bloch = widgets.Output()
67
output_prob = widgets.Output()
68
output_state = widgets.Output()
69
70
def update_all(theta, phi):
71
update_bloch_sphere(theta, phi)
72
update_prob_chart(theta, phi)
73
update_state_output(theta, phi)
74
75
# Create the interactive output and immediately call update_all with initial values
76
interactive_plot = interactive_output(update_all, {'theta': slider_theta, 'phi': slider_phi})
77
78
# Arrange sliders horizontally
79
slider_box = HBox([slider_theta, slider_phi])
80
81
# Single display statement for the entire widget
82
display(VBox([
83
title,
84
output_state,
85
slider_box,
86
HBox([output_bloch, output_prob])
87
]))
88
89
# When imported, this will create and display a new widget
90
if __name__ == '__main__':
91
widget = create_borns_rule_widget()
92
display(widget)
93