Beispiel #1
0
def obj(p_, A, WW):
    p, rs = p_[:15], p_[15:]
    
    B = iMPS([unitary_to_tensor(cirq.unitary(gate(p)))]).left_canonicalise()[0]

    U = Environment(tensor_to_unitary(A), 'U')
    U_ = Environment(tensor_to_unitary(B), 'U\'')

    E = Map(np.tensordot(WW, merge(A, A), [1, 0]), merge(B, B))
    x,r = E.right_fixed_point()
    x_,l = E.left_fixed_point()
    
    R = Environment(put_env_on_left_site(r), 'θR')
    L = Environment(put_env_on_right_site(r.conj().T), 'θL')
    
    W = Environment(WW, 'W')
    
    qbs = cirq.LineQubit.range(5)
    C = cirq.Circuit.from_ops([R(*qbs[3:5]),
                               U(*qbs[2:4]),
                               U(*qbs[1:3]),
                               W(*qbs[2:4]),
                               L(*qbs[0:2]),
                               cirq.inverse(U_)(*qbs[1:3]),
                               cirq.inverse(U_)(*qbs[2:4]),
                               cirq.CNOT(*qbs[3:5]), cirq.H(qbs[3])])
    
    s = cirq.Simulator(dtype=np.complex128)
    return -np.sqrt(np.abs(np.sqrt(2)*s.simulate(C).final_state[0]))
Beispiel #2
0
def obj(p, A, WW):
    B = iMPS([unitary_to_tensor(cirq.unitary(gate(p)))]).left_canonicalise()[0]
    WW_ = np.eye(WW.shape[0])

    E = Map(np.tensordot(WW, merge(A, A), [1, 0]), merge(B, B))

    x, r = E.right_fixed_point()
    x_, l = E.left_fixed_point()
    l = r

    U = Environment(tensor_to_unitary(A), 'U')
    U_ = Environment(tensor_to_unitary(B), 'U\'')

    R = Environment(put_env_on_left_site(r), 'θR')
    left = put_env_on_right_site(l.conj().T)
    L = Environment(left, 'θL')

    W = Environment(WW, 'W')

    qbs = cirq.LineQubit.range(6)
    C = cirq.Circuit([
        cirq.H(qbs[3]),
        cirq.CNOT(*qbs[3:5]),
        U(*qbs[2:4]),
        U(*qbs[1:3]),
        W(*qbs[2:4]),
        L(*qbs[0:2]),
        R(*qbs[4:]),
        cirq.inverse(U_)(*qbs[1:3]),
        cirq.inverse(U_)(*qbs[2:4]),
        cirq.CNOT(*qbs[3:5]),
        cirq.H(qbs[3])
    ])
    #qbs = cirq.LineQubit.range(4)
    #normC = cirq.Circuit.from_ops([cirq.H(qbs[1]),
    #                               cirq.CNOT(*qbs[1:3]),
    #                               L(*qbs[:2]),
    #                               R(*qbs[-2:]),
    #                               cirq.CNOT(*qbs[1:3]),
    #                               cirq.H(qbs[1])
    #                               ])
    s = cirq.Simulator(dtype=np.complex128)
    ff = np.sqrt(
        2 * np.abs(s.simulate(C).final_state[0])
    )  #/np.abs(s.simulate(normC).final_state[0])), np.sqrt(np.abs(x[0]))
    #print(ff[0]-ff[1])
    #print(ff[0], ff[1])
    return -ff
def cost_func(params, U2,U1,Ū2,Ū1):
    m = M(params)
    A1 = alternate_tensor(U2,U1)
    A2 = alternate_tensor(Ū2,Ū1)
    TransferMatrix = Map(A1,A2)
    EigenEqn = TransferMatrix @ m.reshape(4)
    return np.linalg.norm(m - EigenEqn.reshape(2,2))
Beispiel #4
0
    def objective_function(self, params):        
        U_ = self.gate(params)
        U = self.u
        A = unitary_to_tensor(cirq.unitary(U))
        A_ = unitary_to_tensor(cirq.unitary(U_))
        
        _, r = Map(A,A_).right_fixed_point()
        
        R = Environment(put_env_on_left_site(r), 'R')
        L = Environment(put_env_on_right_site(r.conj().T), 'L')
        
        W = Environment(W, 'W')

        qbs = cirq.LineQubit.range(6)
        C = cirq.Circuit.from_ops([cirq.H(qbs[3]), cirq.CNOT(*qbs[3:5]),
                                   U(*qbs[2:4]),
                                   U(*qbs[1:3]),
                                   W(*qbs[2:4]),
                                   L(*qbs[0:2]),
                                   R(*qbs[4:]),
                                   cirq.inverse(U_)(*qbs[1:3]),
                                   cirq.inverse(U_)(*qbs[2:4]),
                                   cirq.CNOT(*qbs[3:5]), cirq.H(qbs[3])])

        s = cirq.Simulator(dtype=np.complex128)
        return -np.abs(s.simulate(C).final_state[0])*2
Beispiel #5
0
def time_evolve_sim_state(params, U, W):
    """
    Circuit which returns the overlap between 2 MPS states, defined by the unitaries U_ = U4(params) & U = tensor_to_unitary(A). The full wavefunction is returns for debugging purposes.
    """

    circ = QuantumCircuit(6, 6)

    U_ = self.gate(params)
    A = unitary_to_tensor(cirq.unitary(U))
    A_ = unitary_to_tensor(cirq.unitary(U_))

    _, r = Map(A, A_).right_fixed_point()

    R = Operator(put_env_on_left_site(r))
    L = Operator(put_env_on_right_site(r.conj().T))

    circ.h(3)
    circ.cx(3, 4)
    circ.unitary(U, [3, 2])
    circ.unitary(U, [2, 1])
    circ.unitary(L, [1, 0])
    circ.unitary(R, [5, 4])
    circ.unitary(H, [3, 2])
    circ.unitary(target_u, [2, 1])
    circ.unitary(target_u, [3, 2])
    circ.cx(3, 4)
    circ.h(3)

    result = execute(circ, simulator).result()
    ψ = result.get_statevector(circ)

    return ψ
def get_overlap_exact(p1, p2, gate=gate, testing=True):
    A = iMPS([unitary_to_tensor(cirq.unitary(gate(p1)))
              ]).left_canonicalise()[0]
    B = iMPS([unitary_to_tensor(cirq.unitary(gate(p2)))
              ]).left_canonicalise()[0]
    x, r = Map(A, B).right_fixed_point()
    if testing:
        return np.abs(x)**2, r
    else:
        return np.abs(x)**2
Beispiel #7
0
def scars_cost_fun_alternate(params, current_params, ham):
    '''
    This cost function doesn't use the quantum circuit parameterisation
    
    params are formatted like: [θ1, ϕ1, ϕ2, θ2], for convenience with the classical differential eqn solver
    '''
    θ1, ϕ1, ϕ2, θ2 = current_params
    θ1_, ϕ1_, ϕ2_, θ2_ = params

    A1 = A(θ1, ϕ1)
    A2 = A(θ2, ϕ2)
    A1_ = A(θ1_, ϕ1_)
    A2_ = A(θ2_, ϕ2_)

    A12 = merge(A1, A2)
    A12_ = merge(A1_, A2_)

    _, r = Map(A12, A12_).right_fixed_point()
    R = Environment(put_env_on_left_site(r), 'R')
    L = Environment(put_env_on_right_site(r.conj().T), 'L')

    U12 = Tensor(tensor_to_unitary(A12), 'U')
    U12_ = Tensor(tensor_to_unitary(A12_), 'U\'')

    q = cirq.LineQubit.range(8)
    circuit = cirq.Circuit.from_ops([
        cirq.H(q[5]),
        cirq.CNOT(q[5], q[6]),
        U12(*q[3:6]),
        U12(*q[1:4]),
        L(*q[0:2]),
        ham(*q[2:6]),
        R(*q[6:8]),
        cirq.inverse(U12_(*q[1:4])),
        cirq.inverse(U12_(*q[3:6])),
        cirq.CNOT(q[5], q[6]),
        cirq.H(q[5])
    ])

    # print(circuit.to_text_diagram(transpose = True))
    sim = cirq.Simulator()
    ψ = sim.simulate(circuit).final_state[0]
    return -np.abs(ψ) * 2
Beispiel #8
0
    def setUp(self):
        N = 10
        D_min, D_max = 10, 11
        d_min, d_max = 2, 3
        p_min, p_max = 1, 2  # always 1 for now
        self.rand_cases1 = [
            iMPS().random(randint(d_min, d_max),
                          randint(D_min, D_max),
                          period=randint(p_min, p_max)) for _ in range(N)
        ]

        self.rand_cases2 = [
            iMPS().random(randint(d_min, d_max),
                          randint(D_min, D_max),
                          period=randint(p_min, p_max)) for _ in range(N)
        ]

        self.maps = [
            Map(case1[0], case2[0])
            for case1, case2 in zip(self.rand_cases1, self.rand_cases2)
        ]
Beispiel #9
0
def scars_time_evolve_cost_function(params, current_params, ham):
    '''
    params are formatted like: [θ1, ϕ1, ϕ2, θ2], for convenience with the classical differential eqn solver
    '''
    θ1, ϕ1, ϕ2, θ2 = current_params
    θ1_, ϕ1_, ϕ2_, θ2_ = params

    A1 = A(θ1, ϕ1)
    A2 = A(θ2, ϕ2)
    A1_ = A(θ1_, ϕ1_)
    A2_ = A(θ2_, ϕ2_)

    _, r = Map(merge(A1, A2), merge(A1_, A2_)).right_fixed_point()
    R = Environment(put_env_on_left_site(r), 'R')
    L = Environment(put_env_on_right_site(r.conj().T), 'L')

    U12 = ScarGate(current_params)
    U12_ = ScarGate(params)
    q = cirq.LineQubit.range(8)
    circuit = cirq.Circuit.from_ops([
        cirq.H(q[5]),
        cirq.CNOT(q[5], q[6]),
        U12(*q[3:6]),
        U12(*q[1:4]),
        L(*q[0:2]),
        ham(*q[2:6]),
        R(*q[6:8]),
        cirq.inverse(U12_(*q[1:4])),
        cirq.inverse(U12_(*q[3:6])),
        cirq.CNOT(q[5], q[6]),
        cirq.H(q[5])
    ])

    # print(circuit.to_text_diagram(transpose = True))
    sim = cirq.Simulator()
    ψ = sim.simulate(circuit).final_state[0]
    return -np.abs(ψ) * 2
Beispiel #10
0
def random_test(N=100,
                dt=1e-2,
                max_tries=20,
                η=0.,
                noisy=False,
                k=1,
                tol=1e-10):
    evals = []
    tqer = tqdm(range(N)) if not noisy else range(N)
    for _ in tqer:
        H = Hamiltonian({'ZZ': 1, 'X': 1}).to_matrix()

        A = iMPS().random(2, 2).left_canonicalise()
        B = (A + dt * A.dA_dt([H])).left_canonicalise()
        EAB = Map(A[0], B[0])

        def objective(p, EAB=EAB, η=η):
            EAB = EAB.asmatrix()
            er, eim, p1, p2 = p[0], p[1], p[2:17], p[17:]
            e = er + 1j * eim
            #v = EAB@vec(p1)-e*vec(p1)
            v = vec(p1)
            return np.real(v.conj().T @ EAB.conj().T @ EAB @ v) + np.abs(
                e)**2 - 2 * np.real(e * v.conj().T @ EAB @ v) + η * np.abs(
                    (0.99 - e))**2
            #return np.real(v.conj().T@v) + η*np.abs((1-e))**2

        def abs_objective(p, EAB=EAB, η=η):
            EAB = EAB.asmatrix()
            er, eim, p1, p2 = p[0], p[1], p[2:17], p[17:]
            e = er + 1j * eim
            #v = EAB@vec(p1)-e*vec(p1)
            v = vec(p1)
            return np.real(v.conj().T @ EAB.conj().T @ EAB
                           @ v) + np.abs(e)**2 - 2 * np.abs(e) * np.abs(
                               v.conj().T @ EAB @ v) + η * np.abs(
                                   (0.99 - e))**2
            #return np.real(v.conj().T@v) + η*np.abs((1-e))**2

        e, r = EAB.right_fixed_point()

        x = randn(9)
        x[0] = 1
        x[1] = 0

        abs_λ = 0
        tries = 0
        eigval_results = []
        eigvec_results = []
        while tries < max_tries and np.abs(abs_λ) < 1 - k * dt:
            abs_res = minimize(abs_objective,
                               randn(9),
                               method='BFGS',
                               options={'disp': noisy},
                               tol=tol)
            abs_λ, abs_result_vector = abs_res.x[0] + 1j * abs_res.x[1], vec(
                abs_res.x[2:9])
            tries += 1
            eigval_results.append(np.abs(abs_λ))
            eigvec_results.append(abs_result_vector)
            #print(np.abs(e), np.abs(abs_λ), 1-10*dt**2)
            if not noisy:
                tqer.set_description(
                    f'{tries} repeats, {np.round(np.abs(abs_λ), 3)}')
                if tries == max_tries - 1:
                    tqer.set_description('max_iters reached')
                    abs_λ = np.max(eigval_results)
                    abs_result_vector = eigvec_results[np.argmax(
                        eigval_results)]

        def dephase(v):
            return v / np.exp(1j * np.angle(v[0]))

        if noisy:
            print('eigenvectors')
            print('actual: ', r.reshape(-1).real)
            print('variational: ', dephase(result_vector).real)
            print('abs variational: ', dephase(abs_result_vector).real)
            print('\n')
            print('eigenvalues')
            print('actual: ', np.abs(e))
            print('variational: ', np.abs(λ))
            print('abs variational: ', np.abs(abs_λ))
        evals.append(np.abs(e) + 1j * np.abs(abs_λ))

    return np.array(evals)
Beispiel #11
0
            get_env_off_left_site(np.prod(put_env_on_left_site(q,
                                                               ret_n=True))),
            q)
        assert np.allclose(
            get_env_off_right_site(
                np.prod(put_env_on_right_site(q, ret_n=True))), q)
        U = put_env_on_left_site(q)
        V = put_env_on_right_site(q)
        assert np.allclose(V.conj().T @ V, np.eye(U.shape[0]))
        assert np.allclose(U.conj().T @ U, np.eye(U.shape[0]))

    for _ in range(N):
        A = iMPS().random(2, 2).left_canonicalise()[0]
        B = iMPS().random(
            2,
            2).left_canonicalise()[0]  #np.tensordot(expm(-1j*Z*dt), A, [1, 0])

        U = Environment(tensor_to_unitary(A), 'U')
        U_ = Environment(tensor_to_unitary(B), 'U\'')

        x, r = Map(merge(A, A), merge(B, B)).right_fixed_point()
        x_, l = Map(merge(A, A), merge(B, B)).left_fixed_point()
        L = put_env_on_right_site(l)
        R = put_env_on_left_site(r)
        assert np.allclose(get_env_off_left_site(put_env_on_left_site(r)), r)
        assert np.allclose(get_env_off_right_site(put_env_on_right_site(l)), l)
        U = put_env_on_left_site(r)
        V = put_env_on_right_site(l)
        assert np.allclose(V.conj().T @ V, np.eye(U.shape[0]))
        assert np.allclose(U.conj().T @ U, np.eye(U.shape[0]))
Beispiel #12
0
def run_tests(N):
    """run_tests: just a whole bunch of tests.

    :param N: number of iterations to run
    """
    for _ in range(N):
        q = np.random.randn(2, 2)+1j*np.random.randn(2, 2)
        assert np.allclose(get_env_off_left_site(np.prod(put_env_on_left_site(q, ret_n=True))), q)
        assert np.allclose(get_env_off_right_site(np.prod(put_env_on_right_site(q, ret_n=True))), q)
        U = put_env_on_left_site(q)
        V = put_env_on_right_site(q)
        assert np.allclose(V.conj().T@V, np.eye(U.shape[0]))
        assert np.allclose(U.conj().T@U, np.eye(U.shape[0]))
        
        A = iMPS().random(2, 2).left_canonicalise()[0]
        B = iMPS().random(2, 2).left_canonicalise()[0]#np.tensordot(expm(-1j*Z*dt), A, [1, 0])

        U = Environment(tensor_to_unitary(A), 'U')
        U_ = Environment(tensor_to_unitary(B), 'U\'')

        x, r = Map(merge(A, A), merge(B, B)).right_fixed_point()
        x_, l = Map(merge(A, A), merge(B, B)).left_fixed_point()
        L = put_env_on_right_site(l)
        R = put_env_on_left_site(r)
        assert np.allclose(get_env_off_left_site(put_env_on_left_site(r)), r)
        assert np.allclose(get_env_off_right_site(put_env_on_right_site(l)), l)
        U = put_env_on_left_site(r)
        V = put_env_on_right_site(l)
        assert np.allclose(V.conj().T@V, np.eye(U.shape[0]))
        assert np.allclose(U.conj().T@U, np.eye(U.shape[0]))

        A = iMPS().random(2, 2).left_canonicalise()[0]
        B = iMPS().random(2, 2).left_canonicalise()[0]#np.tensordot(expm(-1j*Z*dt), A, [1, 0])

        E = Map(A, B)

        x, r = E.right_fixed_point()
        x_, l = E.left_fixed_point()


        U = Environment(tensor_to_unitary(A), 'U')
        U_ = Environment(tensor_to_unitary(B), 'U\'')

        R = Environment(put_env_on_left_site(r), 'R')
        L = Environment(put_env_on_right_site(l.conj().T), 'L')


        qbs = cirq.LineQubit.range(4)
        for g in zip([cirq.I, cirq.X, cirq.Y, cirq.Z], [I, X, Y, Z]):
            C = cirq.Circuit.from_ops([cirq.H(qbs[1]), cirq.CNOT(*qbs[1:3]), 
                                       R(*qbs[2:]),
                                       g[0](qbs[1]),
                                       cirq.CNOT(*qbs[1:3]), cirq.H(qbs[1])])
            s = cirq.Simulator()
            assert np.allclose(2*s.simulate(C).final_state[0]-np.trace(g[1]@r), 0, 1e-6, 1e-6)
        # r is the matrix on the 1st qubit

        qbs = cirq.LineQubit.range(4)
        for g in zip([cirq.I, cirq.X, cirq.Y, cirq.Z], [I, X, Y, Z]):
            C = cirq.Circuit.from_ops([cirq.H(qbs[1]), cirq.CNOT(*qbs[1:3]),
                                       U(*qbs[0:2]),
                                       R(*qbs[2:]),
                                       g[0](qbs[0]),
                                       cirq.inverse(U_)(*qbs[0:2]),
                                       cirq.CNOT(*qbs[1:3]), cirq.H(qbs[1])])
            s = cirq.Simulator()
            assert np.allclose(2*s.simulate(C).final_state[0]-x*np.trace(g[1]@r), 0, 1e-6, 1e-6)

        qbs = cirq.LineQubit.range(5)
        for g in zip([cirq.I, cirq.X, cirq.Y, cirq.Z], [I, X, Y, Z]):
            C = cirq.Circuit.from_ops([cirq.H(qbs[2]), cirq.CNOT(*qbs[2:4]),
                                       U(*qbs[1:3]),
                                       U(*qbs[0:2]),
                                       R(*qbs[3:]),
                                       g[0](qbs[0]),
                                       cirq.inverse(U_)(*qbs[0:2]),
                                       cirq.inverse(U_)(*qbs[1:3]),
                                       cirq.CNOT(*qbs[2:4]), cirq.H(qbs[2])])
            s = cirq.Simulator()
            #print(C.to_text_diagram(transpose=True))
            #raise Exception
            assert np.allclose(2*s.simulate(C).final_state[0]-x**2*np.trace(g[1]@r), 0, 1e-6, 1e-6)


        qbs = cirq.LineQubit.range(3)
        for g in zip([cirq.I, cirq.X, cirq.Y, cirq.Z], [I, X, Y, Z]):
            C = cirq.Circuit.from_ops([cirq.H(qbs[1]), cirq.CNOT(*qbs[1:3]), 
                                       L(*qbs[:2]),
                                       g[0](qbs[2]),
                                       cirq.CNOT(*qbs[1:3]), cirq.H(qbs[1])])
            s = cirq.Simulator()

            assert np.allclose(2*s.simulate(C).final_state[0]-np.trace(g[1]@l.conj()), 0, 1e-6, 1e-6)
        # r is the matrix on the 1st qubit

        qbs = cirq.LineQubit.range(4)
        for g in zip([cirq.I, cirq.X, cirq.Y, cirq.Z], [I, X, Y, Z]):
            C = cirq.Circuit.from_ops([cirq.H(qbs[2]), cirq.CNOT(*qbs[2:4]),
                                       U(*qbs[1:3]),
                                       L(*qbs[:2]),
                                       g[0](qbs[3]),
                                       cirq.inverse(U_)(*qbs[1:3]),
                                       cirq.CNOT(*qbs[2:4]), cirq.H(qbs[2])])
            s = cirq.Simulator()
            #print(C.to_text_diagram(transpose=True))
            #raise Exception
            assert np.allclose(2*s.simulate(C).final_state[0]-x*np.trace(g[1]@l.conj()), 0, 1e-6, 1e-6)

        qbs = cirq.LineQubit.range(5)
        for g in zip([cirq.I, cirq.X, cirq.Y, cirq.Z], [I, X, Y, Z]):
            C = cirq.Circuit.from_ops([cirq.H(qbs[3]), cirq.CNOT(*qbs[3:5]),
                                       U(*qbs[2:4]),
                                       U(*qbs[1:3]),
                                       L(*qbs[0:2]),
                                       g[0](qbs[4]),
                                       cirq.inverse(U_)(*qbs[1:3]),
                                       cirq.inverse(U_)(*qbs[2:4]),
                                       cirq.CNOT(*qbs[3:5]), cirq.H(qbs[3])])
            s = cirq.Simulator()
            assert np.allclose(2*s.simulate(C).final_state[0]-x**2*np.trace(g[1]@l.conj()), 0, 1e-6, 1e-6)

        qbs = cirq.LineQubit.range(6)
        C = cirq.Circuit.from_ops([cirq.H(qbs[3]), cirq.CNOT(*qbs[3:5]),
                                   U(*qbs[2:4]),
                                   U(*qbs[1:3]),
                                   L(*qbs[0:2]),
                                   R(*qbs[4:]),
                                   cirq.inverse(U_)(*qbs[1:3]),
                                   cirq.inverse(U_)(*qbs[2:4]),
                                   cirq.CNOT(*qbs[3:5]), cirq.H(qbs[3])])
        s = cirq.Simulator()
        assert np.allclose(2*s.simulate(C).final_state[0], x**2*np.trace(l.conj().T@r))