Coverage for tests/test_entanglement.py: 100%
23 statements
« prev ^ index » next coverage.py v7.6.10, created at 2025-01-23 11:23 +0000
« prev ^ index » next coverage.py v7.6.10, created at 2025-01-23 11:23 +0000
1from qml_essentials.model import Model
2from qml_essentials.entanglement import Entanglement
4import logging
5import math
6import pytest
8logger = logging.getLogger(__name__)
11@pytest.mark.expensive
12@pytest.mark.unittest
13def test_entanglement() -> None:
14 # Results taken from: https://doi.org/10.1002/qute.201900070
15 # circuits = [1, 7, 3, 16, 8, 5, 18, 17, 4, 10, 19, 13, 12, 14, 11, 6, 2, 15, 9]
16 # ent_res = [0.0000, 0.3246, 0.3424, 0.3464, 0.3932, 0.4099, 0.4383, 0.4541,
17 # 0.4715, 0.5369, 0.5937, 0.6070, 0.6487, 0.6613, 0.7330, 0.7803, 0.8083,
18 # 0.8186, 1.0000]
20 # Circuits [5,7,8,11,12,13,14] are not included in the test cases,
21 # because not implemented in ansaetze.py
23 # Circuit 10 excluded because implementation with current setup not possible
24 test_cases = [
25 {
26 "circuit_type": "No_Entangling",
27 "n_qubits": 4,
28 "n_layers": 1,
29 "result": 0.0,
30 },
31 {
32 "circuit_type": "Strongly_Entangling",
33 "n_qubits": 4,
34 "n_layers": 1,
35 "result": 0.8379,
36 },
37 {
38 "circuit_type": "Circuit_1",
39 "n_qubits": 4,
40 "n_layers": 1,
41 "result": 0.0000,
42 },
43 {
44 "circuit_type": "Circuit_3",
45 "n_qubits": 4,
46 "n_layers": 1,
47 "result": 0.3424,
48 },
49 {
50 "circuit_type": "Circuit_16",
51 "n_qubits": 4,
52 "n_layers": 1,
53 "result": 0.3464,
54 },
55 {
56 "circuit_type": "Circuit_18",
57 "n_qubits": 4,
58 "n_layers": 1,
59 "result": 0.4383,
60 },
61 {
62 "circuit_type": "Circuit_17",
63 "n_qubits": 4,
64 "n_layers": 1,
65 "result": 0.4541,
66 },
67 {
68 "circuit_type": "Circuit_4",
69 "n_qubits": 4,
70 "n_layers": 1,
71 "result": 0.4715,
72 },
73 # {
74 # "circuit_type": "Circuit_10",
75 # "n_qubits": 4,
76 # "n_layers": 1,
77 # "result": 0.5369,
78 # },
79 {
80 "circuit_type": "Circuit_19",
81 "n_qubits": 4,
82 "n_layers": 1,
83 "result": 0.5937,
84 },
85 {
86 "circuit_type": "Circuit_6",
87 "n_qubits": 4,
88 "n_layers": 1,
89 "result": 0.7803,
90 },
91 {
92 "circuit_type": "Circuit_2",
93 "n_qubits": 4,
94 "n_layers": 1,
95 "result": 0.8083,
96 },
97 {
98 "circuit_type": "Circuit_15",
99 "n_qubits": 4,
100 "n_layers": 1,
101 "result": 0.8186,
102 },
103 {
104 "circuit_type": "Circuit_9",
105 "n_qubits": 4,
106 "n_layers": 1,
107 "result": 1.0000,
108 },
109 ]
111 tolerance = 0.55 # FIXME: reduce when reason for discrepancy is found
112 for test_case in test_cases:
113 model = Model(
114 n_qubits=test_case["n_qubits"],
115 n_layers=test_case["n_layers"],
116 circuit_type=test_case["circuit_type"],
117 data_reupload=False,
118 initialization="random",
119 )
121 ent_cap = Entanglement.meyer_wallach(
122 model, n_samples=5000, seed=1000, cache=False
123 )
125 difference = abs(ent_cap - test_case["result"])
126 if math.isclose(difference, 0.0, abs_tol=1e-3):
127 error = 0
128 else:
129 error = abs(ent_cap - test_case["result"]) / (test_case["result"])
131 assert (
132 error < tolerance
133 ), f"Entangling-capability of circuit {test_case['circuit_type']} is not\
134 {test_case['result']} but {ent_cap} instead.\
135 Deviation {(error*100):.1f}%>{tolerance*100}%"
138@pytest.mark.smoketest
139def test_no_sampling() -> None:
140 model = Model(
141 n_qubits=2,
142 n_layers=1,
143 circuit_type="Hardware_Efficient",
144 data_reupload=True,
145 initialization="random",
146 )
148 _ = Entanglement.meyer_wallach(model, n_samples=-1, seed=1000, cache=False)