[{"id":247502,"date":"2026-08-01T11:15:53","date_gmt":"2026-08-01T16:15:53","guid":{"rendered":"https:\/\/www.johndcook.com\/blog\/?p=247502"},"modified":"2026-08-01T11:17:13","modified_gmt":"2026-08-01T16:17:13","slug":"counting-rooted-trees","status":"publish","type":"post","link":"https:\/\/www.johndcook.com\/blog\/2026\/08\/01\/counting-rooted-trees\/","title":{"rendered":"Counting rooted trees"},"content":{"rendered":"<p>Combinatorial problems can be interesting for their own sake, but they are more interesting when there is a connection to a problem outside combinatorics, and the more unexpected the connection the better.<\/p>\n<p>Counting the number of unlabeled rooted trees [1] with <em>n<\/em> nodes is a pure mathematics problem. Designing numerical methods for solving differential equations is an applied mathematics problem. And yet the two are closely linked.<\/p>\n<p>Let <em>t<\/em>(<em>n<\/em>) be the number of distinct unlabeled rooted trees with <em>n<\/em> nodes. The diagram below shows that the first few terms of this sequence are 1, 1, 2, and 4.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-medium\" style=\"background-color: white;\" src=\"https:\/\/www.johndcook.com\/rooted_trees_order_1_to_4.svg\" width=\"680\" height=\"600\" \/><\/p>\n<p>In an <a href=\"https:\/\/www.johndcook.com\/blog\/2026\/07\/31\/runge-kutta-design\/\">earlier post<\/a> I showed that designing a 4-stage explicit Runge-Kutta method required solving a system of 8 equations in 10 unknowns, leaving two degrees of freedom in the solutions.<\/p>\n<p>The number of constraints <em>c<\/em>(<em>s<\/em>) needed to design an <em>s<\/em>-stage explicit RK method is equal to the number of rooted trees with up to <em>s<\/em> nodes:<\/p>\n<p style=\"padding-left: 40px;\"><em>c<\/em>(<em>s<\/em>) = <em>t<\/em>(1) + <em>t<\/em>(2) + <em>t<\/em>(3) + \u2026 + <em>t<\/em>(<em>s<\/em>)<\/p>\n<p>This is because there is a one-to-one correspondence between constrains on the\u00a0<em>n<\/em>th derivative of an RK formula and rooted trees, and an\u00a0<em>s<\/em> stage method has to satisfy the constraints of all stages up to\u00a0<em>s<\/em>. In the example of the 4th order RK method, we have<\/p>\n<p style=\"padding-left: 40px;\"><em>c<\/em>(4) =\u00a0<em>t<\/em>(1) +\u00a0<em>t<\/em>(2)\u00a0 +\u00a0<em>t<\/em>(3) +\u00a0<em>t<\/em>(4) = 1 + 1 + 2 + 4 = 8.<\/p>\n<p>The first few values [2] of <em>t<\/em>(<em>n<\/em>) are<\/p>\n<p style=\"padding-left: 40px;\">1, 1, 2, 4, 9, 20, 48, 115, 286, 719, 1842, 4766, 12486, 32973, \u2026<\/p>\n<p>and so you can see that\u00a0<em>t<\/em>(<em>n<\/em>) grows quickly. In fact, it grows exponentially [3].<\/p>\n<p>However, the number of parameters in an\u00a0<em>s<\/em> stage RK method is\u00a0<em>s<\/em>(<em>s<\/em> + 1)\/2. The number of equations grows exponentially and the number of variables grows only quadratically, so at some point you have more equations than variables. That&#8217;s already the case for <em>s<\/em> = 5 because you have 17 constraints on 15 variables.\u00a0The system has a solution because symmetry considerations render some of the equations redundant.<\/p>\n<p>A 10th order RK method requires 17 stages. (See the <a href=\"https:\/\/www.johndcook.com\/blog\/2026\/08\/01\/butcher-barrier\/\">previous post<\/a> for why the number of stages exceeds the order when the order is greater than 4.) Designing such a method would require solving over a million equations in 153 variables, and yet it can be done. [4]<\/p>\n<h2>Related posts<\/h2>\n<ul>\n<li class='link'><a href='https:\/\/www.johndcook.com\/blog\/2026\/07\/31\/runge-kutta-design\/'>Solving the RK4 equations<\/a><\/li>\n<li class='link'><a href='https:\/\/www.johndcook.com\/blog\/2026\/07\/27\/counting-permutations-with-roots\/'>Counting permutations with roots<\/a><\/li>\n<li class='link'><a href='https:\/\/www.johndcook.com\/blog\/2026\/06\/30\/dna-sequence-alignment-and-kings\/'>DNA alignment and Kings<\/a><\/li>\n<\/ul>\n<p>[1] This is a slightly contradictory term. Unlabeled means the we don&#8217;t distinguish the nodes. But we do distinguish one node, namely the root.<\/p>\n<p>[2] See OEIS <a href=\"https:\/\/oeis.org\/A000081\">A000081<\/a>.<\/p>\n<p>[2] Richard Otter proved in 1948 that the number of unlabeled rooted trees with\u00a0<em>n<\/em> nodes is asymptotically <em>C<\/em> \u03b1<sup><em>n<\/em><\/sup> \/ <em>n<\/em><sup>\u22123\/2<\/sup> where\u00a0<em>C<\/em> = 0.4399\u2026 and \u03b1 = 2.9557\u2026. The cumulative sum is at least this large since Otter&#8217;s estimate gives the size of the last term in the sum.<\/p>\n<p>[3] E. Hairer. A Runge-Kutta Method of Order 10. J. Inst. Maths Applics (1978) 21, 47-59<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Combinatorial problems can be interesting for their own sake, but they are more interesting when there is a connection to a problem outside combinatorics, and the more unexpected the connection the better. Counting the number of unlabeled rooted trees [1] with n nodes is a pure mathematics problem. Designing numerical methods for solving differential equations [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[9],"tags":[197,47],"class_list":["post-247502","post","type-post","status-publish","format-standard","hentry","category-math","tag-combinatorics","tag-differential-equations"],"acf":[],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 4.9.10 - aioseo.com -->\n\t<meta name=\"description\" content=\"The pure math problem of counting rooted trees is closely connected with the applied math problem of designing differential equation solvers.\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"John\"\/>\n\t<meta name=\"keywords\" content=\"combinatorics,differential equations\" \/>\n\t<link rel=\"canonical\" href=\"https:\/\/www.johndcook.com\/blog\/2026\/08\/01\/counting-rooted-trees\/\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 4.9.10\" \/>\n\t\t<meta property=\"og:locale\" content=\"en_US\" \/>\n\t\t<meta property=\"og:site_name\" content=\"John D. Cook | Applied Mathematics Consulting\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"Counting rooted trees\" \/>\n\t\t<meta property=\"og:description\" content=\"The pure math problem of counting rooted trees is closely connected with the applied math problem of designing differential equation solvers.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/www.johndcook.com\/blog\/2026\/08\/01\/counting-rooted-trees\/\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2026-08-01T16:15:53+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2026-08-01T16:17:13+00:00\" \/>\n\t\t<meta name=\"twitter:card\" content=\"summary\" \/>\n\t\t<meta name=\"twitter:title\" content=\"Counting rooted trees\" \/>\n\t\t<meta name=\"twitter:description\" content=\"The pure math problem of counting rooted trees is closely connected with the applied math problem of designing differential equation solvers.\" \/>\n\t\t<meta name=\"twitter:image\" content=\"https:\/\/www.johndcook.com\/blog\/wp-content\/uploads\/2022\/05\/twittercard.png\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"Counting rooted trees","description":"The pure math problem of counting rooted trees is closely connected with the applied math problem of designing differential equation solvers.","canonical_url":"https:\/\/www.johndcook.com\/blog\/2026\/08\/01\/counting-rooted-trees\/","robots":"max-image-preview:large","keywords":"combinatorics,differential equations","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"en_US","og:site_name":"John D. Cook | Applied Mathematics Consulting","og:type":"article","og:title":"Counting rooted trees","og:description":"The pure math problem of counting rooted trees is closely connected with the applied math problem of designing differential equation solvers.","og:url":"https:\/\/www.johndcook.com\/blog\/2026\/08\/01\/counting-rooted-trees\/","article:published_time":"2026-08-01T16:15:53+00:00","article:modified_time":"2026-08-01T16:17:13+00:00","twitter:card":"summary","twitter:title":"Counting rooted trees","twitter:description":"The pure math problem of counting rooted trees is closely connected with the applied math problem of designing differential equation solvers.","twitter:image":"https:\/\/www.johndcook.com\/blog\/wp-content\/uploads\/2022\/05\/twittercard.png"},"aioseo_meta_data":{"post_id":"247502","title":null,"description":"The pure math problem of counting rooted trees is closely connected with the applied math problem of designing differential equation solvers.","keywords":null,"keyphrases":{"focus":{"keyphrase":"","score":0,"analysis":{"keyphraseInTitle":{"score":0,"maxScore":9,"error":1}}},"additional":[]},"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":"","og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"Article","isEnabled":true},"graphs":[]},"schema_type":"default","schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":"-1","robots_max_videopreview":"-1","robots_max_imagepreview":"large","priority":null,"frequency":"default","location":null,"local_seo":null,"breadcrumb_settings":null,"limit_modified_date":false,"created":"2026-08-01 14:08:24","updated":"2026-08-01 17:23:59","ai":{"faqs":[],"keyPoints":[],"schemas":[],"titles":[],"descriptions":[],"socialPosts":{"email":{"subject":"","preview":"","content":""},"linkedin":[],"twitter":[],"facebook":[],"instagram":[]}},"seo_analyzer_scan_date":null},"aioseo_breadcrumb":"<div class=\"aioseo-breadcrumbs\"><span class=\"aioseo-breadcrumb\">\n\t\t\t<a href=\"https:\/\/www.johndcook.com\/blog\" title=\"Home\">Home<\/a>\n\t\t<\/span><span class=\"aioseo-breadcrumb-separator\">&raquo;<\/span><span class=\"aioseo-breadcrumb\">\n\t\t\t<a href=\"https:\/\/www.johndcook.com\/blog\/category\/math\/\" title=\"Math\">Math<\/a>\n\t\t<\/span><span class=\"aioseo-breadcrumb-separator\">&raquo;<\/span><span class=\"aioseo-breadcrumb\">\n\t\t\tCounting rooted trees\n\t\t<\/span><\/div>","aioseo_breadcrumb_json":[{"label":"Home","link":"https:\/\/www.johndcook.com\/blog"},{"label":"Math","link":"https:\/\/www.johndcook.com\/blog\/category\/math\/"},{"label":"Counting rooted trees","link":"https:\/\/www.johndcook.com\/blog\/2026\/08\/01\/counting-rooted-trees\/"}],"_links":{"self":[{"href":"https:\/\/www.johndcook.com\/blog\/wp-json\/wp\/v2\/posts\/247502","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.johndcook.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.johndcook.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.johndcook.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.johndcook.com\/blog\/wp-json\/wp\/v2\/comments?post=247502"}],"version-history":[{"count":8,"href":"https:\/\/www.johndcook.com\/blog\/wp-json\/wp\/v2\/posts\/247502\/revisions"}],"predecessor-version":[{"id":247510,"href":"https:\/\/www.johndcook.com\/blog\/wp-json\/wp\/v2\/posts\/247502\/revisions\/247510"}],"wp:attachment":[{"href":"https:\/\/www.johndcook.com\/blog\/wp-json\/wp\/v2\/media?parent=247502"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.johndcook.com\/blog\/wp-json\/wp\/v2\/categories?post=247502"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.johndcook.com\/blog\/wp-json\/wp\/v2\/tags?post=247502"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}},{"id":247499,"date":"2026-08-01T10:58:15","date_gmt":"2026-08-01T15:58:15","guid":{"rendered":"https:\/\/www.johndcook.com\/blog\/?p=247499"},"modified":"2026-08-01T10:58:15","modified_gmt":"2026-08-01T15:58:15","slug":"butcher-barrier","status":"publish","type":"post","link":"https:\/\/www.johndcook.com\/blog\/2026\/08\/01\/butcher-barrier\/","title":{"rendered":"Runge-Kutta order versus stages"},"content":{"rendered":"<p>The textbook version of the Runge-Kutta method for solving differential equations has 4 stages and has 4th order error. For lower order versions of RK the number of stages <em>s<\/em> also matches the order of the error <em>p<\/em>. But in order to achieve error on the order of\u00a0<em>p<\/em> \u2265 5, you need more than <em>p<\/em> stages. This is known as the Butcher barrier.<\/p>\n<p>Before going any further, let&#8217;s back up and say what we mean by stages and by order.<\/p>\n<h2>Stages<\/h2>\n<p>The number of stages in an RK method to solve the equation<\/p>\n<p><img decoding=\"async\" class=\"aligncenter\" src=\"https:\/\/www.johndcook.com\/first_order_ode.svg\" alt=\"y' = f(t, y)\" width=\"82\" \/><\/p>\n<p>is the number of evaluations of the function\u00a0<em>f<\/em> on the right-hand side. For example, the textbook RK4 method estimates the solution at each step by<\/p>\n<p><img decoding=\"async\" class=\"aligncenter\" src=\"https:\/\/www.johndcook.com\/rk4.svg\" alt=\"y_{n+1} = y_n + \\frac{h}{6}\\left( k_{n1} + 2k_{n2} + 2k_{n3} + k_{n4}\\right)\" width=\"305\" \/><\/p>\n<p>where<\/p>\n<p><img decoding=\"async\" class=\"aligncenter\" src=\"https:\/\/www.johndcook.com\/rk4k.svg\" alt=\"k_{n1} &amp;=&amp; f(t_n, y_n) \\\\ k_{n2} &amp;=&amp; f(t_n + 0.5h, y_n + 0.5hk_{n1}) \\\\ k_{n3} &amp;=&amp; f(t_n + 0.5h, y_n + 0.5hk_{n2}) \\\\ k_{n4} &amp;=&amp; f(t_n + h, y_n + hk_{n3}) \\\\\" width=\"280\" \/><\/p>\n<p>which requires four stages, i.e. four evaluations of\u00a0<em>f<\/em>.<\/p>\n<h2>Order<\/h2>\n<p>A differential equation solver is said to have order <em>p<\/em> if the local error, the error after one step of size <em>h<\/em>, is <em>O<\/em>(<em>h<\/em><sup><em>p<\/em> + 1<\/sup>). Then after solving an ODE over a period of time <em>T<\/em> with <em>N<\/em> = <em>T<\/em>\/<em>h<\/em> steps, the global error is <em>O<\/em>(<em>h<\/em><sup><em>p<\/em><\/sup>). So, for example, if <em>p<\/em> = 4, you would expect that cutting your step size <em>h<\/em> in half would cut your error at <em>T<\/em> by a factor of 16.<\/p>\n<h2>More stages than the order<\/h2>\n<p>John C. Butcher proved that an explicit RK method of order <em>p<\/em> requires\u00a0<em>s<\/em> stages where\u00a0<em>s<\/em> &gt;\u00a0<em>p<\/em> if\u00a0<em>p<\/em> &gt; 4.<\/p>\n<p>An important example is the Dormand-Prince method. It is a version of RK that has order 5 and 7 stages. The clever thing about this method is that you can make a 4th order solver out of a subset of its function evaluations.<\/p>\n<p>That means that after you&#8217;ve evaluated one step of the 5th order method, you can also evaluate a 4th order method essentially for free. And by comparing them, you can get a sense of the error. If the solutions given by the two methods are substantially different, you have probably taken too big a step and need to back up. If the two solutions essentially agree, you&#8217;re probably good to take the next step.<\/p>\n<p>For an explict RK method to have order 5, 6, or 7 you need at least 6, 7, or 9 stages respectively.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>The textbook version of the Runge-Kutta method for solving differential equations has 4 stages and has 4th order error. For lower order versions of RK the number of stages s also matches the order of the error p. But in order to achieve error on the order of\u00a0p \u2265 5, you need more than p [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[9],"tags":[47],"class_list":["post-247499","post","type-post","status-publish","format-standard","hentry","category-math","tag-differential-equations"],"acf":[],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 4.9.10 - aioseo.com -->\n\t<meta name=\"description\" content=\"A Runge-Kutta method of order n has n stages only for n = 1, 2, 3, and 4. After that, the number of stages must exceed the order.\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"John\"\/>\n\t<meta name=\"keywords\" content=\"differential equations\" \/>\n\t<link rel=\"canonical\" href=\"https:\/\/www.johndcook.com\/blog\/2026\/08\/01\/butcher-barrier\/\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 4.9.10\" \/>\n\t\t<meta property=\"og:locale\" content=\"en_US\" \/>\n\t\t<meta property=\"og:site_name\" content=\"John D. Cook | Applied Mathematics Consulting\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"Runge-Kutta: over versus stages | Butcher barrier\" \/>\n\t\t<meta property=\"og:description\" content=\"A Runge-Kutta method of order n has n stages only for n = 1, 2, 3, and 4. After that, the number of stages must exceed the order.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/www.johndcook.com\/blog\/2026\/08\/01\/butcher-barrier\/\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2026-08-01T15:58:15+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2026-08-01T15:58:15+00:00\" \/>\n\t\t<meta name=\"twitter:card\" content=\"summary\" \/>\n\t\t<meta name=\"twitter:title\" content=\"Runge-Kutta: over versus stages | Butcher barrier\" \/>\n\t\t<meta name=\"twitter:description\" content=\"A Runge-Kutta method of order n has n stages only for n = 1, 2, 3, and 4. After that, the number of stages must exceed the order.\" \/>\n\t\t<meta name=\"twitter:image\" content=\"https:\/\/www.johndcook.com\/blog\/wp-content\/uploads\/2022\/05\/twittercard.png\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"Runge-Kutta: over versus stages | Butcher barrier","description":"A Runge-Kutta method of order n has n stages only for n = 1, 2, 3, and 4. After that, the number of stages must exceed the order.","canonical_url":"https:\/\/www.johndcook.com\/blog\/2026\/08\/01\/butcher-barrier\/","robots":"max-image-preview:large","keywords":"differential equations","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"en_US","og:site_name":"John D. Cook | Applied Mathematics Consulting","og:type":"article","og:title":"Runge-Kutta: over versus stages | Butcher barrier","og:description":"A Runge-Kutta method of order n has n stages only for n = 1, 2, 3, and 4. After that, the number of stages must exceed the order.","og:url":"https:\/\/www.johndcook.com\/blog\/2026\/08\/01\/butcher-barrier\/","article:published_time":"2026-08-01T15:58:15+00:00","article:modified_time":"2026-08-01T15:58:15+00:00","twitter:card":"summary","twitter:title":"Runge-Kutta: over versus stages | Butcher barrier","twitter:description":"A Runge-Kutta method of order n has n stages only for n = 1, 2, 3, and 4. After that, the number of stages must exceed the order.","twitter:image":"https:\/\/www.johndcook.com\/blog\/wp-content\/uploads\/2022\/05\/twittercard.png"},"aioseo_meta_data":{"post_id":"247499","title":"Runge-Kutta: over versus stages | Butcher barrier","description":"A Runge-Kutta method of order n has n stages only for n = 1, 2, 3, and 4. After that, the number of stages must exceed the order.","keywords":null,"keyphrases":{"focus":{"keyphrase":"","score":0,"analysis":{"keyphraseInTitle":{"score":0,"maxScore":9,"error":1}}},"additional":[]},"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":"","og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"Article","isEnabled":true},"graphs":[]},"schema_type":"default","schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":"-1","robots_max_videopreview":"-1","robots_max_imagepreview":"large","priority":null,"frequency":"default","location":null,"local_seo":null,"breadcrumb_settings":null,"limit_modified_date":false,"created":"2026-08-01 11:53:29","updated":"2026-08-01 16:00:00","ai":{"faqs":[],"keyPoints":[],"schemas":[],"titles":[],"descriptions":[],"socialPosts":{"email":{"subject":"","preview":"","content":""},"linkedin":[],"twitter":[],"facebook":[],"instagram":[]}},"seo_analyzer_scan_date":null},"aioseo_breadcrumb":"<div class=\"aioseo-breadcrumbs\"><span class=\"aioseo-breadcrumb\">\n\t\t\t<a href=\"https:\/\/www.johndcook.com\/blog\" title=\"Home\">Home<\/a>\n\t\t<\/span><span class=\"aioseo-breadcrumb-separator\">&raquo;<\/span><span class=\"aioseo-breadcrumb\">\n\t\t\t<a href=\"https:\/\/www.johndcook.com\/blog\/category\/math\/\" title=\"Math\">Math<\/a>\n\t\t<\/span><span class=\"aioseo-breadcrumb-separator\">&raquo;<\/span><span class=\"aioseo-breadcrumb\">\n\t\t\tRunge-Kutta order versus stages\n\t\t<\/span><\/div>","aioseo_breadcrumb_json":[{"label":"Home","link":"https:\/\/www.johndcook.com\/blog"},{"label":"Math","link":"https:\/\/www.johndcook.com\/blog\/category\/math\/"},{"label":"Runge-Kutta order versus stages","link":"https:\/\/www.johndcook.com\/blog\/2026\/08\/01\/butcher-barrier\/"}],"_links":{"self":[{"href":"https:\/\/www.johndcook.com\/blog\/wp-json\/wp\/v2\/posts\/247499","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.johndcook.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.johndcook.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.johndcook.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.johndcook.com\/blog\/wp-json\/wp\/v2\/comments?post=247499"}],"version-history":[{"count":3,"href":"https:\/\/www.johndcook.com\/blog\/wp-json\/wp\/v2\/posts\/247499\/revisions"}],"predecessor-version":[{"id":247506,"href":"https:\/\/www.johndcook.com\/blog\/wp-json\/wp\/v2\/posts\/247499\/revisions\/247506"}],"wp:attachment":[{"href":"https:\/\/www.johndcook.com\/blog\/wp-json\/wp\/v2\/media?parent=247499"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.johndcook.com\/blog\/wp-json\/wp\/v2\/categories?post=247499"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.johndcook.com\/blog\/wp-json\/wp\/v2\/tags?post=247499"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}},{"id":247492,"date":"2026-07-31T13:59:02","date_gmt":"2026-07-31T18:59:02","guid":{"rendered":"https:\/\/www.johndcook.com\/blog\/?p=247492"},"modified":"2026-08-01T01:29:19","modified_gmt":"2026-08-01T06:29:19","slug":"runge-kutta-design","status":"publish","type":"post","link":"https:\/\/www.johndcook.com\/blog\/2026\/07\/31\/runge-kutta-design\/","title":{"rendered":"Solving the RK4 design equations"},"content":{"rendered":"<p>I was digging into the Runge-Kutta method for solving differential equations and a line from [1] piqued my curiosity.<\/p>\n<p style=\"padding-left: 40px;\">These calculations, which are not reproduced in Kutta&#8217;s paper (they are however in Huen (1900)), are very tedious.<\/p>\n<p>The calculations are a set of eight constraints that the parameters of a fourth-order Runge-Kutta method must satisfy. I wondered how well Mathematica might have done at assisting Mr. Huen in his &#8220;very tedious&#8221; calculations if it had been available in 1900.<\/p>\n<p>I go into Runge-Kutta methods in <a href=\"https:\/\/www.johndcook.com\/blog\/2020\/02\/13\/runge-kutta-methods\/\">this post<\/a>. Here I&#8217;d like to concentrate on a step in the design of the methods, namely solving the set of equations alluded in the quote above.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter\" style=\"background-color: white;\" src=\"https:\/\/www.johndcook.com\/RK4.svg\" alt=\"\\begin{align*} b_1 + b_2 + b_3 + b_4 &amp;= 1 \\\\ b_2 c_2 + b_3 c_3 + b_4 c_4 &amp;= \\frac{1}{2} \\\\ b_2 c_2^2 + b_3 c_3^2 + b_4 c_4^2 &amp;= \\frac{1}{3} \\\\ b_3 a_{32} c_2 + b_4(a_{42} c_2 + a_{43} c_3) &amp;= \\frac{1}{6} \\\\ b_2 c_2^3 + b_3 c_3^3 + b_4 c_4^3 &amp;= \\frac{1}{4} \\\\ b_3 c_3 a_{32} c_2 + b_4 c_4(a_{42} c_2 + a_{43} c_3) &amp;= \\frac{1}{8} \\\\ b_3 a_{32} c_2^2 + b_4(a_{42} c_2^2 + a_{43} c_3^2) &amp;= \\frac{1}{12} \\\\ b_4 a_{43} a_{32} c_2 &amp;= \\frac{1}{24} \\end{align*} \" width=\"297\" height=\"353\" \/><\/p>\n<p>The first thing to note is that there are 10 variables and only 8 equations, and so the solution is not fully determined. What we think of as\u00a0<em>the<\/em> fourth order Runge-Kutta method is in fact\u00a0<em>a<\/em> fourth order Runge-Kutta method.<\/p>\n<p>One could argue that we should have <em>b<\/em><sub>2<\/sub> = <em>b<\/em><sub>3<\/sub> and <em>c<\/em><sub>2<\/sub> = <em>c<\/em><sub>3<\/sub>. With these additional equations, the system of equations has a unique solution, and Mathematic finds it easily.<\/p>\n<pre>eqs = {\r\n    b1 + b2 + b3 + b4 == 1,\r\n    b2*c2 + b3*c3 + b4*c4 == 1\/2,\r\n    b2*c2^2 + b3*c3^2 + b4*c4^2 == 1\/3,\r\n    b3*a32*c2 + b4*(a42*c2 + a43*c3) == 1\/6,\r\n    b2*c2^3 + b3*c3^3 + b4*c4^3 == 1\/4,\r\n    b3*c3*a32*c2 + b4*c4*(a42*c2 + a43*c3) == 1\/8,\r\n    b3*a32*c2^2 + b4*(a42*c2^2 + a43*c3^2) == 1\/12,\r\n    b4*a43*a32*c2 == 1\/24,\r\n    b2 == b3,\r\n    c2 == c3\r\n};\r\n\r\nvars = {b1, b2, b3, b4, c2, c3, c4, a32, a42, a43};\r\n\r\nsolution = Solve[eqs, vars]\r\n<\/pre>\n<p>This returns the parameters used for the version of Runge-Kutta presented in every textbook.<\/p>\n<p>If you keep the requirement <em>b<\/em><sub>2<\/sub> = <em>b<\/em><sub>3<\/sub> but substitute the requirement 2<em>c<\/em><sub>2<\/sub> = <em>c<\/em><sub>3<\/sub> for <em>c<\/em>&#8216;s Mathematica will return the coefficients for the so-called Runge-Kutta 3\/8 rule. This method has some slight advantages by some criteria.<\/p>\n<p>In 1951 Gill [2] discovered a fourth order Runge-Kutta rule optimized for running in extremely constrained computer hardware. It&#8217;s a strange method, with irrational parameters, but one that was a very clever response to the limitations of its time.<\/p>\n<h2>Related posts<\/h2>\n<ul>\n<li class=\"link\"><a href=\"https:\/\/www.johndcook.com\/blog\/2020\/02\/19\/dormand-prince\/\">Dormand and Prince<\/a><\/li>\n<li class=\"link\"><a href=\"https:\/\/www.johndcook.com\/blog\/2016\/06\/02\/ode-solver-as-a-functional-fold\/\">RK4 as a fold<\/a><\/li>\n<li class=\"link\"><a href=\"https:\/\/www.johndcook.com\/blog\/2020\/02\/02\/stiff-differential-equations\/\">Stiff differential equations<\/a><\/li>\n<\/ul>\n<p>[1] Hairer, N\u00f8rsett, and Wanner. Solving Ordinary Differential Equations I: Nonstiff Problems. Springer-Verlag 1987.<\/p>\n<p>[2] A. Gill. A process for the step-by-step integration of differential equations in an automatic digital computing machine. Proc. Cambridge Philos. Soc., vol 27, pp 95\u2013108.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I was digging into the Runge-Kutta method for solving differential equations and a line from [1] piqued my curiosity. These calculations, which are not reproduced in Kutta&#8217;s paper (they are however in Huen (1900)), are very tedious. The calculations are a set of eight constraints that the parameters of a fourth-order Runge-Kutta method must satisfy. [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[9],"tags":[47,87],"class_list":["post-247492","post","type-post","status-publish","format-standard","hentry","category-math","tag-differential-equations","tag-mathematica"],"acf":[],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 4.9.10 - aioseo.com -->\n\t<meta name=\"description\" content=\"The constraints on Runge-Kutta method parameters are complicated. How well could Mathematica do at solving them?\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"John\"\/>\n\t<meta name=\"keywords\" content=\"differential equations,mathematica\" \/>\n\t<link rel=\"canonical\" href=\"https:\/\/www.johndcook.com\/blog\/2026\/07\/31\/runge-kutta-design\/\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 4.9.10\" \/>\n\t\t<meta property=\"og:locale\" content=\"en_US\" \/>\n\t\t<meta property=\"og:site_name\" content=\"John D. Cook | Applied Mathematics Consulting\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"Solving the fourth order Runge-Kutta design equations\" \/>\n\t\t<meta property=\"og:description\" content=\"The constraints on Runge-Kutta method parameters are complicated. How well could Mathematica do at solving them?\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/www.johndcook.com\/blog\/2026\/07\/31\/runge-kutta-design\/\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2026-07-31T18:59:02+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2026-08-01T06:29:19+00:00\" \/>\n\t\t<meta name=\"twitter:card\" content=\"summary\" \/>\n\t\t<meta name=\"twitter:title\" content=\"Solving the fourth order Runge-Kutta design equations\" \/>\n\t\t<meta name=\"twitter:description\" content=\"The constraints on Runge-Kutta method parameters are complicated. How well could Mathematica do at solving them?\" \/>\n\t\t<meta name=\"twitter:image\" content=\"https:\/\/www.johndcook.com\/blog\/wp-content\/uploads\/2022\/05\/twittercard.png\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"Solving the fourth order Runge-Kutta design equations","description":"The constraints on Runge-Kutta method parameters are complicated. How well could Mathematica do at solving them?","canonical_url":"https:\/\/www.johndcook.com\/blog\/2026\/07\/31\/runge-kutta-design\/","robots":"max-image-preview:large","keywords":"differential equations,mathematica","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"en_US","og:site_name":"John D. Cook | Applied Mathematics Consulting","og:type":"article","og:title":"Solving the fourth order Runge-Kutta design equations","og:description":"The constraints on Runge-Kutta method parameters are complicated. How well could Mathematica do at solving them?","og:url":"https:\/\/www.johndcook.com\/blog\/2026\/07\/31\/runge-kutta-design\/","article:published_time":"2026-07-31T18:59:02+00:00","article:modified_time":"2026-08-01T06:29:19+00:00","twitter:card":"summary","twitter:title":"Solving the fourth order Runge-Kutta design equations","twitter:description":"The constraints on Runge-Kutta method parameters are complicated. How well could Mathematica do at solving them?","twitter:image":"https:\/\/www.johndcook.com\/blog\/wp-content\/uploads\/2022\/05\/twittercard.png"},"aioseo_meta_data":{"post_id":"247492","title":"Solving the fourth order Runge-Kutta design equations","description":"The constraints on Runge-Kutta method parameters are complicated. How well could Mathematica do at solving them?","keywords":null,"keyphrases":{"focus":{"keyphrase":"","score":0,"analysis":{"keyphraseInTitle":{"score":0,"maxScore":9,"error":1}}},"additional":[]},"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":"","og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"Article","isEnabled":true},"graphs":[]},"schema_type":"default","schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":"-1","robots_max_videopreview":"-1","robots_max_imagepreview":"large","priority":null,"frequency":"default","location":null,"local_seo":null,"breadcrumb_settings":null,"limit_modified_date":false,"created":"2026-07-31 17:38:42","updated":"2026-08-01 06:30:02","ai":{"faqs":[],"keyPoints":[],"schemas":[],"titles":[],"descriptions":[],"socialPosts":{"email":{"subject":"","preview":"","content":""},"linkedin":[],"twitter":[],"facebook":[],"instagram":[]}},"seo_analyzer_scan_date":null},"aioseo_breadcrumb":"<div class=\"aioseo-breadcrumbs\"><span class=\"aioseo-breadcrumb\">\n\t\t\t<a href=\"https:\/\/www.johndcook.com\/blog\" title=\"Home\">Home<\/a>\n\t\t<\/span><span class=\"aioseo-breadcrumb-separator\">&raquo;<\/span><span class=\"aioseo-breadcrumb\">\n\t\t\t<a href=\"https:\/\/www.johndcook.com\/blog\/category\/math\/\" title=\"Math\">Math<\/a>\n\t\t<\/span><span class=\"aioseo-breadcrumb-separator\">&raquo;<\/span><span class=\"aioseo-breadcrumb\">\n\t\t\tSolving the RK4 design equations\n\t\t<\/span><\/div>","aioseo_breadcrumb_json":[{"label":"Home","link":"https:\/\/www.johndcook.com\/blog"},{"label":"Math","link":"https:\/\/www.johndcook.com\/blog\/category\/math\/"},{"label":"Solving the RK4 design equations","link":"https:\/\/www.johndcook.com\/blog\/2026\/07\/31\/runge-kutta-design\/"}],"_links":{"self":[{"href":"https:\/\/www.johndcook.com\/blog\/wp-json\/wp\/v2\/posts\/247492","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.johndcook.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.johndcook.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.johndcook.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.johndcook.com\/blog\/wp-json\/wp\/v2\/comments?post=247492"}],"version-history":[{"count":4,"href":"https:\/\/www.johndcook.com\/blog\/wp-json\/wp\/v2\/posts\/247492\/revisions"}],"predecessor-version":[{"id":247498,"href":"https:\/\/www.johndcook.com\/blog\/wp-json\/wp\/v2\/posts\/247492\/revisions\/247498"}],"wp:attachment":[{"href":"https:\/\/www.johndcook.com\/blog\/wp-json\/wp\/v2\/media?parent=247492"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.johndcook.com\/blog\/wp-json\/wp\/v2\/categories?post=247492"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.johndcook.com\/blog\/wp-json\/wp\/v2\/tags?post=247492"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}},{"id":247470,"date":"2026-07-28T09:11:30","date_gmt":"2026-07-28T14:11:30","guid":{"rendered":"https:\/\/www.johndcook.com\/blog\/?p=247470"},"modified":"2026-07-28T13:39:02","modified_gmt":"2026-07-28T18:39:02","slug":"inverse-factorial-improved","status":"publish","type":"post","link":"https:\/\/www.johndcook.com\/blog\/2026\/07\/28\/inverse-factorial-improved\/","title":{"rendered":"Inverse factorial improved"},"content":{"rendered":"<p><a href=\"https:\/\/www.johndcook.com\/blog\/2024\/01\/01\/inverse-factorial\/\">A couple years ago<\/a> I wrote about how to compute the inverse of factorial. I used that code in writing the previous post because the post required solving the equation<\/p>\n<p style=\"padding-left: 40px;\">\u230alog<sub>2<\/sub>(<em>n<\/em>!)\u230b \u2265 <em>b<\/em><\/p>\n<p>given <em>b<\/em>. That is, given a number of bits <em>b<\/em>, find the smallest value of <em>n<\/em>\u00a0such that <em>n<\/em>! \u2265 2<sup><em>b<\/em><\/sup>.<\/p>\n<h2>What the code got right<\/h2>\n<p>Looking back on the code in that post, there are a few changes I&#8217;d like to make. But first of all, I&#8217;d like to point out something the post does right: instead of trying to solve<\/p>\n<p style=\"padding-left: 40px;\">\u0393(<em>y<\/em>) = <em>x<\/em><\/p>\n<p>it solves<\/p>\n<p style=\"padding-left: 40px;\">log \u0393(<em>y<\/em>) = log <em>x<\/em>.<\/p>\n<p>That&#8217;s why the argument to <code>inverse_log_gamma<\/code> is <code>logarg<\/code>. That makes the code useful for values of\u00a0<em>x<\/em> that would far exceed the maximum floating point value, such as in the calculations for the previous post.<\/p>\n<h2>What I&#8217;d change<\/h2>\n<h3>Rounding<\/h3>\n<p>The function <code>inverse_factorial<\/code> from the old post solves finds the closest integer solution. It would be better for it to return the solution without rounding and then let the user round result if they want to. In my calculations in the previous post, I wanted to take the floor, not round.<\/p>\n<h3>Newton&#8217;s method<\/h3>\n<p>The code in the previous post uses the bisection method. This method is very safe, and fast enough for my purposes, but it could be made faster. Newton&#8217;s method is faster, but it can be ill-behaved if you don&#8217;t start close enough to the solution.<\/p>\n<p>It&#8217;s safe to use Newton&#8217;s method to invert log \u0393 for two reasons. First, you can get a good starting point based on Stirling&#8217;s approximation. Second, and more importantly, log \u0393 is convex. Newton&#8217;s method will converge from\u00a0<em>any<\/em> starting point when applied to a convex function. A little caution is necessary because log \u0393 is not convex everywhere, but it is convex on the positive real axis.<\/p>\n<p>Another difficulty with Newton&#8217;s method is that you need to supply the derivative of the function whose root you&#8217;re trying to find. But this isn&#8217;t an issue here because the derivative of log \u0393 is the digamma function, which is implemented in SciPy.<\/p>\n<h3>Tolerance<\/h3>\n<p>Finally, the previous code used the default tolerance for deciding when to stop refining the solution. The revised method lets the user specify tolerance. It provides a default value, but that default is visible in the function call, not hidden down in SciPy.<\/p>\n<h2>Revised code<\/h2>\n<p>Here&#8217;s the revised code.<\/p>\n<pre>from scipy.special import gammaln, digamma\r\nfrom scipy.optimize import newton\r\n\r\ndef inverse_log_gamma(logarg, tol=1e-12):\r\n    assert(logarg &gt; 0)    \r\n    x0 = logarg \/ log(logarg + 1) + 1 if logarg &gt; 1 else 2.0\r\n    def f(z): return gammaln(z) - logarg\r\n    return newton(f, x0, fprime=digamma, tol=tol)\r\n\r\ndef inverse_factorial(logarg):\r\n    g = inverse_log_gamma(logarg)\r\n    return g - 1 \r\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>A couple years ago I wrote about how to compute the inverse of factorial. I used that code in writing the previous post because the post required solving the equation \u230alog2(n!)\u230b \u2265 b given b. That is, given a number of bits b, find the smallest value of n\u00a0such that n! \u2265 2b. What the [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[9],"tags":[129],"class_list":["post-247470","post","type-post","status-publish","format-standard","hentry","category-math","tag-special-functions"],"acf":[],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 4.9.10 - aioseo.com -->\n\t<meta name=\"description\" content=\"Improved code for solving x! = y or more generally \u0393(x) = y for x.\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"John\"\/>\n\t<meta name=\"keywords\" content=\"special functions\" \/>\n\t<link rel=\"canonical\" href=\"https:\/\/www.johndcook.com\/blog\/2026\/07\/28\/inverse-factorial-improved\/\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 4.9.10\" \/>\n\t\t<meta property=\"og:locale\" content=\"en_US\" \/>\n\t\t<meta property=\"og:site_name\" content=\"John D. Cook | Applied Mathematics Consulting\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"Efficient code for inverting the (log) gamma function\" \/>\n\t\t<meta property=\"og:description\" content=\"Improved code for solving x! = y or more generally \u0393(x) = y for x.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/www.johndcook.com\/blog\/2026\/07\/28\/inverse-factorial-improved\/\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2026-07-28T14:11:30+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2026-07-28T18:39:02+00:00\" \/>\n\t\t<meta name=\"twitter:card\" content=\"summary\" \/>\n\t\t<meta name=\"twitter:title\" content=\"Efficient code for inverting the (log) gamma function\" \/>\n\t\t<meta name=\"twitter:description\" content=\"Improved code for solving x! = y or more generally \u0393(x) = y for x.\" \/>\n\t\t<meta name=\"twitter:image\" content=\"https:\/\/www.johndcook.com\/blog\/wp-content\/uploads\/2022\/05\/twittercard.png\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"Efficient code for inverting the (log) gamma function","description":"Improved code for solving x! = y or more generally \u0393(x) = y for x.","canonical_url":"https:\/\/www.johndcook.com\/blog\/2026\/07\/28\/inverse-factorial-improved\/","robots":"max-image-preview:large","keywords":"special functions","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"en_US","og:site_name":"John D. Cook | Applied Mathematics Consulting","og:type":"article","og:title":"Efficient code for inverting the (log) gamma function","og:description":"Improved code for solving x! = y or more generally \u0393(x) = y for x.","og:url":"https:\/\/www.johndcook.com\/blog\/2026\/07\/28\/inverse-factorial-improved\/","article:published_time":"2026-07-28T14:11:30+00:00","article:modified_time":"2026-07-28T18:39:02+00:00","twitter:card":"summary","twitter:title":"Efficient code for inverting the (log) gamma function","twitter:description":"Improved code for solving x! = y or more generally \u0393(x) = y for x.","twitter:image":"https:\/\/www.johndcook.com\/blog\/wp-content\/uploads\/2022\/05\/twittercard.png"},"aioseo_meta_data":{"post_id":"247470","title":"Efficient code for inverting the (log) gamma function","description":"Improved code for solving x! = y or more generally \u0393(x) = y for x.","keywords":null,"keyphrases":{"focus":{"keyphrase":"","score":0,"analysis":{"keyphraseInTitle":{"score":0,"maxScore":9,"error":1}}},"additional":[]},"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":"","og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"Article","isEnabled":true},"graphs":[]},"schema_type":"default","schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":"-1","robots_max_videopreview":"-1","robots_max_imagepreview":"large","priority":null,"frequency":"default","location":null,"local_seo":null,"breadcrumb_settings":null,"limit_modified_date":false,"created":"2026-07-28 13:38:46","updated":"2026-07-29 04:51:41","ai":{"faqs":[],"keyPoints":[],"schemas":[],"titles":[],"descriptions":[],"socialPosts":{"email":{"subject":"","preview":"","content":""},"linkedin":[],"twitter":[],"facebook":[],"instagram":[]}},"seo_analyzer_scan_date":null},"aioseo_breadcrumb":"<div class=\"aioseo-breadcrumbs\"><span class=\"aioseo-breadcrumb\">\n\t\t\t<a href=\"https:\/\/www.johndcook.com\/blog\" title=\"Home\">Home<\/a>\n\t\t<\/span><span class=\"aioseo-breadcrumb-separator\">&raquo;<\/span><span class=\"aioseo-breadcrumb\">\n\t\t\t<a href=\"https:\/\/www.johndcook.com\/blog\/category\/math\/\" title=\"Math\">Math<\/a>\n\t\t<\/span><span class=\"aioseo-breadcrumb-separator\">&raquo;<\/span><span class=\"aioseo-breadcrumb\">\n\t\t\tInverse factorial improved\n\t\t<\/span><\/div>","aioseo_breadcrumb_json":[{"label":"Home","link":"https:\/\/www.johndcook.com\/blog"},{"label":"Math","link":"https:\/\/www.johndcook.com\/blog\/category\/math\/"},{"label":"Inverse factorial improved","link":"https:\/\/www.johndcook.com\/blog\/2026\/07\/28\/inverse-factorial-improved\/"}],"_links":{"self":[{"href":"https:\/\/www.johndcook.com\/blog\/wp-json\/wp\/v2\/posts\/247470","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.johndcook.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.johndcook.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.johndcook.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.johndcook.com\/blog\/wp-json\/wp\/v2\/comments?post=247470"}],"version-history":[{"count":2,"href":"https:\/\/www.johndcook.com\/blog\/wp-json\/wp\/v2\/posts\/247470\/revisions"}],"predecessor-version":[{"id":247476,"href":"https:\/\/www.johndcook.com\/blog\/wp-json\/wp\/v2\/posts\/247470\/revisions\/247476"}],"wp:attachment":[{"href":"https:\/\/www.johndcook.com\/blog\/wp-json\/wp\/v2\/media?parent=247470"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.johndcook.com\/blog\/wp-json\/wp\/v2\/categories?post=247470"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.johndcook.com\/blog\/wp-json\/wp\/v2\/tags?post=247470"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}},{"id":247468,"date":"2026-07-28T07:13:17","date_gmt":"2026-07-28T12:13:17","guid":{"rendered":"https:\/\/www.johndcook.com\/blog\/?p=247468"},"modified":"2026-07-28T13:11:18","modified_gmt":"2026-07-28T18:11:18","slug":"keys-and-cards","status":"publish","type":"post","link":"https:\/\/www.johndcook.com\/blog\/2026\/07\/28\/keys-and-cards\/","title":{"rendered":"Cryptographic Keys and Decks of Cards"},"content":{"rendered":"<p>The <a href=\"https:\/\/www.johndcook.com\/blog\/2026\/07\/27\/hiding-data-in-permutations\/\">previous post<\/a> looked at the idea of storing a cryptographic key in the order of a deck of cards. A deck of 52 cards can store 225 bits of data because<\/p>\n<p style=\"padding-left: 40px;\">\u230alog<sub>2<\/sub>(52!)\u230b = 225.<\/p>\n<p>Here \u230a<em>x<\/em>\u230b is\u00a0<em>x<\/em> rounded down to the nearest integer.<\/p>\n<p>If we want to store bigger keys, we&#8217;re going to need a bigger deck of cards.<\/p>\n<h2>Bitcoin<\/h2>\n<p>A Bitcoin key has 256 bits, which would require a deck of 58 cards. There is a card game called Zwicker that uses a deck of 58 cards, the usual 52 cards plus six jokers. So you could store a Bitcoin key in the permutation of a Zwicker deck.<\/p>\n<p>You could also use a deck of 52 cards, plus 2 jokers, if you also consider orientation. 30 cards are rotationally symmetric, 22 are not, and neither are jokers. So, including two asymmetric jokers, you could add 24 additional bits. Permutations of a 54 card deck can encode 237 bits, and with 24 orientation bits, this is a total of 261 bits.<\/p>\n<h2>RSA<\/h2>\n<p>RSA key sizes vary, but 2048 and 3072 are common. A 2048-bit key would require a deck of 301 cards. Casinos often use a shoe of 312 cards, combining six decks of 52 cards, to deal Baccarat or Blackjack. However, casinos combine identical decks. If you were to combine six unique decks, you could store a 2048-bit key.<\/p>\n<p>Storing a 3072-bit key would require a deck of 422 cards. You could make a deck of 432 cards by combining 8 distinguishable packs of 54 cards (52 + 2 jokers).<\/p>\n<h2>ML-KEM<\/h2>\n<p>ML-KEM is a proposed quantum-resistant replacement for RSA. As with RSA, key sizes for ML-KEM vary, the smallest being ML-<strong>KEM-512<\/strong> with a key size of 1632 bytes, which equals 13056 bits. This would require a deck of 1442 cards. You could combine 28 distinct packs of 52 cards, but that&#8217;s unwieldy.<\/p>\n<p>This illustrates one of the difficult trade-offs with post-quantum cryptography: key sizes are much bigger. If you wanted to create a deck of 1442 cards, you&#8217;d probably want to make your &#8220;cards&#8221; something other than standard playing cards. You&#8217;d want to use permutations of something else.<\/p>\n<h2>Verification<\/h2>\n<p>The following Python code verifies the calculations above.<\/p>\n<pre>from math import log2, factorial, floor\r\n\r\ndef capacity(cards):\r\n    return floor(log2(factorial(cards)))\r\n\r\ndef verify(bits, cards):\r\n    return capacity(cards) &gt;= bits and capacity(cards-1) &lt; bits\r\n\r\nprint(verify(237, 54))\r\nprint(verify(256, 58))\r\nprint(verify(2048, 301))\r\nprint(verify(3072, 422))\r\nprint(verify(1632*8, 1442))\r\n<\/pre>\n<p>For more on how I came up with the deck sizes, see the <a href=\"https:\/\/www.johndcook.com\/blog\/2026\/07\/28\/inverse-factorial-improved\/\">next post<\/a> on computing the inverse factorial.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>The previous post looked at the idea of storing a cryptographic key in the order of a deck of cards. A deck of 52 cards can store 225 bits of data because \u230alog2(52!)\u230b = 225. Here \u230ax\u230b is\u00a0x rounded down to the nearest integer. If we want to store bigger keys, we&#8217;re going to need [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[9],"tags":[197,43],"class_list":["post-247468","post","type-post","status-publish","format-standard","hentry","category-math","tag-combinatorics","tag-cryptography"],"acf":[],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 4.9.10 - aioseo.com -->\n\t<meta name=\"description\" content=\"You can store cryptographic keys in the order of a deck of cards. How big a deck would you need to store Bitcoin, RSA, or ML-KEM keys?\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"John\"\/>\n\t<meta name=\"keywords\" content=\"combinatorics,cryptography\" \/>\n\t<link rel=\"canonical\" href=\"https:\/\/www.johndcook.com\/blog\/2026\/07\/28\/keys-and-cards\/\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 4.9.10\" \/>\n\t\t<meta property=\"og:locale\" content=\"en_US\" \/>\n\t\t<meta property=\"og:site_name\" content=\"John D. Cook | Applied Mathematics Consulting\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"Cryptographic Keys and Decks of Cards\" \/>\n\t\t<meta property=\"og:description\" content=\"You can store cryptographic keys in the order of a deck of cards. How big a deck would you need to store Bitcoin, RSA, or ML-KEM keys?\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/www.johndcook.com\/blog\/2026\/07\/28\/keys-and-cards\/\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2026-07-28T12:13:17+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2026-07-28T18:11:18+00:00\" \/>\n\t\t<meta name=\"twitter:card\" content=\"summary\" \/>\n\t\t<meta name=\"twitter:title\" content=\"Cryptographic Keys and Decks of Cards\" \/>\n\t\t<meta name=\"twitter:description\" content=\"You can store cryptographic keys in the order of a deck of cards. How big a deck would you need to store Bitcoin, RSA, or ML-KEM keys?\" \/>\n\t\t<meta name=\"twitter:image\" content=\"https:\/\/www.johndcook.com\/blog\/wp-content\/uploads\/2022\/05\/twittercard.png\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"Cryptographic Keys and Decks of Cards","description":"You can store cryptographic keys in the order of a deck of cards. How big a deck would you need to store Bitcoin, RSA, or ML-KEM keys?","canonical_url":"https:\/\/www.johndcook.com\/blog\/2026\/07\/28\/keys-and-cards\/","robots":"max-image-preview:large","keywords":"combinatorics,cryptography","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"en_US","og:site_name":"John D. Cook | Applied Mathematics Consulting","og:type":"article","og:title":"Cryptographic Keys and Decks of Cards","og:description":"You can store cryptographic keys in the order of a deck of cards. How big a deck would you need to store Bitcoin, RSA, or ML-KEM keys?","og:url":"https:\/\/www.johndcook.com\/blog\/2026\/07\/28\/keys-and-cards\/","article:published_time":"2026-07-28T12:13:17+00:00","article:modified_time":"2026-07-28T18:11:18+00:00","twitter:card":"summary","twitter:title":"Cryptographic Keys and Decks of Cards","twitter:description":"You can store cryptographic keys in the order of a deck of cards. How big a deck would you need to store Bitcoin, RSA, or ML-KEM keys?","twitter:image":"https:\/\/www.johndcook.com\/blog\/wp-content\/uploads\/2022\/05\/twittercard.png"},"aioseo_meta_data":{"post_id":"247468","title":null,"description":"You can store cryptographic keys in the order of a deck of cards. How big a deck would you need to store Bitcoin, RSA, or ML-KEM keys?","keywords":null,"keyphrases":{"focus":{"keyphrase":"","score":0,"analysis":{"keyphraseInTitle":{"score":0,"maxScore":9,"error":1}}},"additional":[]},"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":"","og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"Article","isEnabled":true},"graphs":[]},"schema_type":"default","schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":"-1","robots_max_videopreview":"-1","robots_max_imagepreview":"large","priority":null,"frequency":"default","location":null,"local_seo":null,"breadcrumb_settings":null,"limit_modified_date":false,"created":"2026-07-28 11:10:29","updated":"2026-07-29 04:51:41","ai":{"faqs":[],"keyPoints":[],"schemas":[],"titles":[],"descriptions":[],"socialPosts":{"email":{"subject":"","preview":"","content":""},"linkedin":[],"twitter":[],"facebook":[],"instagram":[]}},"seo_analyzer_scan_date":null},"aioseo_breadcrumb":"<div class=\"aioseo-breadcrumbs\"><span class=\"aioseo-breadcrumb\">\n\t\t\t<a href=\"https:\/\/www.johndcook.com\/blog\" title=\"Home\">Home<\/a>\n\t\t<\/span><span class=\"aioseo-breadcrumb-separator\">&raquo;<\/span><span class=\"aioseo-breadcrumb\">\n\t\t\t<a href=\"https:\/\/www.johndcook.com\/blog\/category\/math\/\" title=\"Math\">Math<\/a>\n\t\t<\/span><span class=\"aioseo-breadcrumb-separator\">&raquo;<\/span><span class=\"aioseo-breadcrumb\">\n\t\t\tCryptographic Keys and Decks of Cards\n\t\t<\/span><\/div>","aioseo_breadcrumb_json":[{"label":"Home","link":"https:\/\/www.johndcook.com\/blog"},{"label":"Math","link":"https:\/\/www.johndcook.com\/blog\/category\/math\/"},{"label":"Cryptographic Keys and Decks of Cards","link":"https:\/\/www.johndcook.com\/blog\/2026\/07\/28\/keys-and-cards\/"}],"_links":{"self":[{"href":"https:\/\/www.johndcook.com\/blog\/wp-json\/wp\/v2\/posts\/247468","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.johndcook.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.johndcook.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.johndcook.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.johndcook.com\/blog\/wp-json\/wp\/v2\/comments?post=247468"}],"version-history":[{"count":4,"href":"https:\/\/www.johndcook.com\/blog\/wp-json\/wp\/v2\/posts\/247468\/revisions"}],"predecessor-version":[{"id":247475,"href":"https:\/\/www.johndcook.com\/blog\/wp-json\/wp\/v2\/posts\/247468\/revisions\/247475"}],"wp:attachment":[{"href":"https:\/\/www.johndcook.com\/blog\/wp-json\/wp\/v2\/media?parent=247468"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.johndcook.com\/blog\/wp-json\/wp\/v2\/categories?post=247468"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.johndcook.com\/blog\/wp-json\/wp\/v2\/tags?post=247468"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}},{"id":247462,"date":"2026-07-27T18:08:59","date_gmt":"2026-07-27T23:08:59","guid":{"rendered":"https:\/\/www.johndcook.com\/blog\/?p=247462"},"modified":"2026-07-27T18:26:03","modified_gmt":"2026-07-27T23:26:03","slug":"hiding-data-in-permutations","status":"publish","type":"post","link":"https:\/\/www.johndcook.com\/blog\/2026\/07\/27\/hiding-data-in-permutations\/","title":{"rendered":"Hiding data in permutations"},"content":{"rendered":"<p>The <a href=\"https:\/\/pagedout.institute\/download\/PagedOut_009.pdf\">latest issue<\/a> of Paged Out! has an article by Stephen Hewitt &#8220;An off-line backup of your cryptographic key using playing cards.&#8221; The idea is to use a deck of 52 to store a 128-bit cryptographic key. To erase the key, shuffle the deck. Hewitt gives his algorithm for embedding a key, one that can be carried out manually but isn&#8217;t maximally efficient.<\/p>\n<p>You could store a 225-bit key as a permutation of 52 cards because<\/p>\n<p style=\"padding-left: 40px;\">log<sub>2<\/sub>(52!) = 225.581.<\/p>\n<p>But then how would you number permutations so you could go from a number to a particular permutation and later decode the permutation to a number? Is this even practical? For a small number <em>n<\/em>, you could encode a number <em>k<\/em> &lt; <em>n<\/em> by enumerating the first <em>k<\/em> permutations of a set of <em>n<\/em> items, and you could decode by enumerating permutations until you find the one you have. But this is completely impractical for large <em>n<\/em>, such as <em>n<\/em> = 52.<\/p>\n<p>The process of mapping permutation to an integer is called <b>ranking<\/b>, and the mapping from an integer to a permutation is called <b>unranking<\/b>. How efficiently can rankings and unrankings be calculated?<\/p>\n<p>Let <em>n<\/em> be the number of symbols being permuted. Then there are simple algorithms for ranking and unranking with respect to lexicographical order that have complexity <em>O<\/em>(<em>n<\/em>\u00b2) and more sophisticated algorithms that have complexity <em>O<\/em>(<em>n<\/em> log <em>n<\/em>). There are also <em>O<\/em>(<em>n<\/em>) algorithms that do not preserve lexicographical order.<\/p>\n<p>The <code>Permutations<\/code> class in SymPy has methods <code>unrank_lex<\/code> and <code>rank<\/code> to unrank and rank permutations according to lexicographical order.<\/p>\n<p>The notation the <code>Permutations<\/code> class uses requires a little explanation. For example, suppose we unrank 2026.<\/p>\n<pre>&gt;&gt;&gt; from sympy.combinatorics import Permutation\r\n&gt;&gt;&gt; Permutation.unrank_lex(52, 2026)\r\nPermutation(45, 47, 51, 48, 46, 50)\r\n<\/pre>\n<p>The output is not a full list of 52 numbers in permuted order; it is only a cycle. The notation refers to the permutation that sends 45 to 47, 47 to 51, \u2026, 50 to 45 and leaves everything else fixed.<\/p>\n<p>If we rank the permutation given above, we get 2026 back.<\/p>\n<pre>&gt;&gt;&gt; Permutation.rank(Permutation(45, 47, 51, 48, 46, 50))\r\n2026\r\n<\/pre>\n<p>Note that we didn&#8217;t say how many elements (45, 47, 51, 48, 46, 50) is a permutation of. Because of lexicographical order, the rank would be the same whether we viewed this as a permutation of 52 objects or of more objects.<\/p>\n<p>Now let&#8217;s do something larger. Let&#8217;s generate a 220-bit number and encode it as a permutation.<\/p>\n<pre>&gt;&gt;&gt; n = random.getrandbits(225)\r\n&gt;&gt;&gt; a = Permutation.unrank_lex(52, n)\r\n&gt;&gt;&gt; n\r\n40234719030664563684489051530416964877785781669439875437823431388841\r\n&gt;&gt;&gt; a\r\nPermutation(0, 25, 32, 15, 8, 28)(1, 48, 34, 14, 10, 51, 38, 31, 21, 5, 42, 47, 29, 26, 46, 30, 50, 49, 37, 22, 18, 23)(2, 45, 17, 20, 36, 40, 11, 4, 7, 41, 33, 3, 43, 44, 19, 16, 35, 39, 12, 6, 9)\r\n&gt;&gt;&gt; Permutation.rank(a) == n\r\nTrue\r\n<\/pre>\n<p>Now just for fun, let&#8217;s display the permutation above applied to a standard (French) deck of 52 cards. As explained <a href=\"https:\/\/www.johndcook.com\/blog\/2024\/04\/30\/a-deck-of-cards\/\">here<\/a>, symbols associated with these cards have a range of Unicode values. By printing these values, we can visualize the permuted deck.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-medium\" src=\"https:\/\/www.johndcook.com\/shuffled_deck.png\" width=\"720\" height=\"366\" \/><\/p>\n<p>Here&#8217;s the code that made the image above.<\/p>\n<pre>spades = list(range(0x1F0A1, 0x1F0AF))\r\nspades.remove(0x1F0AC) # take out the knight\r\ncards = [s + 16*i for s in spades for i in range(4)]\r\n\r\na = Permutation.unrank_lex(52, n)\r\np = a(cards)\r\n\r\nfor i in range(4):\r\n    for j in range(13):\r\n        print(chr(p[13*i + j]), end=\"\")\r\n    print()\r\n<\/pre>\n<p>The code above is plenty fast, but Permutation has methods <code>rank_nonlex<\/code> and <code>unrank_nonlex<\/code> that run in <em>O<\/em>(<em>n<\/em>) time, which could be useful for <em>n<\/em> much larger than 52.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>The latest issue of Paged Out! has an article by Stephen Hewitt &#8220;An off-line backup of your cryptographic key using playing cards.&#8221; The idea is to use a deck of 52 to store a 128-bit cryptographic key. To erase the key, shuffle the deck. Hewitt gives his algorithm for embedding a key, one that can [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[5],"tags":[197,43,142],"class_list":["post-247462","post","type-post","status-publish","format-standard","hentry","category-computing","tag-combinatorics","tag-cryptography","tag-sympy"],"acf":[],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 4.9.10 - aioseo.com -->\n\t<meta name=\"description\" content=\"The latest issue of Paged Out! has an article by Stephen Hewitt &quot;An off-line backup of your cryptographic key using playing cards.&quot; The idea is to use a deck of 52 to store a 128-bit cryptographic key. To erase the key, shuffle the deck. Hewitt gives his algorithm for embedding a key, one that can\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"John\"\/>\n\t<meta name=\"keywords\" content=\"combinatorics,cryptography,sympy\" \/>\n\t<link rel=\"canonical\" href=\"https:\/\/www.johndcook.com\/blog\/2026\/07\/27\/hiding-data-in-permutations\/\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 4.9.10\" \/>\n\t\t<meta property=\"og:locale\" content=\"en_US\" \/>\n\t\t<meta property=\"og:site_name\" content=\"John D. Cook | Applied Mathematics Consulting\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"Hiding data in permutations\" \/>\n\t\t<meta property=\"og:description\" content=\"The latest issue of Paged Out! has an article by Stephen Hewitt &quot;An off-line backup of your cryptographic key using playing cards.&quot; The idea is to use a deck of 52 to store a 128-bit cryptographic key. To erase the key, shuffle the deck. Hewitt gives his algorithm for embedding a key, one that can\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/www.johndcook.com\/blog\/2026\/07\/27\/hiding-data-in-permutations\/\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2026-07-27T23:08:59+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2026-07-27T23:26:03+00:00\" \/>\n\t\t<meta name=\"twitter:card\" content=\"summary\" \/>\n\t\t<meta name=\"twitter:title\" content=\"Hiding data in permutations\" \/>\n\t\t<meta name=\"twitter:description\" content=\"The latest issue of Paged Out! has an article by Stephen Hewitt &quot;An off-line backup of your cryptographic key using playing cards.&quot; The idea is to use a deck of 52 to store a 128-bit cryptographic key. To erase the key, shuffle the deck. Hewitt gives his algorithm for embedding a key, one that can\" \/>\n\t\t<meta name=\"twitter:image\" content=\"https:\/\/www.johndcook.com\/blog\/wp-content\/uploads\/2022\/05\/twittercard.png\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"Hiding data in permutations","description":"The latest issue of Paged Out! has an article by Stephen Hewitt \"An off-line backup of your cryptographic key using playing cards.\" The idea is to use a deck of 52 to store a 128-bit cryptographic key. To erase the key, shuffle the deck. Hewitt gives his algorithm for embedding a key, one that can","canonical_url":"https:\/\/www.johndcook.com\/blog\/2026\/07\/27\/hiding-data-in-permutations\/","robots":"max-image-preview:large","keywords":"combinatorics,cryptography,sympy","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"en_US","og:site_name":"John D. Cook | Applied Mathematics Consulting","og:type":"article","og:title":"Hiding data in permutations","og:description":"The latest issue of Paged Out! has an article by Stephen Hewitt &quot;An off-line backup of your cryptographic key using playing cards.&quot; The idea is to use a deck of 52 to store a 128-bit cryptographic key. To erase the key, shuffle the deck. Hewitt gives his algorithm for embedding a key, one that can","og:url":"https:\/\/www.johndcook.com\/blog\/2026\/07\/27\/hiding-data-in-permutations\/","article:published_time":"2026-07-27T23:08:59+00:00","article:modified_time":"2026-07-27T23:26:03+00:00","twitter:card":"summary","twitter:title":"Hiding data in permutations","twitter:description":"The latest issue of Paged Out! has an article by Stephen Hewitt &quot;An off-line backup of your cryptographic key using playing cards.&quot; The idea is to use a deck of 52 to store a 128-bit cryptographic key. To erase the key, shuffle the deck. Hewitt gives his algorithm for embedding a key, one that can","twitter:image":"https:\/\/www.johndcook.com\/blog\/wp-content\/uploads\/2022\/05\/twittercard.png"},"aioseo_meta_data":{"post_id":"247462","title":null,"description":null,"keywords":null,"keyphrases":{"focus":{"keyphrase":"","score":0,"analysis":{"keyphraseInTitle":{"score":0,"maxScore":9,"error":1}}},"additional":[]},"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":"","og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"Article","isEnabled":true},"graphs":[]},"schema_type":"default","schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":"-1","robots_max_videopreview":"-1","robots_max_imagepreview":"large","priority":null,"frequency":"default","location":null,"local_seo":null,"breadcrumb_settings":null,"limit_modified_date":false,"created":"2026-07-27 19:47:26","updated":"2026-07-28 00:53:40","ai":{"faqs":[],"keyPoints":[],"schemas":[],"titles":[],"descriptions":[],"socialPosts":{"email":{"subject":"","preview":"","content":""},"linkedin":[],"twitter":[],"facebook":[],"instagram":[]}},"seo_analyzer_scan_date":null},"aioseo_breadcrumb":"<div class=\"aioseo-breadcrumbs\"><span class=\"aioseo-breadcrumb\">\n\t\t\t<a href=\"https:\/\/www.johndcook.com\/blog\" title=\"Home\">Home<\/a>\n\t\t<\/span><span class=\"aioseo-breadcrumb-separator\">&raquo;<\/span><span class=\"aioseo-breadcrumb\">\n\t\t\t<a href=\"https:\/\/www.johndcook.com\/blog\/category\/computing\/\" title=\"Computing\">Computing<\/a>\n\t\t<\/span><span class=\"aioseo-breadcrumb-separator\">&raquo;<\/span><span class=\"aioseo-breadcrumb\">\n\t\t\tHiding data in permutations\n\t\t<\/span><\/div>","aioseo_breadcrumb_json":[{"label":"Home","link":"https:\/\/www.johndcook.com\/blog"},{"label":"Computing","link":"https:\/\/www.johndcook.com\/blog\/category\/computing\/"},{"label":"Hiding data in permutations","link":"https:\/\/www.johndcook.com\/blog\/2026\/07\/27\/hiding-data-in-permutations\/"}],"_links":{"self":[{"href":"https:\/\/www.johndcook.com\/blog\/wp-json\/wp\/v2\/posts\/247462","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.johndcook.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.johndcook.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.johndcook.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.johndcook.com\/blog\/wp-json\/wp\/v2\/comments?post=247462"}],"version-history":[{"count":4,"href":"https:\/\/www.johndcook.com\/blog\/wp-json\/wp\/v2\/posts\/247462\/revisions"}],"predecessor-version":[{"id":247467,"href":"https:\/\/www.johndcook.com\/blog\/wp-json\/wp\/v2\/posts\/247462\/revisions\/247467"}],"wp:attachment":[{"href":"https:\/\/www.johndcook.com\/blog\/wp-json\/wp\/v2\/media?parent=247462"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.johndcook.com\/blog\/wp-json\/wp\/v2\/categories?post=247462"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.johndcook.com\/blog\/wp-json\/wp\/v2\/tags?post=247462"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}},{"id":247457,"date":"2026-07-27T11:03:44","date_gmt":"2026-07-27T16:03:44","guid":{"rendered":"https:\/\/www.johndcook.com\/blog\/?p=247457"},"modified":"2026-07-27T11:13:29","modified_gmt":"2026-07-27T16:13:29","slug":"counting-permutations-with-roots","status":"publish","type":"post","link":"https:\/\/www.johndcook.com\/blog\/2026\/07\/27\/counting-permutations-with-roots\/","title":{"rendered":"Counting permutations with roots"},"content":{"rendered":"<p>My post from <a href=\"https:\/\/www.johndcook.com\/blog\/2026\/07\/26\/permutation-roots\/\">yesterday<\/a> on permutation roots ends with a Mathematica code for finding the probability that a permutation of <em>n<\/em> elements has a <em>k<\/em>th root. This is done by finding the coefficient of <em>x<\/em><sup><em>n<\/em><\/sup> in the generating function<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-medium\" src=\"https:\/\/www.johndcook.com\/expq11.svg\" alt=\"\\prod_{m=1}^\\infty \\exp_{\\text{gcd}(m, k)} \\left\\frac{x^m}{m}\\right)\" width=\"162\" height=\"54\" \/><\/p>\n<p>I wanted to say more about this, and look at implementing the same code in SymPy. I was curious how well SymPy would do because I&#8217;ve noticed that LLMs often generate SymPy code since it&#8217;s an open source <abbr title=\"computer algebra system\">CAS<\/abbr>.<\/p>\n<p>Wilf [1] describes the infinite product above as the exponential generating function (egf) of <em>f<\/em>(<em>n<\/em>, <em>k<\/em>), the number of permutations of <em>n<\/em> objects that have a <em>k<\/em>th root. Since egfs have a <em>n<\/em>! term in the denominator, this is also the ordinary generating function (ogf) of the <em>probability<\/em> that a randomly chosen permutation on <em>n<\/em> objects has a <em>k<\/em>th root.<\/p>\n<p>My first attempt at using Mathematica to probe the generating function was<\/p>\n<pre>expq[x_, q_] := MittagLefflerE[q, x^q]\t \r\np[n_, k_] :=  SeriesCoefficient[\t \r\n    Product[expq[x^m\/m, GCD[m, k]], {m, 1, Infinity}], {x, 0, n}]\r\n<\/pre>\n<p>This hung forever when I tried to use it on a small example. I realized, but apparently Mathematica did not, that <code>Infinity<\/code> could be replaced by <code>n<\/code> since terms higher than <em>n<\/em> do not contribute to the coefficient of <em>x<\/em><sup><em>n<\/em><\/sup>. With that change, the code ran quickly.<\/p>\n<p>This morning I tried converting the Mathematica code to Sympy; Claude did this in one shot. I also reproduced the table of <em>f<\/em>(<em>n<\/em>, <em>k<\/em>) values on page 150 of [1] to test the code. Since Wilf tabulated <em>f<\/em>(<em>n<\/em>, <em>k<\/em>), not <em>f<\/em>(<em>n<\/em>, <em>k<\/em>)\/<em>n<\/em>!, I multiplied the results by <em>n<\/em>!.<\/p>\n<p>Here is the output:<\/p>\n<pre>k = 2 [1, 1, 3, 12, 60, 270, 1890, 14280, 128520, 1096200]\r\nk = 3 [1, 2, 4, 16, 80, 400, 2800, 22400, 181440, 1814400]\r\nk = 4 [1, 1, 3, 12, 60, 270, 1890, 13020, 117180, 1039500]\r\nk = 5 [1, 2, 6, 24, 96, 576, 4032, 32256, 290304, 2612736]\r\nk = 6 [1, 1, 1, 4, 40, 190, 1330, 8680, 52920, 340200]\r\nk = 7 [1, 2, 6, 24, 120, 720, 4320, 34560, 311040, 3110400]\r\n<\/pre>\n<p>and here is the SymPy code. I edited the main but the rest is verbatim from Claude.<\/p>\n<pre>from sympy import symbols, gcd, factorial, Rational, S\r\n\r\nx = symbols('x')\r\n\r\ndef expq_coeffs(m, q, n):\r\n    \"\"\"\r\n    Truncated (degree &lt;= n) series coefficients of\r\n        expq(x**m\/m, q) = MittagLefflerE(q, (x**m\/m)**q)\r\n    Since q is a positive integer:\r\n        E_q(y^q) = sum_j y^(q*j) \/ (q*j)!\r\n    with y = x**m\/m, so the term of degree m*q*j has coefficient\r\n        1 \/ ( m**(q*j) * (q*j)! ).\r\n    Returns a list c[0..n] of coefficients.\r\n    \"\"\"\r\n    c = [S.Zero] * (n + 1)\r\n    j = 0\r\n    while m * q * j &lt;= n:\r\n        deg = m * q * j\r\n        c[deg] += Rational(1, m**(q * j) * factorial(q * j))\r\n        j += 1\r\n    return c\r\n\r\ndef poly_mult_trunc(a, b, n):\r\n    \"\"\"Multiply two series (lists of coeffs, index = degree) truncated to degree n.\"\"\"\r\n    c = [S.Zero] * (n + 1)\r\n    for i, ai in enumerate(a):\r\n        if ai == 0:\r\n            continue\r\n        max_j = n - i\r\n        for j2 in range(max_j + 1):\r\n            bj = b[j2]\r\n            if bj != 0:\r\n                c[i + j2] += ai * bj\r\n    return c\r\n\r\ndef p(n, k):\r\n    \"\"\"\r\n    SymPy equivalent of:\r\n        expq[x_, q_] := MittagLefflerE[q, x^q]\r\n        p[n_, k_] := SeriesCoefficient[\r\n            Product[expq[x^m\/m, GCD[m, k]], {m, 1, n}], {x, 0, n}]\r\n    \"\"\"\r\n    result = [S.Zero] * (n + 1)\r\n    result[0] = S.One\r\n    for m in range(1, n + 1):\r\n        q = gcd(m, k)\r\n        factor = expq_coeffs(m, q, n)\r\n        result = poly_mult_trunc(result, factor, n)\r\n    return result[n]\r\n\r\n# example\r\nif __name__ == \"__main__\":\r\n    for k in range(2, 8):\r\n        print(\"k =\", k, [factorial(n)*p(n, k) for n in range(1,11)])\r\n<\/pre>\n<p>[1] Herbert Wilf. Generatingfunctionology. Available online <a href=\"https:\/\/www2.math.upenn.edu\/~wilf\/DownldGF.html\">here<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>My post from yesterday on permutation roots ends with a Mathematica code for finding the probability that a permutation of n elements has a kth root. This is done by finding the coefficient of xn in the generating function I wanted to say more about this, and look at implementing the same code in SymPy. [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[9],"tags":[197,87,142],"class_list":["post-247457","post","type-post","status-publish","format-standard","hentry","category-math","tag-combinatorics","tag-mathematica","tag-sympy"],"acf":[],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 4.9.10 - aioseo.com -->\n\t<meta name=\"description\" content=\"Counting permutations that have kth roots. A trick to make Mathematica work and porting the code to SymPy.\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"John\"\/>\n\t<meta name=\"keywords\" content=\"combinatorics,mathematica,sympy\" \/>\n\t<link rel=\"canonical\" href=\"https:\/\/www.johndcook.com\/blog\/2026\/07\/27\/counting-permutations-with-roots\/\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 4.9.10\" \/>\n\t\t<meta property=\"og:locale\" content=\"en_US\" \/>\n\t\t<meta property=\"og:site_name\" content=\"John D. Cook | Applied Mathematics Consulting\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"Counting permutations with roots\" \/>\n\t\t<meta property=\"og:description\" content=\"Counting permutations that have kth roots. A trick to make Mathematica work and porting the code to SymPy.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/www.johndcook.com\/blog\/2026\/07\/27\/counting-permutations-with-roots\/\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2026-07-27T16:03:44+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2026-07-27T16:13:29+00:00\" \/>\n\t\t<meta name=\"twitter:card\" content=\"summary\" \/>\n\t\t<meta name=\"twitter:title\" content=\"Counting permutations with roots\" \/>\n\t\t<meta name=\"twitter:description\" content=\"Counting permutations that have kth roots. A trick to make Mathematica work and porting the code to SymPy.\" \/>\n\t\t<meta name=\"twitter:image\" content=\"https:\/\/www.johndcook.com\/blog\/wp-content\/uploads\/2022\/05\/twittercard.png\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"Counting permutations with roots","description":"Counting permutations that have kth roots. A trick to make Mathematica work and porting the code to SymPy.","canonical_url":"https:\/\/www.johndcook.com\/blog\/2026\/07\/27\/counting-permutations-with-roots\/","robots":"max-image-preview:large","keywords":"combinatorics,mathematica,sympy","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"en_US","og:site_name":"John D. Cook | Applied Mathematics Consulting","og:type":"article","og:title":"Counting permutations with roots","og:description":"Counting permutations that have kth roots. A trick to make Mathematica work and porting the code to SymPy.","og:url":"https:\/\/www.johndcook.com\/blog\/2026\/07\/27\/counting-permutations-with-roots\/","article:published_time":"2026-07-27T16:03:44+00:00","article:modified_time":"2026-07-27T16:13:29+00:00","twitter:card":"summary","twitter:title":"Counting permutations with roots","twitter:description":"Counting permutations that have kth roots. A trick to make Mathematica work and porting the code to SymPy.","twitter:image":"https:\/\/www.johndcook.com\/blog\/wp-content\/uploads\/2022\/05\/twittercard.png"},"aioseo_meta_data":{"post_id":"247457","title":null,"description":"Counting permutations that have kth roots. A trick to make Mathematica work and porting the code to SymPy.","keywords":null,"keyphrases":{"focus":{"keyphrase":"","score":0,"analysis":{"keyphraseInTitle":{"score":0,"maxScore":9,"error":1}}},"additional":[]},"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":"","og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"Article","isEnabled":true},"graphs":[]},"schema_type":"default","schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":"-1","robots_max_videopreview":"-1","robots_max_imagepreview":"large","priority":null,"frequency":"default","location":null,"local_seo":null,"breadcrumb_settings":null,"limit_modified_date":false,"created":"2026-07-27 15:38:01","updated":"2026-07-28 00:53:40","ai":{"faqs":[],"keyPoints":[],"schemas":[],"titles":[],"descriptions":[],"socialPosts":{"email":{"subject":"","preview":"","content":""},"linkedin":[],"twitter":[],"facebook":[],"instagram":[]}},"seo_analyzer_scan_date":null},"aioseo_breadcrumb":"<div class=\"aioseo-breadcrumbs\"><span class=\"aioseo-breadcrumb\">\n\t\t\t<a href=\"https:\/\/www.johndcook.com\/blog\" title=\"Home\">Home<\/a>\n\t\t<\/span><span class=\"aioseo-breadcrumb-separator\">&raquo;<\/span><span class=\"aioseo-breadcrumb\">\n\t\t\t<a href=\"https:\/\/www.johndcook.com\/blog\/category\/math\/\" title=\"Math\">Math<\/a>\n\t\t<\/span><span class=\"aioseo-breadcrumb-separator\">&raquo;<\/span><span class=\"aioseo-breadcrumb\">\n\t\t\tCounting permutations with roots\n\t\t<\/span><\/div>","aioseo_breadcrumb_json":[{"label":"Home","link":"https:\/\/www.johndcook.com\/blog"},{"label":"Math","link":"https:\/\/www.johndcook.com\/blog\/category\/math\/"},{"label":"Counting permutations with roots","link":"https:\/\/www.johndcook.com\/blog\/2026\/07\/27\/counting-permutations-with-roots\/"}],"_links":{"self":[{"href":"https:\/\/www.johndcook.com\/blog\/wp-json\/wp\/v2\/posts\/247457","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.johndcook.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.johndcook.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.johndcook.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.johndcook.com\/blog\/wp-json\/wp\/v2\/comments?post=247457"}],"version-history":[{"count":2,"href":"https:\/\/www.johndcook.com\/blog\/wp-json\/wp\/v2\/posts\/247457\/revisions"}],"predecessor-version":[{"id":247461,"href":"https:\/\/www.johndcook.com\/blog\/wp-json\/wp\/v2\/posts\/247457\/revisions\/247461"}],"wp:attachment":[{"href":"https:\/\/www.johndcook.com\/blog\/wp-json\/wp\/v2\/media?parent=247457"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.johndcook.com\/blog\/wp-json\/wp\/v2\/categories?post=247457"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.johndcook.com\/blog\/wp-json\/wp\/v2\/tags?post=247457"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}},{"id":247449,"date":"2026-07-27T10:34:05","date_gmt":"2026-07-27T15:34:05","guid":{"rendered":"https:\/\/www.johndcook.com\/blog\/?p=247449"},"modified":"2026-07-27T15:35:18","modified_gmt":"2026-07-27T20:35:18","slug":"float-binary","status":"publish","type":"post","link":"https:\/\/www.johndcook.com\/blog\/2026\/07\/27\/float-binary\/","title":{"rendered":"Printing floating point numbers in binary"},"content":{"rendered":"<p>It&#8217;s well known that you can convert the base 16 (hex) representation of an integer to the base 2 (binary) representation by simply converting each digit from hex to binary. For example,<\/p>\n<p style=\"padding-left: 40px;\">CAFE<sub>hex<\/sub> = 1100 1010 1111 1110<sub>two<\/sub><\/p>\n<p>I imagine it&#8217;s less well known that you can do the same thing with floating point numbers.<\/p>\n<p>I wanted to find the binary representation of a floating point number using Python, and discovered that it has no function to do this. However, there is a method on floats to show a hex representation. For example, here&#8217;s the hex representation of \u03c0.<\/p>\n<pre>&gt;&gt;&gt; import math\r\n&gt;&gt;&gt; (math.pi).hex()\r\n'0x1.921fb54442d18p+1'\r\n<\/pre>\n<p>Curiously, the p+<em>k<\/em> part at the end is an exponent of 2, not an exponent of 16. So after we convert 1.921fb54442d18 to binary, we&#8217;ll need to multiply by 2, i.e. move the fractional point one space to the right.<\/p>\n<p>So first we convert 1.921fb54442d18<sub>hex<\/sub> to binary by converting 1, 9, 2, etc. each to binary.<\/p>\n<p style=\"padding-left: 40px;\">1.1001 0010 0001 1111 1011 0101 0100 0100 0100 0010 1101 0001 1000<sub>two<\/sub><\/p>\n<p>Then after shifting the fraction point to account for the <code>p+1<\/code> part we have<\/p>\n<p style=\"padding-left: 40px;\">\u03c0 = 11.001001000011111101101010100010001000010110100011000<sub>two<\/sub><\/p>\n<p>You could use Python&#8217;s bin() function to convert the fractional part, interpreted as an integer, to hex, though you may need to pad with 0 bits. For example,<\/p>\n<pre>&gt;&gt;&gt; (1.03).hex()\r\n'0x1.07ae147ae147bp+0\r\n\r\n&gt;&gt;&gt; bin(0x7ae147ae147)\r\n'0b1111010111000010100011110101110000101000111'\r\n<\/pre>\n<p>The binary representation of 1.03<sub>ten<\/sub> is<\/p>\n<p style=\"padding-left: 40px;\">1.000001111010111000010100011110101110000101000111<sub>two<\/sub><\/p>\n<p>We added a total of five zero bits, four for the 0 after the fractional point and one for converting 7 to 0111<sub>two<\/sub>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>It&#8217;s well known that you can convert the base 16 (hex) representation of an integer to the base 2 (binary) representation by simply converting each digit from hex to binary. For example, CAFEhex = 1100 1010 1111 1110two I imagine it&#8217;s less well known that you can do the same thing with floating point numbers. [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[5,9],"tags":[271],"class_list":["post-247449","post","type-post","status-publish","format-standard","hentry","category-computing","category-math","tag-number-systems"],"acf":[],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 4.9.10 - aioseo.com -->\n\t<meta name=\"description\" content=\"Python has no method to show floating point numbers in binary, but it does have a method for showing them in hex. How to make the former out of the latter.\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"John\"\/>\n\t<meta name=\"keywords\" content=\"number systems\" \/>\n\t<link rel=\"canonical\" href=\"https:\/\/www.johndcook.com\/blog\/2026\/07\/27\/float-binary\/\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 4.9.10\" \/>\n\t\t<meta property=\"og:locale\" content=\"en_US\" \/>\n\t\t<meta property=\"og:site_name\" content=\"John D. Cook | Applied Mathematics Consulting\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"Printing floating point numbers in binary\" \/>\n\t\t<meta property=\"og:description\" content=\"Python has no method to show floating point numbers in binary, but it does have a method for showing them in hex. How to make the former out of the latter.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/www.johndcook.com\/blog\/2026\/07\/27\/float-binary\/\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2026-07-27T15:34:05+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2026-07-27T20:35:18+00:00\" \/>\n\t\t<meta name=\"twitter:card\" content=\"summary\" \/>\n\t\t<meta name=\"twitter:title\" content=\"Printing floating point numbers in binary\" \/>\n\t\t<meta name=\"twitter:description\" content=\"Python has no method to show floating point numbers in binary, but it does have a method for showing them in hex. How to make the former out of the latter.\" \/>\n\t\t<meta name=\"twitter:image\" content=\"https:\/\/www.johndcook.com\/blog\/wp-content\/uploads\/2022\/05\/twittercard.png\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"Printing floating point numbers in binary","description":"Python has no method to show floating point numbers in binary, but it does have a method for showing them in hex. How to make the former out of the latter.","canonical_url":"https:\/\/www.johndcook.com\/blog\/2026\/07\/27\/float-binary\/","robots":"max-image-preview:large","keywords":"number systems","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"en_US","og:site_name":"John D. Cook | Applied Mathematics Consulting","og:type":"article","og:title":"Printing floating point numbers in binary","og:description":"Python has no method to show floating point numbers in binary, but it does have a method for showing them in hex. How to make the former out of the latter.","og:url":"https:\/\/www.johndcook.com\/blog\/2026\/07\/27\/float-binary\/","article:published_time":"2026-07-27T15:34:05+00:00","article:modified_time":"2026-07-27T20:35:18+00:00","twitter:card":"summary","twitter:title":"Printing floating point numbers in binary","twitter:description":"Python has no method to show floating point numbers in binary, but it does have a method for showing them in hex. How to make the former out of the latter.","twitter:image":"https:\/\/www.johndcook.com\/blog\/wp-content\/uploads\/2022\/05\/twittercard.png"},"aioseo_meta_data":{"post_id":"247449","title":null,"description":"Python has no method to show floating point numbers in binary, but it does have a method for showing them in hex. How to make the former out of the latter.","keywords":null,"keyphrases":{"focus":{"keyphrase":"","score":0,"analysis":{"keyphraseInTitle":{"score":0,"maxScore":9,"error":1}}},"additional":[]},"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":"","og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"Article","isEnabled":true},"graphs":[]},"schema_type":"default","schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":"-1","robots_max_videopreview":"-1","robots_max_imagepreview":"large","priority":null,"frequency":"default","location":null,"local_seo":null,"breadcrumb_settings":null,"limit_modified_date":false,"created":"2026-07-27 00:05:27","updated":"2026-07-28 00:53:40","ai":{"faqs":[],"keyPoints":[],"schemas":[],"titles":[],"descriptions":[],"socialPosts":{"email":{"subject":"","preview":"","content":""},"linkedin":[],"twitter":[],"facebook":[],"instagram":[]}},"seo_analyzer_scan_date":null},"aioseo_breadcrumb":"<div class=\"aioseo-breadcrumbs\"><span class=\"aioseo-breadcrumb\">\n\t\t\t<a href=\"https:\/\/www.johndcook.com\/blog\" title=\"Home\">Home<\/a>\n\t\t<\/span><span class=\"aioseo-breadcrumb-separator\">&raquo;<\/span><span class=\"aioseo-breadcrumb\">\n\t\t\t<a href=\"https:\/\/www.johndcook.com\/blog\/category\/computing\/\" title=\"Computing\">Computing<\/a>\n\t\t<\/span><span class=\"aioseo-breadcrumb-separator\">&raquo;<\/span><span class=\"aioseo-breadcrumb\">\n\t\t\tPrinting floating point numbers in binary\n\t\t<\/span><\/div>","aioseo_breadcrumb_json":[{"label":"Home","link":"https:\/\/www.johndcook.com\/blog"},{"label":"Computing","link":"https:\/\/www.johndcook.com\/blog\/category\/computing\/"},{"label":"Printing floating point numbers in binary","link":"https:\/\/www.johndcook.com\/blog\/2026\/07\/27\/float-binary\/"}],"_links":{"self":[{"href":"https:\/\/www.johndcook.com\/blog\/wp-json\/wp\/v2\/posts\/247449","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.johndcook.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.johndcook.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.johndcook.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.johndcook.com\/blog\/wp-json\/wp\/v2\/comments?post=247449"}],"version-history":[{"count":7,"href":"https:\/\/www.johndcook.com\/blog\/wp-json\/wp\/v2\/posts\/247449\/revisions"}],"predecessor-version":[{"id":247463,"href":"https:\/\/www.johndcook.com\/blog\/wp-json\/wp\/v2\/posts\/247449\/revisions\/247463"}],"wp:attachment":[{"href":"https:\/\/www.johndcook.com\/blog\/wp-json\/wp\/v2\/media?parent=247449"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.johndcook.com\/blog\/wp-json\/wp\/v2\/categories?post=247449"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.johndcook.com\/blog\/wp-json\/wp\/v2\/tags?post=247449"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}},{"id":247440,"date":"2026-07-26T15:32:02","date_gmt":"2026-07-26T20:32:02","guid":{"rendered":"https:\/\/www.johndcook.com\/blog\/?p=247440"},"modified":"2026-07-27T10:45:23","modified_gmt":"2026-07-27T15:45:23","slug":"permutation-roots","status":"publish","type":"post","link":"https:\/\/www.johndcook.com\/blog\/2026\/07\/26\/permutation-roots\/","title":{"rendered":"Permutation roots"},"content":{"rendered":"<p>Let \u03c3 be a permutation on <em>n<\/em> elements. If there is a permutation \u03c4 such that applying \u03c4 twice has the same effect on the list of elements as applying \u03c3 once, we say \u03c3 = \u03c4\u00b2 and \u03c4 is a square root of \u03c3.<\/p>\n<p>If we let our <em>n<\/em> elements be the integers 0 through <em>n<\/em> \u2212 1, then we can represent permutations by what they do to this list of numbers. In Python as a tuple of length <em>n<\/em> and compose permutations with the following function:<\/p>\n<pre>import itertools\r\n\r\ndef compose(sigma, tau):\r\n    \"Return the composition \u03c3 \u2218 \u03c4 (apply \u03c4 first, then \u03c3).\"\r\n    return tuple(sigma[j] for j in tau)\r\n<\/pre>\n<p>We can always construct permutations that have square roots by squaring a permutation. If we run the following code<\/p>\n<pre>tau = (3, 1, 4, 5, 2, 0)\r\nsigma = compose(tau, tau)\r\n<\/pre>\n<p>we find \u03c3 = (5, 1, 2, 0, 4, 3), and by construction (3, 1, 4, 5, 2, 0) is a square root of &amp;sigma, though it&#8217;s not the only one.<\/p>\n<p>The following code shows that \u03c3 has four roots.<\/p>\n<pre>import itertools\r\n\r\ndef numroots(sigma):\r\n    n = len(sigma)\r\n    c = 0\r\n    for tau in itertools.permutations(range(n)):\r\n        if sigma == compose(tau, tau):\r\n            c += 1\r\n    return c\r\n\r\nprint( numroots(sigma) )\r\nprint( numroots( (1, 2, 3, 4, 5, 0) ) )\r\n<\/pre>\n<p>It also shows that the rotation (1, 2, 3, 4, 5. 0) has no roots.<\/p>\n<p>The function <code>numroots<\/code> has runtime proportional to <em>n<\/em>! and so it&#8217;s not practical for large permutations. There is a theorem that says a permutation \u03c3 has a square root if and only if the number of cycles it has of every even length is even. See [1].<\/p>\n<p>We can also define cubes and cube roots of permutations, and higher powers and roots.<\/p>\n<p>How common is it for permutations to have square roots, or cube roots, etc.? If you pick a random permutation on <em>n<\/em> elements, what is the probability that it has a <em>k<\/em>th root?<\/p>\n<p>This is a hard question in general, but it is equivalent to finding the coefficient of <em>x<\/em><sup><em>k<\/em><\/sup> in the infinite product<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-medium\" src=\"https:\/\/www.johndcook.com\/expq11.svg\" alt=\"\\prod_{m=1}^\\infty \\exp_{\\text{gcd}(m, k)} \\left(\\frac{x^m}{m}\\right)\" width=\"162\" height=\"54\" \/><\/p>\n<p>This is theorem 4.8.3 in [1]. This theorem was the motivation for writing about exp<sub><em>q<\/em><\/sub> in the <a href=\"https:\/\/www.johndcook.com\/blog\/2026\/07\/26\/exp-q\/\">previous post<\/a>.<\/p>\n<p>Although the product is infinite, there&#8217;s no need to compute terms in the product that only contribute powers of <em>x<\/em> higher than you&#8217;re interested in. The following Mathematica code will compute the probability that a permutation on <em>n<\/em> elements has a <em>k<\/em>th root.<\/p>\n<pre>expq[x_, q_] := MittagLefflerE[q, x^q]\t \r\np[n_, k_] :=  SeriesCoefficient[\t \r\n    Product[expq[x^m\/m, GCD[m, k]], {m, 1, n}], {x, 0, n}]\r\n<\/pre>\n<p>So, for example, the probability that a permutation of 10 elements has a square root is 29\/96.<\/p>\n<p>[1] Herbert Wilf. Generatingfunctionology. Available online <a href=\"https:\/\/www2.math.upenn.edu\/~wilf\/DownldGF.html\">here<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Let \u03c3 be a permutation on n elements. If there is a permutation \u03c4 such that applying \u03c4 twice has the same effect on the list of elements as applying \u03c3 once, we say \u03c3 = \u03c4\u00b2 and \u03c4 is a square root of \u03c3. If we let our n elements be the integers 0 [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[],"class_list":["post-247440","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"acf":[],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 4.9.10 - aioseo.com -->\n\t<meta name=\"description\" content=\"Let \u03c3 be a permutation on n elements. If there is a permutation \u03c4 such that applying \u03c4 twice has the same effect on the list of elements as applying \u03c3 once, we say \u03c3 = \u03c4\u00b2 and \u03c4 is a square root of \u03c3. If we let our n elements be the integers 0\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"John\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/www.johndcook.com\/blog\/2026\/07\/26\/permutation-roots\/\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 4.9.10\" \/>\n\t\t<meta property=\"og:locale\" content=\"en_US\" \/>\n\t\t<meta property=\"og:site_name\" content=\"John D. Cook | Applied Mathematics Consulting\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"Permutation roots\" \/>\n\t\t<meta property=\"og:description\" content=\"Let \u03c3 be a permutation on n elements. If there is a permutation \u03c4 such that applying \u03c4 twice has the same effect on the list of elements as applying \u03c3 once, we say \u03c3 = \u03c4\u00b2 and \u03c4 is a square root of \u03c3. If we let our n elements be the integers 0\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/www.johndcook.com\/blog\/2026\/07\/26\/permutation-roots\/\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2026-07-26T20:32:02+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2026-07-27T15:45:23+00:00\" \/>\n\t\t<meta name=\"twitter:card\" content=\"summary\" \/>\n\t\t<meta name=\"twitter:title\" content=\"Permutation roots\" \/>\n\t\t<meta name=\"twitter:description\" content=\"Let \u03c3 be a permutation on n elements. If there is a permutation \u03c4 such that applying \u03c4 twice has the same effect on the list of elements as applying \u03c3 once, we say \u03c3 = \u03c4\u00b2 and \u03c4 is a square root of \u03c3. If we let our n elements be the integers 0\" \/>\n\t\t<meta name=\"twitter:image\" content=\"https:\/\/www.johndcook.com\/blog\/wp-content\/uploads\/2022\/05\/twittercard.png\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"Permutation roots","description":"Let \u03c3 be a permutation on n elements. If there is a permutation \u03c4 such that applying \u03c4 twice has the same effect on the list of elements as applying \u03c3 once, we say \u03c3 = \u03c4\u00b2 and \u03c4 is a square root of \u03c3. If we let our n elements be the integers 0","canonical_url":"https:\/\/www.johndcook.com\/blog\/2026\/07\/26\/permutation-roots\/","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"en_US","og:site_name":"John D. Cook | Applied Mathematics Consulting","og:type":"article","og:title":"Permutation roots","og:description":"Let \u03c3 be a permutation on n elements. If there is a permutation \u03c4 such that applying \u03c4 twice has the same effect on the list of elements as applying \u03c3 once, we say \u03c3 = \u03c4\u00b2 and \u03c4 is a square root of \u03c3. If we let our n elements be the integers 0","og:url":"https:\/\/www.johndcook.com\/blog\/2026\/07\/26\/permutation-roots\/","article:published_time":"2026-07-26T20:32:02+00:00","article:modified_time":"2026-07-27T15:45:23+00:00","twitter:card":"summary","twitter:title":"Permutation roots","twitter:description":"Let \u03c3 be a permutation on n elements. If there is a permutation \u03c4 such that applying \u03c4 twice has the same effect on the list of elements as applying \u03c3 once, we say \u03c3 = \u03c4\u00b2 and \u03c4 is a square root of \u03c3. If we let our n elements be the integers 0","twitter:image":"https:\/\/www.johndcook.com\/blog\/wp-content\/uploads\/2022\/05\/twittercard.png"},"aioseo_meta_data":{"post_id":"247440","title":null,"description":null,"keywords":null,"keyphrases":{"focus":{"keyphrase":"","score":0,"analysis":{"keyphraseInTitle":{"score":0,"maxScore":9,"error":1}}},"additional":[]},"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":"","og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"Article","isEnabled":true},"graphs":[]},"schema_type":"default","schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":"-1","robots_max_videopreview":"-1","robots_max_imagepreview":"large","priority":null,"frequency":"default","location":null,"local_seo":null,"breadcrumb_settings":null,"limit_modified_date":false,"created":"2026-07-26 19:13:37","updated":"2026-07-28 00:53:40","ai":{"faqs":[],"keyPoints":[],"schemas":[],"titles":[],"descriptions":[],"socialPosts":{"email":{"subject":"","preview":"","content":""},"linkedin":[],"twitter":[],"facebook":[],"instagram":[]}},"seo_analyzer_scan_date":null},"aioseo_breadcrumb":"<div class=\"aioseo-breadcrumbs\"><span class=\"aioseo-breadcrumb\">\n\t\t\t<a href=\"https:\/\/www.johndcook.com\/blog\" title=\"Home\">Home<\/a>\n\t\t<\/span><span class=\"aioseo-breadcrumb-separator\">&raquo;<\/span><span class=\"aioseo-breadcrumb\">\n\t\t\t<a href=\"https:\/\/www.johndcook.com\/blog\/category\/uncategorized\/\" title=\"Uncategorized\">Uncategorized<\/a>\n\t\t<\/span><span class=\"aioseo-breadcrumb-separator\">&raquo;<\/span><span class=\"aioseo-breadcrumb\">\n\t\t\tPermutation roots\n\t\t<\/span><\/div>","aioseo_breadcrumb_json":[{"label":"Home","link":"https:\/\/www.johndcook.com\/blog"},{"label":"Uncategorized","link":"https:\/\/www.johndcook.com\/blog\/category\/uncategorized\/"},{"label":"Permutation roots","link":"https:\/\/www.johndcook.com\/blog\/2026\/07\/26\/permutation-roots\/"}],"_links":{"self":[{"href":"https:\/\/www.johndcook.com\/blog\/wp-json\/wp\/v2\/posts\/247440","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.johndcook.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.johndcook.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.johndcook.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.johndcook.com\/blog\/wp-json\/wp\/v2\/comments?post=247440"}],"version-history":[{"count":8,"href":"https:\/\/www.johndcook.com\/blog\/wp-json\/wp\/v2\/posts\/247440\/revisions"}],"predecessor-version":[{"id":247459,"href":"https:\/\/www.johndcook.com\/blog\/wp-json\/wp\/v2\/posts\/247440\/revisions\/247459"}],"wp:attachment":[{"href":"https:\/\/www.johndcook.com\/blog\/wp-json\/wp\/v2\/media?parent=247440"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.johndcook.com\/blog\/wp-json\/wp\/v2\/categories?post=247440"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.johndcook.com\/blog\/wp-json\/wp\/v2\/tags?post=247440"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}},{"id":247432,"date":"2026-07-26T13:20:36","date_gmt":"2026-07-26T18:20:36","guid":{"rendered":"https:\/\/www.johndcook.com\/blog\/?p=247432"},"modified":"2026-07-26T15:32:54","modified_gmt":"2026-07-26T20:32:54","slug":"exp-q","status":"publish","type":"post","link":"https:\/\/www.johndcook.com\/blog\/2026\/07\/26\/exp-q\/","title":{"rendered":"exp_q"},"content":{"rendered":"<p>The function exp<sub><em>q<\/em><\/sub>(<em>x<\/em>) is defined by taking the power series for exp(<em>x<\/em>) and keeping only the terms whose index is a multiple of <em>q<\/em>. For example, exp<sub>2<\/sub>(<em>x<\/em>) keeps only the even-numbered terms in the exponential power series and so equals cosh(<em>x<\/em>).<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter\" style=\"background-color: white;\" src=\"https:\/\/www.johndcook.com\/expqx.svg\" alt=\"\\exp_2(x) = 1 + \\frac{x^2}{2!} + \\frac{x^4}{4!} + \\frac{x^6}{6!} + \\cdots = \\cosh(x)\" width=\"359\" height=\"44\" \/><\/p>\n<p>In general,<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter\" style=\"background-color: white;\" src=\"https:\/\/www.johndcook.com\/expq2.svg\" alt=\"\\exp_q(x) = \\sum_{n=0}^\\infty [q \\mid n] \\frac{x^n}{n!} = \\sum_{n=0}^\\infty \\frac{x^{nq}}{(nq)!}\" width=\"285\" height=\"54\" \/><\/p>\n<p>The first sum uses <a href=\"https:\/\/www.johndcook.com\/blog\/2023\/07\/01\/activation-functions\/\">Iverson&#8217;s bracket notation<\/a>: a Boolean expression in brackets denotes the function that returns 1 when the expression is true and zero when it is false. Here the bracket equals 1 when <em>q<\/em> divides <em>n<\/em> and is zero otherwise.<\/p>\n<h2>Closed forms<\/h2>\n<p>Let \u03c9 = exp(2\u03c0<em>i<\/em> \/ <em>q<\/em>). Then<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter\" style=\"background-color: white;\" src=\"https:\/\/www.johndcook.com\/expq3.svg\" alt=\"\\exp_q(x) = \\frac{1}{q}\\sum_{k=0}^{q-1} \\exp(\\omega^k x)\" width=\"209\" height=\"60\" \/><\/p>\n<p>This lets us find closed-form expressions for exp<sub><em>q<\/em><\/sub>(<em>x<\/em>). For example, when <em>q<\/em> = 4, \u03c9 = <em>i<\/em> and<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter\" style=\"background-color: white;\" src=\"https:\/\/www.johndcook.com\/expq4.svg\" alt=\"\\exp_4(x) = \\frac{1}{2}\\left( \\cosh(x) + \\cos(x) \\right)\" width=\"257\" height=\"40\" \/><\/p>\n<p>Here&#8217;s a proof of the identity above:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter\" style=\"background-color: white;\" src=\"https:\/\/www.johndcook.com\/expq5.svg\" alt=\"\\begin{align*} \\frac{1}{q} \\sum_{k=0}^{q-1} \\exp(\\omega^k x) &amp;= \\frac{1}{q} \\sum_{k=0}^{q-1} \\sum_{n=0}^\\infty \\frac{\\omega^{kn}x^n}{n!} \\\\ &amp;= \\sum_{n=0}^\\infty \\left( \\frac{1}{q} \\sum_{k=0}^{q-1} \\omega^{kn}\\right) \\frac{x^n}{n!} \\\\ &amp;= \\sum_{n=0}^\\infty [q \\mid n] \\frac{x^n}{n!} \\\\ &amp;= \\exp_q(x) \\end{align*} \" width=\"296\" height=\"230\" \/><\/p>\n<p>In the proof we used the identity<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter\" style=\"background-color: white;\" src=\"https:\/\/www.johndcook.com\/expq6.svg\" alt=\"\\frac{1}{q} \\sum_{k=0}^{q-1} \\omega^{kn} = [q \\mid n]\" width=\"150\" height=\"60\" \/><\/p>\n<p>which is important in deriving the properties of the discrete Fourier transform.<\/p>\n<h2>Differential equations<\/h2>\n<p>The first time I saw the function exp<sub><em>q<\/em><\/sub>(<em>x<\/em>) was in differential equations, though I didn&#8217;t know at the time the function had a name.<\/p>\n<p>When a course in differential equations gets to power series solutions, a common example or homework problem is to solve<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter\" style=\"background-color: white;\" src=\"https:\/\/www.johndcook.com\/expq7.svg\" alt=\"y^{(k)}(x) = y(x)\" width=\"117\" height=\"23\" \/><\/p>\n<p>for <em>k<\/em> = 3 or 4, i.e. to find a function that equals its third or fourth derivative.<\/p>\n<p>If the initial conditions are<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter\" style=\"background-color: white;\" src=\"https:\/\/www.johndcook.com\/expq8.svg\" alt=\"y(0) = 0\" width=\"70\" height=\"18\" \/><\/p>\n<p>and<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter\" style=\"background-color: white;\" src=\"https:\/\/www.johndcook.com\/expq9.svg\" alt=\"y^\\prime(0) = y^{\\prime\\prime}(0) = \\cdots = y^{(k-1)}(0) = 0\" width=\"285\" height=\"23\" \/><\/p>\n<p>the unique solution to<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter\" style=\"background-color: white;\" src=\"https:\/\/www.johndcook.com\/expq7.svg\" alt=\"y^{(k)}(x) = y(x)\" width=\"117\" height=\"23\" \/><\/p>\n<p>is <em>y<\/em>(<em>x<\/em>) = exp<sub><em>k<\/em><\/sub>(<em>x<\/em>).<\/p>\n<h2>Mathematica and Mittag-Leffler<\/h2>\n<p>Mathematica does not have a built-in function implementing exp<sub><em>q<\/em><\/sub>(<em>x<\/em>), but it does have an implementation of the <a href=\"https:\/\/www.johndcook.com\/blog\/2016\/07\/17\/mittag-leffler-function-and-probability-distribution\/\">Mittag-Leffler function<\/a>, and so thanks to a relation between this function and exp<sub><em>q<\/em><\/sub>(<em>x<\/em>) you can implement the latter as<\/p>\n<pre>expq[x_, q_] := MittagLefflerE[q, x^q]<\/pre>\n<h2>Combinatorics<\/h2>\n<p>The first time I saw the <em>notation<\/em> exp<sub><em>q<\/em><\/sub>(<em>x<\/em>) was in combinatorics. I had intended to include an application from that book here, but I make that the topic for the <a href=\"https:\/\/www.johndcook.com\/blog\/2026\/07\/26\/permutation-roots\/\">next post<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>The function expq(x) is defined by taking the power series for exp(x) and keeping only the terms whose index is a multiple of q. For example, exp2(x) keeps only the even-numbered terms in the exponential power series and so equals cosh(x). In general, The first sum uses Iverson&#8217;s bracket notation: a Boolean expression in brackets [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[9],"tags":[47,129],"class_list":["post-247432","post","type-post","status-publish","format-standard","hentry","category-math","tag-differential-equations","tag-special-functions"],"acf":[],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 4.9.10 - aioseo.com -->\n\t<meta name=\"description\" content=\"The function exp_q(x) is a generalization of the exponential function. It comes up in numerous applications, such as differential equations and combinatorics.\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"John\"\/>\n\t<meta name=\"keywords\" content=\"differential equations,special functions\" \/>\n\t<link rel=\"canonical\" href=\"https:\/\/www.johndcook.com\/blog\/2026\/07\/26\/exp-q\/\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 4.9.10\" \/>\n\t\t<meta property=\"og:locale\" content=\"en_US\" \/>\n\t\t<meta property=\"og:site_name\" content=\"John D. Cook | Applied Mathematics Consulting\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"exp_q(x) keeps every qth term in the power series for exp(x)\" \/>\n\t\t<meta property=\"og:description\" content=\"The function exp_q(x) is a generalization of the exponential function. It comes up in numerous applications, such as differential equations and combinatorics.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/www.johndcook.com\/blog\/2026\/07\/26\/exp-q\/\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2026-07-26T18:20:36+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2026-07-26T20:32:54+00:00\" \/>\n\t\t<meta name=\"twitter:card\" content=\"summary\" \/>\n\t\t<meta name=\"twitter:title\" content=\"exp_q(x) keeps every qth term in the power series for exp(x)\" \/>\n\t\t<meta name=\"twitter:description\" content=\"The function exp_q(x) is a generalization of the exponential function. It comes up in numerous applications, such as differential equations and combinatorics.\" \/>\n\t\t<meta name=\"twitter:image\" content=\"https:\/\/www.johndcook.com\/blog\/wp-content\/uploads\/2022\/05\/twittercard.png\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"exp_q(x) keeps every qth term in the power series for exp(x)","description":"The function exp_q(x) is a generalization of the exponential function. It comes up in numerous applications, such as differential equations and combinatorics.","canonical_url":"https:\/\/www.johndcook.com\/blog\/2026\/07\/26\/exp-q\/","robots":"max-image-preview:large","keywords":"differential equations,special functions","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"en_US","og:site_name":"John D. Cook | Applied Mathematics Consulting","og:type":"article","og:title":"exp_q(x) keeps every qth term in the power series for exp(x)","og:description":"The function exp_q(x) is a generalization of the exponential function. It comes up in numerous applications, such as differential equations and combinatorics.","og:url":"https:\/\/www.johndcook.com\/blog\/2026\/07\/26\/exp-q\/","article:published_time":"2026-07-26T18:20:36+00:00","article:modified_time":"2026-07-26T20:32:54+00:00","twitter:card":"summary","twitter:title":"exp_q(x) keeps every qth term in the power series for exp(x)","twitter:description":"The function exp_q(x) is a generalization of the exponential function. It comes up in numerous applications, such as differential equations and combinatorics.","twitter:image":"https:\/\/www.johndcook.com\/blog\/wp-content\/uploads\/2022\/05\/twittercard.png"},"aioseo_meta_data":{"post_id":"247432","title":"exp_q(x) keeps every qth term in the power series for exp(x)","description":"The function exp_q(x) is a generalization of the exponential function. It comes up in numerous applications, such as differential equations and combinatorics.","keywords":null,"keyphrases":{"focus":{"keyphrase":"","score":0,"analysis":{"keyphraseInTitle":{"score":0,"maxScore":9,"error":1}}},"additional":[]},"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":"","og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"Article","isEnabled":true},"graphs":[]},"schema_type":"default","schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":"-1","robots_max_videopreview":"-1","robots_max_imagepreview":"large","priority":null,"frequency":"default","location":null,"local_seo":null,"breadcrumb_settings":null,"limit_modified_date":false,"created":"2026-07-26 16:38:25","updated":"2026-07-28 00:53:40","ai":{"faqs":[],"keyPoints":[],"schemas":[],"titles":[],"descriptions":[],"socialPosts":{"email":{"subject":"","preview":"","content":""},"linkedin":[],"twitter":[],"facebook":[],"instagram":[]}},"seo_analyzer_scan_date":null},"aioseo_breadcrumb":"<div class=\"aioseo-breadcrumbs\"><span class=\"aioseo-breadcrumb\">\n\t\t\t<a href=\"https:\/\/www.johndcook.com\/blog\" title=\"Home\">Home<\/a>\n\t\t<\/span><span class=\"aioseo-breadcrumb-separator\">&raquo;<\/span><span class=\"aioseo-breadcrumb\">\n\t\t\t<a href=\"https:\/\/www.johndcook.com\/blog\/category\/math\/\" title=\"Math\">Math<\/a>\n\t\t<\/span><span class=\"aioseo-breadcrumb-separator\">&raquo;<\/span><span class=\"aioseo-breadcrumb\">\n\t\t\texp_q\n\t\t<\/span><\/div>","aioseo_breadcrumb_json":[{"label":"Home","link":"https:\/\/www.johndcook.com\/blog"},{"label":"Math","link":"https:\/\/www.johndcook.com\/blog\/category\/math\/"},{"label":"exp_q","link":"https:\/\/www.johndcook.com\/blog\/2026\/07\/26\/exp-q\/"}],"_links":{"self":[{"href":"https:\/\/www.johndcook.com\/blog\/wp-json\/wp\/v2\/posts\/247432","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.johndcook.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.johndcook.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.johndcook.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.johndcook.com\/blog\/wp-json\/wp\/v2\/comments?post=247432"}],"version-history":[{"count":9,"href":"https:\/\/www.johndcook.com\/blog\/wp-json\/wp\/v2\/posts\/247432\/revisions"}],"predecessor-version":[{"id":247446,"href":"https:\/\/www.johndcook.com\/blog\/wp-json\/wp\/v2\/posts\/247432\/revisions\/247446"}],"wp:attachment":[{"href":"https:\/\/www.johndcook.com\/blog\/wp-json\/wp\/v2\/media?parent=247432"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.johndcook.com\/blog\/wp-json\/wp\/v2\/categories?post=247432"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.johndcook.com\/blog\/wp-json\/wp\/v2\/tags?post=247432"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}]