# Strangeworks QAOA

The `strangeworks-qaoa`

package allows users to run construct and solve problems with the QAOA algorithm on multiple hardware providers.

## Overviewâ€‹

The QAOA algorithm allows you to solve quadratic unconstrained binary optimization (QUBO) problems by making use of the power of quantum resources. It is a classical-quantum hybrid algorithm: the general idea is that we propose a quantum ansatz circuit with some variational parameters as the coefficients for some of the quantum gates. We then apply this circuit to our qubits, measure the output and repeat many times in order to build up the required statistics. We take these measurement results and compute the cost function with our defined problem. We then hand the algorithm over to a classical CPU which optimizes the circuit parameters before passing back to the quantum side to re-measure the cost function but now for the new parameterized quantum circuit. The algorithm then iterates back and forth between the application of the quantum circuit and the classical optimization of the circuit parameters before eventually converging on a solution with the lowest cost.

This page will describe how to install and begin to use the QAOA service as well as giving some technical details of the algorithm. â€‹

## Prerequisitesâ€‹

In order to use the AWS Hybrid job service and/or the IBM Cloud devices, the user must have a billing account properly enabled. Without this, the user can still utilize qiskit runtime jobs through IBMs free services. â€‹

## Installationâ€‹

To get started, make sure you have **Python 3.9 or above** (installation) and are familiar with setting up and using virtual environments.

Install packages using pip: â€‹

`pip install strangeworks`

pip install strangeworks-qaoa

â€‹ Import package into python: â€‹

`from strangeworks_qaoa.sdk import StrangeworksQAOA`

â€‹

### Authenticationâ€‹

Any issues authenticating, you may need to add a QAOA resource to your account through the Platform, https://portal.strangeworks.com â€‹

## Usageâ€‹

Before running:

- Set up your environment and install
`strangeworks-qaoa`

and`strangeworks`

- In the portal, Activate Strangeworks QAOA Service to create a Resource
- Replace
`your-api-key`

with your key from the Portal homepage - Use examples below to utilize the various functionality. See Examples section below for an example script.

Authenticate with Strangeworks Python sdk using users API token:

`strangeworks.authenticate(api_key="your-api-key")`

â€‹ Get QAOA resource using qaoa sdk extension and users resource slug:

`sw_qaoa = StrangeworksQAOA(resource_slug="your-resource-slug"))`

â€‹ List compatible backends for the qaoa product:

`sw_qaoa.backends()`

â€‹ List all user qaoa jobs:

`jobs = sw_qaoa.job_list(update_status=True)`

â€‹ Run problem:

`sw_job = sw_qaoa.run(backend, problem, problem_params)`

â€‹ Retrieve job with specific slug:

`sw_job = strangeworks.jobs(slug=slug)[0]`

â€‹ Check the status of job and update

`status = sw_qaoa.update_status(sw_job)`

Display results

`result = sw_qaoa.get_results(sw_job,calculate_exact_sol=True, display_results=True)`

## Examplesâ€‹

### IBMâ€‹

Here is an example run for a small problem on an IBM simulator:

`import strangeworks`

from strangeworks_qaoa.sdk import StrangeworksQAOA

import strangeworks_qaoa.utils as utils

strangeworks.authenticate(api_key=" ", store_credentials=False)

sw_qaoa = StrangeworksQAOA(resource_slug=" ")

################################

######## Create problem from QUBO

nodes = 4

seed = 0

n = 3

problem = utils.get_nReg_MaxCut_QUBO(n, nodes, seed)

################################

################################

######## Define algorithm parameters

problem_params = {

"nqubits": nodes, # Number of variables in the problem / number of qubits

"maxiter": 50, # Maximum number of iterations in algorithm

"shotsin": 1000, # Number of times quantum circuit is measured at each iteration

"p": 1, # Optional Input: Controls the depth of the Quantum Circuit ansatz. Default p=1

"theta0": [1.0, 1.0], # Optional Input: Starting point for variational parameters. If specified must be equal to 2p

"alpha": 0.1, # Optional Input: Cvar parameter, float between 0 and 1 - https://arxiv.org/pdf/1907.04769.pdf. Default alpha=1.0

"optimizer": "COBYLA", # Optional Input: Classical optimizer to use:

# Possible Values:

# 'COBYLA' (Default), 'Nelder-Mead', 'Powell', 'CG', 'BFGS', 'Newton-CG', 'L-BFGS-B', 'TNC',

# 'SLSQP', 'trust-constr', 'dogleg', 'trust-ncg', 'trust-exact', 'trust-krylov'

# Additionals for IBM backends: 'SPSA', 'NFT'

"ising": False, # Optional Input: is the problem an Ising problem or a QUBO problem, i.e. are the values of the variables {-1/2,+1/2} (Ising) or {0,1} (QUBO, Default)

"warm_start": False, # Optional Input: Run warm start qaoa or not - https://arxiv.org/abs/2009.10095. Default False: Standard QAOA ansatz

"qrr": False, # Optional Input: Quantum Relax and Round QAOA algorithm - https://arxiv.org/abs/2307.05821. Default False: Standard QAOA

}

backend = "ibmq_qasm_simulator" # Change this to another ibm backend name or an aws device name

sw_job = sw_qaoa.run(backend, problem, problem_params)

result = sw_qaoa.get_results(sw_job,calculate_exact_sol=True, display_results=True)

ðŸ¥³ Success! You may view your job in the portal.

ðŸ˜… Something went wrong? Find us in Slack!

### AWS Braketâ€‹

Here is an example run for a small problem on an AWS Braket simulator:

`import strangeworks`

from strangeworks_qaoa.sdk import StrangeworksQAOA

import strangeworks_qaoa.utils as utils

strangeworks.authenticate(api_key=" ", store_credentials=False)

sw_qaoa = StrangeworksQAOA(resource_slug=" ")

################################

######## Create problem from QUBO

nodes = 4

seed = 0

n = 3

problem = utils.get_nReg_MaxCut_QUBO(n, nodes, seed)

################################

################################

######## Define algorithm parameters

problem_params = {

"nqubits": nodes, # Number of variables in the problem / number of qubits

"maxiter": 50, # Maximum number of iterations in algorithm

"shotsin": 1000, # Number of times quantum circuit is measured at each iteration

"p": 1, # Optional Input: Controls the depth of the Quantum Circuit ansatz. Default p=1

"theta0": [1.0, 1.0], # Optional Input: Starting point for variational parameters. If specified must be equal to 2p

"alpha": 0.1, # Optional Input: Cvar parameter, float between 0 and 1 - https://arxiv.org/pdf/1907.04769.pdf. Default alpha=1.0

"optimizer": "COBYLA", # Optional Input: Classical optimizer to use:

# Possible Values:

# 'COBYLA' (Default), 'Nelder-Mead', 'Powell', 'CG', 'BFGS', 'Newton-CG', 'L-BFGS-B', 'TNC',

# 'SLSQP', 'trust-constr', 'dogleg', 'trust-ncg', 'trust-exact', 'trust-krylov'

# Additionals for IBM backends: 'SPSA', 'NFT'

"ising": False, # Optional Input: is the problem an Ising problem or a QUBO problem, i.e. are the values of the variables {-1/2,+1/2} (Ising) or {0,1} (QUBO, Default)

"warm_start": False, # Optional Input: Run warm start qaoa or not - https://arxiv.org/abs/2009.10095. Default False: Standard QAOA ansatz

"qrr": False, # Optional Input: Quantum Relax and Round QAOA algorithm - https://arxiv.org/abs/2307.05821. Default False: Standard QAOA

}

backend = "SV1" # Change this to another ibm backend name or an aws device name

sw_job = sw_qaoa.run(backend, problem, problem_params)

result = sw_qaoa.get_results(sw_job,calculate_exact_sol=True, display_results=True)

ðŸ¥³ Success! You may view your job in the portal.

ðŸ˜… Something went wrong? Find us in Slack!

## Accepted Problem Input Typesâ€‹

### Network X Graphâ€‹

`import strangeworks_qaoa.utils as utils`

nodes = 4

seed = 0

n = 3

problem = utils.get_nReg_MaxCut_graph(n, nodes, seed)

### QUBO Matrixâ€‹

`import strangeworks_qaoa.utils as utils`

nodes = 4

seed = 0

n = 3

problem = utils.get_nReg_MaxCut_QUBO(n, nodes, seed)

### Qiskit PauliSumOpâ€‹

`import strangeworks_qaoa.utils as utils`

nodes = 4

seed = 0

n = 3

problem = utils.get_nReg_MaxCut_PauliSumOp(n, nodes, seed)

### Dwave/Dimod BQMâ€‹

`from dimod import BinaryQuadraticModel`

import dimod

linear = {1: -2, 2: -2, 3: -3, 4: -3, 5: -2}

quadratic = {(1, 2): 2, (1, 3): 2, (2, 4): 2, (3, 4): 2, (3, 5): 2, (4, 5): 2}

bqm = BinaryQuadraticModel(linear, quadratic,dimod.Vartype.BINARY)

problem = {"BQM": bqm,

"variable_order": bqm.variables, # Can specify custom variable order. This will correspond to the solution bitstring.

}

## Algorithm Detailsâ€‹

The QAOA algorithm solves quadratic unconstrained binary optimization (QUBO) problems with binary variables $x_n = \{0, 1 \}$, such as one with the (general) cost function,

Typically, upon mapping to a quantum problem so that it can be solved with qubits on a quantum computer, we transform the problem from $x_n = \{0, 1 \}$ variables to a new set of variables, $z_n = \{-1, 1 \}$ transforming the cost function into a Quantum Ising Hamiltonian. However, in this service we have omitted this step (unless the 'ising' field in the problem parameter dictionary is set to True). Note that this does not change the validity or performance of the algorithm and in both cases the optimal solution is the same - this choice only changes the value of the cost function (the "energy") that is outputed.

Thus, when defining a QUBO problem to be inputted into the service, it is this problem that is directly minimised and the value of the cost function displayed. When 'ising'=False (default option) it is the QUBO that is optimized not the Ising Hamiltonian.

If the problem input is defined as a `PauliSumOp`

and `'ising'=False`

, then the Pauli `Z`

terms in the Hamiltonian are treated as having the possible binary values of {0, 1}. Whereas if `'ising'=True`

, we take the conventional choice of binary values {-1/2, 1/2}. Again this does not affect the quantum part of the algorithm, only the values we assign to each of the qubits measured basis states in the classical computation of the cost function.

A user should take care in order to ensure that they are solving their desired problem.

### QAOA Ansatzâ€‹

We use the standard QAOA ansatz described in Ref. [1], see the figure below for an example. This ansatz is problem dependent: we apply ZZ rotation gates between qubits when we have connections between variables in the qubo/graph problem.

## Troubleshootingâ€‹

This section provides troubleshooting tips for the product or service this page covers. â€‹ â€‹ â€‹

## Further Readingâ€‹

This section provides links to other pages in the documentation that are relevant to the product or service this page covers to drive further exploration and engagement.

[1] - More info on the QAOA algorithm: https://qiskit.org/textbook/ch-applications/qaoa.html

[2] - A list of problems that can be solved with QAOA: https://blog.xa0.de/post/List-of-QUBO-formulations/