{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "A common question in computer science is to measure the [computational complexity of algorithms](https://en.wikipedia.org/wiki/Computational_complexity_theory). I've recently taken a programming test where the two aspects of programming that were measured as part of the test were **correctness** and **speed**, as each programming task had an assigned target complexity ($\\mathcal{O}(n\\log{}n)$ or $\\mathcal{O}(n)$ for example).\n", "\n", "This is obviously a very important topic, for instance when working on scaling a particular algorithm for a size of data. Usually, the algorithm itself can be analyzed to determine its complexity. For instance, if your input is an array and you're looping over all elements, then this will have a $\\mathcal{O}(n)$ complexity, where $n$ is the size of the array. If you're doing two nested loops, then the complexity is $\\mathcal{O}(n^2)$. \n", "\n", "But it's not always possible to actually be sure of the complexity before you write the algorithm. For instance when you use built-in functions for which the complexity is not straightforward. A simpler alternative is then to measure the timings of your function as a function of the input array size. I like this practical benchmarking idea, which we will demonstrate on three implementations that compute the [Fibonacci numbers](https://en.wikipedia.org/wiki/Fibonacci_number). " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# First implementation: recursion " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The first implementation I'd like to use if the recursive one:" ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "collapsed": false }, "outputs": [], "source": [ "def fib_rec(n):\n", " \"Computes Fibonacci number recursively.\"\n", " if n == 0: \n", " return 0\n", " elif n == 1: \n", " return 1\n", " else:\n", " return fib_rec(n-1) + fib_rec(n-2)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let's test this:" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "[0, 1, 1, 2, 3, 5, 8, 13, 21, 34]" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "[fib_rec(i) for i in range(10)]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Second implementation: loop style " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The second one is a loop style implementation:" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def fib_loop(n):\n", " \"Computes Fibonacci number by iterating over all elements.\"\n", " if n == 0: \n", " return 0\n", " elif n == 1: \n", " return 1\n", " else: \n", " a, b = 0, 1\n", " for i in range(n - 1):\n", " a, b = b, a + b\n", " return b" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "[0, 1, 1, 2, 3, 5, 8, 13, 21, 34]" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "[fib_loop(i) for i in range(10)]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Third implementation: log time " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The last implementation makes use of the fact that the Fibonacci numbers can be computed a [matrix multiplication in log time](http://kukuruku.co/hub/algorithms/the-nth-fibonacci-number-in-olog-n). The idea here is to decompose the number $n$ in powers of two to yield a speedup.\n", "\n", "It is based on the following things:\n", "\n", "- decompose $n$ in a sum of powers of 2\n", "- compute the $Q$ matrix exponents up to the highest power of two needed\n", "- assemble the result\n", "\n", "Let's look at this in a step by step process. First, let's decompose any number in powers of 2. We use a simple iterative algorithm:" ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "collapsed": true }, "outputs": [], "source": [ "from math import log2\n", "\n", "def powers_of_two(n):\n", " \"Returns a list of the powers of 2 that sum to equal n.\"\n", " powers = []\n", " remainder = n\n", " while remainder != 0:\n", " powers.append(int(log2(remainder)))\n", " remainder -= 2 ** powers[-1]\n", " return powers" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "[(1, [0]),\n", " (2, [1]),\n", " (3, [1, 0]),\n", " (4, [2]),\n", " (5, [2, 0]),\n", " (6, [2, 1]),\n", " (7, [2, 1, 0]),\n", " (8, [3]),\n", " (9, [3, 0])]" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "[(i, powers_of_two(i)) for i in range(1, 10)]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The second step is to compute the matrices needed for rapid multiplication. We will store each 2x2 matrix as a tuple. We also need to define a matrix multiplication operation:" ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def precompute_matrix(max_power):\n", " \"Precomputes matrix until highest power of 2 needed.\"\n", " matrix_powers = {}\n", " matrix_powers[0] = (1, 1, 1, 0)\n", " for i in range(1, max_power + 1):\n", " matrix_powers[i] = matrix_mult(matrix_powers[i-1], matrix_powers[i-1])\n", " return matrix_powers\n", "\n", "def matrix_mult(mat1, mat2):\n", " \"Multiplication of 2x2 matrices.\"\n", " a, b, c, d = mat1\n", " e, f, g, h = mat2\n", " return (a*e + b*g, \n", " a*f + b*h,\n", " c*e + d*g,\n", " c*f + d*h)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let's check that the results are correct for the first few powers:" ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "{0: (1, 1, 1, 0),\n", " 1: (2, 1, 1, 1),\n", " 2: (5, 3, 3, 2),\n", " 3: (34, 21, 21, 13),\n", " 4: (1597, 987, 987, 610)}" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "precompute_matrix(4)" ] }, { "cell_type": "code", "execution_count": 9, "metadata": { "collapsed": true }, "outputs": [], "source": [ "import numpy as np\n", "from numpy.linalg import matrix_power" ] }, { "cell_type": "code", "execution_count": 10, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "array([[2, 1],\n", " [1, 1]])" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "matrix_power(np.array([[1, 1], [1, 0]]), 2)" ] }, { "cell_type": "code", "execution_count": 11, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "array([[5, 3],\n", " [3, 2]])" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "matrix_power(np.array([[1, 1], [1, 0]]), 4)" ] }, { "cell_type": "code", "execution_count": 12, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "array([[34, 21],\n", " [21, 13]])" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "matrix_power(np.array([[1, 1], [1, 0]]), 8)" ] }, { "cell_type": "code", "execution_count": 13, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "array([[1597, 987],\n", " [ 987, 610]])" ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "matrix_power(np.array([[1, 1], [1, 0]]), 16)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This seems good, so we can now assemble the final parts of our log fibonacci function:" ] }, { "cell_type": "code", "execution_count": 14, "metadata": { "collapsed": true }, "outputs": [], "source": [ "from math import sqrt\n", "\n", "def fib_log(n):\n", " \"Computes Fibonacci number in logarithmic time.\"\n", " if n == 0: return 0\n", " terms = powers_of_two(n)\n", " matrix_terms = precompute_matrix(max(terms))\n", " result = (1, 0, 0, 1)\n", " for term in terms:\n", " result = matrix_mult(result, matrix_terms[term])\n", " return result[1]" ] }, { "cell_type": "code", "execution_count": 15, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "[0, 1, 1, 2, 3, 5, 8, 13, 21, 34]" ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "[fib_log(i) for i in range(10)]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Measuring timings" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "At this point, one can wonder: what is the complexity of these three implementations? Except for the loop one, which is linear, it's not easy to tell right away. That's why, I suggest, we just measure this." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Measuring is quite easy, in fact. Let's just create a timing function, that accepts a function as an argument and a number." ] }, { "cell_type": "code", "execution_count": 16, "metadata": { "collapsed": true }, "outputs": [], "source": [ "import time\n", "\n", "def time_func(func, *arg):\n", " \"Times the execution of a function. Result is in seconds.\"\n", " tic = time.clock()\n", " func(*arg)\n", " toc = time.clock()\n", " return toc - tic" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let's see if it works:" ] }, { "cell_type": "code", "execution_count": 17, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "1.2619419745651634" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "time_func(fib_rec, 32)" ] }, { "cell_type": "code", "execution_count": 18, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "0.4757292146374297" ] }, "execution_count": 18, "metadata": {}, "output_type": "execute_result" } ], "source": [ "time_func(fib_loop, 200000)" ] }, { "cell_type": "code", "execution_count": 19, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "0.47338340004959445" ] }, "execution_count": 19, "metadata": {}, "output_type": "execute_result" } ], "source": [ "time_func(fib_log, 1000000)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Comparison of the three implementations using a plot " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "With this tool, we can devise a test case for which we can compare all three implementations." ] }, { "cell_type": "code", "execution_count": 20, "metadata": { "collapsed": true }, "outputs": [], "source": [ "test_case_rec = [2, 4, 8, 16, 24, 26, 28, 30, 32]\n", "test_case_loop = [10, 100, 200, 300, 500, 1000, 2000, 5000, 10000, 20000, 50000, 75000, 100000]\n", "test_case_power = [10, 100, 200, 300, 500, 1000]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We use different test cases for each algorithm as will become clear in a second." ] }, { "cell_type": "code", "execution_count": 21, "metadata": { "collapsed": true }, "outputs": [], "source": [ "import matplotlib.pyplot as plt\n", "plt.style.use('bmh')\n", "%matplotlib inline" ] }, { "cell_type": "code", "execution_count": 22, "metadata": { "collapsed": false }, "outputs": [ { "data": { "image/png": "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\nAABJRU5ErkJggg==\n", "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "plt.figure(figsize=(10, 4))\n", "for ind, func, tc in zip(range(1, 4), \n", " [fib_rec, fib_loop, fib_log],\n", " [test_case_rec, test_case_loop, test_case_loop]):\n", " timings = [time_func(func, test) for test in tc]\n", " plt.subplot(1, 3, ind)\n", " plt.plot(tc, timings, '-o')\n", " plt.xlabel('size of input (n)')\n", " plt.ylabel('time (s)')\n", " plt.title(\"{}\".format(func.__name__))\n", "plt.tight_layout()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can put that same plot on the same axis to see things more concretely:" ] }, { "cell_type": "code", "execution_count": 31, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "(-1000, 100000.0)" ] }, "execution_count": 31, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "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\nL9ePfvQjDRs2TBdeeKHOOecc9e/fX+vXr9fOnTvVtWvXkL6rcJi5A00H2q5E68IhfsjeNvK3i+wP\n7lDPem7durWaNGmiHj166LrrrtOUKVPUpUuXap/v3nvvVadOnXT22Wfr6KOP1uDBgys+jJienq5H\nHnlEY8eOVceOHXXBBRcoPz//+31TEXAHK5LXVHPnzvXp6en77bv0xU+0cVeRnh/SU60apUa0MgAA\nUNutXbt2v04wwnGwf845OTnKzMwM/SfCmLkDTQfarkTrwiF+yN428reL7BE2OtAAAAA4qH79+lVZ\ns5g6daoGDx4cwYqiZ2aApgNtF104u8jeNvK3i+yD9d5770W9hIRjpsIBAAAABMHMAE0H2i66cHaR\nvW3kbxfZI2xmBmgAAAAgCGYGaDrQdtGFs4vsbSN/u8geYTMzQAMAAFi3YsUKDRgwQGlpaWrZsqUm\nT54sSXr33XfVq1evap9vxIgRmjBhQtDLTHhmBmg60HbRhbOL7G0jf7vI/uAefvhhnX766crLy9PG\njRs1cuTIitcO9VMKsT8zj7EDAACISl5urp6c8KAK1m9U/TYtddXY25XWsWPcz7F69Wqzz24Okpk7\n0HSg7aILZxfZ20b+diVa9nm5uXpg8OXqPXuBfvThavWevUAPDL5cebm5cT3HoEGDlJ2drdGjRyst\nLU3XXnvtfvUL772mTp2qrl27qnfv3srKyqrW9ylJf/zjH5WRkaEuXbpo2LBhWr9+fcVrH374oc48\n80wdc8wxOvPMMzVv3ryK1y644AKNHz9eZ555pjp27KjLLrtM27dvr/b148XMAA0AABCFJyc8qB+v\nLlQ9Vzp21XNJ+vHqQo3POEtvtOkX06/xGWdVeY4nJzwY8zpmz56tU089VZMmTVJeXp5SUlL2e33D\nhg3aunWrli5dqmnTpunWW2/VypUrYz7/v/71L91///165plntGzZMrVv315XX321JGnbtm0aOnSo\nrrvuOq1cuVLXX3+9hgwZom3btlUc/6c//UnTpk3T8uXLlZSUpNGjR8d87XgzM0DTgbaLLpxdZG8b\n+duVaNkXrN9YMfiWq+eS5L2P+Rze+yrPUfD1pmqv52DXdc5p7NixSklJUb9+/XTWWWdp9uzZMZ83\nKytLw4YNU69evZSSkqJx48ZpwYIFys/P15w5c9S5c2ddeOGFSkpK0uDBg9W1a1e98cYbFcdffPHF\n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\nP/xDm7yR6wm5AAAAAElFTkSuQmCC\n", "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "plt.figure(figsize=(10, 10))\n", "for ind, func, tc in zip(range(1, 4), \n", " [fib_rec, fib_loop, fib_log],\n", " [test_case_rec, test_case_loop, test_case_loop]):\n", " timings = [time_func(func, test) for test in tc]\n", " plt.plot(tc, timings, '-o', label=\"{}\".format(func.__name__))\n", " plt.xlabel('size of input (n)')\n", " plt.ylabel('time (s)')\n", "plt.tight_layout()\n", "plt.legend()\n", "plt.ylim(-0.01, 0.4)\n", "plt.xlim(-1000, 1e5)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "What we see above is quite interesting:\n", "\n", "- the recursive implementation explodes so much it doesn't even show on the plot (effectively making any usage above n=32 unpractical)\n", "- the loop style scales better\n", "- the log time implementation fares even better than the loop style" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Conclusions " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Time for some takeaways. As the last plot has shown, the log implementation is definitely the fastest. The recursive implementation, while true to the spirit of the \"sequence style definition\" of the Fibonacci numbers is **very** impractical. It turns out that a straightforward way of making it faster is to memoize it, as [this blog post shows in the context of dynamic programming](https://jeremykun.com/2012/01/12/a-spoonful-of-python/). Another thought is that the algorithm's complexity effectively makes it tractable for large cases or just don't. If all you can come up with is something like the recursive implementation, there's many problems that will not be tractable (I'm thinking in terms of [project Euler problems](https://projecteuler.net/) here). " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This post was entirely written using the IPython notebook. Its content is BSD-licensed. You can see a static view or download this notebook with the help of nbviewer at [20160531_MeasuringComplexityAlgorithm.ipynb](http://nbviewer.ipython.org/urls/raw.github.com/flothesof/posts/master/20160531_MeasuringComplexityAlgorithm.ipynb)." ] } ], "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.5.1" } }, "nbformat": 4, "nbformat_minor": 0 }