123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492 |
- from sympy.external import import_module
- from sympy.core.mul import Mul
- from sympy.core.numbers import Integer
- from sympy.physics.quantum.dagger import Dagger
- from sympy.physics.quantum.gate import (X, Y, Z, H, CNOT,
- IdentityGate, CGate, PhaseGate, TGate)
- from sympy.physics.quantum.identitysearch import (generate_gate_rules,
- generate_equivalent_ids, GateIdentity, bfs_identity_search,
- is_scalar_sparse_matrix,
- is_scalar_nonsparse_matrix, is_degenerate, is_reducible)
- from sympy.testing.pytest import skip
- def create_gate_sequence(qubit=0):
- gates = (X(qubit), Y(qubit), Z(qubit), H(qubit))
- return gates
- def test_generate_gate_rules_1():
- # Test with tuples
- (x, y, z, h) = create_gate_sequence()
- ph = PhaseGate(0)
- cgate_t = CGate(0, TGate(1))
- assert generate_gate_rules((x,)) == {((x,), ())}
- gate_rules = {((x, x), ()),
- ((x,), (x,))}
- assert generate_gate_rules((x, x)) == gate_rules
- gate_rules = {((x, y, x), ()),
- ((y, x, x), ()),
- ((x, x, y), ()),
- ((y, x), (x,)),
- ((x, y), (x,)),
- ((y,), (x, x))}
- assert generate_gate_rules((x, y, x)) == gate_rules
- gate_rules = {((x, y, z), ()), ((y, z, x), ()), ((z, x, y), ()),
- ((), (x, z, y)), ((), (y, x, z)), ((), (z, y, x)),
- ((x,), (z, y)), ((y, z), (x,)), ((y,), (x, z)),
- ((z, x), (y,)), ((z,), (y, x)), ((x, y), (z,))}
- actual = generate_gate_rules((x, y, z))
- assert actual == gate_rules
- gate_rules = {
- ((), (h, z, y, x)), ((), (x, h, z, y)), ((), (y, x, h, z)),
- ((), (z, y, x, h)), ((h,), (z, y, x)), ((x,), (h, z, y)),
- ((y,), (x, h, z)), ((z,), (y, x, h)), ((h, x), (z, y)),
- ((x, y), (h, z)), ((y, z), (x, h)), ((z, h), (y, x)),
- ((h, x, y), (z,)), ((x, y, z), (h,)), ((y, z, h), (x,)),
- ((z, h, x), (y,)), ((h, x, y, z), ()), ((x, y, z, h), ()),
- ((y, z, h, x), ()), ((z, h, x, y), ())}
- actual = generate_gate_rules((x, y, z, h))
- assert actual == gate_rules
- gate_rules = {((), (cgate_t**(-1), ph**(-1), x)),
- ((), (ph**(-1), x, cgate_t**(-1))),
- ((), (x, cgate_t**(-1), ph**(-1))),
- ((cgate_t,), (ph**(-1), x)),
- ((ph,), (x, cgate_t**(-1))),
- ((x,), (cgate_t**(-1), ph**(-1))),
- ((cgate_t, x), (ph**(-1),)),
- ((ph, cgate_t), (x,)),
- ((x, ph), (cgate_t**(-1),)),
- ((cgate_t, x, ph), ()),
- ((ph, cgate_t, x), ()),
- ((x, ph, cgate_t), ())}
- actual = generate_gate_rules((x, ph, cgate_t))
- assert actual == gate_rules
- gate_rules = {(Integer(1), cgate_t**(-1)*ph**(-1)*x),
- (Integer(1), ph**(-1)*x*cgate_t**(-1)),
- (Integer(1), x*cgate_t**(-1)*ph**(-1)),
- (cgate_t, ph**(-1)*x),
- (ph, x*cgate_t**(-1)),
- (x, cgate_t**(-1)*ph**(-1)),
- (cgate_t*x, ph**(-1)),
- (ph*cgate_t, x),
- (x*ph, cgate_t**(-1)),
- (cgate_t*x*ph, Integer(1)),
- (ph*cgate_t*x, Integer(1)),
- (x*ph*cgate_t, Integer(1))}
- actual = generate_gate_rules((x, ph, cgate_t), return_as_muls=True)
- assert actual == gate_rules
- def test_generate_gate_rules_2():
- # Test with Muls
- (x, y, z, h) = create_gate_sequence()
- ph = PhaseGate(0)
- cgate_t = CGate(0, TGate(1))
- # Note: 1 (type int) is not the same as 1 (type One)
- expected = {(x, Integer(1))}
- assert generate_gate_rules((x,), return_as_muls=True) == expected
- expected = {(Integer(1), Integer(1))}
- assert generate_gate_rules(x*x, return_as_muls=True) == expected
- expected = {((), ())}
- assert generate_gate_rules(x*x, return_as_muls=False) == expected
- gate_rules = {(x*y*x, Integer(1)),
- (y, Integer(1)),
- (y*x, x),
- (x*y, x)}
- assert generate_gate_rules(x*y*x, return_as_muls=True) == gate_rules
- gate_rules = {(x*y*z, Integer(1)),
- (y*z*x, Integer(1)),
- (z*x*y, Integer(1)),
- (Integer(1), x*z*y),
- (Integer(1), y*x*z),
- (Integer(1), z*y*x),
- (x, z*y),
- (y*z, x),
- (y, x*z),
- (z*x, y),
- (z, y*x),
- (x*y, z)}
- actual = generate_gate_rules(x*y*z, return_as_muls=True)
- assert actual == gate_rules
- gate_rules = {(Integer(1), h*z*y*x),
- (Integer(1), x*h*z*y),
- (Integer(1), y*x*h*z),
- (Integer(1), z*y*x*h),
- (h, z*y*x), (x, h*z*y),
- (y, x*h*z), (z, y*x*h),
- (h*x, z*y), (z*h, y*x),
- (x*y, h*z), (y*z, x*h),
- (h*x*y, z), (x*y*z, h),
- (y*z*h, x), (z*h*x, y),
- (h*x*y*z, Integer(1)),
- (x*y*z*h, Integer(1)),
- (y*z*h*x, Integer(1)),
- (z*h*x*y, Integer(1))}
- actual = generate_gate_rules(x*y*z*h, return_as_muls=True)
- assert actual == gate_rules
- gate_rules = {(Integer(1), cgate_t**(-1)*ph**(-1)*x),
- (Integer(1), ph**(-1)*x*cgate_t**(-1)),
- (Integer(1), x*cgate_t**(-1)*ph**(-1)),
- (cgate_t, ph**(-1)*x),
- (ph, x*cgate_t**(-1)),
- (x, cgate_t**(-1)*ph**(-1)),
- (cgate_t*x, ph**(-1)),
- (ph*cgate_t, x),
- (x*ph, cgate_t**(-1)),
- (cgate_t*x*ph, Integer(1)),
- (ph*cgate_t*x, Integer(1)),
- (x*ph*cgate_t, Integer(1))}
- actual = generate_gate_rules(x*ph*cgate_t, return_as_muls=True)
- assert actual == gate_rules
- gate_rules = {((), (cgate_t**(-1), ph**(-1), x)),
- ((), (ph**(-1), x, cgate_t**(-1))),
- ((), (x, cgate_t**(-1), ph**(-1))),
- ((cgate_t,), (ph**(-1), x)),
- ((ph,), (x, cgate_t**(-1))),
- ((x,), (cgate_t**(-1), ph**(-1))),
- ((cgate_t, x), (ph**(-1),)),
- ((ph, cgate_t), (x,)),
- ((x, ph), (cgate_t**(-1),)),
- ((cgate_t, x, ph), ()),
- ((ph, cgate_t, x), ()),
- ((x, ph, cgate_t), ())}
- actual = generate_gate_rules(x*ph*cgate_t)
- assert actual == gate_rules
- def test_generate_equivalent_ids_1():
- # Test with tuples
- (x, y, z, h) = create_gate_sequence()
- assert generate_equivalent_ids((x,)) == {(x,)}
- assert generate_equivalent_ids((x, x)) == {(x, x)}
- assert generate_equivalent_ids((x, y)) == {(x, y), (y, x)}
- gate_seq = (x, y, z)
- gate_ids = {(x, y, z), (y, z, x), (z, x, y), (z, y, x),
- (y, x, z), (x, z, y)}
- assert generate_equivalent_ids(gate_seq) == gate_ids
- gate_ids = {Mul(x, y, z), Mul(y, z, x), Mul(z, x, y),
- Mul(z, y, x), Mul(y, x, z), Mul(x, z, y)}
- assert generate_equivalent_ids(gate_seq, return_as_muls=True) == gate_ids
- gate_seq = (x, y, z, h)
- gate_ids = {(x, y, z, h), (y, z, h, x),
- (h, x, y, z), (h, z, y, x),
- (z, y, x, h), (y, x, h, z),
- (z, h, x, y), (x, h, z, y)}
- assert generate_equivalent_ids(gate_seq) == gate_ids
- gate_seq = (x, y, x, y)
- gate_ids = {(x, y, x, y), (y, x, y, x)}
- assert generate_equivalent_ids(gate_seq) == gate_ids
- cgate_y = CGate((1,), y)
- gate_seq = (y, cgate_y, y, cgate_y)
- gate_ids = {(y, cgate_y, y, cgate_y), (cgate_y, y, cgate_y, y)}
- assert generate_equivalent_ids(gate_seq) == gate_ids
- cnot = CNOT(1, 0)
- cgate_z = CGate((0,), Z(1))
- gate_seq = (cnot, h, cgate_z, h)
- gate_ids = {(cnot, h, cgate_z, h), (h, cgate_z, h, cnot),
- (h, cnot, h, cgate_z), (cgate_z, h, cnot, h)}
- assert generate_equivalent_ids(gate_seq) == gate_ids
- def test_generate_equivalent_ids_2():
- # Test with Muls
- (x, y, z, h) = create_gate_sequence()
- assert generate_equivalent_ids((x,), return_as_muls=True) == {x}
- gate_ids = {Integer(1)}
- assert generate_equivalent_ids(x*x, return_as_muls=True) == gate_ids
- gate_ids = {x*y, y*x}
- assert generate_equivalent_ids(x*y, return_as_muls=True) == gate_ids
- gate_ids = {(x, y), (y, x)}
- assert generate_equivalent_ids(x*y) == gate_ids
- circuit = Mul(*(x, y, z))
- gate_ids = {x*y*z, y*z*x, z*x*y, z*y*x,
- y*x*z, x*z*y}
- assert generate_equivalent_ids(circuit, return_as_muls=True) == gate_ids
- circuit = Mul(*(x, y, z, h))
- gate_ids = {x*y*z*h, y*z*h*x,
- h*x*y*z, h*z*y*x,
- z*y*x*h, y*x*h*z,
- z*h*x*y, x*h*z*y}
- assert generate_equivalent_ids(circuit, return_as_muls=True) == gate_ids
- circuit = Mul(*(x, y, x, y))
- gate_ids = {x*y*x*y, y*x*y*x}
- assert generate_equivalent_ids(circuit, return_as_muls=True) == gate_ids
- cgate_y = CGate((1,), y)
- circuit = Mul(*(y, cgate_y, y, cgate_y))
- gate_ids = {y*cgate_y*y*cgate_y, cgate_y*y*cgate_y*y}
- assert generate_equivalent_ids(circuit, return_as_muls=True) == gate_ids
- cnot = CNOT(1, 0)
- cgate_z = CGate((0,), Z(1))
- circuit = Mul(*(cnot, h, cgate_z, h))
- gate_ids = {cnot*h*cgate_z*h, h*cgate_z*h*cnot,
- h*cnot*h*cgate_z, cgate_z*h*cnot*h}
- assert generate_equivalent_ids(circuit, return_as_muls=True) == gate_ids
- def test_is_scalar_nonsparse_matrix():
- numqubits = 2
- id_only = False
- id_gate = (IdentityGate(1),)
- actual = is_scalar_nonsparse_matrix(id_gate, numqubits, id_only)
- assert actual is True
- x0 = X(0)
- xx_circuit = (x0, x0)
- actual = is_scalar_nonsparse_matrix(xx_circuit, numqubits, id_only)
- assert actual is True
- x1 = X(1)
- y1 = Y(1)
- xy_circuit = (x1, y1)
- actual = is_scalar_nonsparse_matrix(xy_circuit, numqubits, id_only)
- assert actual is False
- z1 = Z(1)
- xyz_circuit = (x1, y1, z1)
- actual = is_scalar_nonsparse_matrix(xyz_circuit, numqubits, id_only)
- assert actual is True
- cnot = CNOT(1, 0)
- cnot_circuit = (cnot, cnot)
- actual = is_scalar_nonsparse_matrix(cnot_circuit, numqubits, id_only)
- assert actual is True
- h = H(0)
- hh_circuit = (h, h)
- actual = is_scalar_nonsparse_matrix(hh_circuit, numqubits, id_only)
- assert actual is True
- h1 = H(1)
- xhzh_circuit = (x1, h1, z1, h1)
- actual = is_scalar_nonsparse_matrix(xhzh_circuit, numqubits, id_only)
- assert actual is True
- id_only = True
- actual = is_scalar_nonsparse_matrix(xhzh_circuit, numqubits, id_only)
- assert actual is True
- actual = is_scalar_nonsparse_matrix(xyz_circuit, numqubits, id_only)
- assert actual is False
- actual = is_scalar_nonsparse_matrix(cnot_circuit, numqubits, id_only)
- assert actual is True
- actual = is_scalar_nonsparse_matrix(hh_circuit, numqubits, id_only)
- assert actual is True
- def test_is_scalar_sparse_matrix():
- np = import_module('numpy')
- if not np:
- skip("numpy not installed.")
- scipy = import_module('scipy', import_kwargs={'fromlist': ['sparse']})
- if not scipy:
- skip("scipy not installed.")
- numqubits = 2
- id_only = False
- id_gate = (IdentityGate(1),)
- assert is_scalar_sparse_matrix(id_gate, numqubits, id_only) is True
- x0 = X(0)
- xx_circuit = (x0, x0)
- assert is_scalar_sparse_matrix(xx_circuit, numqubits, id_only) is True
- x1 = X(1)
- y1 = Y(1)
- xy_circuit = (x1, y1)
- assert is_scalar_sparse_matrix(xy_circuit, numqubits, id_only) is False
- z1 = Z(1)
- xyz_circuit = (x1, y1, z1)
- assert is_scalar_sparse_matrix(xyz_circuit, numqubits, id_only) is True
- cnot = CNOT(1, 0)
- cnot_circuit = (cnot, cnot)
- assert is_scalar_sparse_matrix(cnot_circuit, numqubits, id_only) is True
- h = H(0)
- hh_circuit = (h, h)
- assert is_scalar_sparse_matrix(hh_circuit, numqubits, id_only) is True
- # NOTE:
- # The elements of the sparse matrix for the following circuit
- # is actually 1.0000000000000002+0.0j.
- h1 = H(1)
- xhzh_circuit = (x1, h1, z1, h1)
- assert is_scalar_sparse_matrix(xhzh_circuit, numqubits, id_only) is True
- id_only = True
- assert is_scalar_sparse_matrix(xhzh_circuit, numqubits, id_only) is True
- assert is_scalar_sparse_matrix(xyz_circuit, numqubits, id_only) is False
- assert is_scalar_sparse_matrix(cnot_circuit, numqubits, id_only) is True
- assert is_scalar_sparse_matrix(hh_circuit, numqubits, id_only) is True
- def test_is_degenerate():
- (x, y, z, h) = create_gate_sequence()
- gate_id = GateIdentity(x, y, z)
- ids = {gate_id}
- another_id = (z, y, x)
- assert is_degenerate(ids, another_id) is True
- def test_is_reducible():
- nqubits = 2
- (x, y, z, h) = create_gate_sequence()
- circuit = (x, y, y)
- assert is_reducible(circuit, nqubits, 1, 3) is True
- circuit = (x, y, x)
- assert is_reducible(circuit, nqubits, 1, 3) is False
- circuit = (x, y, y, x)
- assert is_reducible(circuit, nqubits, 0, 4) is True
- circuit = (x, y, y, x)
- assert is_reducible(circuit, nqubits, 1, 3) is True
- circuit = (x, y, z, y, y)
- assert is_reducible(circuit, nqubits, 1, 5) is True
- def test_bfs_identity_search():
- assert bfs_identity_search([], 1) == set()
- (x, y, z, h) = create_gate_sequence()
- gate_list = [x]
- id_set = {GateIdentity(x, x)}
- assert bfs_identity_search(gate_list, 1, max_depth=2) == id_set
- # Set should not contain degenerate quantum circuits
- gate_list = [x, y, z]
- id_set = {GateIdentity(x, x),
- GateIdentity(y, y),
- GateIdentity(z, z),
- GateIdentity(x, y, z)}
- assert bfs_identity_search(gate_list, 1) == id_set
- id_set = {GateIdentity(x, x),
- GateIdentity(y, y),
- GateIdentity(z, z),
- GateIdentity(x, y, z),
- GateIdentity(x, y, x, y),
- GateIdentity(x, z, x, z),
- GateIdentity(y, z, y, z)}
- assert bfs_identity_search(gate_list, 1, max_depth=4) == id_set
- assert bfs_identity_search(gate_list, 1, max_depth=5) == id_set
- gate_list = [x, y, z, h]
- id_set = {GateIdentity(x, x),
- GateIdentity(y, y),
- GateIdentity(z, z),
- GateIdentity(h, h),
- GateIdentity(x, y, z),
- GateIdentity(x, y, x, y),
- GateIdentity(x, z, x, z),
- GateIdentity(x, h, z, h),
- GateIdentity(y, z, y, z),
- GateIdentity(y, h, y, h)}
- assert bfs_identity_search(gate_list, 1) == id_set
- id_set = {GateIdentity(x, x),
- GateIdentity(y, y),
- GateIdentity(z, z),
- GateIdentity(h, h)}
- assert id_set == bfs_identity_search(gate_list, 1, max_depth=3,
- identity_only=True)
- id_set = {GateIdentity(x, x),
- GateIdentity(y, y),
- GateIdentity(z, z),
- GateIdentity(h, h),
- GateIdentity(x, y, z),
- GateIdentity(x, y, x, y),
- GateIdentity(x, z, x, z),
- GateIdentity(x, h, z, h),
- GateIdentity(y, z, y, z),
- GateIdentity(y, h, y, h),
- GateIdentity(x, y, h, x, h),
- GateIdentity(x, z, h, y, h),
- GateIdentity(y, z, h, z, h)}
- assert bfs_identity_search(gate_list, 1, max_depth=5) == id_set
- id_set = {GateIdentity(x, x),
- GateIdentity(y, y),
- GateIdentity(z, z),
- GateIdentity(h, h),
- GateIdentity(x, h, z, h)}
- assert id_set == bfs_identity_search(gate_list, 1, max_depth=4,
- identity_only=True)
- cnot = CNOT(1, 0)
- gate_list = [x, cnot]
- id_set = {GateIdentity(x, x),
- GateIdentity(cnot, cnot),
- GateIdentity(x, cnot, x, cnot)}
- assert bfs_identity_search(gate_list, 2, max_depth=4) == id_set
- cgate_x = CGate((1,), x)
- gate_list = [x, cgate_x]
- id_set = {GateIdentity(x, x),
- GateIdentity(cgate_x, cgate_x),
- GateIdentity(x, cgate_x, x, cgate_x)}
- assert bfs_identity_search(gate_list, 2, max_depth=4) == id_set
- cgate_z = CGate((0,), Z(1))
- gate_list = [cnot, cgate_z, h]
- id_set = {GateIdentity(h, h),
- GateIdentity(cgate_z, cgate_z),
- GateIdentity(cnot, cnot),
- GateIdentity(cnot, h, cgate_z, h)}
- assert bfs_identity_search(gate_list, 2, max_depth=4) == id_set
- s = PhaseGate(0)
- t = TGate(0)
- gate_list = [s, t]
- id_set = {GateIdentity(s, s, s, s)}
- assert bfs_identity_search(gate_list, 1, max_depth=4) == id_set
- def test_bfs_identity_search_xfail():
- s = PhaseGate(0)
- t = TGate(0)
- gate_list = [Dagger(s), t]
- id_set = {GateIdentity(Dagger(s), t, t)}
- assert bfs_identity_search(gate_list, 1, max_depth=3) == id_set
|