{"id":196,"date":"2021-03-03T20:16:35","date_gmt":"2021-03-03T20:16:35","guid":{"rendered":"https:\/\/gnikesh.com\/?p=196"},"modified":"2021-03-05T19:28:48","modified_gmt":"2021-03-05T19:28:48","slug":"tail-recursive-nth-fibonacci-number","status":"publish","type":"post","link":"https:\/\/gnikesh.com\/index.php\/2021\/03\/03\/tail-recursive-nth-fibonacci-number\/","title":{"rendered":"Tail Recursive nth Fibonacci Number"},"content":{"rendered":"\n<p><\/p>\n\n\n\n<p>When a function is called, it gets it&#8217;s own stack to store the parameters, and it&#8217;s local variables. So, an implementation of recursive function that stores a local variable and waits for the values returned from another recursive call to the function and so on would require stack to store the results. Let&#8217;s see an example of a recursive function implemented in <a href=\"https:\/\/en.wikipedia.org\/wiki\/Standard_ML\">Standard ML<\/a> (SML), a general-purpose functional programming language,<\/p>\n\n\n\n<!--more-->\n\n\n\n<pre class=\"wp-block-code\"><code>fun factorial n = \n\tif n = 0 then 1\n\telse n * (factorial (n - 1))<\/code><\/pre>\n\n\n\n<p>I will base my writing for a functional programming language and will use SML as my language of choice. Python, however, does not optimize tail recursive calls by default. And we are still bounded by default maximum recursion depth of 1000 (we can manually increase this limit). However, I will also write python equivalent code.<\/p>\n\n\n\n<span class=\"collapseomatic \" id=\"id69f261ce31e4d\"  tabindex=\"0\" title=\"Python equivalent code\"    >Python equivalent code<\/span><div id=\"target-id69f261ce31e4d\" class=\"collapseomatic_content \">\n<pre class=\"wp-block-code\"><code>\ndef factorial(n):\n    if n == 0:\n        return 1\n    else:\n        return n * factorial(n - 1)\n<\/code><\/pre>\n<\/div>\n\n\n\n<p><\/p>\n\n\n\n<p>The above code that calculates the factorial of a given number n, requires stack to store all values of n unless base condition is met. So, if n is really big, we can see how stack space grows linearly with n. One way of solving this is to write the above recursive function using tail recursion. We call a function tail recursive if  no computation happens after a recursive call. In our case the above <em>factorial()<\/em> function would look like<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>(* HELPER FUNCTION TO CALCULATE FACTORIAL *)\nfun calculate_fact r n =  \n\tif n = 0 then r\n\telse calculate_fact (r * n) (n - 1)\n\n(* MAIN FUNCTION *)\nfun factorial n = calculate_fact 1 n <\/code><\/pre>\n\n\n\n<span class=\"collapseomatic \" id=\"id69f261ce31ea1\"  tabindex=\"0\" title=\"Python equivalent code\"    >Python equivalent code<\/span><div id=\"target-id69f261ce31ea1\" class=\"collapseomatic_content \">\n<pre class=\"wp-block-code\"><code>def factorial(n, r=1):\n    if n == 0:\n        return r\n    else:\n        return factorial(n - 1, r * n)\n<\/code><\/pre>\n<\/div>\n\n\n\n<p><\/p>\n\n\n\n<p>In this above program, we do not need to save the local variables as we did in the first program because they are not referenced after the recursive call. Hence, compiler can optimize the tail recursion and there&#8217;s no use of saving the current function&#8217;s stack frame. One way of thinking tail recursion would be as an iteration in disguise as used in imperative language. For example, this above tail recursion could be coded as<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>def factorial(n):\n    r = 1\n    while n != 0:\n        r = r * n\n        n = n - 1\n    return r<\/code><\/pre>\n\n\n\n<p>One thing to note is, ideally we would want tail recursion not to be bounded by maximum recursion depth. However, python has a default recursion depth of 1000 and we cannot go past this limit without increasing it. But functional languages do not have this limit.<\/p>\n\n\n\n<p>Now let&#8217;s look into these concept in case of Fibonacci sequence.<\/p>\n\n\n\n<p><strong>Fibonacci sequence<\/strong> is generated by Fibonacci numbers where each number is the sum of two preceding ones, starting from 0 and 1. The sequence goes like 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, &#8230;.. and so on. So, <img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/gnikesh.com\/wp-content\/ql-cache\/quicklatex.com-4f5493a5d21a6325e09f24fd036e360b_l3.png\" class=\"ql-img-inline-formula quicklatex-auto-format\" alt=\"&#70;&#95;&#48;&#32;&#61;&#32;&#48;&#44;&#32;&#70;&#95;&#49;&#32;&#61;&#32;&#49;\" title=\"Rendered by QuickLaTeX.com\" height=\"16\" width=\"110\" style=\"vertical-align: -4px;\"\/> and for <img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/gnikesh.com\/wp-content\/ql-cache\/quicklatex.com-ea6a19b56af2c73af90505acc42eb52f_l3.png\" class=\"ql-img-inline-formula quicklatex-auto-format\" alt=\"&#110;&#32;&#62;&#32;&#49;\" title=\"Rendered by QuickLaTeX.com\" height=\"14\" width=\"42\" style=\"vertical-align: -2px;\"\/>, <img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/gnikesh.com\/wp-content\/ql-cache\/quicklatex.com-0c53e0bbaf1d7c9f1f5fc5ad0b8a0304_l3.png\" class=\"ql-img-inline-formula quicklatex-auto-format\" alt=\"&#70;&#95;&#110;&#32;&#61;&#32;&#70;&#95;&#123;&#110;&#45;&#49;&#125;&#32;&#43;&#32;&#70;&#95;&#123;&#110;&#45;&#50;&#125;\" title=\"Rendered by QuickLaTeX.com\" height=\"15\" width=\"141\" style=\"vertical-align: -3px;\"\/>. Some implementation ignores 0 and, <img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/gnikesh.com\/wp-content\/ql-cache\/quicklatex.com-44212467234cfb9d1fc14f2c086aefce_l3.png\" class=\"ql-img-inline-formula quicklatex-auto-format\" alt=\"&#70;&#95;&#49;&#32;&#61;&#32;&#70;&#95;&#50;&#32;&#61;&#32;&#49;\" title=\"Rendered by QuickLaTeX.com\" height=\"15\" width=\"93\" style=\"vertical-align: -3px;\"\/> is taken as starting of the sequence. We will use the  convention that 1 is the first element in the sequence.<\/p>\n\n\n\n<p>We can see that numbers can get really big quickly. Hence, to generate <img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/gnikesh.com\/wp-content\/ql-cache\/quicklatex.com-4df089ece0b22647e14bb99816b9de87_l3.png\" class=\"ql-img-inline-formula quicklatex-auto-format\" alt=\"&#110;&#94;&#123;&#116;&#104;&#125;\" title=\"Rendered by QuickLaTeX.com\" height=\"15\" width=\"24\" style=\"vertical-align: 0px;\"\/> Fibonacci number, we might want to evaluate the performance of our algorithm even if it gives correct results for smaller value of <img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/gnikesh.com\/wp-content\/ql-cache\/quicklatex.com-a8f81f758e120a3c01f39acbe077ec6d_l3.png\" class=\"ql-img-inline-formula quicklatex-auto-format\" alt=\"&#110;\" title=\"Rendered by QuickLaTeX.com\" height=\"8\" width=\"11\" style=\"vertical-align: 0px;\"\/>. Let&#8217;s see some approaches, their pitfalls, and improvements we could make.<\/p>\n\n\n\n<p>A straight forward solution to calculate <img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/gnikesh.com\/wp-content\/ql-cache\/quicklatex.com-4df089ece0b22647e14bb99816b9de87_l3.png\" class=\"ql-img-inline-formula quicklatex-auto-format\" alt=\"&#110;&#94;&#123;&#116;&#104;&#125;\" title=\"Rendered by QuickLaTeX.com\" height=\"15\" width=\"24\" style=\"vertical-align: 0px;\"\/> Fibonacci number is to recursively calculate sum of <img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/gnikesh.com\/wp-content\/ql-cache\/quicklatex.com-e3b942ef454e09293265c934bc002789_l3.png\" class=\"ql-img-inline-formula quicklatex-auto-format\" alt=\"&#40;&#110;&#32;&#45;&#32;&#49;&#41;&#94;&#123;&#116;&#104;&#125;\" title=\"Rendered by QuickLaTeX.com\" height=\"20\" width=\"67\" style=\"vertical-align: -5px;\"\/> and <img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/gnikesh.com\/wp-content\/ql-cache\/quicklatex.com-4f58c4af82bb1f91ff81e17b26dd085c_l3.png\" class=\"ql-img-inline-formula quicklatex-auto-format\" alt=\"&#40;&#110;&#32;&#45;&#32;&#50;&#41;&#94;&#123;&#116;&#104;&#125;\" title=\"Rendered by QuickLaTeX.com\" height=\"20\" width=\"67\" style=\"vertical-align: -5px;\"\/> Fibonacci numbers.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>fun fibonacci n =\n\tif n = 0 then 0\n \telse if n = 1 then 1\n\t\telse (fibonacci (n - 1)) + (fibonacci (n - 2));<\/code><\/pre>\n\n\n\n<span class=\"collapseomatic \" id=\"id69f261ce31ebe\"  tabindex=\"0\" title=\"Python equivalent code\"    >Python equivalent code<\/span><div id=\"target-id69f261ce31ebe\" class=\"collapseomatic_content \">\n<pre class=\"wp-block-code\"><code>def fibonacci(n):\n    if n == 0:\n        return 0\n    elif n == 1:\n        return 1\n    else:\n        return fibonacci(n - 1) + fibonacci (n - 2)<\/code><\/pre>\n<\/div>\n\n\n\n<p><\/p>\n\n\n\n<p>Running this python equivalent function <em>fibonacci(35)<\/em> took 4.0823 seconds in my computer.<br>If we analyze this function, we can see two main drawbacks of this implementation, <\/p>\n\n\n\n<ol class=\"wp-block-list\"><li>It is not tail recursive and so requires stack space to run.<\/li><li>It repeatedly calls the <em>fibonacci<\/em> function on smaller numbers i.e. recomputing previously computed results. For example,<br>     <em>fibonacci (7)<br>=&gt; fibonacci (6) + fibonacci (5)<br>=&gt; fibonacci (5) + fibonacci (4) + fibonacci (5)<br>=&gt; fibonacci (4) + fibonacci (3) + fibonacci (4) + fibonacci (5) &#8230; and so on<\/em><br><\/li><\/ol>\n\n\n\n<p>Time complexity: Exponential<br>Space complexity: <img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/gnikesh.com\/wp-content\/ql-cache\/quicklatex.com-839a1bea811b14b50a5dbd36669826ef_l3.png\" class=\"ql-img-inline-formula quicklatex-auto-format\" alt=\"&#79;&#40;&#110;&#41;\" title=\"Rendered by QuickLaTeX.com\" height=\"19\" width=\"38\" style=\"vertical-align: -5px;\"\/> (stack usage)<\/p>\n\n\n\n<p>Let&#8217;s write this <em>fibonacci<\/em> function using tail recursion.  <\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>(* HELPER FUNCTION TO CALCULATE FIBONACCI NUMBER *)\nfun fib_calculate prev curr n =\n\tif n = 0 orelse n = 1 then curr\n\telse fib_calculate curr (prev + curr) (n - 1);\n\n(* MAIN FUNCTION TO ABSTRACT prev AND curr VALUES *)\nfun fibonacci n = fib_calculate 0 1 n;<\/code><\/pre>\n\n\n\n<span class=\"collapseomatic \" id=\"id69f261ce31ed9\"  tabindex=\"0\" title=\"Python equivalent code\"    >Python equivalent code<\/span><div id=\"target-id69f261ce31ed9\" class=\"collapseomatic_content \">\n<pre class=\"wp-block-code\"><code>def fibonacci(n, prev=0, curr=1):\n    if n == 0 or n == 1:\n        return curr\n    else:\n        return fibonacci(n - 1, curr, prev + curr)<\/code><\/pre>\n<\/div>\n\n\n\n<p><\/p>\n\n\n\n<p>Running this function <em>fibonacci(35)<\/em> took <img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/gnikesh.com\/wp-content\/ql-cache\/quicklatex.com-6cc6db814d0325118df7589fef79ed41_l3.png\" class=\"ql-img-inline-formula quicklatex-auto-format\" alt=\"&#48;&#46;&#48;&#48;&#48;&#48;\" title=\"Rendered by QuickLaTeX.com\" height=\"12\" width=\"50\" style=\"vertical-align: 0px;\"\/> seconds in my computer. Here, we do not recompute previously computed results and also, stack space is constant and does not grow with the size of input n. For this implementation,<\/p>\n\n\n\n<p>Time complexity: <img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/gnikesh.com\/wp-content\/ql-cache\/quicklatex.com-839a1bea811b14b50a5dbd36669826ef_l3.png\" class=\"ql-img-inline-formula quicklatex-auto-format\" alt=\"&#79;&#40;&#110;&#41;\" title=\"Rendered by QuickLaTeX.com\" height=\"19\" width=\"38\" style=\"vertical-align: -5px;\"\/><br>Space complexity: <img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/gnikesh.com\/wp-content\/ql-cache\/quicklatex.com-1090f6c53f92ebedacf91e50203fc963_l3.png\" class=\"ql-img-inline-formula quicklatex-auto-format\" alt=\"&#79;&#40;&#49;&#41;\" title=\"Rendered by QuickLaTeX.com\" height=\"19\" width=\"36\" style=\"vertical-align: -5px;\"\/><\/p>\n\n\n\n<p>So, we reduced the exponential time complexity to linear and stack space complexity from linear to constant by using tail recursion and preventing duplicate computations. <\/p>\n\n\n\n<p>Fun Fact: There exists mathematical formula we can calculate <img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/gnikesh.com\/wp-content\/ql-cache\/quicklatex.com-4df089ece0b22647e14bb99816b9de87_l3.png\" class=\"ql-img-inline-formula quicklatex-auto-format\" alt=\"&#110;&#94;&#123;&#116;&#104;&#125;\" title=\"Rendered by QuickLaTeX.com\" height=\"15\" width=\"24\" style=\"vertical-align: 0px;\"\/> Fibonacci number with constant time and space complexity. It&#8217;s called <a href=\"https:\/\/en.wikipedia.org\/wiki\/Fibonacci_number#Binet's_formula\">Binet&#8217;s Formula<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>When a function is called, it gets it&#8217;s own stack to store the parameters, and it&#8217;s local variables. So, an implementation of recursive function that stores a local variable and waits for the values returned from another recursive call to the function and so on would require stack to store the results. Let&#8217;s see an [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[7,12],"tags":[19,20],"class_list":["post-196","post","type-post","status-publish","format-standard","hentry","category-computer-science","category-functional-programming","tag-computer","tag-programming"],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/gnikesh.com\/index.php\/wp-json\/wp\/v2\/posts\/196","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/gnikesh.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/gnikesh.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/gnikesh.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/gnikesh.com\/index.php\/wp-json\/wp\/v2\/comments?post=196"}],"version-history":[{"count":50,"href":"https:\/\/gnikesh.com\/index.php\/wp-json\/wp\/v2\/posts\/196\/revisions"}],"predecessor-version":[{"id":471,"href":"https:\/\/gnikesh.com\/index.php\/wp-json\/wp\/v2\/posts\/196\/revisions\/471"}],"wp:attachment":[{"href":"https:\/\/gnikesh.com\/index.php\/wp-json\/wp\/v2\/media?parent=196"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/gnikesh.com\/index.php\/wp-json\/wp\/v2\/categories?post=196"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/gnikesh.com\/index.php\/wp-json\/wp\/v2\/tags?post=196"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}