Example #1
0
def create_product_testvectors():
    """yield instances of class ``QStateMatrix`` for tests """
    for m1_data, m2_data, nqb in qs_matrix_data:
        m1 = create_m(*m1_data)
        m2 = create_m(*m2_data)
        yield m1, m2, nqb
    yield qs_unit_matrix(4), qs_unit_matrix(4), 3
    for i in range(20):
        nqb = randint(0, 2)
        yield qs_rand_matrix(2, 0, 3), qs_rand_matrix(2, 0, 3), nqb
    for cols1 in range(2, 6):
        for cols2 in range(2, 6):
            for nqb in range(min(cols1, cols2)):
                for n in range(2):
                    m1 = qs_rand_matrix(0, cols1, cols1 + 3)
                    rand_mul_scalar(m1)
                    m2 = qs_rand_matrix(0, cols2, cols2 + 3)
                    rand_mul_scalar(m2)
                    yield m1, m2, nqb
    # Sparse states
    for cols1 in range(2, 6):
        for cols2 in range(2, 6):
            for nqb in range(min(cols1, cols2)):
                for r in range(3):
                    for n in range(2):
                        m1 = qs_rand_matrix(0, cols1, r)
                        m1.mul_scalar(randint(-8, 8), randint(0, 7))
                        m2 = qs_rand_matrix(0, cols2, r)
                        m1.mul_scalar(randint(-8, 8), randint(0, 7))
                        yield m1, m2, nqb
Example #2
0
def create_exp_data():
    yield qs_unit_matrix(2), 0
    yield qs_unit_matrix(4), -3
    for n in range(1, 13):
        for i in range(10):
            m = rand_unitary_matrix(n)
            m.mul_scalar(randint(-2, 2))
            e = randint(-10000, 10000)
            yield m, e
Example #3
0
def ref_power(m, e):
    if e > 1:
        m1 = ref_power(m, e >> 1)
        m1 = m1 @ m1
        return m1 @ m if e & 1 else m1
    if e == 1:
        return m
    if e == 0:
        return qs_unit_matrix(m.shape[0])
    if e < 0:
        mi = m.inv()
        assert m @ mi == qs_unit_matrix(m.shape[0])
        return ref_power(mi, -e)
Example #4
0
def test_qs_errors(verbose=0):
    FORMAT_REDUCED = False
    with pytest.raises(ValueError):
        QStateMatrix(10000, 10000)
    with pytest.raises(ValueError):
        QStateMatrix(1, 1, [0, 0, 0xf])
    m1, m2 = qs_unit_matrix(1), qs_unit_matrix(2)
    with pytest.raises(ValueError):
        m1 @ m2
    with pytest.raises(ValueError):
        m1 * m2
    m = QStateMatrix(3, 3, [0, 0, 0xf], 2)
    with pytest.raises(ValueError):
        m.power(-1)
    FORMAT_REDUCED = True
Example #5
0
def rand_unitary_matrix(n, scalar=True):
    m = qs_unit_matrix(n)
    e = randint(-16, 16) if scalar else 0
    m.mul_scalar(e, randint(0, 7))
    if n == 0:
        return m
    mask = (1 << n) - 1
    for i in range(n + 2):
        v = randint(0, mask - 1)
        vc = randint(0, mask) & ~v
        m.gate_ctrl_not(vc, v)
        v1 = randint(0, mask)
        v2 = randint(0, mask)
        m.gate_ctrl_phi(v1, v2)
    m.gate_phi(randint(0, mask), 1)
    m.gate_phi(randint(0, mask), 2)
    m.gate_h(randint(0, mask))
    m.gate_not(randint(0, mask))
    for i in range(n + 2):
        v = randint(0, mask - 1)
        vc = randint(0, mask) & ~v
        m.gate_ctrl_not(vc, v)
        v1 = randint(0, mask)
        v2 = randint(0, mask)
        m.gate_ctrl_phi(v1, v2)
    return m.echelon()
Example #6
0
def create_conjugate_data():
    yield rand_unitary_matrix(0), [0, 1, 2, 3]
    yield qs_unit_matrix(1), [0, 1, 2, 3]

    for n in range(1, 13):
        for i in range(10):
            m = rand_unitary_matrix(n)
            v = rand_pauli_vectors(n, max(10, n))
            yield m, v
Example #7
0
def test_matrix_power(verbose=0):
    MAX_ORDER = (2**8 - 1) * (2**6 - 1) * 2**10
    """Test matrix exponentiation and commputation of trace"""
    for ntest, (m, e) in enumerate(create_exp_data()):
        # Test exponentiation
        me = m.power(e)
        me_ref = ref_power(m, e)
        ok = me == me_ref
        if verbose or not ok:
            mm = m.copy()
            print("\nTest %d: exponent = %d, " % (ntest, e))
            print("m =", m.reduce())
            print("Result of exponentiation:", me_ref)
            if not ok:
                print("Obtained:", me)
                raise ValueError("Matrix exponentiation failed")
        nqb = m.shape[0]
        m.mul_scalar(-m.lb_norm2())
        assert m.H == m.inv()

        # Test computation of trace
        if nqb > 8:
            continue
        tr = m.trace()
        tr_ref = ref_trace(m)
        if tr == 0:
            ok = tr_ref == 0
        else:
            ok = abs(tr_ref / tr - 1) < 1.0e-6
        if verbose or not ok:
            print("\nTrace of m:", tr)
            if not ok:
                print("m =", m.reduce())
                if nqb < 3:
                    print("m =\n", m.complex())
                print("\nTrace expected:", tr_ref)
                s, f = m._trace_factor()
                print("Low level trace result:", s, hex(f))
                print("Intermediate")
                m1 = m.copy()
                for i in range(nqb):
                    m1.gate_ctrl_not(1 << i, 1 << (nqb + i))
                print(m1)
                m1 = m1.restrict(nqb, nqb)
                print(m1)
                raise ValueError("Computation of trace failed")

        # Testing order
        if nqb > 4:
            continue
        order = m.order(MAX_ORDER)
        if verbose:
            s = print("Scaled matrix m has order %d" % order)
        assert m.power(order) == qs_unit_matrix(m.shape[0])
Example #8
0
def create_display_testvectors():
    """yield instances of class ``QStateMatrix`` for tests """
    for rows, cols, factor, data in qs_matrix_data:
        m = QStateMatrix(rows, cols, data)
        m.mul_scalar(*factor)
        yield m
    yield qs_unit_matrix(4)
    for i in range(20):
        yield qs_rand_matrix(2, 0, 3)
    for i in range(20):
        yield qs_rand_matrix(1, 0, 2)
    for rows in range(6):
        for cols in range(5):
            for nr in [1, 2] + list(range(rows + cols, rows + cols + 3)):
                m = qs_rand_matrix(rows, cols, nr)
                m.mul_scalar(randint(-8, 8), randint(0, 7))
                yield m
def create_testmatrices():
    """yield instances of class ``QStateMatrix`` for tests """
    for m_data in qs_matrix_data:
        m = create_m(*m_data)
        yield m
    yield qs_unit_matrix(4)  
    for i in range(20):
        yield qs_rand_matrix(2, 2, 4)
    for cols in range(0,7):
        for rows in range(0, 7):
            if rows + cols > 9:
                 break
            yield QStateMatrix(rows, cols)
            for data_rows in range(1, rows + cols + 3):
                for n in range(2):
                    m = qs_rand_matrix(rows, cols, data_rows)
                    rand_mul_scalar(m)  
                    yield m   
Example #10
0
def test_pauli_conjugate(verbose=0):
    """Test the conjugation of Pauli matrix with unitary matrix"""
    for ntest, (m, v) in enumerate(create_conjugate_data()):
        n = m.shape[0]
        p = [qs_pauli_matrix(n, x) for x in v]
        pv = [x.pauli_vector() for x in p]
        ok = pv == v
        if verbose or not ok:
            mm = m.copy()
            print("\nTest %d: v = %s" % (ntest, binary(v[0], 0, 2 * n + 2)))
            print("m =", mm.reduce_matrix(), mm)
            print("Pauli matrix of v", p[0])
            if not ok:
                print("Input and recomputed Pauli vectors:")
                for i, x in enumerate(v):
                    bv = binary(x, 0, 2 * n + 2)
                    bpv = binary(pv[i], 0, 2 * n + 2)
                    print(bv, ",", bpv)
                if not ok:
                    err = "Error in recomputation of Pauli vector"
                    raise ValueError(err)
        mi = m.inv()
        assert m @ mi == qs_unit_matrix(n), (str(m), str(mi), str(m @ mi))

        w = m.pauli_conjugate(v)
        w_ref = [(m @ x @ mi).pauli_vector() for x in p]
        if verbose or w != w_ref:
            for i, w_i in enumerate(w):
                w_i_ref = w_ref[i]
                if w_i_ref != w_i:
                    s = "Pauli vector: %s, conjugated: %s, obtained: %s"
                    print(s % (hex(v[i]), hex(w_i_ref), hex(w_i)))
                    err = "Pauli vector conjugation error"
                    raise ValueError(err)
                elif verbose:
                    s = "Pauli vector: %s, conjugated: %s"
                    print(s % (hex(v[i]), hex(w_i)))

        w_noarg = m.pauli_conjugate(v, arg=False)
        if verbose:
            print("Without arg", [hex(x) for x in w_noarg])
        mask = (1 << (2 * n)) - 1
        assert w_noarg == [x & mask for x in w]
Example #11
0
def test_pauli_multiplication(verbose=0):
    for ntest, (n, v1, v2) in enumerate(create_pauli_vectors()):
        p1 = qs_pauli_matrix(n, v1)
        p2 = qs_pauli_matrix(n, v2)
        # Check product v1 * v2
        v3 = pauli_vector_mul(n, v1, v2)
        p3 = qs_pauli_matrix(n, v3)
        v3_ref = (p1 @ p2).pauli_vector()
        ok = v3 == v3_ref
        if verbose or not ok:
            print("Test %d, dim = %d" % (ntest, n))
            print("v1 = %s, v2 = %s, v1 * v2 = %s" %
                  (hex(v1), hex(v2), hex(v3_ref)))
            if not ok:
                print("m1", p1)
                print("m2", p2)
                print("m1 * m2", p1 @ p2)
                print("pauli vector obtained: ", hex(v3))
                err = "Pauli vector multiplication failed"
                raise ValueError(err)
        # Check powers of v1
        p_e_list = [qs_unit_matrix(n), p1, p1 @ p1, p1.H]
        v_e_ref_list = [m.pauli_vector() for m in p_e_list]
        v_e_list = [pauli_vector_exp(n, v1, e) for e in range(4)]
        ok = v_e_list == v_e_ref_list
        if verbose or not ok:
            print("v1 = ", hex(v1))
            for e, v_ref in enumerate(v_e_ref_list):
                if ok:
                    print("v1 ** %d = %s" % (e, hex(v_ref)))
                else:
                    print("v1 ** %d = %s, obtained: %s, v1 = %s" %
                          (e, hex(v_ref), hex(v_e_list[e]), v1))
            if not ok:
                err = "Pauli vector exponentiation failed"
                raise ValueError(err)