Repository: amazon-braket/amazon-braket-algorithm-library (language: python)

Issue:
QAOA v2
I simplified some stuff now that we have parametric circuits. This should be more in the style of algo-lib. 


Discussion / hints:

Fix patch:
diff --git a/README.md b/README.md
index 847260ca..1b4e4483 100644
--- a/README.md
+++ b/README.md
@@ -14,4 +14,3 @@ See [CONTRIBUTING](CONTRIBUTING.md#security-issue-notifications) for more inform
 ## License
 
 This project is licensed under the Apache-2.0 License.
-
diff --git a/doc/conf.py b/doc/conf.py
index 5d587735..79c3347f 100644
--- a/doc/conf.py
+++ b/doc/conf.py
@@ -7,7 +7,7 @@
 project = "amazon-braket-algorithm-library"
 version = pkg_resources.require(project)[0].version
 release = version
-copyright = "{}, Amazon.com".format(datetime.datetime.now().year)
+copyright = f"{datetime.datetime.now().year}, Amazon.com"
 
 extensions = [
     "sphinxcontrib.apidoc",
@@ -26,7 +26,7 @@
 default_role = "py:obj"
 
 html_theme = "sphinx_rtd_theme"
-htmlhelp_basename = "{}doc".format(project)
+htmlhelp_basename = f"{project}doc"
 
 napoleon_use_rtype = False
 
diff --git a/examples/QAOA.ipynb b/examples/QAOA.ipynb
new file mode 100644
index 00000000..1f2915bf
--- /dev/null
+++ b/examples/QAOA.ipynb
@@ -0,0 +1,261 @@
+{
+ "cells": [
+  {
+   "cell_type": "markdown",
+   "id": "8b423ad7",
+   "metadata": {},
+   "source": [
+    "# QUANTUM APPROXIMATE OPTIMIZATION ALGORITHM (QAOA)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "12e108d5",
+   "metadata": {},
+   "source": [
+    "In this tutorial we show how to (approximately) solve binary combinatorial optimization problems, using the __Quantum Approximate Optimization Algorithm (QAOA)__, as introduced in Ref.[1]. \n",
+    "The QAOA algorithm belongs to the class of __hybrid quantum algorithms__ (leveraging both classical as well as quantum compute), that are widely believed to be the working horse for the current __NISQ (noisy intermediate-scale quantum) era__.\n",
+    "In this NISQ era QAOA is also an emerging approach for benchmarking quantum devices and is a prime candidate for demonstrating a practical quantum speed-up on near-term NISQ device [1,4]. \n",
+    "To validate our approach we benchmark our results with exact results as obtained from classical QUBO solvers. \n",
+    "\n",
+    "We provide a step-by-step walkthrough explaining the QAOA quantum algorithm and show how to build the corresponding parametrized quantum circuit ansatz using the ```Braket``` SDK, with simple modular building blocks (that can be re-used for other purposes). \n",
+    "We use open-source off-the-shelf ```scipy``` optimizers for classical numerical optimization. \n",
+    "While we demonstrate our proof-of-concept approach using classical simulators for circuit execution, our code could in principle be run on actual quantum hardware by simply changing the definition of the ```device``` object (provided that the gate set used in the ansatz is supported by the device, as is the case here for IonQ; for Rigetti we need to apply one more extra trick as shown below). "
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 1,
+   "id": "bd0a975d",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "import numpy as np\n",
+    "from braket.devices import LocalSimulator\n",
+    "from scipy.optimize import minimize\n",
+    "\n",
+    "from braket.experimental.algorithms.qaoa import cost_function, qaoa"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "68ac1f67",
+   "metadata": {},
+   "source": [
+    "We are now all set to run some QAOA simulation experiments. \n",
+    "First of all, you can play and experiment yourself with the number of qubits $N$. \n",
+    "Secondly, you may also experiment with the classical optimizer. \n",
+    "Since we are using an off-the-shelf, black-box ```scipy``` minimizer (as described in more detail [here](https://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.minimize.html)), you can simply swap between different optimizers by setting the ```OPT_METHOD``` parameter below. \n",
+    "Some popular options readily available within this library include *Nelder-Mead*, *BFGS* and *COBYLA*. \n",
+    "As a precautionary warning, note that the classical optimization step may get stuck in a local optimum, rather than finding the global minimum for our parametrized QAOA ansatz wavefunction. \n",
+    "To address this issue, we may run several optimization loops, starting from different random parameter seeds. \n",
+    "While this brute-force approach does not provide any guarantee to find the global optimum, from a pragmatic point of view at least it does increase the odds of finding an acceptable solution, at the expense of potentially having to run many more circuits on the simulator or QPU, respectively.\n",
+    "Finally, the optimization loop may require the execution of many individual quantum tasks (i.e., single circuit executions for fixed parameters). \n",
+    "For example, when choosing the classical [Powell](https://docs.scipy.org/doc/scipy/reference/optimize.minimize-powell.html#optimize-minimize-powell) optimizer for the graph considered here, we find $\\sim 270$ cycles in the for loop. \n",
+    "For the local simulator device chosen here by default this is not an issue, but if you run this algorithm on any QPU you may want to adjust the ```maxfev``` parameter to control the maximum allowed number function evaluations (compare comment in the next code block below)."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "id": "50e4d13a",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "[[0.         0.63535649]\n",
+      " [0.23771676 0.        ]]\n"
+     ]
+    }
+   ],
+   "source": [
+    "n_qubits = 2\n",
+    "n_layers = 1\n",
+    "\n",
+    "coupling_matrix = np.diag(np.ones(n_qubits - 1), 1)\n",
+    "coupling_matrix = np.random.rand(n_qubits, n_qubits)\n",
+    "for i in range(n_qubits):\n",
+    "    coupling_matrix[i, i] = 0  # remove diagonal elements\n",
+    "\n",
+    "print(coupling_matrix)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "id": "6e26acc1",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "T  : |0|1|              2              |3|4|              5              |6|     7      |          Result Types           |\n",
+      "                                                                                                                           \n",
+      "q0 : -H-C-------------------------------C-X-Rz(0.237716759249556*gamma_0)-X-Rx(2*beta_0)-Expectation(Z@Z)-Expectation(Z@Z)-\n",
+      "        |                               | |                               |              |                |                \n",
+      "q1 : -H-X-Rz(0.635356490744946*gamma_0)-X-C-------------------------------C-Rx(2*beta_0)-Expectation(Z@Z)-Expectation(Z@Z)-\n",
+      "\n",
+      "T  : |0|1|              2              |3|4|              5              |6|     7      |          Result Types           |\n",
+      "\n",
+      "Unassigned parameters: [beta_0, gamma_0].\n"
+     ]
+    }
+   ],
+   "source": [
+    "circ = qaoa(n_qubits, n_layers, coupling_matrix)\n",
+    "print(circ)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "id": "223d34d0",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "[0.6353564907449465, 0.2377167592495565]\n"
+     ]
+    }
+   ],
+   "source": [
+    "idx = coupling_matrix.nonzero()\n",
+    "coeffs = [coupling_matrix[qubit_pair] for qubit_pair in zip(idx[0], idx[1])]\n",
+    "print(coeffs)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "8cc043c3",
+   "metadata": {},
+   "source": [
+    "## Run on a local simulator\n",
+    "\n",
+    "Now we run the QAOA on a local simulator by the Nelder-Mead method from scipy.optimize."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "id": "c700195c",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "device = LocalSimulator()\n",
+    "\n",
+    "init_values = np.random.rand(2 * n_layers)\n",
+    "\n",
+    "# set bounds for search space\n",
+    "bounds = [(0, 2 * np.pi) for _ in range(2 * n_layers)]\n",
+    "\n",
+    "losses = []"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "id": "bc524eef",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Optimization terminated successfully.\n",
+      "         Current function value: -0.873073\n",
+      "         Iterations: 49\n",
+      "         Function evaluations: 88\n"
+     ]
+    }
+   ],
+   "source": [
+    "losses = []\n",
+    "result = minimize(\n",
+    "    cost_function,\n",
+    "    init_values,\n",
+    "    args=(device, circ, coeffs, losses, 0),  # shots=0\n",
+    "    options={\"disp\": True, \"maxfev\": 150},\n",
+    "    method=\"Nelder-Mead\",\n",
+    "    bounds=bounds,\n",
+    ")"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 10,
+   "id": "16df2abe",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "Text(0.5, 1.0, 'QAOA convergence of cost function')"
+      ]
+     },
+     "execution_count": 10,
+     "metadata": {},
+     "output_type": "execute_result"
+    },
+    {
+     "data": {
+      "image/png": "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IZfLRUBAgBg6dKh4/fXXDTV26hdUNGfHjh1iwIABhoKM77//vnjyySeFUqk0ufbLL78Uw4cPF15eXsLLy0v06tVLPProo+LEiRMtep/l5eXiueeeExEREcLd3V2o1Wpxzz33GC2fFkKI//znPyI2NlZ4eHgIb29v0adPH/H000+LS5cumX1P9W3fvl0MGzZMeHh4CB8fH5GYmGhUUFGI5i2fF0KI/Px8MXfuXNGlSxchl8tF165dxdSpU43+rF6+fFlMnz5dBAQECLlcLvr06SP++9//Gr3OF198IcaOHSuCgoKEXC4X3bp1E7Nnzzapc/Xee++JyMhIIZPJmlxKb2n5vBBCvPHGG4YCicOGDRMHDhywuHy+4c9C/+eo4XvYs2ePGDNmjKEAYt++fY2KftbW1orHHntMBAYGColEYlVBxXHjxolOnToJT09P8Ze//MVQC6mp96hvu7WlBsjxSITgDC/qWD7++GNMmzYNU6ZMwccff2zv5pCVJkyYgKNHj+LUqVP2bgoRuRAOjVGH88ADDyA7OxsLFy5E165d8e9//9veTaIGKioqjCYinzp1Clu3bnX5/diIqP2xR4iI2l1ISAimTZtmqHu0Zs0aVFVV4ffffzeUIiAiag/sESKidpeQkIBPP/0UOTk5UCgUiIuLw7///W+GICJqd+wRIiIiIpfFOkJERETkshiEiIiIyGVxjlATtFotLl26BG9vb5uVnSciIqK2JYRASUkJQkNDTTYjro9BqAmXLl3iXjNERERO6sKFC+jatavF8wxCTdCXpb9w4QL3nCEiInISxcXFCAsLM/wet4RBqAn64TAfHx8GISIiIifT1LQWTpYmIiIil8UgRERERC6LQYiIiIhcFoMQERERuSwGISIiInJZDEJERETkshiEiIiIyGUxCBEREZHLYhAiIiIil8XK0g5EoxVIzSpAbkklgryVGBzhD5mUG70SERG1FQYhB5Gcno3FmzOQXVRpOBaiUiIpMRoJMSF2bBkREVHHxaExB5Ccno0569OMQhAA5BRVYs76NCSnZ9upZURERB0bg5CdabQCizdnQJg5pz+2eHMGNFpzVxAREVFrcGjMDurPBcorqTLpCapPAMguqkRqVgHiojq3XyOJiIhcAINQOzM3F8gauSXNu56IiIiaxiDUjvRzgVoyyBXkrbR5e4iIiFwdg1A7aWwu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o9esP98oPDwcL730Eh5++GG88847kMvlUKlUkEgkRs9raMeOHThy5AiysrIQFhYGAPj4449xww03YP/+/bjxxhsB6ALThx9+CG9vbwDA/fffjx07duDll19u3Q+GiGyKPUJE5FT++OMP/PTTT+jUqZPhq1evXgB0vTB6sbGxJvdu374do0ePRpcuXeDt7Y37778f+fn5KC8vt/r5x44dQ1hYmCEEAUB0dDR8fX1x7Ngxw7Hw8HBDCAKAkJAQ5ObmNuu9ElHbY48QETmV0tJSJCYmYtmyZSbnQkJCDP/t5eVldO7s2bO4/fbbMWfOHLz88svw9/fHnj17MGPGDFRXV8PT09Om7XR3dzf6XiKRQKvV2vQZRNR6DEJE5LDkcjk0Go3RsYEDB+LLL79EeHg43Nys/yvs4MGD0Gq1eOONNyCV6jrDP//88yaf11Dv3r1x4cIFXLhwwdArlJGRgcLCQkRHR1vdHiJyDBwaIyKHFR4ejn379uHs2bPIy8uDVqvFo48+ioKCAtx3333Yv38/MjMz8cMPP2D69OmNhpgePXqgpqYGK1euxJkzZ7Bu3TrDJOr6zystLcWOHTuQl5dndsgsPj4effr0weTJk5GWlobU1FQ88MADGDlyJAYNGmTznwERtS0GISJyWP/4xz8gk8kQHR2NwMBAnD9/HqGhofj111+h0WgwduxY9OnTB/Pnz4evr6+hp8ecfv364c0338SyZcsQExODDRs2YOnSpUbXDB06FA8//DAmTZqEwMBAk8nWgG6I69tvv4Wfnx9uvvlmxMfHIzIyEp999pnN3z8RtT2JEELYuxFERERE9sAeISIiInJZDEJERETkshiEiIiIyGUxCBEREZHLYhAiIiIil8UgRERERC6LQYiIiIhcFoMQERERuSwGISIiInJZDEJERETkshiEiIiIyGUxCBEREZHL+n/ra5dSfsxp7QAAAABJRU5ErkJggg==",
+      "text/plain": [
+       "<Figure size 640x480 with 1 Axes>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "import matplotlib.pyplot as plt\n",
+    "\n",
+    "%matplotlib inline\n",
+    "\n",
+    "plt.plot(losses, \"-o\")\n",
+    "plt.ylabel(\"Cost\")\n",
+    "plt.xlabel(\"Iteration\")\n",
+    "plt.title(\"QAOA convergence of cost function\")"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "96992efa",
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "Python 3.9.5 64-bit ('braket')",
+   "language": "python",
+   "name": "python3"
+  },
+  "language_info": {
+   "codemirror_mode": {
+    "name": "ipython",
+    "version": 3
+   },
+   "file_extension": ".py",
+   "mimetype": "text/x-python",
+   "name": "python",
+   "nbconvert_exporter": "python",
+   "pygments_lexer": "ipython3",
+   "version": "3.9.5"
+  },
+  "vscode": {
+   "interpreter": {
+    "hash": "5904cb9a2089448a2e1aeb5d493d227c9de33e591d7c07e4016fb81e71061a5d"
+   }
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/examples/Quantum_Phase_Estimation_Algorithm.ipynb b/examples/Quantum_Phase_Estimation_Algorithm.ipynb
index a739889d..5343893a 100644
--- a/examples/Quantum_Phase_Estimation_Algorithm.ipynb
+++ b/examples/Quantum_Phase_Estimation_Algorithm.ipynb
@@ -36,13 +36,13 @@
    "outputs": [],
    "source": [
     "import matplotlib.pyplot as plt\n",
-    "\n",
+    "from braket.aws import AwsDevice\n",
     "from braket.circuits import Circuit, circuit\n",
     "from braket.devices import LocalSimulator\n",
-    "from braket.aws import AwsDevice\n",
+    "\n",
     "from braket.experimental.algorithms.quantum_phase_estimation import (\n",
-    "    run_quantum_phase_estimation,\n",
     "    get_quantum_phase_estimation_results,\n",
+    "    run_quantum_phase_estimation,\n",
     ")\n",
     "\n",
     "# magic word for producing visualizations in notebook\n",
diff --git a/setup.py b/setup.py
index f86040e8..7f91a1cf 100644
--- a/setup.py
+++ b/setup.py
@@ -13,7 +13,7 @@
 
 from setuptools import find_namespace_packages, setup
 
-with open("README.md", "r") as fh:
+with open("README.md") as fh:
     long_description = fh.read()
 
 with open("src/braket/_algos/_version.py") as f:
diff --git a/src/braket/experimental/algorithms/qaoa/__init__.py b/src/braket/experimental/algorithms/qaoa/__init__.py
new file mode 100644
index 00000000..15b5a632
--- /dev/null
+++ b/src/braket/experimental/algorithms/qaoa/__init__.py
@@ -0,0 +1,18 @@
+# Copyright Amazon.com Inc. or its affiliates. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"). You
+# may not use this file except in compliance with the License. A copy of
+# the License is located at
+#
+#     http://aws.amazon.com/apache2.0/
+#
+# or in the "license" file accompanying this file. This file is
+# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
+# ANY KIND, either express or implied. See the License for the specific
+# language governing permissions and limitations under the License.
+
+from braket.experimental.algorithms.qaoa.qaoa import (  # noqa: F401
+    cost_function,
+    qaoa,
+    run_qaoa_circuit,
+)
diff --git a/src/braket/experimental/algorithms/qaoa/qaoa.py b/src/braket/experimental/algorithms/qaoa/qaoa.py
new file mode 100644
index 00000000..9b6001e5
--- /dev/null
+++ b/src/braket/experimental/algorithms/qaoa/qaoa.py
@@ -0,0 +1,167 @@
+# Copyright Amazon.com Inc. or its affiliates. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"). You
+# may not use this file except in compliance with the License. A copy of
+# the License is located at
+#
+#     http://aws.amazon.com/apache2.0/
+#
+# or in the "license" file accompanying this file. This file is
+# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
+# ANY KIND, either express or implied. See the License for the specific
+# language governing permissions and limitations under the License.
+
+
+from typing import List
+
+import numpy as np
+from braket.circuits import Circuit, FreeParameter, Observable, circuit
+from braket.devices import Device
+from braket.tasks import QuantumTask
+
+
+def cost_function(
+    values: np.ndarray,
+    device: Device,
+    circ: Circuit,
+    coeffs: np.ndarray,
+    cost_history: List[float],
+    shots: int = 0,
+) -> float:
+    """Cost function and append to loss history list.
+
+    Args:
+        values (ndarray): Values for the parameters.
+        device (Device): Braket device to run on.
+        circ (Circuit): QAOA circuit to run.
+        coeffs (ndarray): The coefficients of the cost Hamiltonian.
+        cost_history (List[float]): History of cost evaluations.
+        shots (int): Number of shots. Defaults to 0.
+
+    Returns:
+        float: The cost function value
+    """
+    task = run_qaoa_circuit(device, circ, values, shots=shots)
+    cost = get_cost(task, coeffs)
+    cost_history.append(cost)
+    return cost
+
+
+def run_qaoa_circuit(device: Device, circ: Circuit, values: np.ndarray, shots: int) -> QuantumTask:
+    """Evaluate a QAOA circuit with parameters=values.
+
+    Args:
+        device (Device): Braket device to run on.
+        circ (Circuit): QAOA circuit to run.
+        values (np.ndarray): Values for the parameters.
+        shots (int): Number of shots.
+
+    Returns:
+        QuantumTask: The Braket task to run.
+    """
+    fixed_circuit = circ.make_bound_circuit(
+        dict(zip(np.array(list(circ.parameters), dtype=str), values))
+    )
+    task = device.run(fixed_circuit, shots=shots)
+    return task
+
+
+def get_cost(task: QuantumTask, coeffs: np.ndarray) -> float:
+    """Evaluate the cost function from a QAOA task.
+
+    Args:
+        task (QuantumTask): QAOA task.
+        coeffs (np.ndarray): The coefficients of the cost Hamiltonian.
+
+    Returns:
+        float: Loss function value.
+    """
+    exp_vals = task.result().result_types
+    cost = sum(c * s.value for c, s in zip(coeffs, exp_vals))
+    return cost
+
+
+def qaoa(n_qubits: int, n_layers: int, ising: np.ndarray) -> Circuit:
+    """QAOA template.
+
+    Args:
+        n_qubits (int): Number of qubits
+        n_layers (int): Number of layers. Defaults to 1.
+        ising (ndarray): Ising interaction matrix.
+
+    Returns:
+        Circuit: The parameteric QAOA Circuit
+    """
+
+    gammas = [FreeParameter(f"gamma_{p}") for p in range(n_layers)]
+    betas = [FreeParameter(f"beta_{p}") for p in range(n_layers)]
+
+    circ = Circuit()
+    circ.h(range(n_qubits))  # prepare |+> state
+    for gamma, beta in zip(gammas, betas):
+        circ.cost_layer(gamma, ising)
+        circ.driver_layer(beta, n_qubits)
+
+    # add Result types
+    idx = ising.nonzero()
+    for qubit_pair in zip(idx[0], idx[1]):
+        # get interaction strength from Ising matrix
+        circ.expectation(observable=Observable.Z() @ Observable.Z(), target=qubit_pair)
+    return circ
+
+
+@circuit.subroutine(register=True)
+def driver_layer(beta: float, n_qubits: int) -> Circuit:
+    """Returns circuit for driver Hamiltonian U(Hb, beta).
+
+    Args:
+        beta (float): Rotation angle to apply parameterized rotation around x
+        n_qubits (int): number of qubits to apply rx gate
+
+    Returns:
+        Circuit: Circuit object that implements evolution with driver Hamiltonian
+    """
+    return Circuit().rx(range(n_qubits), 2 * beta)
+
+
+@circuit.subroutine(register=True)
+def cost_layer(
+    gamma: float,
+    ising: np.ndarray,
+) -> Circuit:
+    """Returns circuit for evolution with cost Hamiltonian.
+
+    Args:
+        gamma (float): Rotation angle to apply parameterized rotation around z
+        ising (np.ndarray): Ising matrix
+
+    Returns:
+        Circuit: Circuit for evolution with cost Hamiltonian
+    """
+    circ = Circuit()
+    # get all non-zero entries (edges) from Ising matrix
+    idx = ising.nonzero()
+    edges = list(zip(idx[0], idx[1]))
+    # apply ZZ gate for every edge (with corresponding interaction strength)
+    for qubit_pair in edges:
+        # get interaction strength from Ising matrix
+        interaction_strength = ising[qubit_pair[0], qubit_pair[1]]
+        circ.decomposed_zz_gate(qubit_pair[0], qubit_pair[1], gamma * interaction_strength)
+    return circ
+
+
+@circuit.subroutine(register=True)
+def decomposed_zz_gate(qubit0: int, qubit1: int, gamma: float) -> Circuit:
+    """Return a circuit implementing exp(-i gamma Z_i Z_j) using CNOT gates if ZZ not supported.
+
+    Args:
+        qubit0 (int): Index value for the controlling qubit for CNOT gate
+        qubit1 (int): Index value for the target qubit for CNOT gate
+        gamma (float): Rotation angle to apply parameterized rotation around z
+
+    Returns:
+        Circuit: Circuit object that implements ZZ gate using CNOT gates
+    """
+    circ_zz = Circuit()
+    circ_zz.cnot(qubit0, qubit1).rz(qubit1, gamma).cnot(qubit0, qubit1)
+    return circ_zz


Test patch:
diff --git a/test/unit_tests/braket/experimental/algorithms/qaoa/test_qaoa.py b/test/unit_tests/braket/experimental/algorithms/qaoa/test_qaoa.py
new file mode 100644
index 00000000..e4c81d3e
--- /dev/null
+++ b/test/unit_tests/braket/experimental/algorithms/qaoa/test_qaoa.py
@@ -0,0 +1,48 @@
+# Copyright Amazon.com Inc. or its affiliates. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"). You
+# may not use this file except in compliance with the License. A copy of
+# the License is located at
+#
+#     http://aws.amazon.com/apache2.0/
+#
+# or in the "license" file accompanying this file. This file is
+# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
+# ANY KIND, either express or implied. See the License for the specific
+# language governing permissions and limitations under the License.
+
+import numpy as np
+from braket.circuits import Circuit, FreeParameter
+from braket.devices import LocalSimulator
+
+from braket.experimental.algorithms.qaoa import cost_function, qaoa, run_qaoa_circuit
+
+
+def test_qaoa():
+    n_qubits = 2
+    n_layers = 1
+    coupling_matrix = np.diag(np.ones(n_qubits - 1), 1)
+    circ = qaoa(n_qubits, n_layers, coupling_matrix)
+    assert circ.qubit_count == 2
+
+
+def test_qaoa_evaluate_circuit():
+    param = FreeParameter("theta")
+    circ = Circuit().rx(0, param).probability()
+    device = LocalSimulator()
+    shots = 0
+    values = [0]
+    task = run_qaoa_circuit(device, circ, values, shots)
+    result = task.result().values[0]
+    assert np.isclose(result[0], 1)
+
+
+def test_qaoa_cost_function():
+    coeffs = [1]
+    n_qubits = 2
+    n_layers = 1
+    coupling_matrix = np.diag(np.ones(n_qubits - 1), 1)
+    circ = qaoa(n_qubits, n_layers, coupling_matrix)
+    cost = cost_function(np.ones(2), LocalSimulator(), circ, coeffs, [])
+    print("loss is", cost)
+    assert np.isclose(cost, -0.636827341031835, rtol=1e-6)