From 09da3841e4481515b1b5c438166a13c04a29e06a Mon Sep 17 00:00:00 2001 From: James Wootton Date: Thu, 28 Mar 2019 16:00:31 +0100 Subject: [PATCH 1/6] Add quantum animations --- community/games/quantum_animations.ipynb | 494 +++++++++++++++++++++++ 1 file changed, 494 insertions(+) create mode 100644 community/games/quantum_animations.ipynb diff --git a/community/games/quantum_animations.ipynb b/community/games/quantum_animations.ipynb new file mode 100644 index 000000000..14b461db8 --- /dev/null +++ b/community/games/quantum_animations.ipynb @@ -0,0 +1,494 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\"Note: Trusted Notebook (and the image needs to be where this notebook is expecting it)\" width=\"500 px\" align=\"left\">" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# _*Quantum Animations*_\n", + "\n", + "The latest version of this notebook is available on https://github.com/qiskit/qiskit-tutorial.\n", + "\n", + "***\n", + "### Contributors\n", + "James R. Wootton, IBM Research\n", + "***" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In the notebook on [random terrain generation](random_terrain_generation.ipynb), we used qubits to make black and white pixel images.\n", + "\n", + "Here we will use the same principle to make colour images. For this we use the fact that each colour can be expressed using the [RGB_color_model](https://en.wikipedia.org/wiki/RGB_color_model). This uses three values to expressed a colour, which tell us how much red, green and blue must be mixed together. These values are typically in the range from 0 to 255. For example, black is (0,0,0), white is (255,255,255) and red is (255,0,0). With this in mind, we can simply have three separate monochromatic process for these three colour channels, and then combine them at the end.\n", + "\n", + "Another new aspect we'll introduce here is the ability to encode an existing image. For example, consider the 'image' below." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "plumber = {(0, 0): (255, 255, 255), (0, 1): (255, 255, 255), (0, 2): (255, 255, 255), (0, 3): (255, 0, 0), (0, 4): (255, 0, 0), (0, 5): (255, 0, 0), (0, 6): (255, 255, 255), (0, 7): (92, 64, 51), (1, 0): (255, 255, 255), (1, 1): (255, 0, 0), (1, 2): (255, 255, 255), (1, 3): (0, 0, 255), (1, 4): (0, 0, 255), (1, 5): (0, 0, 255), (1, 6): (0, 0, 255), (1, 7): (92, 64, 51), (2, 0): (255, 0, 0), (2, 1): (255, 0, 0), (2, 2): (255, 192, 203), (2, 3): (255, 0, 0), (2, 4): (0, 0, 255), (2, 5): (0, 0, 255), (2, 6): (255, 255, 255), (2, 7): (255, 255, 255), (3, 0): (255, 0, 0), (3, 1): (255, 0, 0), (3, 2): (255, 192, 203), (3, 3): (255, 0, 0), (3, 4): (0, 0, 255), (3, 5): (0, 0, 255), (3, 6): (255, 255, 255), (3, 7): (255, 255, 255), (4, 0): (255, 255, 255), (4, 1): (255, 0, 0), (4, 2): (255, 255, 255), (4, 3): (0, 0, 255), (4, 4): (0, 0, 255), (4, 5): (0, 0, 255), (4, 6): (0, 0, 255), (4, 7): (92, 64, 51), (5, 0): (255, 255, 255), (5, 1): (255, 255, 255), (5, 2): (255, 255, 255), (5, 3): (255, 0, 0), (5, 4): (255, 0, 0), (5, 5): (255, 0, 0), (5, 6): (255, 255, 255), (5, 7): (92, 64, 51), (6, 0): (255, 255, 255), (6, 1): (255, 255, 255), (6, 2): (255, 255, 255), (6, 3): (255, 255, 255), (6, 4): (255, 255, 255), (6, 5): (210, 180, 140), (6, 6): (255, 255, 255), (6, 7): (255, 255, 255), (7, 0): (255, 255, 255), (7, 1): (255, 255, 255), (7, 2): (255, 255, 255), (7, 3): (107, 92, 72), (7, 4): (210, 180, 140), (7, 5): (107, 92, 72), (7, 6): (255, 255, 255), (7, 7): (255, 255, 255)}" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This is an 8x8 pixel picture of a plumber with a Tanooki tail, expressed as a Python dictionary. For each coordinate of a pixel, it gives the corresponding RGB values. This can then be turned into a proper image. In this notebook, we'll use the `PIL` package to do this." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAQAAAAEACAIAAADTED8xAAADUklEQVR4nO3dsY1VMRBA0We0HbE5ENID2wGtUAAxCQ2QISHyzSjo0cEmXyPLuucUYI8sXTmz133f19HW2j3BY04//8O92z0A7CQA0gRAmgBIEwBpAiBNAKQJgDQBkCYA0gRAmgBIEwBpAiBNAKQJgDQBkCYA0gRAmgBIEwBpAiBNAKQJgDQBkCYA0gRAmgBIEwBpAiBNAKQ9je9w+vv906bPx/8Db3IDkCYA0gRAmgBIEwBpAiBNAKQJgDQBkCYA0gRAmgBIEwBpAiBNAKQJgDQBkCYA0gRAmgBIEwBpAiBNAKQJgDQBkCYA0gRAmgBIEwBpAiBNAKTN/w8w/T7939fZ9ad9eN49QZobgDQBkCYA0gRAmgBIEwBpAiBNAKQJgDQBkCYA0gRAmgBIEwBpAiBNAKQJgDQBkCYA0gRAmgBIEwBpAiBNAKQJgDQBkCYA0gRAmgBIEwBpAiBtDb/ef61rdof7WqPrTzv+fIb/f/j68nl0fTcAaQIgTQCkCYA0AZAmANIEQJoASBMAaQIgTQCkCYA0AZAmANIEQJoASBMAaQIgTQCkCYA0AZAmANIEQJoASBMAaQIgTQCkCYA0AZAmANIEQNrx/wPwttP/B/j369vo+m4A0gRAmgBIEwBpAiBNAKQJgDQBkCYA0gRAmgBIEwBpAiBNAKQJgDQBkCYA0gRAmgBIEwBpAiBNAKQJgDQBkCYA0gRAmgBIEwBpAiBNAKQJgLSn3QNwtun3+7///D26vhuANAGQJgDSBECaAEgTAGkCIE0ApAmANAGQJgDSBECaAEgTAGkCIE0ApAmANAGQJgDSBECaAEgTAGkCIE0ApAmANAGQJgDSBECaAEgTAGkCIG3d9z27wRpd/hoef5zz2csNQJoASBMAaQIgTQCkCYA0AZAmANIEQJoASBMAaQIgTQCkCYA0AZAmANIEQJoASBMAaQIgTQCkCYA0AZAmANIEQJoASBMAaQIgTQCkCYA0AZC2vnx8v3uGh/z487p7hIe8fHrePcJDTj9/NwBpAiBNAKQJgDQBkCYA0gRAmgBIEwBpAiBNAKQJgDQBkCYA0gRAmgBIEwBpAiBNAKQJgDQBkCYA0gRAmgBIEwBpAiBNAKQJgDQBkCYA0gRA2n8dmy0sa+CUzwAAAABJRU5ErkJggg==\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "from PIL import Image\n", + "from IPython.display import display\n", + "\n", + "def save_image(image,filename='output.png',scale=None):\n", + "\n", + " img = Image.new('RGB',(8,8))\n", + "\n", + " for x in range(img.size[0]):\n", + " for y in range(img.size[1]):\n", + " img.load()[x,y] = image[x,y]\n", + "\n", + " if scale:\n", + " img = img.resize((256,256))\n", + "\n", + " img.save(filename)\n", + "\n", + " \n", + "save_image(plumber,scale=[300,300])\n", + "display(Image.open('output.png'))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We will now turn this image into a quantum state. More precisely, we'll turn him into three states, with one for each colour channel. We will assign a bit string to each coordinate in the image, and use the probabilities of those bit strings as the value for the colour channels of that coordinate.\n", + "\n", + "The above image has $8x8=2^6$ pixels, and so needs 6 qubits." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "n = 6" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "When we set the probabilities for each bit string, we need to account for the fact that we do not have the freedom to do this arbitrarily. As probabilities, they must all be in the range from 0 to 1, and they must all sum to 1. We can do this simply by renormalizing. The corresponding amplitudes of the quantum state are then the square roots of these values.\n", + "\n", + "First we must decide which bitstrings belong to which values. This can be done in exactly the same way as for the terrain generation notebook." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "\n", + "L = int(2**(n/2))\n", + "\n", + "grid = {}\n", + "for y in range(L):\n", + " for x in range(L):\n", + " grid[(x,y)] = ''\n", + "\n", + "for (x,y) in grid:\n", + " for j in range(n):\n", + " if (j%2)==0:\n", + " xx = np.floor(x/2**(j/2))\n", + " grid[(x,y)] = str( int( ( xx + np.floor(xx/2) )%2 ) ) + grid[(x,y)]\n", + " else:\n", + " yy = np.floor(y/2**((j-1)/2))\n", + " grid[(x,y)] = str( int( ( yy + np.floor(yy/2) )%2 ) ) + grid[(x,y)]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The following function then takes an image and a mapping of coordinates to bit strings and makes three quantum states, one for each colour channel. Each is expressed as a Python lists of amplitudes." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "scrolled": false + }, + "outputs": [], + "source": [ + "def image2state(image,grid):\n", + " \n", + " N = len(grid)\n", + " state = [[0]*N,[0]*N,[0]*N] # different states for R, G and B\n", + "\n", + " for pos in image:\n", + " for j in range(3):\n", + " state[j][ int(grid[pos],2) ] = np.sqrt( image[pos][j] ) # amplitude is square root of colour value\n", + "\n", + " for j in range(3): \n", + " Z = sum(np.absolute(state[j])**2)\n", + " state[j] = [amp / np.sqrt(Z) for amp in state[j]] # amplitudes are normalized\n", + " \n", + " return state\n", + "\n", + "\n", + "state = image2state(plumber,grid)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now we can load the states into quantum circuits using the `initialize()` function of Qiskit, which initializes a circuit with a given quantum state. We can then manipulate the image in a quantum way. Here we'll use the statevector simulator to do this, which outputs the final quantum state." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "from qiskit import *\n", + "\n", + "backend = Aer.get_backend('statevector_simulator')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The final statevector is a set of amplitudes, but our encoding of RGB was done via the probabilities. For this reason, it would be useful to have the standard counts dictionary as we get from other simulators and real quantum devices. The following function performs the conversion." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "def ket2counts (ket):\n", + " \n", + " counts = {}\n", + " N = len(ket)\n", + " n = int( np.log(N)/np.log(2) ) # figure out the qubit number that this state describes\n", + " for j in range(N):\n", + " string = bin(j)[2:]\n", + " string = '0'*(n-len(string)) + string\n", + " counts[string] = np.absolute(ket[j])**2 # square amplitudes to get probabilities\n", + " \n", + " return counts" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now let's have a simple example where we load the image in and then extract the results." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [], + "source": [ + "q = QuantumRegister(n)\n", + "\n", + "counts = []\n", + "for j in range(3): # j=0 for red, j=1 for green, j=2 for blue\n", + " qc = QuantumCircuit(q)\n", + " qc.initialize( state[j], q )\n", + " job = execute(qc, backend)\n", + " counts.append( ket2counts( job.result().get_statevector() ) )" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The only remaining job is to turn the three dictionaries of counts back into an image. This is going to be a bit ambiguous, because we need to undo our earlier normalization step. To do this, we'll assume that, for every colour channel, there is at least one pixel with the value 255. This means that the maximum probaility for each colour channel will be given the value 255, and all other values are assigned proportionally. This is done by the following function." + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAQAAAAEACAIAAADTED8xAAADYElEQVR4nO3dsWkdQRRA0b8fVWSUC4eqwagDtyLnjpW4gZ8JhHJl6metDpQsj2W45xQw+xj2MtnMtu/7ZWnX69kTHLP6/i9u8b8HjhEAaQIgTQCkCYA0AZAmANIEQJoASBMAaQIgTQCkCYA0AZAmANIEQJoASBMAaQIgTQCkCYA0AZAmANIEQJoASBMAaQIgTQCkCYA0AZAmANLuxr+w+v3906b3x/sD3/J3kiYA0gRAmgBIEwBpAiBNAKQJgDQBkCYA0gRAmgBIEwBpAiBNAKQJgDQBkCYA0gRAmgBIEwBpAiBNAKQJgDQBkCYA0gRAmgBIEwBpAiBNAKTNvw8wfT/9+8fs+tMe7s+eIM0JQJoASBMAaQIgTQCkCYA0AZAmANIEQJoASBMAaQIgTQCkCYA0AZAmANIEQJoASBMAaQIgTQCkCYA0AZAmANIEQJoASBMAaQIgTQCkCYA0AZC2Dd/ef7leZr+wL97w8vsz/P7D76fH0fXX/nvgIAGQJgDSBECaAEgTAGkCIE0ApAmANAGQJgDSBECaAEgTAGkCIE0ApAmANAGQJgDSBECaAEgTAGkCIE0ApAmANAGQJgDSBECaAEgTAGkCIG359wH43urvA3ze/oyu7wQgTQCkCYA0AZAmANIEQJoASBMAaQIgTQCkCYA0AZAmANIEQJoASBMAaQIgTQCkCYA0AZAmANIEQJoASBMAaQIgTQCkCYA0AZAmANIEQJoASLs7ewDW9nl7Hl3/77/X0fWdAKQJgDQBkCYA0gRAmgBIEwBpAiBNAKQJgDQBkCYA0gRAmgBIEwBpAiBNAKQJgDQBkCYA0gRAmgBIEwBpAiBNAKQJgDQBkCYA0gRAmgBIEwBp277vox+4Dic2PP641fdnm13+8n94fScAaQIgTQCkCYA0AZAmANIEQJoASBMAaQIgTQCkCYA0AZAmANIEQJoASBMAaQIgTQCkCYA0AZAmANIEQJoASBMAaQIgTQCkCYA0AZAmANIEQNr26+HH2TMc8vL2cfYIhzz9vD97hEPm93/2BQInAGkCIE0ApAmANAGQJgDSBECaAEgTAGkCIE0ApAmANAGQJgDSBECaAEgTAGkCIE0ApAmANAGQJgDSBECaAEgTAGkCIE0ApAmANAGQJgDSBEDaF+faLh/C7eNFAAAAAElFTkSuQmCC\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "def counts2image(counts,grid):\n", + " \n", + " image = { pos:[0,0,0] for pos in grid}\n", + "\n", + " for j in range(3):\n", + "\n", + " rescale = 255/max(counts[j].values()) # rescale so that largest probability becomes value of 255\n", + "\n", + " for pos in image:\n", + " try:\n", + " image[pos][j] = int( rescale*counts[j][grid[pos]] )\n", + " except:\n", + " image[pos][j] = int( rescale*counts[j][grid[pos]] )\n", + "\n", + " for pos in image:\n", + " image[pos] = tuple(image[pos])\n", + "\n", + " return image\n", + "\n", + "\n", + "save_image( counts2image(counts,grid), scale=[300,300])\n", + "display(Image.open('output.png'))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Our brave adventurer has been inside a quantum circuit and emerged intact!\n", + "\n", + "Now let's do some simple manipulation. We'll simply apply a rotation around the y axis over the course of a number of frames." + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [], + "source": [ + "frame_num = 100" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "These will then be compiled into an animated PNG using the `apng` package. Note that you'll need to run this notebook yourself in order to see this." + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [], + "source": [ + "from apng import APNG\n", + "\n", + "state = image2state(plumber,grid)\n", + "\n", + "filenames = []\n", + "for f in range(frame_num):\n", + " \n", + " circuits = []\n", + " for j in range(3):\n", + " qc = QuantumCircuit(q)\n", + " qc.initialize(state[j],q)\n", + " qc.ry(2*np.pi*f/frame_num,q)\n", + " circuits.append( qc )\n", + "\n", + " job = execute(circuits, backend)\n", + "\n", + " counts = []\n", + " for j in range(3):\n", + " counts.append( ket2counts( job.result().get_statevector(circuits[j]) ) )\n", + " \n", + " frame = counts2image(counts,grid)\n", + " \n", + " filename = 'output'+str(f)+'.png'\n", + " save_image( counts2image(counts,grid), scale=[300,300], filename=filename)\n", + " filenames.append( filename )\n", + "\n", + "APNG.from_files(filenames,delay=250).save('animation.png')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "![](animation.png)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In the above example, each qubit from each circuit is rotated in the y axis at the same rate. These rotations all cover the range from $0$ to $2\\pi$ over the course of the frames. To explore different possibilities, we could choose different fractions of $2\\pi$ to be covered over the frames. Setting this $>1$ will cause a faster rotation, and $<1$ will cause a slower one. Setting it to an integer will mean that the corresponding qubit will return to its original state by the final frame (or almost, anyway). For a non-integer, it will not.\n", + "\n", + "Below you can choose values of these fractions for each qubit for each colour channel via Jupyter widgets." + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": { + "scrolled": false + }, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "a7922e53d2fa420a8ec3db828e8a5db6", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Tab(children=(VBox(children=(FloatSlider(value=1.0, description='qubit 0', max=5.0, step=0.01), FloatSlider(va…" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "import ipywidgets as widgets\n", + "\n", + "def make_box():\n", + " children = [widgets.FloatSlider(value=1,max=5.0,step=0.01,description='qubit '+str(qubit),show=True) for qubit in range(n)]\n", + " box = widgets.VBox(children)\n", + " return box\n", + "\n", + "tab = widgets.Tab()\n", + "tab.children = [make_box() for j in range(3)]\n", + "channels = ['Red Channel','Green Channel','Blue Channel']\n", + "for j in range(3):\n", + " tab.set_title(j, channels[j])\n", + " \n", + "tab" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Once you've chose, run the cells below to extract the values and create the animation." + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [], + "source": [ + "fraction = [[],[],[]]\n", + "for j in range(3):\n", + " for qubit in range(n):\n", + " fraction[j].append( tab.children[j].children[qubit].value)" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [], + "source": [ + "state = image2state(plumber,grid)\n", + "\n", + "filenames = []\n", + "for f in range(frame_num):\n", + " \n", + " circuits = []\n", + " for j in range(3):\n", + " qc = QuantumCircuit(q)\n", + " qc.initialize(state[j],q)\n", + " for qubit in range(n):\n", + " qc.ry(2*np.pi*fraction[j][qubit]*f/frame_num,q[qubit])\n", + " circuits.append( qc )\n", + "\n", + " job = execute(circuits, backend)\n", + "\n", + " counts = []\n", + " for j in range(3):\n", + " counts.append( ket2counts( job.result().get_statevector(circuits[j]) ) )\n", + " \n", + " frame = counts2image(counts,grid)\n", + " \n", + " filename = 'output'+str(f)+'.png'\n", + " save_image( counts2image(counts,grid), scale=[300,300], filename=filename)\n", + " filenames.append( filename )\n", + "\n", + "APNG.from_files(filenames,delay=250).save('new_animation.png')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "![](new_animation.png)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "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.7.0" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} From 6764c99131add0b52947023ad7f9965575c3f69b Mon Sep 17 00:00:00 2001 From: James Wootton Date: Mon, 1 Apr 2019 15:33:59 +0200 Subject: [PATCH 2/6] Update animations --- community/games/quantum_animations.ipynb | 51 ++++++++++++++---------- 1 file changed, 29 insertions(+), 22 deletions(-) diff --git a/community/games/quantum_animations.ipynb b/community/games/quantum_animations.ipynb index 14b461db8..be5738471 100644 --- a/community/games/quantum_animations.ipynb +++ b/community/games/quantum_animations.ipynb @@ -45,7 +45,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "This is an 8x8 pixel picture of a plumber with a Tanooki tail, expressed as a Python dictionary. For each coordinate of a pixel, it gives the corresponding RGB values. This can then be turned into a proper image. In this notebook, we'll use the `PIL` package to do this." + "This is an 8x8 pixel picture of a tanuki plumber, expressed as a Python dictionary. For each coordinate of a pixel, it gives the corresponding RGB values. This can then be turned into a proper image. In this notebook, we'll use the `PIL` package to do this." ] }, { @@ -57,7 +57,7 @@ "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAQAAAAEACAIAAADTED8xAAADUklEQVR4nO3dsY1VMRBA0We0HbE5ENID2wGtUAAxCQ2QISHyzSjo0cEmXyPLuucUYI8sXTmz133f19HW2j3BY04//8O92z0A7CQA0gRAmgBIEwBpAiBNAKQJgDQBkCYA0gRAmgBIEwBpAiBNAKQJgDQBkCYA0gRAmgBIEwBpAiBNAKQJgDQBkCYA0gRAmgBIEwBpAiBNAKQ9je9w+vv906bPx/8Db3IDkCYA0gRAmgBIEwBpAiBNAKQJgDQBkCYA0gRAmgBIEwBpAiBNAKQJgDQBkCYA0gRAmgBIEwBpAiBNAKQJgDQBkCYA0gRAmgBIEwBpAiBNAKTN/w8w/T7939fZ9ad9eN49QZobgDQBkCYA0gRAmgBIEwBpAiBNAKQJgDQBkCYA0gRAmgBIEwBpAiBNAKQJgDQBkCYA0gRAmgBIEwBpAiBNAKQJgDQBkCYA0gRAmgBIEwBpAiBtDb/ef61rdof7WqPrTzv+fIb/f/j68nl0fTcAaQIgTQCkCYA0AZAmANIEQJoASBMAaQIgTQCkCYA0AZAmANIEQJoASBMAaQIgTQCkCYA0AZAmANIEQJoASBMAaQIgTQCkCYA0AZAmANIEQNrx/wPwttP/B/j369vo+m4A0gRAmgBIEwBpAiBNAKQJgDQBkCYA0gRAmgBIEwBpAiBNAKQJgDQBkCYA0gRAmgBIEwBpAiBNAKQJgDQBkCYA0gRAmgBIEwBpAiBNAKQJgLSn3QNwtun3+7///D26vhuANAGQJgDSBECaAEgTAGkCIE0ApAmANAGQJgDSBECaAEgTAGkCIE0ApAmANAGQJgDSBECaAEgTAGkCIE0ApAmANAGQJgDSBECaAEgTAGkCIG3d9z27wRpd/hoef5zz2csNQJoASBMAaQIgTQCkCYA0AZAmANIEQJoASBMAaQIgTQCkCYA0AZAmANIEQJoASBMAaQIgTQCkCYA0AZAmANIEQJoASBMAaQIgTQCkCYA0AZC2vnx8v3uGh/z487p7hIe8fHrePcJDTj9/NwBpAiBNAKQJgDQBkCYA0gRAmgBIEwBpAiBNAKQJgDQBkCYA0gRAmgBIEwBpAiBNAKQJgDQBkCYA0gRAmgBIEwBpAiBNAKQJgDQBkCYA0gRA2n8dmy0sa+CUzwAAAABJRU5ErkJggg==\n", "text/plain": [ - "" + "" ] }, "metadata": {}, @@ -68,7 +68,7 @@ "from PIL import Image\n", "from IPython.display import display\n", "\n", - "def save_image(image,filename='output.png',scale=None):\n", + "def save_image(image,filename='image.png',scale=None):\n", "\n", " img = Image.new('RGB',(8,8))\n", "\n", @@ -79,11 +79,11 @@ " if scale:\n", " img = img.resize((256,256))\n", "\n", - " img.save(filename)\n", + " img.save('game_engines/outputs/'+filename)\n", "\n", " \n", - "save_image(plumber,scale=[300,300])\n", - "display(Image.open('output.png'))" + "save_image(plumber,scale=[300,300],filename='image1.png')\n", + "display(Image.open('game_engines/outputs/image1.png'))" ] }, { @@ -255,7 +255,7 @@ "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAQAAAAEACAIAAADTED8xAAADYElEQVR4nO3dsWkdQRRA0b8fVWSUC4eqwagDtyLnjpW4gZ8JhHJl6metDpQsj2W45xQw+xj2MtnMtu/7ZWnX69kTHLP6/i9u8b8HjhEAaQIgTQCkCYA0AZAmANIEQJoASBMAaQIgTQCkCYA0AZAmANIEQJoASBMAaQIgTQCkCYA0AZAmANIEQJoASBMAaQIgTQCkCYA0AZAmANLuxr+w+v3906b3x/sD3/J3kiYA0gRAmgBIEwBpAiBNAKQJgDQBkCYA0gRAmgBIEwBpAiBNAKQJgDQBkCYA0gRAmgBIEwBpAiBNAKQJgDQBkCYA0gRAmgBIEwBpAiBNAKTNvw8wfT/9+8fs+tMe7s+eIM0JQJoASBMAaQIgTQCkCYA0AZAmANIEQJoASBMAaQIgTQCkCYA0AZAmANIEQJoASBMAaQIgTQCkCYA0AZAmANIEQJoASBMAaQIgTQCkCYA0AZC2Dd/ef7leZr+wL97w8vsz/P7D76fH0fXX/nvgIAGQJgDSBECaAEgTAGkCIE0ApAmANAGQJgDSBECaAEgTAGkCIE0ApAmANAGQJgDSBECaAEgTAGkCIE0ApAmANAGQJgDSBECaAEgTAGkCIG359wH43urvA3ze/oyu7wQgTQCkCYA0AZAmANIEQJoASBMAaQIgTQCkCYA0AZAmANIEQJoASBMAaQIgTQCkCYA0AZAmANIEQJoASBMAaQIgTQCkCYA0AZAmANIEQJoASLs7ewDW9nl7Hl3/77/X0fWdAKQJgDQBkCYA0gRAmgBIEwBpAiBNAKQJgDQBkCYA0gRAmgBIEwBpAiBNAKQJgDQBkCYA0gRAmgBIEwBpAiBNAKQJgDQBkCYA0gRAmgBIEwBp277vox+4Dic2PP641fdnm13+8n94fScAaQIgTQCkCYA0AZAmANIEQJoASBMAaQIgTQCkCYA0AZAmANIEQJoASBMAaQIgTQCkCYA0AZAmANIEQJoASBMAaQIgTQCkCYA0AZAmANIEQNr26+HH2TMc8vL2cfYIhzz9vD97hEPm93/2BQInAGkCIE0ApAmANAGQJgDSBECaAEgTAGkCIE0ApAmANAGQJgDSBECaAEgTAGkCIE0ApAmANAGQJgDSBECaAEgTAGkCIE0ApAmANAGQJgDSBEDaF+faLh/C7eNFAAAAAElFTkSuQmCC\n", "text/plain": [ - "" + "" ] }, "metadata": {}, @@ -283,8 +283,8 @@ " return image\n", "\n", "\n", - "save_image( counts2image(counts,grid), scale=[300,300])\n", - "display(Image.open('output.png'))" + "save_image( counts2image(counts,grid), scale=[300,300], filename='image2.png' )\n", + "display(Image.open('game_engines/outputs/image2.png'))" ] }, { @@ -302,7 +302,7 @@ "metadata": {}, "outputs": [], "source": [ - "frame_num = 100" + "frame_num = 20" ] }, { @@ -319,12 +319,13 @@ "outputs": [], "source": [ "from apng import APNG\n", + "import os\n", "\n", "state = image2state(plumber,grid)\n", "\n", "filenames = []\n", "for f in range(frame_num):\n", - " \n", + " \n", " circuits = []\n", " for j in range(3):\n", " qc = QuantumCircuit(q)\n", @@ -340,18 +341,21 @@ " \n", " frame = counts2image(counts,grid)\n", " \n", - " filename = 'output'+str(f)+'.png'\n", + " filename = 'frame_'+str(f)+'.png'\n", " save_image( counts2image(counts,grid), scale=[300,300], filename=filename)\n", - " filenames.append( filename )\n", + " filenames.append( 'game_engines/outputs/' + filename )\n", + "\n", + "APNG.from_files(filenames,delay=250).save('game_engines/outputs/animation.png')\n", "\n", - "APNG.from_files(filenames,delay=250).save('animation.png')" + "for file in filenames:\n", + " os.remove(file)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "![](animation.png)" + "![](game_engines/outputs/animation.png)" ] }, { @@ -373,7 +377,7 @@ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "a7922e53d2fa420a8ec3db828e8a5db6", + "model_id": "2969de7e3f194c0c9616a4372d8aee08", "version_major": 2, "version_minor": 0 }, @@ -406,7 +410,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Once you've chose, run the cells below to extract the values and create the animation." + "Once you've chosen, run the cells below to extract the values and create the animation." ] }, { @@ -431,7 +435,7 @@ "\n", "filenames = []\n", "for f in range(frame_num):\n", - " \n", + " \n", " circuits = []\n", " for j in range(3):\n", " qc = QuantumCircuit(q)\n", @@ -448,18 +452,21 @@ " \n", " frame = counts2image(counts,grid)\n", " \n", - " filename = 'output'+str(f)+'.png'\n", + " filename = 'frame_'+str(f)+'.png'\n", " save_image( counts2image(counts,grid), scale=[300,300], filename=filename)\n", - " filenames.append( filename )\n", + " filenames.append( 'game_engines/outputs/' + filename )\n", + "\n", + "APNG.from_files(filenames,delay=250).save('game_engines/outputs/new_animation.png')\n", "\n", - "APNG.from_files(filenames,delay=250).save('new_animation.png')" + "for file in filenames:\n", + " os.remove(file) " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "![](new_animation.png)" + "![](game_engines/outputs/new_animation.png)" ] }, { From 2bef78686b19e8255fb81ce811c8e584a7f47978 Mon Sep 17 00:00:00 2001 From: James Wootton Date: Mon, 1 Apr 2019 15:34:54 +0200 Subject: [PATCH 3/6] Add outputs folder for animations, etc --- .../games/game_engines/outputs/animation.png | Bin 0 -> 21272 bytes community/games/game_engines/outputs/image1.png | Bin 0 -> 907 bytes community/games/game_engines/outputs/image2.png | Bin 0 -> 921 bytes .../game_engines/outputs/new_animation.png | Bin 0 -> 21386 bytes 4 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 community/games/game_engines/outputs/animation.png create mode 100644 community/games/game_engines/outputs/image1.png create mode 100644 community/games/game_engines/outputs/image2.png create mode 100644 community/games/game_engines/outputs/new_animation.png diff --git a/community/games/game_engines/outputs/animation.png b/community/games/game_engines/outputs/animation.png new file mode 100644 index 0000000000000000000000000000000000000000..45c4bd55c9349af7f03777728f14c95e234d3e2a GIT binary patch literal 21272 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 Date: Mon, 1 Apr 2019 15:36:27 +0200 Subject: [PATCH 4/6] Add reference to animations --- community/games/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/community/games/README.md b/community/games/README.md index fa8aa2ec3..aa071422c 100644 --- a/community/games/README.md +++ b/community/games/README.md @@ -19,6 +19,7 @@ This is exactly what we'd like to replicate in this folder. Here you'll find bas * [Random Terrain Generation](random_terrain_generation.ipynb) - A simple example of using quantum computers for the kind of procedural generation often used in games. +* [Quantum Animations](quantum_animations.ipynb) - A simple example of making pixel art animations with quantum computers. ## Contributing From 6b4f71509bd712d05e7b0ccef58df37b8d7f4b00 Mon Sep 17 00:00:00 2001 From: James Wootton Date: Mon, 1 Apr 2019 15:38:33 +0200 Subject: [PATCH 5/6] Add reference to animations notebook --- community/games/random_terrain_generation.ipynb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/community/games/random_terrain_generation.ipynb b/community/games/random_terrain_generation.ipynb index 3bbf6b703..475413648 100644 --- a/community/games/random_terrain_generation.ipynb +++ b/community/games/random_terrain_generation.ipynb @@ -765,7 +765,9 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Clearly our Terrain maps are blockier than the example of Perlin noise shown at the top. This could be dealt with by adding more qubits, or simply by being careful in choosing how we apply the method. When generating terrain with Perlin noise, multiple layers are often used to create a good effect. Perhaps in future, some of those layers could be quantum." + "Clearly our Terrain maps are blockier than the example of Perlin noise shown at the top. This could be dealt with by adding more qubits, or simply by being careful in choosing how we apply the method. When generating terrain with Perlin noise, multiple layers are often used to create a good effect. Perhaps in future, some of those layers could be quantum.", + "\n", + "For another example of generation images using qubits, see the [Quantum Animations](quantum_animations.ipynb) notebook." ] } ], From 913b895f54802e13152ceb2c9cd225e75084812f Mon Sep 17 00:00:00 2001 From: James Wootton Date: Mon, 1 Apr 2019 15:39:34 +0200 Subject: [PATCH 6/6] Update random_terrain_generation.ipynb --- community/games/random_terrain_generation.ipynb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/community/games/random_terrain_generation.ipynb b/community/games/random_terrain_generation.ipynb index 475413648..ae321d222 100644 --- a/community/games/random_terrain_generation.ipynb +++ b/community/games/random_terrain_generation.ipynb @@ -765,7 +765,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Clearly our Terrain maps are blockier than the example of Perlin noise shown at the top. This could be dealt with by adding more qubits, or simply by being careful in choosing how we apply the method. When generating terrain with Perlin noise, multiple layers are often used to create a good effect. Perhaps in future, some of those layers could be quantum.", + "Clearly our Terrain maps are blockier than the example of Perlin noise shown at the top. This could be dealt with by adding more qubits, or simply by being careful in choosing how we apply the method. When generating terrain with Perlin noise, multiple layers are often used to create a good effect. Perhaps in future, some of those layers could be quantum.\n", "\n", "For another example of generation images using qubits, see the [Quantum Animations](quantum_animations.ipynb) notebook." ]