Esempio n. 1
0
    def objective_function_monte_carlo(self, u_params):
        U = U4(u_params)
        V = self.get_env(U)
        assert abs(
            full_tomography_env_objective_function(FullStateTensor(U),
                                                   FullEnvironment(V))) < 1e-6

        qbs = cirq.LineQubit.range(4)

        C = cirq.Circuit().from_ops(
            cirq.decompose(
                State(FullStateTensor(U), FullEnvironment(V), 2)(*qbs)))

        noise = cirq.ConstantQubitNoiseModel(
            cirq.depolarize(self.depolarizing_prob))

        system_qubits = sorted(C.all_qubits())
        noisy_circuit = cirq.Circuit()
        for moment in C:
            noisy_circuit.append(noise.noisy_moment(moment, system_qubits))

        sim = cirq.Simulator()
        ψ = sim.simulate(noisy_circuit).final_state
        H = kron(kron(eye(2), self.H), eye(2))
        f = real(ψ.conj().T @ H @ ψ)

        #sim = cirq.DensityMatrixSimulator(noise=noise)
        #ρ = sim.simulate(noisy_circuit).final_density_matrix

        #f =  real(trace(ρ@H))
        return f
Esempio n. 2
0
def evolve_U1():
    hh = HH(1)
    U1 = np.array([[0, 1, 0, 0], [1, 0, 0, 0], [0, 0, 0, 1], [0, 0, 1, 0]])

    STEPS = 100
    init_params = np.random.rand(15)
    results = []
    RE = RightEnvironment()

    def obj2(p, U1, h_):
        U1_ = U4(p).conj().T
        _, Mr = RE.exact_environment(r(U1), r(np.eye(4)), r(U1_), r(np.eye(4)))

        return -2 * np.abs(
            (U1_ @ h_ @ U1)[0, 0] * Mr[0, 0] * Mr[0, 0].conj())**2

    U1 = U1.conj().T
    hh = expm(1j * hh * 0.01)
    for _ in tqdm(range(STEPS)):
        res = minimize(obj2,
                       x0=init_params,
                       args=(U1, hh),
                       method="Nelder-Mead",
                       tol=1e-8,
                       options={
                           "maxiter": 40000,
                           "disp": True,
                           "adaptive": True
                       })

        init_params = res.x
        U1 = U4(res.x)
        results.append(res.x)

    return results
Esempio n. 3
0
def test_U_parametrisation_effectiveness(reps=100):
    """
    
    We want to test the effectiveness of this parametrisation of 
    unitary matrices. We specify random unitaries and then use the 
    parametrisation to find a U1' and U2' that give maximal overlap with 
    the initial matrices. In every case the overlap with the 0s was within
    1e-4 of 1.0. However U1' did not compile to U1. I suggest this might
    be because of the freedom to insert a resolution of the identity along the 
    closed legs of the overlap circuit.

    """
    results = []
    U1s = []
    U1_s = []
    for _ in range(reps):
        U1, U2 = unitary_group.rvs(4), unitary_group.rvs(4)
        cost_func = partial(params_overlaps, U1=U1, U2=U2)
        grad = partial(approx_fprime, f=cost_func, epsilon=0.001)
        res = minimize(cost_func,
                       x0=np.random.rand(18),
                       method="BFGS",
                       jac=grad)

        results.append(res.fun)
        U1s.append(U1)
        U1_s.append(U4(res.x[3:]))

    return results, U1s, U1_s
Esempio n. 4
0
def parametrised_Us(params):
    a, b, c = params[:3]
    U1_params = params[3:]

    U1 = U4(U1_params)
    u2 = (Z(a) @ X(b) @ D1(c) @ X(-b) @ Z(-a)).reshape(4, 1)
    U2 = np.concatenate((u2, null_space(u2.conj().T)), axis=1)

    return U1, U2
Esempio n. 5
0
def two_cost_functions():
    p = np.random.rand(15)
    U1 = np.array([[0, 1, 0, 0], [1, 0, 0, 0], [0, 0, 0, 1], [0, 0, 1, 0]])
    h = HH(1)

    print(obj(p, U1, h))

    U1_ = U4(p).conj().T
    LE, RE = LeftEnvironment(), RightEnvironment()
    _, Ml = LE.exact_environment(r(U1), r(np.eye(4)), r(U1_), r(np.eye(4)))
    _, Mr = RE.exact_environment(r(U1), r(np.eye(4)), r(U1_), r(np.eye(4)))
    print(Ml, "\n", Mr)
    print((U1_ @ expm(1j * h * 0.01) @ U1)[0, 0] * Mr[0, 0] * Ml[0, 0])
Esempio n. 6
0
def evolve_and_plot_U1():
    res = evolve_U1()
    states = []
    for r_ in res:
        U2 = U4(r_)
        state = U2 @ np.array([1, 0, 0, 0])
        states.append(state)

    plt.figure()
    plt.plot(np.abs(np.array(states)[:, 1])**2, label="|01>")
    plt.plot(np.abs(np.array(states)[:, 2])**2, label="|10>")
    plt.legend()
    plt.show()
Esempio n. 7
0
def obj(p, U1, h_):
    LE = LeftEnvironment()
    RE = RightEnvironment()

    psi1 = bwMPS([np.eye(4), U1], 2).state()
    U1_ = U4(p)

    _, Ml = LE.exact_environment(r(U1), r(np.eye(4)), r(U1_.conj().T),
                                 r(np.eye(4)))
    _, Mr = RE.exact_environment(r(U1), r(np.eye(4)), r(U1_.conj().T),
                                 r(np.eye(4)))

    Ut = expm(1j * h_ * 0.01)
    Ut_m = tensor([Ml, Ut, Mr])

    psi2 = bwMPS([np.eye(4), U1_], 2).state()
    return np.abs(psi2.conj().T @ Ut_m @ psi1)**2
Esempio n. 8
0
    def __init__(self,
                 H,
                 depolarizing_prob,
                 D=2,
                 get_env_function=get_env_exact,
                 initial_guess=None,
                 settings: Dict = None):
        self.get_env = get_env_function
        if D != 2:
            raise NotImplementedError('D>2 not implemented')
        self.H = H
        self.D = D
        self.d = 2
        self.depolarizing_prob = depolarizing_prob
        initial_guess = (randn(15) if initial_guess is None else initial_guess)
        u_original = FullStateTensor(U4(initial_guess))
        v_original = None

        super().__init__(u_original, v_original, initial_guess=initial_guess)
Esempio n. 9
0
def paramU(params):
    """
        Return unitaries U1 and U2 from 22 params (15 params for the fully
        parametrised U1 and 7 for the single column of the unitary U2)
        """
    p1 = params[7:]
    p2 = params[:7]

    U1 = U4(p1)
    # find a unit norm column that is going to be accessed by the circuit
    #   and embed this column into a larger unitary matrix.

    ##################################
    # u2 =  (self.Z(a) @ self.X(b) @ self.D1(c) @ self.X(-b) @ self.Z(-a)).reshape(4,1)
    #U2 = np.concatenate((u2, null_space(u2.conj().T)), axis = 1)
    ##################################
    # Doesnt look like it works

    U2 = OO_unitary(p2)

    return U1, U2
Esempio n. 10
0
    def objective_function(self, params):
        target_u = FullStateTensor(U4(params).conj())
        num_qubits = 2 * self.u.num_qubits()
        qubits = cirq.LineQubit.range(num_qubits)
        self.circuit.circuit = cirq.Circuit.from_ops([
            cirq.H.on(qubits[0]),
            cirq.H.on(qubits[1]),
            cirq.CNOT.on(qubits[0], qubits[2]),
            cirq.CNOT.on(qubits[1], qubits[3]),
            self.u.on(*qubits[0:2]),
            target_u.on(*qubits[2:4]),
            cirq.CNOT.on(qubits[0], qubits[2]),
            cirq.CNOT.on(qubits[1], qubits[3]),
            cirq.H.on(qubits[0]),
            cirq.H.on(qubits[1])
        ])

        simulator = cirq.Simulator()
        results = simulator.simulate(self.circuit.circuit)
        final_state = results.final_simulator_state.state_vector[0]
        score = np.abs(final_state)**2
        return 1 - score
Esempio n. 11
0
    def obj2(p, U1, h_):
        U1_ = U4(p).conj().T
        _, Mr = RE.exact_environment(r(U1), r(np.eye(4)), r(U1_), r(np.eye(4)))

        return -2 * np.abs(
            (U1_ @ h_ @ U1)[0, 0] * Mr[0, 0] * Mr[0, 0].conj())**2
Esempio n. 12
0
def trace_distance_cost_function(params, U):
    '''
        Circuit 1:              Circuit 2:              Circuit 3:
        Trace distance objective function:
        |   |   |   |   |   |`  |   |   |   |   |   |   |   |   |   |   |
        |   |-V-|   |   |   |`  |   |-V-|   |   |-V-|   |   |   |   |   |
        |-U-|   |   |-V-|   |`  |-U-|   |   |-U-|   |   |   |-V-|   |-V-|
        @-----------X       |`  @-----------X           |   @-------X
        H                   |`  H                       |   H
                         break1 |                    break2 |
                               rho                         sigma
    '''

    environment = FullStateTensor(U4(params))
    state = State(U, environment, 1)

    state_qubits = state.num_qubits()
    env_qubits = environment.num_qubits()

    aux_qubits = int(env_qubits / 2)
    control_qubits = list(range(aux_qubits))

    target_qubits1 = list(range(state_qubits, state_qubits + aux_qubits))
    target_qubits2 = list(range(state_qubits, state_qubits + aux_qubits))
    target_qubits3 = list(range(env_qubits, env_qubits + aux_qubits))

    total_qubits = (2 * state_qubits)
    qubits = cirq.LineQubit.range(total_qubits)

    cnots1 = [
        cirq.CNOT(qubits[i], qubits[j])
        for i, j in zip(control_qubits, target_qubits1)
    ]
    cnots2 = [
        cirq.CNOT(qubits[i], qubits[j])
        for i, j in zip(control_qubits, target_qubits2)
    ]
    cnots3 = [
        cirq.CNOT(qubits[i], qubits[j])
        for i, j in zip(control_qubits, target_qubits3)
    ]

    hadamards = [cirq.H(qubits[i]) for i in control_qubits]

    circuit1 = cirq.Circuit.from_ops([
        state(*qubits[:state_qubits]),
        environment(*qubits[state_qubits:state_qubits + env_qubits])
    ] + cnots1 + hadamards)

    circuit2 = cirq.Circuit.from_ops([
        state(*qubits[:state_qubits]),
        state(*qubits[state_qubits:total_qubits])
    ] + cnots2 + hadamards)

    circuit3 = cirq.Circuit.from_ops([
        environment(*qubits[:env_qubits]),
        environment(*qubits[env_qubits:2 * env_qubits])
    ] + cnots3 + hadamards)

    simulator = cirq.Simulator()
    results1 = simulator.simulate(circuit1)
    results2 = simulator.simulate(circuit2)
    results3 = simulator.simulate(circuit3)

    circuit1qubits = [*qubits[:aux_qubits]
                      ] + [*qubits[state_qubits:state_qubits + aux_qubits]]
    circuit3qubits = [*qubits[:aux_qubits]
                      ] + [*qubits[env_qubits:env_qubits + aux_qubits]]

    r_s = 1 - 2 * results1.density_matrix_of(circuit1qubits)[-1, -1]
    r_squared = 1 - 2 * results2.density_matrix_of(circuit1qubits)[-1, -1]
    s_squared = 1 - 2 * results3.density_matrix_of(circuit3qubits)[-1, -1]

    score = (r_squared + s_squared - 2 * r_s).real
    return np.abs(score)
Esempio n. 13
0
 def update_state(self):
     self.U = U4(self.optimized_result.x)