Skip to content

Commit

Permalink
change argument order
Browse files Browse the repository at this point in the history
  • Loading branch information
wistaria committed Nov 3, 2023
1 parent f2c18f6 commit 906e49a
Show file tree
Hide file tree
Showing 15 changed files with 100 additions and 51 deletions.
18 changes: 9 additions & 9 deletions example/grover.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,32 +5,32 @@ def oracle(v, target):
n = q.sv.num_qubits(v)
for i in range(n):
if (target >> i) & 1 == 0:
v = q.sv.apply(q.op.x(), v, [i])
v = q.sv.apply(v, q.op.x(), [i])
assert q.op.is_operator(q.op.cz(n))
assert q.sv.is_state_vector(v)
v = q.sv.apply(q.op.cz(n), v)
v = q.sv.apply(v, q.op.cz(n))
for i in range(n):
if (target >> i) & 1 == 0:
v = q.sv.apply(q.op.x(), v, [i])
v = q.sv.apply(v, q.op.x(), [i])
return v


def diffusion(v):
n = q.sv.num_qubits(v)
for i in range(n):
v = q.sv.apply(q.op.h(), v, [i])
v = q.sv.apply(q.op.x(), v, [i])
v = q.sv.apply(q.op.cz(n), v)
v = q.sv.apply(v, q.op.h(), [i])
v = q.sv.apply(v, q.op.x(), [i])
v = q.sv.apply(v, q.op.cz(n))
for i in range(n):
v = q.sv.apply(q.op.x(), v, [i])
v = q.sv.apply(q.op.h(), v, [i])
v = q.sv.apply(v, q.op.x(), [i])
v = q.sv.apply(v, q.op.h(), [i])
return v


def grover(n, target, iter):
v = q.sv.state_vector(n)
for i in range(n):
v = q.sv.apply(q.op.h(), v, [i])
v = q.sv.apply(v, q.op.h(), [i])
for k in range(iter):
v = oracle(v, target)
v = diffusion(v)
Expand Down
10 changes: 5 additions & 5 deletions example/shimada-2.2.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ def main():
print("state vector:", q.sv.vector(v))
print("probabitily:", q.sv.probability(v))

v = q.sv.apply(q.op.h(), v, [0])
v = q.sv.apply(q.op.h(), v, [2])
v = q.sv.apply(q.op.cx(), v, [0, 1])
v = q.sv.apply(q.op.cz(), v, [1, 2])
v = q.sv.apply(q.op.h(), v, [2])
v = q.sv.apply(v, q.op.h(), [0])
v = q.sv.apply(v, q.op.h(), [2])
v = q.sv.apply(v, q.op.cx(), [0, 1])
v = q.sv.apply(v, q.op.cz(), [1, 2])
v = q.sv.apply(v, q.op.h(), [2])

print("output:")
print("state vector:", q.sv.vector(v))
Expand Down
5 changes: 2 additions & 3 deletions src/qailo/mps/__init__.py
Original file line number Diff line number Diff line change
@@ -1,21 +1,20 @@
from .apply import apply
from .mps import MPS
from .norm import norm
from .num_qubits import num_qubits
from .product_state import product_state
from .state_vector import state_vector
from .svd import compact_svd, tensor_svd
from .type import is_canonical, is_mps
from .type import is_canonical, is_mps, num_qubits

__all__ = [
apply,
MPS,
norm,
num_qubits,
product_state,
state_vector,
compact_svd,
tensor_svd,
is_canonical,
is_mps,
num_qubits,
]
49 changes: 49 additions & 0 deletions src/qailo/mps/apply.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
from copy import deepcopy

from ..operator import type as op
from ..operator.swap import swap
from .type import num_qubits


def _swap_tensors(m, s, maxdim=None):
"""
swap neighboring two tensors at s and s+1
"""
assert s in range(0, num_qubits(m) - 1)
m._apply_two(swap(), s, maxdim=maxdim)
p0, p1 = m.t2q[s], m.t2q[s + 1]
m.q2t[p0], m.q2t[p1] = s + 1, s
m.t2q[s], m.t2q[s + 1] = p1, p0


def _move_qubit(m, p, s, maxdim=None):
if m.q2t[p] != s:
# print(f"moving qubit {p} at {m.q2t[p]} to {s}")
for u in range(m.q2t[p], s):
# print(f"swap tensors {u} and {u+1}")
_swap_tensors(m, u, maxdim=maxdim)
for u in range(m.q2t[p], s, -1):
# print(f"swap tensors {u-1} and {u}")
_swap_tensors(m, u - 1, maxdim=maxdim)


def _apply(m, p, qpos, maxdim=None):
assert op.is_operator(p) and len(qpos) == op.num_qubits(p)
if op.num_qubits(p) == 1:
m._apply_one(p, m.q2t[qpos[0]])
elif op.num_qubits(p) == 2:
tpos = [m.q2t[qpos[0]], m.q2t[qpos[1]]]
assert tpos[0] != tpos[1]
if tpos[0] < tpos[1]:
_move_qubit(m, qpos[1], tpos[0] + 1)
m._apply_two(p, tpos[0], maxdim=maxdim)
else:
_move_qubit(m, qpos[0], tpos[1] + 1)
m._apply_two(p, tpos[1], maxdim=maxdim, reverse=True)
else:
raise ValueError
return m


def apply(m, p, qpos, maxdim=None):
return _apply(deepcopy(m), p, qpos, maxdim)
2 changes: 1 addition & 1 deletion src/qailo/mps/norm.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import numpy as np

from .num_qubits import num_qubits
from .type import num_qubits


def norm(m):
Expand Down
2 changes: 0 additions & 2 deletions src/qailo/mps/num_qubits.py

This file was deleted.

3 changes: 1 addition & 2 deletions src/qailo/mps/state_vector.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import numpy as np

from ..util.strops import letters, replace
from .num_qubits import num_qubits
from .type import is_mps
from .type import is_mps, num_qubits


def state_vector(m):
Expand Down
4 changes: 4 additions & 0 deletions src/qailo/mps/type.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,7 @@ def is_canonical(m):

def is_mps(m):
return hasattr(m, "tensors")


def num_qubits(m):
return len(m.tensors)
12 changes: 6 additions & 6 deletions src/qailo/operator/multiply.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@
from .type import is_operator, num_qubits


def multiply(op, opi, pos=None):
assert is_operator(opi)
assert is_operator(op)
n = num_qubits(opi)
m = num_qubits(op)
def multiply(pin, p, pos=None):
assert is_operator(pin)
assert is_operator(p)
n = num_qubits(pin)
m = num_qubits(p)
if pos is None:
assert m == n
pos = range(n)
Expand All @@ -21,4 +21,4 @@ def multiply(op, opi, pos=None):
for i in range(m):
ss_opi = replace(ss_opi, pos[i], ss_op[m + i])
ss_to = replace(ss_to, pos[i], ss_op[i])
return np.einsum("{},{}->{}".format(ss_opi, ss_op, ss_to), opi, op)
return np.einsum("{},{}->{}".format(ss_opi, ss_op, ss_to), pin, p)
4 changes: 2 additions & 2 deletions src/qailo/state_vector/apply.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
from . import type as sv


def apply(p, v, pos=None):
assert op.is_operator(p) and sv.is_state_vector(v)
def apply(v, p, pos=None):
assert sv.is_state_vector(v) and op.is_operator(p)
n = sv.num_qubits(v)
m = op.num_qubits(p)
if pos is None:
Expand Down
2 changes: 1 addition & 1 deletion test/mps/test_apply.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
def apply(op, m0, m1, v, pos, maxdim=None):
m0 = q.mps.apply(m0, op, pos)
m1 = q.mps.apply(m1, op, pos, maxdim)
v = q.sv.apply(op, v, pos)
v = q.sv.apply(v, op, pos)
return m0, m1, v


Expand Down
12 changes: 6 additions & 6 deletions test/operator/test_controlled.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,14 @@ def test_cz():
assert q.op.is_hermitian(q.op.cz())
assert q.op.is_unitary(q.op.cz())
# Cz01 = Cz10
assert q.op.is_close(q.op.cz(), q.op.multiply(q.op.cz(), q.op.identity(2), [1, 0]))
assert q.op.is_close(q.op.cz(), q.op.multiply(q.op.identity(2), q.op.cz(), [1, 0]))


def test_ccccx():
for n in range(3, 8):
op = q.op.identity(n)
op = q.op.multiply(q.op.control_begin(), op, [0, 1])
p = q.op.identity(n)
p = q.op.multiply(p, q.op.control_begin(), [0, 1])
for i in range(1, n - 2):
op = q.op.multiply(q.op.control_propagate(), op, [i, i + 1])
op = q.op.multiply(q.op.control_end(q.op.x()), op, [n - 2, n - 1])
assert q.op.is_close(op, q.op.cx(n))
p = q.op.multiply(p, q.op.control_propagate(), [i, i + 1])
p = q.op.multiply(p, q.op.control_end(q.op.x()), [n - 2, n - 1])
assert q.op.is_close(p, q.op.cx(n))
24 changes: 12 additions & 12 deletions test/operator/test_swap.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,19 @@


def test_swap():
op = q.op.swap()
assert q.op.is_hermitian(op)
assert q.op.is_unitary(op)
assert q.op.is_identity(q.op.multiply(op, op, [0, 1]))
p = q.op.swap()
assert q.op.is_hermitian(p)
assert q.op.is_unitary(p)
assert q.op.is_identity(q.op.multiply(p, p, [0, 1]))

op = q.op.cx()
op = q.op.multiply(q.op.cx(), op, [1, 0])
op = q.op.multiply(q.op.cx(), op, [0, 1])
assert q.op.is_close(op, q.op.swap())
p = q.op.cx()
p = q.op.multiply(p, q.op.cx(), [1, 0])
p = q.op.multiply(p, q.op.cx(), [0, 1])
assert q.op.is_close(p, q.op.swap())

v = q.sv.state_vector(2)
v = q.sv.apply(q.op.h(), v, [0])
v = q.sv.apply(q.op.swap(), v, [0, 1])
v = q.sv.apply(q.op.h(), v, [1])
v = q.sv.apply(q.op.swap(), v, [0, 1])
v = q.sv.apply(v, q.op.h(), [0])
v = q.sv.apply(v, q.op.swap(), [0, 1])
v = q.sv.apply(v, q.op.h(), [1])
v = q.sv.apply(v, q.op.swap(), [0, 1])
assert q.op.is_close(v, q.sv.state_vector(2))
2 changes: 1 addition & 1 deletion test/state_vector/test_fidelity.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ def test_fidelity():
sv0 = q.sv.state_vector(n)
sv1 = sv0
for i in range(n):
sv1 = q.sv.apply(q.op.h(), sv1, [i])
sv1 = q.sv.apply(sv1, q.op.h(), [i])
assert q.sv.fidelity(sv0, sv0) == approx(1)
assert q.sv.fidelity(sv1, sv1) == approx(1)
assert q.sv.fidelity(sv0, sv1) == approx(1 / np.sqrt(2**n))
2 changes: 1 addition & 1 deletion test/state_vector/test_pure_state.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ def test_pure_state():
assert q.op.is_density_matrix(dm)

for i in range(n):
sv = q.sv.apply(q.op.h(), sv, [i])
sv = q.sv.apply(sv, q.op.h(), [i])
print(q.sv.vector(sv))
dm = q.sv.pure_state(sv)
print(q.op.matrix(dm))
Expand Down

0 comments on commit 906e49a

Please sign in to comment.