Пример #1
0
def singleProjectorSample(args):
    (P, L, seed) = args  # unpack arguments (easier for parallel code)
    (phases, xs, zs) = P
    t = len(xs[0])

    # init seed
    np.random.seed(seed)

    # sample random theta
    theta = StabilizerState.randomStabilizerState(t)

    # project random state to P
    projfactor = 1
    for g in range(len(phases)):
        res = theta.measurePauli(phases[g], zs[g], xs[g])
        projfactor *= res

        if res == 0: return 0  # theta annihilated by P

    total = 0
    if L is None:  # exact decomposition
        size = int(np.ceil(t / 2))
        for i in range(0, 2**size):
            phi = prepH(i, t)
            total += StabilizerState.innerProduct(theta, phi)

    else:  # approximate decomposition
        size = len(L)
        for i in range(0, 2**size):
            phi = prepL(i, t, L)
            total += StabilizerState.innerProduct(theta, phi)

    return 2**t * np.abs(projfactor * total)**2
Пример #2
0
def prepL(i, t, L):
    # compute bitstring by adding rows of l
    Lbits = list(np.binary_repr(i, width=len(L)))
    bitstring = np.zeros(t)
    for idx in range(len(Lbits)):
        if Lbits[idx] == '1':
            bitstring += L[idx]
    bitstring = bitstring.astype(int) % 2

    # Stabilizer state is product of |0> and |+>
    # 1's in bitstring indicate positions of |+>

    # initialize stabilizer state
    phi = StabilizerState(t, t)

    # construct state using shrink
    for xtildeidx in range(t):
        if bitstring[xtildeidx] == 0:
            vec = np.zeros(t)
            vec[xtildeidx] = 1
            phi.shrink(vec, 0)
            # |0> at index, inner prod with 1 is 0
        # |+> at index -> do nothing

    return phi
Пример #3
0
def exactThread(args):
    (P, L, i) = args
    (phases, xs, zs) = P

    t = len(xs[0])
    if L is None: size = int(np.ceil(t/2))
    else: size = len(L)

    total = 0

    if L is None: theta = prepH(i, t)
    else: theta = prepL(i, t, L)

    projfactor = 1
    for g in range(len(phases)):
        res = theta.measurePauli(phases[g], zs[g], xs[g])
        projfactor *= res
        if res == 0: return 0  # theta annihilated by P

    for j in range(0, 2**size):
        if L is None: phi = prepH(j, t)
        else: phi = prepL(j, t, L)

        inner = StabilizerState.innerProduct(theta, phi)

        total += inner * projfactor
    return total
Пример #4
0
def load(psi):
    state = StabilizerState(psi["n"], psi["k"])
    state.G = np.array(psi["G"])
    state.Gbar = np.array(psi["Gbar"])
    state.h = np.array(psi["h"])

    if "D" in psi:
        state.D = np.array(psi["D"])[:state.k]
        state.J = np.array(psi["J"])[:state.k, :state.k] * 4
        state.Q = psi["Q"]

    return state
Пример #5
0
def evalHcomponent(args):
    (i, _, theta, t) = args  # unpack arguments (easier for parallel code)

    size = int(np.ceil(t/2))
    odd = t % 2 == 1

    bits = list(np.binary_repr(i, width=size))

    # initialize stabilizer state
    phi = StabilizerState(t, t)

    for idx in range(size):
        bit = int(bits[idx])

        if bit == 0 and not (odd and idx == size-1):
            # phi.J = np.array([[0, 4], [4, 0]])
            phi.J[idx*2+1, idx*2] = 4
            phi.J[idx*2, idx*2+1] = 4

    for idx in range(size):
        bit = int(bits[idx])
        vec = np.zeros(t)

        if odd and idx == size-1:
            vec[t-1] = 1
            # last qubit: |H> = (1/2v)(|0> + |+>)
            if bit == 0:
                phi.measurePauli(0, vec, np.zeros(t))  # |0>, measure Z
            else:
                phi.measurePauli(0, np.zeros(t), vec)  # |+>, measure X

            continue

        if bit == 0: continue

        vec[idx*2+1] = 1
        vec[idx*2] = 1

        phi.measurePauli(0, np.zeros(t), vec)  # measure XX
        phi.measurePauli(0, vec, np.zeros(t))  # measure ZZ

    return StabilizerState.innerProduct(theta, phi)
Пример #6
0
def evalLcomponent(args):
    (i, L, theta, t) = args  # unpack arguments (easier for parallel code)

    # compute bitstring by adding rows of l
    Lbits = list(np.binary_repr(i, width=len(L)))
    bitstring = np.zeros(t)
    for idx in range(len(Lbits)):
        if Lbits[idx] == '1':
            bitstring += L[idx]
    bitstring = bitstring.astype(int) % 2

    # Stabilizer state is product of |0> and |+>
    # 1's in bitstring indicate positions of |+>

    # initialize stabilizer state
    phi = StabilizerState(t, t)

    # construct state by measuring paulis
    for xtildeidx in range(t):
        vec = np.zeros(t)
        vec[xtildeidx] = 1
        if bitstring[xtildeidx] == 1:
            # |+> at index, so measure X
            phi.measurePauli(0, np.zeros(t), vec)
        else:
            # |0> at index, so measure Z
            phi.measurePauli(0, vec, np.zeros(t))

    return StabilizerState.innerProduct(theta, phi)
Пример #7
0
def sampleProjector(args):
    (P, L, seed, parallel) = args  # unpack arguments (easier for parallel code)
    (phases, xs, zs) = P

    # empty projector
    if len(phases) == 0:
        return 1

    t = len(xs[0])

    # clifford circuit
    if t == 0:
        lookup = {0: 1, 2: -1}
        generators = [1]  # include identity
        for phase in phases: generators.append(lookup[phase])

        # calculate sum of all permutations of generators
        return sum(generators)/len(generators)

    # set unique seed for this calculation
    # np.random.seed((seed) % 4294967296)

    # sample random theta
    theta = StabilizerState.randomStabilizerState(t)

    # project random state to P
    projfactor = 1
    for g in range(len(phases)):
        res = theta.measurePauli(phases[g], zs[g], xs[g])
        projfactor *= res

        # if res == 0: return 0  # theta annihilated by P

    if L is None:  # use exact decomp into pairs of stabilizer states
        func = evalHcomponent
        size = int(np.ceil(t/2))  # need one bit for each pair, plus one more if t is odd
    else:
        func = evalLcomponent
        size = len(L)

    parallel = False

    if parallel:  # parallelize for large enough L
        pool = Pool()
        total = sum(pool.map(func, [(i, L, theta, t) for i in range(0, 2**size)]))
        pool.close()
        pool.join()
    else:
        total = sum(map(func, [(i, L, theta, t) for i in range(0, 2**size)]))

    return 2**t * np.abs(projfactor*total)**2
Пример #8
0
def load(psi):
    state = StabilizerState(psi["n"], psi["k"])
    state.G = np.array(psi["G"])
    state.Gbar = np.array(psi["Gbar"])
    state.h = np.array(psi["h"])

    if "D" in psi:
        state.D = np.array(psi["D"])[:state.k]
        state.J = np.array(psi["J"])[:state.k, :state.k]*4
        state.Q = psi["Q"]

    return state
Пример #9
0
def prepH(i, t):
    size = int(np.ceil(t / 2))
    odd = t % 2 == 1

    bits = list(np.binary_repr(i, width=size))

    # initialize stabilizer state
    phi = StabilizerState(t, t)

    # set J matrix
    for idx in range(size):
        bit = int(bits[idx])
        if bit == 0 and not (odd and idx == size - 1):
            # phi.J = np.array([[0, 4], [4, 0]])
            phi.J[idx * 2 + 1, idx * 2] = 4
            phi.J[idx * 2, idx * 2 + 1] = 4

    # truncate affine space using shrink
    for idx in range(size):
        bit = int(bits[idx])
        vec = np.zeros(t)

        if odd and idx == size - 1:
            # bit = 0 is |+>
            # bit = 1 is |0>
            if bit == 1:
                vec[t - 1] = 1
                phi.shrink(vec, 0)
            continue

        # bit = 1 corresponds to |00> + |11> state
        # bit = 0 corresponds to |00> + |01> + |10> - |11>

        if bit == 1:
            vec[idx * 2] = 1
            vec[idx * 2 + 1] = 1
            phi.shrink(vec, 0)  # only 00 and 11 have inner prod 0 with 11

    return phi
Пример #10
0
def exactProjectorWork(args):
    (P, L, l) = args
    (phases, xs, zs) = P

    t = len(xs[0])
    if L is None: size = int(np.ceil(t / 2))
    else: size = len(L)

    chi = 2**size

    i = 0
    while l >= chi - i:
        l -= chi - i
        i += 1
    j = l + i

    if L is None: theta = prepH(i, t)
    else: theta = prepL(i, t, L)

    projfactor = 1
    for g in range(len(phases)):
        res, status = theta.measurePauli(phases[g],
                                         zs[g],
                                         xs[g],
                                         give_status=True)

        projfactor *= res

        if res == 0: return 0  # theta annihilated by P

    if L is None: phi = prepH(j, t)
    else: phi = prepL(j, t, L)

    inner = StabilizerState.innerProduct(theta, phi)
    if i == j:
        return inner * projfactor
    else:
        return 2 * np.real(inner) * projfactor
Пример #11
0
f = open(directory + "ExponentialSum.txt")
tests = json.loads(f.read())
# tests = []

indexcut = 0
failed = 0
index = 0
starttime = datetime.now()
for test in tests:
    index += 1
    if index < indexcut: continue
    # don't actually depend on n, but need for initialization
    k = len(test["D"]["D"])
    # k = 4
    state = StabilizerState(k, k)
    # state.D = np.array(test["D"]["D"])[:4]
    state.D = np.array(test["D"]["D"])
    # state.J = np.array(test["J"]["J"])[:4, :4]*4
    state.J = np.array(test["J"]["J"])*4
    state.Q = test["Q"]["Q"]

    (eps, p, m) = state.exponentialSum(exact=True)
    if eps != test["eps_out"]\
            or m != test["m_out"] % 8\
            or p != test["p_out"]:
        if failed == 0: print("ExponentialSum errors:")
        print("ExponentialSum %d (k=%d) failed: (%d,%d,%d) should be (%d,%d,%d)" %
              (index, state.k, eps, p, m, test["eps_out"], test["p_out"], test["m_out"]))
        failed += 1
    # break
Пример #12
0
f = open(directory + "ExponentialSum.txt")
tests = json.loads(f.read())
tests = []

indexcut = 0
failed = 0
index = 0
starttime = datetime.now()
for test in tests:
    index += 1
    if index < indexcut: continue
    # don't actually depend on n, but need for initialization
    k = len(test["D"]["D"])
    # k = 4
    state = StabilizerState(k, k)
    # state.D = np.array(test["D"]["D"])[:4]
    state.D = np.array(test["D"]["D"])
    # state.J = np.array(test["J"]["J"])[:4, :4]*4
    state.J = np.array(test["J"]["J"]) * 4
    state.Q = test["Q"]["Q"]

    (eps, p, m) = state.exponentialSum(exact=True)
    if eps != test["eps_out"]\
            or m != test["m_out"] % 8\
            or p != test["p_out"]:
        if failed == 0: print("ExponentialSum errors:")
        print(
            "ExponentialSum %d (k=%d) failed: (%d,%d,%d) should be (%d,%d,%d)"
            % (index, state.k, eps, p, m, test["eps_out"], test["p_out"],
               test["m_out"]))