示例#1
0
def run_circuitset_and_measure(
    backend_specs: Specs,
    circuitset: str,
    n_samples: Optional[int] = None,
    noise_model: Optional[str] = None,
    device_connectivity: Optional[str] = None,
):

    if isinstance(backend_specs, str):
        backend_specs = json.loads(backend_specs)
    if noise_model is not None:
        backend_specs["noise_model"] = load_noise_model(noise_model)
    if device_connectivity is not None:
        backend_specs["device_connectivity"] = layouts.load_circuit_connectivity(
            device_connectivity
        )

    circuit_set = circuits.load_circuitset(circuitset)
    backend = create_object(backend_specs)

    n_samples_list = [n_samples for _ in circuit_set]
    measurements_set = backend.run_circuitset_and_measure(
        circuit_set, n_samples=n_samples_list
    )
    list_of_measurements = [measurement.bitstrings for measurement in measurements_set]
    save_list(list_of_measurements, "measurements-set.json")
示例#2
0
def generate_random_list_of_integers(seed: Union[None, int] = None, **kwargs):
    """Generate a random list of integers. Docs can be found at the link below, but the keyword argument "low" is mandatory.
    https://numpy.org/devdocs/reference/random/generated/numpy.random.Generator.integers.html#numpy.random.Generator.integers
    """
    rng = np.random.default_rng(seed=seed)
    generated_integers = rng.integers(**kwargs).tolist()
    save_list(generated_integers, "integers.json")
def solve_relaxed_qubo(
    qubo,
    optimizer_specs=None,
    number_of_trials=10,
    symmetrize_matrix=True,
):
    qubo = load_qubo(qubo)

    qubo_matrix = qubo.to_numpy_matrix().astype(float)
    if symmetrize_matrix:
        qubo_matrix = (qubo_matrix + qubo_matrix.T) / 2

    if is_matrix_positive_semidefinite(qubo_matrix):
        solution, optimal_value = solve_qp_problem_for_psd_matrix(
            qubo_matrix, symmetrize_matrix)
    else:
        if optimizer_specs is None:
            raise ValueError(
                "For qubo with semipositive definite matrix, an optimizer must be provided."
            )
        optimizer = create_object(optimizer_specs)
        solution, optimal_value = solve_qp_problem_with_optimizer(
            qubo_matrix, optimizer, number_of_trials, symmetrize_matrix)

    save_list(solution.tolist(), "solution.json")
    save_value_estimate(ValueEstimate(optimal_value), "energy.json")
示例#4
0
 def test_list_io(self):
     # Given
     initial_list = [0.1, 0.3, -0.3]
     # When
     save_list(initial_list, "list.json")
     loaded_list = load_list("list.json")
     # Then
     assert initial_list == loaded_list
     remove_file_if_exists("list.json")
示例#5
0
 def test_named_list_io(self):
     # Given
     initial_list = [0.1, 0.3, -0.3]
     # When
     save_list(initial_list, "list.json", "number")
     loaded_list = load_list("list.json")
     # Then
     assert initial_list == loaded_list
     # And
     # After manually loading json
     if isinstance("list.json", str):
         with open("list.json", "r") as f:
             data = json.load(f)
     else:
         data = json.load("list.json")
     # Check that
     assert data["schema"] == SCHEMA_VERSION + "-number-list"
     remove_file_if_exists("list.json")
示例#6
0
def run_circuit_and_get_expval(
    backend_specs: dict,
    circuit: str,
    operators: str,
):
    """Takes a circuit to obtain the expectation value of an operator on a
    given backend.

    All backend calls used in this function are defined as ``QuantumBackend``
    and ``QuantumSimulator`` interface standard methods implemented are defined
    in the ``z-quantum-core`` repository.

    There are two computation modes: sampling and exact. Expectation values are
    computed by post-processing samples when an Orquestra ``QuantumBackend`` is
    used or the number of samples was specified for a ``QuantumSimulator``
    backend. When the number of samples was not specified, ``QuantumSimulator``
    backends run in exact mode.

    Args:
        backend_specs (dict): the parsed Orquestra backend specifications
        circuit (str): the circuit represented as an OpenQASM 2.0 program
        operators (str): the operator in an ``openfermion.QubitOperator``
            or ``openfermion.IsingOperator`` representation
    """
    backend_specs = json.loads(backend_specs)
    operators = json.loads(operators)

    backend = create_object(backend_specs)

    # 1. Parse circuit
    qc = QuantumCircuit.from_qasm_str(circuit)

    # 2. Create operators
    ops = []
    for op in operators:
        if backend.n_samples is not None:
            # Operator for Backend/Simulator in sampling mode
            ops.append(IsingOperator(op))
        else:
            # Operator for Simulator exact mode
            ops.append(QubitOperator(op))

    # 2.+1
    # Activate the qubits that are measured but were not acted on
    # By applying the identity
    # Note: this is a temporary logic subject to be removed once supported by
    # Orquestra

    # Get the active qubits of the circuit
    active_qubits = []
    for instr in qc.data:
        instruction_qubits = [qubit.index for qubit in instr[1]]
        active_qubits.extend(instruction_qubits)

    active_qubits = set(active_qubits)

    # Get the qubits we'd like to measure
    # Data for identities is not stored, need to account for empty terms
    op_qubits = [term[0][0] for op in ops for term in op.terms if term]

    need_to_activate = set(op_qubits) - active_qubits
    if not need_to_activate == set():
        for qubit in need_to_activate:
            # Apply the identity
            qc.id(qubit)

    # If there are still no instructions, apply identity to the first qubit
    # Can happen for an empty circuit when measuring the identity operator
    if not qc.data:
        qc.id(qc.qubits[0])

    # Convert to zquantum.core.circuit.Circuit
    circuit = Circuit(qc)

    # 3. Expval
    results = _get_expval(backend, circuit, ops)

    save_list(results, "expval.json")
示例#7
0
def convert_relaxed_solution_to_angles(solution, epsilon=0.5):
    solution = np.array(load_list(solution))
    thetas = warm_start_ansatz.convert_relaxed_solution_to_angles(
        solution, epsilon)
    save_list(thetas.tolist(), "thetas.json")
示例#8
0
def run_circuit_and_get_expval(
    backend_specs: str,
    circuit: str,
    operators: str,
):
    """Executes a circuit to obtain the expectation value of an operator on a
    given backend.

    All Orquestra backend interface calls used in this function are standard
    methods of the ``QuantumBackend`` and ``QuantumSimulator`` interfaces as
    defined in the ``z-quantum-core`` repository.

    There are two computation modes: sampling and exact. Expectation values are
    computed by post-processing samples when an Orquestra ``QuantumBackend`` is
    used or the number of samples was specified for a ``QuantumSimulator``
    backend. When the number of samples isn't specified, ``QuantumSimulator``
    backends run in exact mode.

    Args:
        backend_specs (str): the Orquestra backend specification in a json
            representation
        circuit (str): the circuit represented as an OpenQASM 2.0 program
        operators (str): the operator in an ``openfermion.QubitOperator``
            or ``openfermion.IsingOperator`` representation
    """
    backend_specs = json.loads(backend_specs)
    n_samples = backend_specs.pop("n_samples", None)

    operators = json.loads(operators)

    backend = create_object(backend_specs)

    # 1. Parse circuit
    qc = QuantumCircuit.from_qasm_str(circuit)

    # 2. Create operators
    ops = []
    if n_samples is not None:
        # Operators for Backend/Simulator in sampling mode
        for op in operators:
            ops.append(IsingOperator(op))
    else:
        # Operators for Simulator exact mode
        for op in operators:
            ops.append(QubitOperator(op))

    # 2.+1
    # Activate the qubits that are measured but were not acted on
    # by applying the identity
    # Note: this is a temporary logic subject to be removed once supported by
    # Orquestra

    # Get the active qubits of the circuit
    active_qubits = []
    for instr in qc.data:
        instruction_qubits = [qubit.index for qubit in instr[1]]
        active_qubits.extend(instruction_qubits)

    need_to_activate = set(range(len(qc.qubits))) - set(active_qubits)
    if need_to_activate:
        # We activate all the qubits for convenience
        for qubit in need_to_activate:
            # Apply the identity
            qc.id(qubit)

    # Convert to zquantum.core.circuits.Circuit
    circuit = import_from_qiskit(qc)

    # 3. Expval
    results = _get_expval(backend, circuit, ops, n_samples)

    save_list(results, "expval.json")