Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Quintessential Quantum Quintuplets #7

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
18 changes: 18 additions & 0 deletions team_solutions/Quintessential_Quantum_Quintuplets/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Quantum Image Processing Visualization

Project for IQuHack 2023 IonQ Challenge at https://github.com/iQuHACK/2023_IonQ.

Image processing is in growing needs with the development of applications like facial recognition and autonomous vehicles. Due to the large volume and complexity of data, image processing is computationally expensive. More and more often, specialized hardwares such as GPUs are used to accelerate image processing. Quantum computing promises speed ups in a number of image processing algorithms, such as edge extraction [1].

We demonstrate Quantum Image Processing on the trapped ion quantum computers provided by IonQ. We first transform the image into a qubit representation named Flexible Representation of Quantum Images (FRQI). Next, we perform Quantum Fourier Transform on the input image as a demonstration of practical image processing on quantum computers. We visualize this process by repeatedly measuring the output qubits and feed the output into a fractal generation routine.

## Documentation

The link to our documentation and process can be found here: https://docs.google.com/document/d/1rIbXHpgPaqvQ9ja3OycBM_sBB9STySyqZ8Fe9A27SLs/edit

To generate the fractals, you can upload an image (preferably 8 x 8 or smaller) and then follow the steps in fractal_generation.ipynb. We support larger image sizes but are constrained by simulation speed/hardware limitations.

## Credit

Credit to https://www.linkedin.com/pulse/space-fractal-art-qiskit-wiktor-mazin-phd-mmt/ for fractal generation method.

Large diffs are not rendered by default.

183 changes: 183 additions & 0 deletions team_solutions/Quintessential_Quantum_Quintuplets/gpu_fractal.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
{
"nbformat": 4,
"nbformat_minor": 0,
"metadata": {
"colab": {
"provenance": []
},
"kernelspec": {
"name": "python3",
"display_name": "Python 3"
},
"language_info": {
"name": "python"
},
"accelerator": "GPU",
"gpuClass": "standard"
},
"cells": [
{
"cell_type": "markdown",
"source": [
"# GPU Version of Fractal Generation"
],
"metadata": {
"id": "cyU9rG615ujj"
}
},
{
"cell_type": "code",
"execution_count": 26,
"metadata": {
"id": "AEGh5t_ghw6N"
},
"outputs": [],
"source": [
"amps = {'0': (0.05334708691207961+0.02209708691207961j), '1': (0.1923456572581369+0.07967217989988726j), '10': (0.07544417382415922+0.03125j), '11': (0.15088834764831843+0.0625j), '100': (0.2502200171930884+0.10364452469860624j), '101': (0.1686983011771303+0.06987712429686843j), '110': (0.15088834764831843+0.0625j), '111': (0.2970240093698727+0.12303137303143455j), '1000': (0.23857542547399874+0.09882117688026186j), '1001': (0.2502200171930884+0.10364452469860624j), '1010': (0.17693227094584735+0.07328774624724109j), '1011': (0.10669417382415922+0.04419417382415922j), '1100': (0.07544417382415922+0.03125j), '1101': 0j, '1110': (0.05334708691207961+0.02209708691207961j), '1111': (0.10669417382415922+0.04419417382415922j), '10000': (0.07544417382415922+0.03125j), '10001': (0.11928771273699937+0.04941058844013093j), '10010': 0j, '10011': (0.07544417382415922+0.03125j), '10100': (0.10669417382415922+0.04419417382415922j), '10101': (0.11928771273699937+0.04941058844013093j), '10110': (0.1600412607362388+0.06629126073623882j), '10111': 0j, '11000': (0.18479972993502913+0.07654655446197431j), '11001': (0.1923456572581369+0.07967217989988726j), '11010': (0.10669417382415922+0.04419417382415922j), '11011': 0j, '11100': (0.09239986496751457+0.038273277230987154j), '11101': 0j, '11110': (0.09239986496751457+0.038273277230987154j), '11111': (0.09239986496751457+0.038273277230987154j), '100000': (0.09239986496751457+0.038273277230987154j), '100001': (0.15088834764831843+0.0625j), '100010': (0.10669417382415922+0.04419417382415922j), '100011': 0j, '100100': (0.2444670638799928+0.10126157341262282j), '100101': (0.05334708691207961+0.02209708691207961j), '100110': (0.09239986496751457+0.038273277230987154j), '100111': (0.13067314219850173+0.05412658773652741j), '101000': (0.05334708691207961+0.02209708691207961j), '101001': (0.1411431251391113+0.05846339666834283j), '101010': (0.10669417382415922+0.04419417382415922j), '101011': (0.05334708691207961+0.02209708691207961j), '101100': (0.07544417382415922+0.03125j), '101101': 0j, '101110': (0.13067314219850173+0.05412658773652741j), '101111': (0.13067314219850173+0.05412658773652741j), '110000': (0.10669417382415922+0.04419417382415922j), '110001': (0.10669417382415922+0.04419417382415922j), '110010': (0.11928771273699937+0.04941058844013093j), '110011': (0.09239986496751457+0.038273277230987154j), '110100': (0.1411431251391113+0.05846339666834283j), '110101': (0.10669417382415922+0.04419417382415922j), '110110': (0.10669417382415922+0.04419417382415922j), '110111': (0.1923456572581369+0.07967217989988726j), '111000': (0.1686983011771303+0.06987712429686843j), '111001': 0j, '111010': (0.05334708691207961+0.02209708691207961j), '111011': (0.10669417382415922+0.04419417382415922j), '111100': (0.3064556827767503+0.1269381000724369j), '111101': (0.27719959490254376+0.11481983169296148j), '111110': 0j, '111111': (0.3156056223678123+0.1307281291459493j)}"
]
},
{
"cell_type": "code",
"source": [
"! pip install celluloid"
],
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "Kh6TqlrDh1lL",
"outputId": "83cc7667-32df-4d7e-8850-5b65daf993a9"
},
"execution_count": 2,
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"Looking in indexes: https://pypi.org/simple, https://us-python.pkg.dev/colab-wheels/public/simple/\n",
"Requirement already satisfied: celluloid in /usr/local/lib/python3.8/dist-packages (0.2.0)\n",
"Requirement already satisfied: matplotlib in /usr/local/lib/python3.8/dist-packages (from celluloid) (3.2.2)\n",
"Requirement already satisfied: kiwisolver>=1.0.1 in /usr/local/lib/python3.8/dist-packages (from matplotlib->celluloid) (1.4.4)\n",
"Requirement already satisfied: python-dateutil>=2.1 in /usr/local/lib/python3.8/dist-packages (from matplotlib->celluloid) (2.8.2)\n",
"Requirement already satisfied: pyparsing!=2.0.4,!=2.1.2,!=2.1.6,>=2.0.1 in /usr/local/lib/python3.8/dist-packages (from matplotlib->celluloid) (3.0.9)\n",
"Requirement already satisfied: numpy>=1.11 in /usr/local/lib/python3.8/dist-packages (from matplotlib->celluloid) (1.21.6)\n",
"Requirement already satisfied: cycler>=0.10 in /usr/local/lib/python3.8/dist-packages (from matplotlib->celluloid) (0.11.0)\n",
"Requirement already satisfied: six>=1.5 in /usr/local/lib/python3.8/dist-packages (from python-dateutil>=2.1->matplotlib->celluloid) (1.15.0)\n"
]
}
]
},
{
"cell_type": "code",
"source": [
"import matplotlib.pyplot as plt\n",
"import matplotlib.image as mpimg\n",
"import numpy as np\n",
"from celluloid import Camera\n",
"import torch\n",
"import tqdm\n",
"\n",
"c = 1.4 + 0.2j\n",
"\n",
"print(\"c= \",c)\n",
"\n",
"# Define the size\n",
"size = 1000\n",
"heightsize = size\n",
"widthsize = size\n",
"\n",
"def julia_set(c=c, height=heightsize, width=widthsize, x=0, y=0, zoom=1, max_iterations=100, amps=amps):\n",
" # To make navigation easier we calculate these values\n",
" x_width = 1.5\n",
" y_height = 1.5*height/width\n",
" x_from = x - x_width/zoom\n",
" x_to = x + x_width/zoom\n",
" y_from = y - y_height/zoom\n",
" y_to = y + y_height/zoom\n",
" \n",
" # Here the actual algorithm starts and the z paramter is defined for the Julia set function\n",
" x = torch.tensor(np.linspace(x_from, x_to, width).reshape((1, width)), device='cuda')\n",
" y = torch.tensor(np.linspace(y_from, y_to, height).reshape((height, 1)), device='cuda')\n",
" z = x + 1j * y\n",
" \n",
" # Initialize c to the complex number obtained from the quantum circuit\n",
" c = torch.tensor(np.full(z.shape, c), device='cuda')\n",
"\n",
" # To keep track in which iteration the point diverged\n",
" div_time = torch.tensor(np.zeros(z.shape, dtype=int), device='cuda')\n",
" \n",
" # To keep track on which points did not converge so far\n",
" m = torch.tensor(np.full(c.shape, True, dtype=bool), device='cuda')\n",
" \n",
" for key in amps:\n",
" amps[key] = torch.tensor(np.full(z.shape, amps[key]), device='cuda')\n",
" \n",
" for i in range(max_iterations):\n",
" num = z[m]**4 + sum([amps[bin(num)[2:]][m] * z[m] ** ((num // 2) % 4) for num in range(len(amps.keys()), 2)])\n",
" den = z[m]**4 + sum([amps[bin(num)[2:]][m] * z[m] ** (((num - 1) // 2) % 4) for num in range(1, len(amps.keys()), 2)])\n",
" # print(num.shape)\n",
" # print(den.shape)\n",
" z[m] = num / den + c[m]\n",
" m[torch.abs(z) > 2] = False\n",
" div_time[m] = i\n",
" # print(div_time.max())\n",
" # print(div_time.min())\n",
" return div_time.cpu().numpy()\n",
"\n",
"\n",
"fig, ax = plt.subplots(1, 1) \n",
"camera = Camera(fig)\n",
"def color(data, i):\n",
" normalizedData = (data - np.min(data)) / (np.max(data) - np.min(data))\n",
" normi = i/(frameno)\n",
" # print(data.shape)\n",
" rgb = np.zeros((data.shape[0], data.shape[1], 3))\n",
" r = normalizedData*normi\n",
" b = (1-normi)*normalizedData\n",
" # print(r,b)\n",
" rgb[:,:,0] = r#np.full(rgb[:,:,1].shape, 0)\n",
" rgb[:,:,1] = np.full(rgb[:,:,1].shape, 0)\n",
" rgb[:,:,2] = b#normalizedData\n",
" return rgb\n",
"\n",
"\n",
"frameno = 50\n",
"for i in tqdm.tqdm(range(frameno)):\n",
" map = julia_set(c=c, amps=amps.copy())\n",
" data = color(map, i)\n",
" ax.imshow(data)\n",
" ax.axis('off')\n",
" camera.snap()\n",
" plt.close()\n",
" c += 0.03 + 0.03j\n",
" \n",
"anim = camera.animate(blit=True)\n",
"anim.save('1qubit_simulator_4animations_H_2' + str(frameno) + ' steps c=' + str(c) + '.gif', writer='pillow')"
],
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "53XULgCwh4Lh",
"outputId": "af0ecee6-07bb-4358-91ec-eec2ffb2dc1b"
},
"execution_count": 27,
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"c= (1.4+0.2j)\n"
]
},
{
"output_type": "stream",
"name": "stderr",
"text": [
"100%|██████████| 50/50 [00:54<00:00, 1.09s/it]\n"
]
}
]
}
]
}
101 changes: 101 additions & 0 deletions team_solutions/Quintessential_Quantum_Quintuplets/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
anyio==3.6.2
attrs==21.4.0
cachetools==5.3.0
celluloid==0.2.0
certifi==2022.12.7
cffi==1.15.1
charset-normalizer==3.0.1
cirq==1.1.0
cirq-aqt==1.1.0
cirq-core==1.1.0
cirq-google==1.1.0
cirq-ionq==1.1.0
cirq-pasqal==1.1.0
cirq-rigetti==1.1.0
cirq-web==1.1.0
contourpy==1.0.7
cryptography==39.0.0
cycler==0.11.0
decorator==5.1.1
dill==0.3.6
duet==0.2.7
exceptiongroup==1.0.4
fonttools==4.38.0
google-api-core==1.34.0
google-auth==2.16.0
googleapis-common-protos==1.58.0
grpcio==1.51.1
grpcio-status==1.48.2
h11==0.14.0
httpcore==0.16.3
httpx==0.23.3
idna==3.4
importlib-metadata==6.0.0
iniconfig==1.1.1
iso8601==1.1.0
kiwisolver==1.4.4
lark==0.11.3
matplotlib==3.6.3
mpmath==1.2.1
msgpack==0.6.2
networkx==2.8.8
ntlm-auth==1.5.0
numpy==1.23.5
packaging==22.0
pandas==1.5.3
pbr==5.11.1
Pillow==9.4.0
pluggy==1.0.0
ply==3.11
powerline-status==2.7
proto-plus==1.22.2
protobuf==3.20.3
psutil==5.9.4
py==1.11.0
pyasn1==0.4.8
pyasn1-modules==0.2.8
pycparser==2.21
pydantic==1.10.4
Pygments==2.13.0
PyJWT==2.6.0
pyparsing==3.0.9
pyquil==3.3.3
pytest==7.2.0
python-dateutil==2.8.2
python-rapidjson==1.9
pytz==2022.7.1
pyzmq==25.0.0
qcs-api-client==0.21.3
qiskit==0.40.0
qiskit-aer==0.11.2
qiskit-ibmq-provider==0.19.2
qiskit-ionq==0.3.10
qiskit-terra==0.23.0
requests==2.28.2
requests-ntlm==1.1.0
retry==0.9.2
retrying==1.3.4
rfc3339==6.2
rfc3986==1.5.0
rpcq==3.10.0
rsa==4.9
ruamel.yaml==0.17.21
ruamel.yaml.clib==0.2.7
rustworkx==0.12.1
scipy==1.9.3
six==1.16.0
sniffio==1.3.0
sortedcontainers==2.4.0
stevedore==4.1.1
symengine==0.9.2
sympy==1.11.1
toml==0.10.2
tomli==2.0.1
tqdm==4.64.1
types-python-dateutil==2.8.19.6
types-retry==0.9.9.1
typing_extensions==4.4.0
urllib3==1.26.14
websocket-client==1.5.0
websockets==10.4
zipp==3.12.0
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.