Exemplo n.º 1
0
def vqe(molecule='H2', depth=6, max_trials=200, shots=1):
    if molecule == 'H2':
        n_qubits = 2
        Z1 = 1
        Z2 = 1
        min_distance = 0.2
        max_distance = 4

    elif molecule == 'LiH':
        n_qubits = 4
        Z1 = 1
        Z2 = 3
        min_distance = 0.5
        max_distance = 5

    else:
        raise QISKitError("Unknown molecule for VQE.")

    # Read Hamiltonian
    ham_name = os.path.join(os.path.dirname(__file__),
                            molecule + '/' + molecule + 'Equilibrium.txt')
    pauli_list = Hamiltonian_from_file(ham_name)
    H = make_Hamiltonian(pauli_list)

    # Exact Energy
    exact = np.amin(la.eig(H)[0]).real
    print('The exact ground state energy is: {}'.format(exact))

    # Optimization
    device = 'local_qasm_simulator'
    qp = QuantumProgram()

    if shots != 1:
        H = group_paulis(pauli_list)

    entangler_map = qp.get_backend_configuration(device)['coupling_map']

    if entangler_map == 'all-to-all':
        entangler_map = {i: [j for j in range(n_qubits) if j != i] for i in range(n_qubits)}
    else:
        entangler_map = mapper.coupling_list2dict(entangler_map)

    initial_theta = np.random.randn(2 * n_qubits * depth)   # initial angles
    initial_c = 0.01                                        # first theta perturbations
    target_update = 2 * np.pi * 0.1                         # aimed update on first trial
    save_step = 20                                          # print optimization trajectory

    cost = partial(cost_function, qp, H, n_qubits, depth, entangler_map, shots, device)

    SPSA_params = SPSA_calibration(cost, initial_theta, initial_c, target_update, stat=25)
    output = SPSA_optimization(cost, initial_theta, SPSA_params, max_trials, save_step, last_avg=1)

    return qp
Exemplo n.º 2
0
def transpile_dag(dag,
                  basis_gates='u1,u2,u3,cx,id',
                  coupling_map=None,
                  initial_layout=None,
                  get_layout=False,
                  format='dag',
                  seed_mapper=None,
                  pass_manager=None):
    """Transform a dag circuit into another dag circuit (transpile), through
    consecutive passes on the dag.

    Args:
        dag (DAGCircuit): dag circuit to transform via transpilation
        basis_gates (str): a comma separated string for the target basis gates
        coupling_map (list): A graph of coupling::

            [
             [control0(int), target0(int)],
             [control1(int), target1(int)],
            ]

            eg. [[0, 2], [1, 2], [1, 3], [3, 4]}

        initial_layout (dict): A mapping of qubit to qubit::

                              {
                                ("q", start(int)): ("q", final(int)),
                                ...
                              }
                              eg.
                              {
                                ("q", 0): ("q", 0),
                                ("q", 1): ("q", 1),
                                ("q", 2): ("q", 2),
                                ("q", 3): ("q", 3)
                              }
        get_layout (bool): flag for returning the final layout after mapping
        format (str): The target format of the compilation:
            {'dag', 'json', 'qasm'}
        seed_mapper (int): random seed_mapper for the swap mapper
        pass_manager (PassManager): pass manager instance for the transpilation process
            If None, a default set of passes are run.
            Otherwise, the passes defined in it will run.
            If contains no passes in it, no dag transformations occur.

    Returns:
        DAGCircuit: transformed dag
        DAGCircuit, dict: transformed dag along with the final layout on backend qubits

    Raises:
        TranspilerError: if the format is not valid.
    """
    # TODO: `basis_gates` will be removed after we have the unroller pass.
    # TODO: `coupling_map`, `initial_layout`, `get_layout`, `seed_mapper` removed after mapper pass.

    # TODO: move this to the mapper pass
    num_qubits = sum([qreg.size for qreg in dag.qregs.values()])
    if num_qubits == 1 or coupling_map == "all-to-all":
        coupling_map = None

    final_layout = None

    if pass_manager:
        # run the passes specified by the pass manager
        # TODO return the property set too. See #1086
        dag = pass_manager.run_passes(dag)
    else:
        # default set of passes
        # TODO: move each step here to a pass, and use a default passmanager below
        basis = basis_gates.split(',') if basis_gates else []
        dag_unroller = _dagunroller.DagUnroller(dag,
                                                _dagbackend.DAGBackend(basis))
        dag = dag_unroller.expand_gates()
        # if a coupling map is given compile to the map
        if coupling_map:
            logger.info("pre-mapping properties: %s", dag.property_summary())
            # Insert swap gates
            coupling = Coupling(coupling_list2dict(coupling_map))
            removed_meas = remove_last_measurements(dag)
            logger.info("measurements moved: %s", removed_meas)
            logger.info("initial layout: %s", initial_layout)
            dag, final_layout, last_layout = swap_mapper(dag,
                                                         coupling,
                                                         initial_layout,
                                                         trials=20,
                                                         seed=seed_mapper)
            logger.info("final layout: %s", final_layout)
            # Expand swaps
            dag_unroller = _dagunroller.DagUnroller(
                dag, _dagbackend.DAGBackend(basis))
            dag = dag_unroller.expand_gates()
            # Change cx directions
            dag = direction_mapper(dag, coupling)
            # Simplify cx gates
            cx_cancellation(dag)
            # Simplify single qubit gates
            dag = optimize_1q_gates(dag)
            return_last_measurements(dag, removed_meas, last_layout)
            logger.info("post-mapping properties: %s", dag.property_summary())

    # choose output format
    # TODO: do we need all of these formats, or just the dag?
    if format == 'dag':
        compiled_circuit = dag
    elif format == 'json':
        # FIXME: JsonBackend is wrongly taking an ordered dict as basis, not list
        dag_unroller = _dagunroller.DagUnroller(
            dag, _jsonbackend.JsonBackend(dag.basis))
        compiled_circuit = dag_unroller.execute()
    elif format == 'qasm':
        compiled_circuit = dag.qasm()
    else:
        raise TranspilerError('unrecognized circuit format')

    if get_layout:
        return compiled_circuit, final_layout
    return compiled_circuit
Exemplo n.º 3
0
def transpile(dag_circuit,
              basis_gates='u1,u2,u3,cx,id',
              coupling_map=None,
              initial_layout=None,
              get_layout=False,
              format='dag',
              seed=None,
              pass_manager=None):
    """Transform a dag circuit into another dag circuit (transpile), through
    consecutive passes on the dag.

    Args:
        dag_circuit (DAGCircuit): dag circuit to transform via transpilation
        basis_gates (str): a comma seperated string for the target basis gates
        coupling_map (list): A graph of coupling::

            [
             [control0(int), target0(int)],
             [control1(int), target1(int)],
            ]

            eg. [[0, 2], [1, 2], [1, 3], [3, 4]}

        initial_layout (dict): A mapping of qubit to qubit::

                              {
                                ("q", start(int)): ("q", final(int)),
                                ...
                              }
                              eg.
                              {
                                ("q", 0): ("q", 0),
                                ("q", 1): ("q", 1),
                                ("q", 2): ("q", 2),
                                ("q", 3): ("q", 3)
                              }
        get_layout (bool): flag for returning the layout
        format (str): The target format of the compilation:
            {'dag', 'json', 'qasm'}
        seed (int): random seed for simulators
        pass_manager (PassManager): pass manager instance for the tranpilation process
            If None, a default set of passes are run.
            Otherwise, the passes defined in it will run.
            If contains no passes in it, no dag transformations occur.

    Returns:
        object: If get_layout == False, the compiled circuit in the specified
            format. If get_layout == True, a tuple is returned, with the
            second element being the layout.

    Raises:
        TranspilerError: if the format is not valid.
    """
    final_layout = None

    if pass_manager:
        # run the passes specified by the pass manager
        for pass_ in pass_manager.passes():
            pass_.run(dag_circuit)
    else:
        # default set of passes
        # TODO: move each step here to a pass, and use a default passmanager below
        basis = basis_gates.split(',') if basis_gates else []
        dag_unroller = DagUnroller(dag_circuit, DAGBackend(basis))
        dag_circuit = dag_unroller.expand_gates()
        # if a coupling map is given compile to the map
        if coupling_map:
            logger.info("pre-mapping properties: %s",
                        dag_circuit.property_summary())
            # Insert swap gates
            coupling = Coupling(coupling_list2dict(coupling_map))
            logger.info("initial layout: %s", initial_layout)
            dag_circuit, final_layout = swap_mapper(dag_circuit,
                                                    coupling,
                                                    initial_layout,
                                                    trials=20,
                                                    seed=seed)
            logger.info("final layout: %s", final_layout)
            # Expand swaps
            dag_unroller = DagUnroller(dag_circuit, DAGBackend(basis))
            dag_circuit = dag_unroller.expand_gates()
            # Change cx directions
            dag_circuit = direction_mapper(dag_circuit, coupling)
            # Simplify cx gates
            cx_cancellation(dag_circuit)
            # Simplify single qubit gates
            dag_circuit = optimize_1q_gates(dag_circuit)
            logger.info("post-mapping properties: %s",
                        dag_circuit.property_summary())

    # choose output format
    # TODO: do we need all of these formats, or just the dag?
    if format == 'dag':
        compiled_circuit = dag_circuit
    elif format == 'json':
        # FIXME: JsonBackend is wrongly taking an ordered dict as basis, not list
        dag_unroller = DagUnroller(dag_circuit, JsonBackend(dag_circuit.basis))
        compiled_circuit = dag_unroller.execute()
    elif format == 'qasm':
        compiled_circuit = dag_circuit.qasm()
    else:
        raise TranspilerError('unrecognized circuit format')

    if get_layout:
        return compiled_circuit, final_layout
    return compiled_circuit
Exemplo n.º 4
0
def vqe(molecule='H2', depth=6, max_trials=200, shots=1):
    if molecule == 'H2':
        n_qubits = 2
        Z1 = 1
        Z2 = 1
        min_distance = 0.2
        max_distance = 4

    elif molecule == 'LiH':
        n_qubits = 4
        Z1 = 1
        Z2 = 3
        min_distance = 0.5
        max_distance = 5

    else:
        raise QISKitError("Unknown molecule for VQE.")

    # Read Hamiltonian
    ham_name = os.path.join(os.path.dirname(__file__),
                            molecule + '/' + molecule + 'Equilibrium.txt')
    pauli_list = Hamiltonian_from_file(ham_name)
    H = make_Hamiltonian(pauli_list)

    # Exact Energy
    exact = np.amin(la.eig(H)[0]).real
    print('The exact ground state energy is: {}'.format(exact))

    # Optimization
    device = 'local_qasm_simulator'
    if shots == 1:
        device = 'local_statevector_simulator'

    if 'statevector' not in device:
        H = group_paulis(pauli_list)

    entangler_map = get_backend(device).configuration()['coupling_map']

    if entangler_map == 'all-to-all':
        entangler_map = {
            i: [j for j in range(n_qubits) if j != i]
            for i in range(n_qubits)
        }
    else:
        entangler_map = mapper.coupling_list2dict(entangler_map)

    initial_theta = np.random.randn(2 * n_qubits * depth)  # initial angles
    initial_c = 0.01  # first theta perturbations
    target_update = 2 * np.pi * 0.1  # aimed update on first trial
    save_step = 20  # print optimization trajectory

    cost = partial(cost_function, H, n_qubits, depth, entangler_map, shots,
                   device)

    SPSA_params, circuits_cal = SPSA_calibration(cost,
                                                 initial_theta,
                                                 initial_c,
                                                 target_update,
                                                 stat=25)
    output, circuits_opt = SPSA_optimization(cost,
                                             initial_theta,
                                             SPSA_params,
                                             max_trials,
                                             save_step,
                                             last_avg=1)

    return circuits_cal + circuits_opt