Пример #1
0
    def test_sample_2qb(self):

        qpu = PyLinalg()
        prog = Program()
        qbits = prog.qalloc(2)
        prog.apply(X, qbits[0])
        circ = prog.to_circ()

        obs = Observable(2, pauli_terms=[Term(1., "ZZ", [0, 1])])
        job = circ.to_job("OBS", observable=obs)

        result = qpu.submit(job)
        self.assertAlmostEqual(result.value, -1)

        prog = Program()
        qbits = prog.qalloc(2)
        prog.apply(X, qbits[0])

        prog.apply(X, qbits[1])
        circ = prog.to_circ()

        obs = Observable(2, pauli_terms=[Term(1., "ZZ", [0, 1])])
        job = circ.to_job("OBS", observable=obs)

        result = qpu.submit(job)
        self.assertAlmostEqual(result.value, 1)
Пример #2
0
def C(graph):

    energy = Observable(graph.V)
    for edge in itertools.combinations(range(graph.V), 2):
        energy.add_term(Term(-graph.E[edge] / 2, "ZZ", edge))
    energy.constant_coeff += np.sum(graph.E) / 4

    return energy
Пример #3
0
def generate_random_observable(nbqbit: int) -> Observable:
    """
    Generate a random observable.

    Args:
        nbqbit (int): number of qubits

    Returns:
        Observable: an observable
    """

    # Determine randomly the number of Pauli terms in the observable
    nb_terms = rd.randint(1, nbqbit)

    pauli_terms = []
    for _ in range(nb_terms):
        # Determine randomly the number of qubits involve in the Pauli term
        nb_qbit_term = rd.randint(1, nbqbit)
        # Build randomly the tensor of the term
        tensor = ''.join(
            [rd.choice(['X', 'Y', 'Z']) for _ in range(nb_qbit_term)])
        # Create and add the term to the list
        pauli_terms.append(
            Term(rd.random(), tensor, rd.sample(range(nbqbit), nb_qbit_term)))
    # build and return the observable
    return Observable(nbqbit,
                      pauli_terms=pauli_terms,
                      constant_coeff=rd.random())
Пример #4
0
    def test4_cannot_measure_observable(self):
        """
        Checks if measuring an Observable raises an error
        """
        prog = Program()
        qbits = prog.qalloc(1)
        prog.apply(X, qbits)
        circ = prog.to_circ()

        qpu = BackendToQPU(Aer.get_backend('qasm_simulator'))
        self.assertRaises(QPUException, qpu.submit,
                          circ.to_job("OBS", observable=Observable(1)))
    def test_basic(self):
        with self.assertRaises(QPUException):
            prog = Program()
            qbits = prog.qalloc(1)
            prog.apply(X, qbits)
            circ = prog.to_circ()

            obs = Observable(1, pauli_terms=[Term(1., "Z", [0])])
            job = circ.to_job("OBS", observable=obs, nbshots=10)

            qpu = PyLinalg()

            result = qpu.submit(job)
Пример #6
0
    def test_sample_1qb_Y(self):

        prog = Program()
        qbits = prog.qalloc(1)
        prog.apply(H, qbits)
        prog.apply(PH(-np.pi / 2), qbits)
        circ = prog.to_circ()

        obs = Observable(1, pauli_terms=[Term(1., "Y", [0])])
        job = circ.to_job("OBS", observable=obs)

        qpu = PyLinalg()
        result = qpu.submit(job)
        self.assertAlmostEqual(result.value, -1)

        obs = Observable(1, pauli_terms=[Term(18., "Y", [0])])
        job = circ.to_job("OBS", observable=obs)

        result = qpu.submit(job)
        self.assertAlmostEqual(result.value, -18)

        prog = Program()
        qbits = prog.qalloc(1)
        prog.apply(H, qbits)
        prog.apply(PH(np.pi / 2), qbits)
        circ = prog.to_circ()

        obs = Observable(1, pauli_terms=[Term(1., "Y", [0])])
        job = circ.to_job("OBS", observable=obs)

        result = qpu.submit(job)
        self.assertAlmostEqual(result.value, 1)

        obs = Observable(1, pauli_terms=[Term(18., "Y", [0])])
        job = circ.to_job("OBS", observable=obs)

        result = qpu.submit(job)
        self.assertAlmostEqual(result.value, 18)
Пример #7
0
    def test_submit_job(self):

        # Create a valid qpu
        qpu_valid = SimulatedAnnealing(
            temp_t=TestSimulatedAnnealing.temp_t_valid,
            n_steps=TestSimulatedAnnealing.n_steps_valid,
            seed=8017)

        # Create an Observable Job and check that such Jobs are not dealt with by the qpu
        observable = Observable(5)
        job = Job(observable=observable)
        with pytest.raises(exceptions_types.QPUException):
            assert result == qpu_valid.submit_job(job)

        # Create a circuit Job a and check that such Jobs are not dealt with by the qpu
        from qat.lang.AQASM import Program, H
        prog = Program()
        reg = prog.qalloc(1)
        prog.apply(H, reg)
        prog.reset(reg)
        with pytest.raises(exceptions_types.QPUException):
            assert result == qpu_valid.submit(prog.to_circ().to_job(nbshots=1))

        # Create a Job from a Schedule with empty drive and check that such
        # Jobs are not dealt with by the qpu
        schedule = Schedule()
        job = Job(schedule=schedule)
        with pytest.raises(exceptions_types.QPUException):
            assert result == qpu_valid.submit_job(job)

        # Create a job from a Schedule with a drive with more than one observable
        # or an observable with coefficient not 1 to check that such Jobs don't work
        # with the qpu
        observable = get_observable(TestSimulatedAnnealing.J_valid,
                                    TestSimulatedAnnealing.h_valid,
                                    TestSimulatedAnnealing.offset_valid)
        drive_invalid_1 = [(1, observable), (1, observable)]
        schedule = Schedule(drive=drive_invalid_1)
        job = schedule.to_job()
        with pytest.raises(exceptions_types.QPUException):
            assert result == qpu_valid.submit_job(job)
        drive_invalid_2 = [(5, observable)]
        schedule = Schedule(drive=drive_invalid_2)
        job = schedule.to_job()
        with pytest.raises(exceptions_types.QPUException):
            assert result == qpu_valid.submit_job(job)

        # Solve the problem and check that the returned result is Result
        result = qpu_valid.submit_job(TestSimulatedAnnealing.job_valid)
        assert isinstance(result, Result)
Пример #8
0
def get_observable(J, h, offset):
    """
    Returns an Observable from a J coupling and magnetic field h
    of an Ising problem.

    Returns:
        :class:`~qat.core.Observable`: an Ising Hamiltonian encoding the problem
    """

    n_spins = J.shape[0]
    observable = Observable(n_spins, constant_coeff=-offset)
    for i in range(n_spins):
        if not np.isclose(h[i], 0):
            observable.terms.append(Term(-h[i], "Z", [i]))
        for j in range(i + 1, n_spins):
            if not np.isclose(J[i, j], 0):
                observable.terms.append(Term(-J[i, j], "ZZ", [i, j]))
    return observable
Пример #9
0
def bipartition(s, p):
    
    ###Define a variational circuit
    #As a Program
    prog = Program()
    
    #With n qubits
    nqbits = len(s)
    qbits = prog.qalloc(nqbits)
    
    #Define the variational states (einsatz)
    #|psi(theta)> = Rx1(theta1x)...Rxn(theta1n)|0,...,0>
    
    for i in range(0, nqbits):
        
        for j in range(1):
            #H(qbits[i])
            thetaij = prog.new_var(float, "theta"+str(i)+str(j))    
            if j == 0 :
                RX(np.pi*thetaij)(qbits[i])
                #RZ(thetaij)(qbits[i]) #H Rz H method
            #elif j ==1 :
            #    RY(thetaij)(qbits[i])
            #elif j == 2:
            #    RZ(thetaij)(qbits[i])
            # elif j == 3 :
            #     RY(thetaij)(qbits[i])
            # elif j == 4 :
            #     RX(thetaij)(qbits[i])
            #H(qbits[i])
    
    #export program into a quntum circuit
    circuit = prog.to_circ()
    
    #print created variables"
    print("Variables:", circuit.get_variables())
    
    ###Define an observable
    #Initialization
    obs = Observable(nqbits)
    
    #Observable = Hamiltonian we want to minimize
    # => Reformulate bi-partition problem in Hamiltonian minimalization problem :
    #Bi-partition problem : Find A1,A2 such that A1 u A2 = s and minimizes |sum_{n1 in A1}n1 - sum_{n2 in A2}n2|
    #Optimization Problem : Find e = {ei} in {-1,1}^n minimizing |sum_{1<=i<=n}ei.si|
    #Non-Linear Integer Programming Optimization Problem Find e = {ei} in {-1,1}^n minimizing (sum_{1<=i<=n}ei.si)^2
    #Ising problem : Find e = {ei} in {-1,1}^n minimizing sum_{1<=i<=n}(si)^2 + sum_{1<=i<=n, 1<=i<j<=n} (si.sj).ei.ej)^2 (si^2 = 1)
    
    J = [[si*sj for si in s] for sj in s] 
    b = [si**2 for si in s]
    
    obs += sum(b)*Observable(nqbits, constant_coeff = sum(b))
    
    for i in range(nqbits):
        for j in range(i-1):
        
            obs += Observable(nqbits, pauli_terms = [Term(J[i][j], "ZZ", [i, j])]) #Term(coefficient, tensorprod, [qubits]) 
        
    ###Create a quantum job
    #Made of a circuit and and an observable
    job = circuit.to_job(observable = obs) #nbshots=inf
    
    ###Define classical optimizer : scipy.optimia.minimize
    method_name = "COBYLA" #"Nelder-Mead", "Powell", "CG",...
    optimize = ScipyMinimizePlugin(method = method_name, tol = 1e-3, options = {"maxiter" : p})
    
    ###Define qpu on which to run quantum job
    stack = optimize | get_default_qpu()
    
    optimizer_args = {"method": method_name, "tol":1e-3, "options":{"maxiter":p}}
    
    result = stack.submit(job, meta_data ={"ScipyMinimizePlugin": json.dumps(optimizer_args)})
    
    ###Get characteristics of best parametrized circuit found
    final_energy = result.value
    parameters = json.loads(result.meta_data['parameters'])
    
    print("final energy:", final_energy)
    print('best parameters:', parameters)
    #print('trace:', result.meta_data['optimization_trace'])
    
    ###Deduce the most probable state => solution of the problem
    #Probability to measure qubit i in state |0> : cos(theta_i)^2
    #Probability to measure qubit i in state |1> : sin(theta_i)^2
    states = {}
    
    best_state = ''
    max_proba = 0
    
    for i in range(2**nqbits):
        
        state = bin(i)[2:].zfill(nqbits)
        proba = 1

        for i in range(nqbits):
            proba = proba/2*((1+(-1)**int(state[nqbits-i-1]))*np.cos(parameters[i]*np.pi/2)+(1+(-1)**(int(state[nqbits-i-1])+1))*np.sin(parameters[i]*np.pi/2))
        
        if max_proba < proba:
            max_proba = proba
            best_state = state
        
        states[state] = proba
    
    print(states)
    
    A1 = []
    A2 = []
    
    for i in range(nqbits):
    
        if best_state[i] == '0':
            A1.append(s[i])
    
        elif best_state[i] == '1':
            A2.append(s[i])
    
    return A1, A2