|
| 1 | +from tests.utils_for_testbook import ( |
| 2 | + validate_quantum_program_size, |
| 3 | + validate_quantum_model, |
| 4 | + wrap_testbook, |
| 5 | +) |
| 6 | +from testbook.client import TestbookNotebookClient |
| 7 | +import numpy as np |
| 8 | +import pandas as pd |
| 9 | +from scipy.special import rel_entr |
| 10 | + |
| 11 | + |
| 12 | +@wrap_testbook("discrete_log", timeout_seconds=600) |
| 13 | +def test_notebook(tb: TestbookNotebookClient) -> None: |
| 14 | + # test models |
| 15 | + validate_quantum_model(tb.ref("qmod_Z5")) |
| 16 | + validate_quantum_model(tb.ref("qmod_Z13")) |
| 17 | + # test quantum programs |
| 18 | + validate_quantum_program_size( |
| 19 | + tb.ref("qprog_Z5"), |
| 20 | + expected_width=12, # actual width: 12 |
| 21 | + expected_depth=5000, # actual depth: 4658 |
| 22 | + ) |
| 23 | + validate_quantum_program_size( |
| 24 | + tb.ref("qprog_Z13"), |
| 25 | + expected_width=22, # actual width: 20 |
| 26 | + expected_depth=21000, # actual depth: 19770 |
| 27 | + ) |
| 28 | + |
| 29 | + # test notebook content |
| 30 | + df = _get_result_as_dataframe(tb) |
| 31 | + actual_values = _get_distribution(df) |
| 32 | + expected_values = _get_uniform_distribution(df) |
| 33 | + # check that the distribution we got is close to even distribution |
| 34 | + distance = rel_entr(actual_values, expected_values) # 1.8, 3.01, 1.7, 3.1, 0.6, 4.4 |
| 35 | + assert distance.sum() < 10 |
| 36 | + |
| 37 | + |
| 38 | +def _get_result_as_dataframe(tb: TestbookNotebookClient) -> pd.DataFrame: |
| 39 | + parsed_counts = tb.ref("result_Z5.parsed_counts") |
| 40 | + data_list = [ |
| 41 | + (sample_state.state["func_res"], sample_state.shots) |
| 42 | + for sample_state in parsed_counts |
| 43 | + ] |
| 44 | + df = pd.DataFrame(data_list).rename(columns={0: "func_res", 1: "shots"}) |
| 45 | + return df |
| 46 | + |
| 47 | + |
| 48 | +def _get_distribution(df: DataFrame) -> np.ndarray: |
| 49 | + grouped = df.groupby("func_res").sum() |
| 50 | + values = grouped_data.values.flatten() |
| 51 | + return values |
| 52 | + |
| 53 | + |
| 54 | +def _get_uniform_distribution(df: DataFrame) -> np.ndarray: |
| 55 | + total_num_shots = data["shots"].sum() |
| 56 | + num_func_res_options = len(data["func_res"].unique()) |
| 57 | + |
| 58 | + expected_values = [total_num_shots / num_func_res_options] * num_func_res_options |
| 59 | + return expected_values |
0 commit comments