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

1from qml_essentials.model import Model 

2from qml_essentials.entanglement import Entanglement 

3 

4import logging 

5import math 

6import pytest 

7 

8logger = logging.getLogger(__name__) 

9 

10 

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] 

19 

20 # Circuits [5,7,8,11,12,13,14] are not included in the test cases, 

21 # because not implemented in ansaetze.py 

22 

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 ] 

110 

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 ) 

120 

121 ent_cap = Entanglement.meyer_wallach( 

122 model, n_samples=5000, seed=1000, cache=False 

123 ) 

124 

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"]) 

130 

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}%" 

136 

137 

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 ) 

147 

148 _ = Entanglement.meyer_wallach(model, n_samples=-1, seed=1000, cache=False)