图片解析应用
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

402 lines
13 KiB

  1. from sympy.core.mul import Mul
  2. from sympy.core.numbers import Integer
  3. from sympy.core.symbol import Symbol
  4. from sympy.utilities import numbered_symbols
  5. from sympy.physics.quantum.gate import X, Y, Z, H, CNOT, CGate
  6. from sympy.physics.quantum.identitysearch import bfs_identity_search
  7. from sympy.physics.quantum.circuitutils import (kmp_table, find_subcircuit,
  8. replace_subcircuit, convert_to_symbolic_indices,
  9. convert_to_real_indices, random_reduce, random_insert,
  10. flatten_ids)
  11. from sympy.testing.pytest import slow
  12. def create_gate_sequence(qubit=0):
  13. gates = (X(qubit), Y(qubit), Z(qubit), H(qubit))
  14. return gates
  15. def test_kmp_table():
  16. word = ('a', 'b', 'c', 'd', 'a', 'b', 'd')
  17. expected_table = [-1, 0, 0, 0, 0, 1, 2]
  18. assert expected_table == kmp_table(word)
  19. word = ('P', 'A', 'R', 'T', 'I', 'C', 'I', 'P', 'A', 'T', 'E', ' ',
  20. 'I', 'N', ' ', 'P', 'A', 'R', 'A', 'C', 'H', 'U', 'T', 'E')
  21. expected_table = [-1, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0,
  22. 0, 0, 0, 0, 1, 2, 3, 0, 0, 0, 0, 0]
  23. assert expected_table == kmp_table(word)
  24. x = X(0)
  25. y = Y(0)
  26. z = Z(0)
  27. h = H(0)
  28. word = (x, y, y, x, z)
  29. expected_table = [-1, 0, 0, 0, 1]
  30. assert expected_table == kmp_table(word)
  31. word = (x, x, y, h, z)
  32. expected_table = [-1, 0, 1, 0, 0]
  33. assert expected_table == kmp_table(word)
  34. def test_find_subcircuit():
  35. x = X(0)
  36. y = Y(0)
  37. z = Z(0)
  38. h = H(0)
  39. x1 = X(1)
  40. y1 = Y(1)
  41. i0 = Symbol('i0')
  42. x_i0 = X(i0)
  43. y_i0 = Y(i0)
  44. z_i0 = Z(i0)
  45. h_i0 = H(i0)
  46. circuit = (x, y, z)
  47. assert find_subcircuit(circuit, (x,)) == 0
  48. assert find_subcircuit(circuit, (x1,)) == -1
  49. assert find_subcircuit(circuit, (y,)) == 1
  50. assert find_subcircuit(circuit, (h,)) == -1
  51. assert find_subcircuit(circuit, Mul(x, h)) == -1
  52. assert find_subcircuit(circuit, Mul(x, y, z)) == 0
  53. assert find_subcircuit(circuit, Mul(y, z)) == 1
  54. assert find_subcircuit(Mul(*circuit), (x, y, z, h)) == -1
  55. assert find_subcircuit(Mul(*circuit), (z, y, x)) == -1
  56. assert find_subcircuit(circuit, (x,), start=2, end=1) == -1
  57. circuit = (x, y, x, y, z)
  58. assert find_subcircuit(Mul(*circuit), Mul(x, y, z)) == 2
  59. assert find_subcircuit(circuit, (x,), start=1) == 2
  60. assert find_subcircuit(circuit, (x, y), start=1, end=2) == -1
  61. assert find_subcircuit(Mul(*circuit), (x, y), start=1, end=3) == -1
  62. assert find_subcircuit(circuit, (x, y), start=1, end=4) == 2
  63. assert find_subcircuit(circuit, (x, y), start=2, end=4) == 2
  64. circuit = (x, y, z, x1, x, y, z, h, x, y, x1,
  65. x, y, z, h, y1, h)
  66. assert find_subcircuit(circuit, (x, y, z, h, y1)) == 11
  67. circuit = (x, y, x_i0, y_i0, z_i0, z)
  68. assert find_subcircuit(circuit, (x_i0, y_i0, z_i0)) == 2
  69. circuit = (x_i0, y_i0, z_i0, x_i0, y_i0, h_i0)
  70. subcircuit = (x_i0, y_i0, z_i0)
  71. result = find_subcircuit(circuit, subcircuit)
  72. assert result == 0
  73. def test_replace_subcircuit():
  74. x = X(0)
  75. y = Y(0)
  76. z = Z(0)
  77. h = H(0)
  78. cnot = CNOT(1, 0)
  79. cgate_z = CGate((0,), Z(1))
  80. # Standard cases
  81. circuit = (z, y, x, x)
  82. remove = (z, y, x)
  83. assert replace_subcircuit(circuit, Mul(*remove)) == (x,)
  84. assert replace_subcircuit(circuit, remove + (x,)) == ()
  85. assert replace_subcircuit(circuit, remove, pos=1) == circuit
  86. assert replace_subcircuit(circuit, remove, pos=0) == (x,)
  87. assert replace_subcircuit(circuit, (x, x), pos=2) == (z, y)
  88. assert replace_subcircuit(circuit, (h,)) == circuit
  89. circuit = (x, y, x, y, z)
  90. remove = (x, y, z)
  91. assert replace_subcircuit(Mul(*circuit), Mul(*remove)) == (x, y)
  92. remove = (x, y, x, y)
  93. assert replace_subcircuit(circuit, remove) == (z,)
  94. circuit = (x, h, cgate_z, h, cnot)
  95. remove = (x, h, cgate_z)
  96. assert replace_subcircuit(circuit, Mul(*remove), pos=-1) == (h, cnot)
  97. assert replace_subcircuit(circuit, remove, pos=1) == circuit
  98. remove = (h, h)
  99. assert replace_subcircuit(circuit, remove) == circuit
  100. remove = (h, cgate_z, h, cnot)
  101. assert replace_subcircuit(circuit, remove) == (x,)
  102. replace = (h, x)
  103. actual = replace_subcircuit(circuit, remove,
  104. replace=replace)
  105. assert actual == (x, h, x)
  106. circuit = (x, y, h, x, y, z)
  107. remove = (x, y)
  108. replace = (cnot, cgate_z)
  109. actual = replace_subcircuit(circuit, remove,
  110. replace=Mul(*replace))
  111. assert actual == (cnot, cgate_z, h, x, y, z)
  112. actual = replace_subcircuit(circuit, remove,
  113. replace=replace, pos=1)
  114. assert actual == (x, y, h, cnot, cgate_z, z)
  115. def test_convert_to_symbolic_indices():
  116. (x, y, z, h) = create_gate_sequence()
  117. i0 = Symbol('i0')
  118. exp_map = {i0: Integer(0)}
  119. actual, act_map, sndx, gen = convert_to_symbolic_indices((x,))
  120. assert actual == (X(i0),)
  121. assert act_map == exp_map
  122. expected = (X(i0), Y(i0), Z(i0), H(i0))
  123. exp_map = {i0: Integer(0)}
  124. actual, act_map, sndx, gen = convert_to_symbolic_indices((x, y, z, h))
  125. assert actual == expected
  126. assert exp_map == act_map
  127. (x1, y1, z1, h1) = create_gate_sequence(1)
  128. i1 = Symbol('i1')
  129. expected = (X(i0), Y(i0), Z(i0), H(i0))
  130. exp_map = {i0: Integer(1)}
  131. actual, act_map, sndx, gen = convert_to_symbolic_indices((x1, y1, z1, h1))
  132. assert actual == expected
  133. assert act_map == exp_map
  134. expected = (X(i0), Y(i0), Z(i0), H(i0), X(i1), Y(i1), Z(i1), H(i1))
  135. exp_map = {i0: Integer(0), i1: Integer(1)}
  136. actual, act_map, sndx, gen = convert_to_symbolic_indices((x, y, z, h,
  137. x1, y1, z1, h1))
  138. assert actual == expected
  139. assert act_map == exp_map
  140. exp_map = {i0: Integer(1), i1: Integer(0)}
  141. actual, act_map, sndx, gen = convert_to_symbolic_indices(Mul(x1, y1,
  142. z1, h1, x, y, z, h))
  143. assert actual == expected
  144. assert act_map == exp_map
  145. expected = (X(i0), X(i1), Y(i0), Y(i1), Z(i0), Z(i1), H(i0), H(i1))
  146. exp_map = {i0: Integer(0), i1: Integer(1)}
  147. actual, act_map, sndx, gen = convert_to_symbolic_indices(Mul(x, x1,
  148. y, y1, z, z1, h, h1))
  149. assert actual == expected
  150. assert act_map == exp_map
  151. exp_map = {i0: Integer(1), i1: Integer(0)}
  152. actual, act_map, sndx, gen = convert_to_symbolic_indices((x1, x, y1, y,
  153. z1, z, h1, h))
  154. assert actual == expected
  155. assert act_map == exp_map
  156. cnot_10 = CNOT(1, 0)
  157. cnot_01 = CNOT(0, 1)
  158. cgate_z_10 = CGate(1, Z(0))
  159. cgate_z_01 = CGate(0, Z(1))
  160. expected = (X(i0), X(i1), Y(i0), Y(i1), Z(i0), Z(i1),
  161. H(i0), H(i1), CNOT(i1, i0), CNOT(i0, i1),
  162. CGate(i1, Z(i0)), CGate(i0, Z(i1)))
  163. exp_map = {i0: Integer(0), i1: Integer(1)}
  164. args = (x, x1, y, y1, z, z1, h, h1, cnot_10, cnot_01,
  165. cgate_z_10, cgate_z_01)
  166. actual, act_map, sndx, gen = convert_to_symbolic_indices(args)
  167. assert actual == expected
  168. assert act_map == exp_map
  169. args = (x1, x, y1, y, z1, z, h1, h, cnot_10, cnot_01,
  170. cgate_z_10, cgate_z_01)
  171. expected = (X(i0), X(i1), Y(i0), Y(i1), Z(i0), Z(i1),
  172. H(i0), H(i1), CNOT(i0, i1), CNOT(i1, i0),
  173. CGate(i0, Z(i1)), CGate(i1, Z(i0)))
  174. exp_map = {i0: Integer(1), i1: Integer(0)}
  175. actual, act_map, sndx, gen = convert_to_symbolic_indices(args)
  176. assert actual == expected
  177. assert act_map == exp_map
  178. args = (cnot_10, h, cgate_z_01, h)
  179. expected = (CNOT(i0, i1), H(i1), CGate(i1, Z(i0)), H(i1))
  180. exp_map = {i0: Integer(1), i1: Integer(0)}
  181. actual, act_map, sndx, gen = convert_to_symbolic_indices(args)
  182. assert actual == expected
  183. assert act_map == exp_map
  184. args = (cnot_01, h1, cgate_z_10, h1)
  185. exp_map = {i0: Integer(0), i1: Integer(1)}
  186. actual, act_map, sndx, gen = convert_to_symbolic_indices(args)
  187. assert actual == expected
  188. assert act_map == exp_map
  189. args = (cnot_10, h1, cgate_z_01, h1)
  190. expected = (CNOT(i0, i1), H(i0), CGate(i1, Z(i0)), H(i0))
  191. exp_map = {i0: Integer(1), i1: Integer(0)}
  192. actual, act_map, sndx, gen = convert_to_symbolic_indices(args)
  193. assert actual == expected
  194. assert act_map == exp_map
  195. i2 = Symbol('i2')
  196. ccgate_z = CGate(0, CGate(1, Z(2)))
  197. ccgate_x = CGate(1, CGate(2, X(0)))
  198. args = (ccgate_z, ccgate_x)
  199. expected = (CGate(i0, CGate(i1, Z(i2))), CGate(i1, CGate(i2, X(i0))))
  200. exp_map = {i0: Integer(0), i1: Integer(1), i2: Integer(2)}
  201. actual, act_map, sndx, gen = convert_to_symbolic_indices(args)
  202. assert actual == expected
  203. assert act_map == exp_map
  204. ndx_map = {i0: Integer(0)}
  205. index_gen = numbered_symbols(prefix='i', start=1)
  206. actual, act_map, sndx, gen = convert_to_symbolic_indices(args,
  207. qubit_map=ndx_map,
  208. start=i0,
  209. gen=index_gen)
  210. assert actual == expected
  211. assert act_map == exp_map
  212. i3 = Symbol('i3')
  213. cgate_x0_c321 = CGate((3, 2, 1), X(0))
  214. exp_map = {i0: Integer(3), i1: Integer(2),
  215. i2: Integer(1), i3: Integer(0)}
  216. expected = (CGate((i0, i1, i2), X(i3)),)
  217. args = (cgate_x0_c321,)
  218. actual, act_map, sndx, gen = convert_to_symbolic_indices(args)
  219. assert actual == expected
  220. assert act_map == exp_map
  221. def test_convert_to_real_indices():
  222. i0 = Symbol('i0')
  223. i1 = Symbol('i1')
  224. (x, y, z, h) = create_gate_sequence()
  225. x_i0 = X(i0)
  226. y_i0 = Y(i0)
  227. z_i0 = Z(i0)
  228. qubit_map = {i0: 0}
  229. args = (z_i0, y_i0, x_i0)
  230. expected = (z, y, x)
  231. actual = convert_to_real_indices(args, qubit_map)
  232. assert actual == expected
  233. cnot_10 = CNOT(1, 0)
  234. cnot_01 = CNOT(0, 1)
  235. cgate_z_10 = CGate(1, Z(0))
  236. cgate_z_01 = CGate(0, Z(1))
  237. cnot_i1_i0 = CNOT(i1, i0)
  238. cnot_i0_i1 = CNOT(i0, i1)
  239. cgate_z_i1_i0 = CGate(i1, Z(i0))
  240. qubit_map = {i0: 0, i1: 1}
  241. args = (cnot_i1_i0,)
  242. expected = (cnot_10,)
  243. actual = convert_to_real_indices(args, qubit_map)
  244. assert actual == expected
  245. args = (cgate_z_i1_i0,)
  246. expected = (cgate_z_10,)
  247. actual = convert_to_real_indices(args, qubit_map)
  248. assert actual == expected
  249. args = (cnot_i0_i1,)
  250. expected = (cnot_01,)
  251. actual = convert_to_real_indices(args, qubit_map)
  252. assert actual == expected
  253. qubit_map = {i0: 1, i1: 0}
  254. args = (cgate_z_i1_i0,)
  255. expected = (cgate_z_01,)
  256. actual = convert_to_real_indices(args, qubit_map)
  257. assert actual == expected
  258. i2 = Symbol('i2')
  259. ccgate_z = CGate(i0, CGate(i1, Z(i2)))
  260. ccgate_x = CGate(i1, CGate(i2, X(i0)))
  261. qubit_map = {i0: 0, i1: 1, i2: 2}
  262. args = (ccgate_z, ccgate_x)
  263. expected = (CGate(0, CGate(1, Z(2))), CGate(1, CGate(2, X(0))))
  264. actual = convert_to_real_indices(Mul(*args), qubit_map)
  265. assert actual == expected
  266. qubit_map = {i0: 1, i2: 0, i1: 2}
  267. args = (ccgate_x, ccgate_z)
  268. expected = (CGate(2, CGate(0, X(1))), CGate(1, CGate(2, Z(0))))
  269. actual = convert_to_real_indices(args, qubit_map)
  270. assert actual == expected
  271. @slow
  272. def test_random_reduce():
  273. x = X(0)
  274. y = Y(0)
  275. z = Z(0)
  276. h = H(0)
  277. cnot = CNOT(1, 0)
  278. cgate_z = CGate((0,), Z(1))
  279. gate_list = [x, y, z]
  280. ids = list(bfs_identity_search(gate_list, 1, max_depth=4))
  281. circuit = (x, y, h, z, cnot)
  282. assert random_reduce(circuit, []) == circuit
  283. assert random_reduce(circuit, ids) == circuit
  284. seq = [2, 11, 9, 3, 5]
  285. circuit = (x, y, z, x, y, h)
  286. assert random_reduce(circuit, ids, seed=seq) == (x, y, h)
  287. circuit = (x, x, y, y, z, z)
  288. assert random_reduce(circuit, ids, seed=seq) == (x, x, y, y)
  289. seq = [14, 13, 0]
  290. assert random_reduce(circuit, ids, seed=seq) == (y, y, z, z)
  291. gate_list = [x, y, z, h, cnot, cgate_z]
  292. ids = list(bfs_identity_search(gate_list, 2, max_depth=4))
  293. seq = [25]
  294. circuit = (x, y, z, y, h, y, h, cgate_z, h, cnot)
  295. expected = (x, y, z, cgate_z, h, cnot)
  296. assert random_reduce(circuit, ids, seed=seq) == expected
  297. circuit = Mul(*circuit)
  298. assert random_reduce(circuit, ids, seed=seq) == expected
  299. @slow
  300. def test_random_insert():
  301. x = X(0)
  302. y = Y(0)
  303. z = Z(0)
  304. h = H(0)
  305. cnot = CNOT(1, 0)
  306. cgate_z = CGate((0,), Z(1))
  307. choices = [(x, x)]
  308. circuit = (y, y)
  309. loc, choice = 0, 0
  310. actual = random_insert(circuit, choices, seed=[loc, choice])
  311. assert actual == (x, x, y, y)
  312. circuit = (x, y, z, h)
  313. choices = [(h, h), (x, y, z)]
  314. expected = (x, x, y, z, y, z, h)
  315. loc, choice = 1, 1
  316. actual = random_insert(circuit, choices, seed=[loc, choice])
  317. assert actual == expected
  318. gate_list = [x, y, z, h, cnot, cgate_z]
  319. ids = list(bfs_identity_search(gate_list, 2, max_depth=4))
  320. eq_ids = flatten_ids(ids)
  321. circuit = (x, y, h, cnot, cgate_z)
  322. expected = (x, z, x, z, x, y, h, cnot, cgate_z)
  323. loc, choice = 1, 30
  324. actual = random_insert(circuit, eq_ids, seed=[loc, choice])
  325. assert actual == expected
  326. circuit = Mul(*circuit)
  327. actual = random_insert(circuit, eq_ids, seed=[loc, choice])
  328. assert actual == expected