diff --git a/applications/finance/option_pricing/option_pricing.ipynb b/applications/finance/option_pricing/option_pricing.ipynb index 64296694..98070875 100644 --- a/applications/finance/option_pricing/option_pricing.ipynb +++ b/applications/finance/option_pricing/option_pricing.ipynb @@ -511,10 +511,10 @@ ], "source": [ "measured_payoff = result_iqae.estimation * scaling_factor\n", - "condidence_interval = np.array(result_iqae.confidence_interval) * scaling_factor\n", + "confidence_interval = np.array(result_iqae.confidence_interval) * scaling_factor\n", "\n", "print(\"Measured Payoff:\", measured_payoff)\n", - "print(\"Confidence Interval:\", condidence_interval)" + "print(\"Confidence Interval:\", confidence_interval)" ] }, { @@ -554,7 +554,7 @@ "assert np.isclose(\n", " measured_payoff,\n", " expected_payoff,\n", - " atol=10 * (condidence_interval[1] - condidence_interval[0]),\n", + " atol=10 * (confidence_interval[1] - confidence_interval[0]),\n", ")" ] }, diff --git a/tests/notebooks/test_credit_card_fraud.py b/tests/notebooks/test_credit_card_fraud.py new file mode 100644 index 00000000..8c4d27e4 --- /dev/null +++ b/tests/notebooks/test_credit_card_fraud.py @@ -0,0 +1,28 @@ +from tests.utils_for_testbook import ( + validate_quantum_program_size, + validate_quantum_model, + wrap_testbook, +) +from testbook.client import TestbookNotebookClient + + +@wrap_testbook("credit_card_fraud", timeout_seconds=1084) +def test_notebook(tb: TestbookNotebookClient) -> None: + # test models + validate_quantum_model(tb.ref("QSVM_FRAUD_BLOCH_SHPERE")) + validate_quantum_model(tb.ref("QSVM_FRAUD_PAULI_ZZ")) + # test quantum programs + validate_quantum_program_size( + tb.ref("qprog"), + expected_width=5, # actual width: 3 + expected_depth=50, # actual depth: 38 + ) + + # test notebook content + + # true_labels = np.array(selected_prediction_true_labels.values.tolist()) + # sklearn.metrics.accuracy_score(predicted_labels, true_labels) + accuracy = tb.ref( + "sklearn.metrics.accuracy_score(predicted_labels, np.array(selected_prediction_true_labels.values.tolist()))" + ) + assert accuracy >= 0.9 diff --git a/tests/notebooks/test_option_pricing.py b/tests/notebooks/test_option_pricing.py new file mode 100644 index 00000000..bc962457 --- /dev/null +++ b/tests/notebooks/test_option_pricing.py @@ -0,0 +1,28 @@ +from tests.utils_for_testbook import ( + validate_quantum_program_size, + validate_quantum_model, + wrap_testbook, +) +from testbook.client import TestbookNotebookClient + +import numpy as np + + +@wrap_testbook("option_pricing", timeout_seconds=140) +def test_notebook(tb: TestbookNotebookClient) -> None: + # test models + validate_quantum_model(tb.ref("qmod")) + # test quantum programs + validate_quantum_program_size( + tb.ref("qprog"), + expected_width=10, # actual width: 8 + expected_depth=9500, # actual depth: 8934 + ) + + # test notebook content + confidence_interval = tb.ref_numpy("confidence_interval") + assert np.isclose( + tb.ref("measured_payoff"), + tb.ref("expected_payoff"), + atol=10 * (confidence_interval[1] - confidence_interval[0]), + ) diff --git a/tests/notebooks/test_portfolio_optimization.py b/tests/notebooks/test_portfolio_optimization.py new file mode 100644 index 00000000..8fea1598 --- /dev/null +++ b/tests/notebooks/test_portfolio_optimization.py @@ -0,0 +1,21 @@ +from tests.utils_for_testbook import ( + validate_quantum_program_size, + validate_quantum_model, + wrap_testbook, +) +from testbook.client import TestbookNotebookClient + + +@wrap_testbook("portfolio_optimization", timeout_seconds=400) +def test_notebook(tb: TestbookNotebookClient) -> None: + # test models + validate_quantum_model(tb.ref("qmod")) + # test quantum programs + validate_quantum_program_size( + tb.ref("qprog"), + expected_width=15, # actual width: 12 + expected_depth=300, # actual depth: 217 + ) + + # test notebook content + pass # todo diff --git a/tests/utils_for_testbook.py b/tests/utils_for_testbook.py index 76928863..4bd1407f 100644 --- a/tests/utils_for_testbook.py +++ b/tests/utils_for_testbook.py @@ -1,4 +1,6 @@ import json +import base64 +import pickle import os from typing import Any, Callable import pytest @@ -12,9 +14,15 @@ from classiq.interface.generator.quantum_program import QuantumProgram +from testbook.client import TestbookNotebookClient + +_PATCHED = False + def wrap_testbook(notebook_name: str, timeout_seconds: float = 10) -> Callable: def inner_decorator(func: Callable) -> Any: + _patch_testbook() + notebook_path = resolve_notebook_path(notebook_name) for decorator in [ @@ -54,6 +62,30 @@ def _build_skip_decorator(notebook_path: str) -> Callable: ) +def _patch_testbook() -> None: + global _PATCHED + + if _PATCHED: + return + + def ref_numpy(self, obj_name: str) -> Any: + """ + s = base64.b64encode( pickle.dumps(obj) ).decode() + result = pickle.loads(base64.b64decode(s)) + result == obj + """ + + string = self.ref( + f"__import__('base64').b64encode(__import__('pickle').dumps({obj_name})).decode()" + ) + result = pickle.loads(base64.b64decode(string)) + return result + + TestbookNotebookClient.ref_numpy = ref_numpy + + _PATCHED = True + + def validate_quantum_model(model: str) -> None: # currently that's some dummy test - only checking that it's a valid dict assert isinstance(json.loads(model), dict)