Skip to content

Commit e56f7e8

Browse files
committed
add a test to general_kraus
1 parent f8cd778 commit e56f7e8

File tree

1 file changed

+54
-13
lines changed

1 file changed

+54
-13
lines changed

tests/test_quditcircuit.py

Lines changed: 54 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -537,22 +537,63 @@ def test_unitary_kraus_qutrit_single(backend):
537537
c = tc.QuditCircuit(1, dim=d)
538538
idx = c.unitary_kraus([I, X], 0, prob=[0.0, 1.0])
539539
assert idx == 1
540-
541-
a0 = c.amplitude("0")
542-
a1 = c.amplitude("1")
543-
a2 = c.amplitude("2")
544-
np.testing.assert_allclose(a1, 1.0 + 0j, atol=1e-6)
545-
np.testing.assert_allclose(a0, 0.0 + 0j, atol=1e-6)
546-
np.testing.assert_allclose(a2, 0.0 + 0j, atol=1e-6)
540+
np.testing.assert_allclose(c.amplitude("0"), 0.0 + 0j, atol=1e-6)
541+
np.testing.assert_allclose(c.amplitude("1"), 1.0 + 0j, atol=1e-6)
542+
np.testing.assert_allclose(c.amplitude("2"), 0.0 + 0j, atol=1e-6)
547543

548544
# Case B: choose I branch deterministically
549545
c2 = tc.QuditCircuit(1, dim=d)
550546
idx2 = c2.unitary_kraus([I, X], 0, prob=[1.0, 0.0])
551547
assert idx2 == 0
548+
np.testing.assert_allclose(c2.amplitude("0"), 1.0 + 0j, atol=1e-6)
549+
np.testing.assert_allclose(c2.amplitude("1"), 0.0 + 0j, atol=1e-6)
550+
np.testing.assert_allclose(c2.amplitude("2"), 0.0 + 0j, atol=1e-6)
551+
552+
553+
@pytest.mark.parametrize("backend", [lf("npb"), lf("tfb"), lf("jaxb")])
554+
def test_general_kraus_qutrit_single(backend):
555+
r"""
556+
Qutrit (d=3) tests for general_kraus on a single site (Part B only).
557+
558+
True general Kraus with normalization and `with_prob=True`:
559+
K0 = sqrt(p) * I, K1 = sqrt(1-p) * X
560+
(K0^\dagger K0 + K1^\dagger K1 = I)
561+
`status` controls which branch is sampled.
562+
"""
563+
d = 3
564+
565+
# Identity and qutrit shift X (|k> -> |k+1 mod 3)
566+
I = tc.quditgates.i_matrix_func(d)
567+
X = tc.quditgates.x_matrix_func(d)
568+
569+
p = 0.7
570+
K0 = np.sqrt(p) * I
571+
K1 = np.sqrt(1.0 - p) * X
572+
573+
# ---- completeness check in numpy space (works for all backends) ----
574+
np.testing.assert_allclose(
575+
tc.backend.transpose(tc.backend.conj(K0)) @ K0
576+
+ tc.backend.transpose(tc.backend.conj(K1)) @ K1,
577+
I,
578+
atol=1e-6,
579+
)
552580

553-
b0 = c2.amplitude("0")
554-
b1 = c2.amplitude("1")
555-
b2 = c2.amplitude("2")
556-
np.testing.assert_allclose(b0, 1.0 + 0j, atol=1e-6)
557-
np.testing.assert_allclose(b1, 0.0 + 0j, atol=1e-6)
558-
np.testing.assert_allclose(b2, 0.0 + 0j, atol=1e-6)
581+
# ---- Case B1: status small -> pick K0 with prob ~ p; state remains |0\rangle ----
582+
c3 = tc.QuditCircuit(1, dim=d)
583+
idx3, prob3 = c3.general_kraus([K0, K1], 0, status=0.2, with_prob=True)
584+
assert idx3 == 0
585+
np.testing.assert_allclose(np.array(prob3), np.array([p, 1 - p]), atol=1e-6)
586+
np.testing.assert_allclose(np.array(prob3)[idx3], p, atol=1e-6)
587+
np.testing.assert_allclose(c3.amplitude("0"), 1.0 + 0j, atol=1e-6)
588+
np.testing.assert_allclose(c3.amplitude("1"), 0.0 + 0j, atol=1e-6)
589+
np.testing.assert_allclose(c3.amplitude("2"), 0.0 + 0j, atol=1e-6)
590+
591+
# ---- Case B2: status large -> pick K1 with prob ~ (1-p); state becomes |1\rangle ----
592+
c4 = tc.QuditCircuit(1, dim=d)
593+
idx4, prob4 = c4.general_kraus([K0, K1], 0, status=0.95, with_prob=True)
594+
assert idx4 == 1
595+
np.testing.assert_allclose(np.array(prob4), np.array([p, 1 - p]), atol=1e-6)
596+
np.testing.assert_allclose(np.array(prob4)[idx4], 1.0 - p, atol=1e-6)
597+
np.testing.assert_allclose(c4.amplitude("0"), 0.0 + 0j, atol=1e-6)
598+
np.testing.assert_allclose(c4.amplitude("1"), 1.0 + 0j, atol=1e-6)
599+
np.testing.assert_allclose(c4.amplitude("2"), 0.0 + 0j, atol=1e-6)

0 commit comments

Comments
 (0)