Path: blob/main/quick-start-to-quantum/interactive_widget/CNOT_visualization.py
1120 views
# Generates an interactive visualization of the CNOT gate1def create_CNOT_widget():2# Clear any existing widgets3import IPython.display4IPython.display.clear_output()56import cudaq7import numpy as np8import matplotlib.pyplot as plt9from IPython.display import display, HTML, clear_output10import ipywidgets as widgets11from ipywidgets import interactive_output, HBox, VBox1213@cudaq.kernel14def initialize(qubits: cudaq.qview, state: list[int]):15"""Kernel to initialize the state indicated by the given list160: |0>, 1: |1>, 2: |+>, 3: |->"""17for idx in range(len(state)):18if state[idx] == 1:19x(qubits[idx])20elif state[idx] == 2: # |+>21h(qubits[idx])22elif state[idx] == 3: # |->23x(qubits[idx])24h(qubits[idx])2526@cudaq.kernel27def CNOT_example(state: list[int]):28"""Apply CNOT to the state given by the state numbers"""29qubits = cudaq.qvector(2)30# Initialize state31initialize(qubits, state)32# Apply CNOT33x.ctrl(qubits[0], qubits[1])3435# Function to format complex number nicely36def format_complex(c):37if abs(c.imag) < 1e-10: # Real number38return f"{c.real:.3f}"39elif abs(c.real) < 1e-10: # Imaginary number40if abs(c.imag - 1) < 1e-10:41return "i"42elif abs(c.imag + 1) < 1e-10:43return "-i"44else:45return f"{c.imag:.3f}i"46else:47sign = "+" if c.imag >= 0 else "-"48return f"{c.real:.3f}{sign}{abs(c.imag):.3f}i"4950# Function to update the circuit diagram51def update_circuit(q0_state, q1_state):52with output_circuit:53clear_output(wait=True)54print("Circuit:")55state_list = [q0_state, q1_state]56print(cudaq.draw(CNOT_example, state_list))5758# Function to update the probability distribution59def update_prob_chart(q0_state, q1_state):60with output_prob:61clear_output(wait=True)6263# Get the state after circuit execution64state_list = [q0_state, q1_state]65state = cudaq.get_state(CNOT_example, state_list)6667# Calculate probabilities using Born's rule68probs = np.abs(state)**26970plt.figure(figsize=(6,4))71plt.bar(['|00⟩', '|01⟩', '|10⟩', '|11⟩'], probs, color='#76b900') # NVIDIA green72plt.ylim(0, 1)73plt.ylabel('Probability')74plt.title('Measurement Probability Distribution')75plt.show()7677# Function to update the final state display78def update_final_state(q0_state, q1_state):79with output_state:80clear_output(wait=True)81state_list = [q0_state, q1_state]82state = cudaq.get_state(CNOT_example, state_list)8384print("Final State:")85state_str = ""86basis_states = ['|00⟩', '|01⟩', '|10⟩', '|11⟩']8788# Find first non-zero term89first_term = True90for i, (amplitude, basis) in enumerate(zip(state, basis_states)):91if abs(amplitude) > 1e-10: # Only show non-zero terms92if first_term:93state_str += f"({format_complex(amplitude)}){basis}"94first_term = False95else:96# Add explicit + or - sign97if amplitude.real < 0:98state_str += f"<span style='color: red'>-</span>({format_complex(abs(amplitude))}){basis}"99else:100state_str += f"+({format_complex(abs(amplitude))}){basis}"101102display(HTML(state_str))103104# Add titles105main_title = widgets.HTML(value="<h3>Two-Qubit CNOT Gate Visualization</h3>")106initial_state_title = widgets.HTML(value="<h4>Initial States:</h4>")107108# Create dropdowns for each qubit109q0_dropdown = widgets.Dropdown(110options=[('|0⟩', 0), ('|1⟩', 1), ('|+⟩', 2), ('|-⟩', 3)],111value=0,112description='Qubit 0:',113)114115q1_dropdown = widgets.Dropdown(116options=[('|0⟩', 0), ('|1⟩', 1), ('|+⟩', 2), ('|-⟩', 3)],117value=0,118description='Qubit 1:',119)120121# Create output widgets122output_circuit = widgets.Output()123output_prob = widgets.Output()124output_state = widgets.Output()125126def update_all(change):127update_circuit(q0_dropdown.value, q1_dropdown.value)128update_prob_chart(q0_dropdown.value, q1_dropdown.value)129update_final_state(q0_dropdown.value, q1_dropdown.value)130131# Observe changes in dropdowns132q0_dropdown.observe(update_all, names='value')133q1_dropdown.observe(update_all, names='value')134135# Display everything136display(VBox([137main_title,138initial_state_title,139HBox([q0_dropdown, q1_dropdown]),140output_circuit,141output_state,142output_prob143]))144145# Initial update146update_circuit(q0_dropdown.value, q1_dropdown.value)147update_prob_chart(q0_dropdown.value, q1_dropdown.value)148update_final_state(q0_dropdown.value, q1_dropdown.value)149150# When imported, this will create and display a new widget151if __name__ == '__main__':152widget = create_CNOT_widget()153display(widget)154155156