{"id":13484542,"url":"https://github.com/jzakiya/roots","last_synced_at":"2025-03-27T16:30:58.775Z","repository":{"id":56892658,"uuid":"39701992","full_name":"jzakiya/roots","owner":"jzakiya","description":"roots gem","archived":false,"fork":false,"pushed_at":"2017-07-01T16:30:42.000Z","size":16,"stargazers_count":1,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-19T20:38:50.024Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jzakiya.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-07-25T20:31:34.000Z","updated_at":"2017-02-20T00:58:18.000Z","dependencies_parsed_at":"2022-08-20T16:10:33.834Z","dependency_job_id":null,"html_url":"https://github.com/jzakiya/roots","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jzakiya%2Froots","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jzakiya%2Froots/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jzakiya%2Froots/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jzakiya%2Froots/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jzakiya","download_url":"https://codeload.github.com/jzakiya/roots/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245882304,"owners_count":20687862,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-07-31T17:01:25.857Z","updated_at":"2025-03-27T16:30:57.505Z","avatar_url":"https://github.com/jzakiya.png","language":"Ruby","funding_links":[],"categories":["Scientific"],"sub_categories":[],"readme":"# Roots\n\n## Introduction\n\nThis gem originally provided two methods `root` and `roots` to find all the nth roots of real and complex values.\n\nFor details on their mathematical foundation and implementation details see my paper:\n\n`Roots in Ruby`\n\nhttps://www.scribd.com/doc/60067570/Roots-in-Ruby\n\nIn 2017 I added the methods `iroot2` and `iroot`|`irootn` to find the integer roots for arbitrary sized integers.\n\n## Installation\n\nAdd this line to your application's Gemfile:\n\n    gem 'roots'\n\nAnd then execute:\n\n    $ bundle\n\nOr install it yourself as:\n\n    $ gem install roots\n\nThen require as:\n\n    require 'roots'\n\n## Description\n\nStarting with Roots 2.0.0 (2017-2-21) the methods **iroot2** and **irootn** were added (with\n**iroot** added as an alias to **irootn** 2017-6-1). With 2.1.0 **iroot2** uses optimized Newton's\nmethod. With 2.2.0 (2017-6-17) **iroot|n** uses optimized Newton's method for any nth root. All are instance_methods \nof **class Integer** and accurately compute the exact real value square|nth roots for arbitrary sized integers.\n\nIf you have an application where you need the exact correct integer real value for roots,\nespecially for arbitrary sized (large) integers, use these methods instead of **root|s**.\nThese methods work strictly in the integer domain, and do not first create floating point\napproximations of these roots and then convert them to integers.\n\nThey are useful for applications in pure math, Number Theory, Cryptography, etc, where you\nneed to find the exact real integer roots of polynomials, encryption functions, etc.\n\nThe methods **root** and **roots** work for all the **Numeric** classes (integers, floats,\ncomplex, rationals), and produce floating point results.  They, thus, produce floating\npoint approximations to the exact **Integer** values for real roots for arbitrary sized integers.\n\n## Usage\n\n**iroot2**\n```\nUse syntax:  ival.iroot2\nReturn the largest Integer +root+ of Integer ival such that root**2 \u003c= ival\nA negative ival will result in 'nil' being returned.\n\n 9.iroot2 =\u003e 3\n-9.iroot2 =\u003e nil\n\n120.iroot2 =\u003e 10\n121.iroot2 =\u003e 11\n121.iroot2.class =\u003e Integer\n\n(10**10).iroot2 =\u003e 100000\n(10**10).root(2) =\u003e 100000.0\n(10**10).roots(2)[0] =\u003e 100000.0+0.0i\n\n(10**11).iroot2 =\u003e 316227\n(10**11).root(2) =\u003e 316227.76601684\n(10**11).roots(2)[0] =\u003e 316227.76601684+0.0i\n\n(10**110).iroot2 =\u003e 10000000000000000000000000000000000000000000000000000000\n(10**110).root(2) =\u003e 1.0e+55\n(10**110).roots(2)[0] =\u003e 1.0e+55+0.0i\n\n(10**111).iroot2 =\u003e 31622776601683793319988935444327185337195551393252168268\n(10**111).root(2) =\u003e 3.1622776601683795e+55\n(10**111).roots(2)[0] =\u003e 3.1622776601683795e+55+0.0i\n```\n\n**irootn or iroot**\n```\nUse syntax:  ival.irootn(n) or ival.iroot(n), where n is an Integer \u003e 1\nReturn the largest Integer +root+ of Integer ival such that root**n \u003c= ival\nA negative ival for an even root n will result in 'nil' being returned.\n\n81.irootn(2) =\u003e 9\n81.irootn 3 =\u003e 4\n81.iroot 4 =\u003e 3\n81.iroot(4).class =\u003e Integer\n\n-81.irootn(3) =\u003e -4\n-81.irootn(4) =\u003e nil\n\n100.irootn 4.5 =\u003e RuntimeError: root n is \u003c 2 or not an Integer\n100.iroot -2   =\u003e RuntimeError: root n is \u003c 2 or not an Integer\n\n(10**110).iroot(2)  =\u003e 10000000000000000000000000000000000000000000000000000000\n(10**110).irootn(3) =\u003e 4641588833612778892410076350919446576\n(10**110).iroot 4   =\u003e 3162277660168379331998893544\n(10**110).iroot(5)  =\u003e 10000000000000000000000\n(10**110).irootn(6) =\u003e 2154434690031883721\n(10**110).irootn(7) =\u003e 5179474679231211\n(10**110).irootn(8) =\u003e 56234132519034\n(10**110).iroot(9)  =\u003e 1668100537200\n(10**110).iroot 10  =\u003e 100000000000\n```\n\n**root**\n```\nUse syntax:  val.root(n,{k})\nroot(n,k=0) n is root 1/n exponent,  integer \u003e 0\n            k is nth ccw root 1..n , integer \u003e=0\nIf k not given default root returned, which are:\nfor +val =\u003e real root  |val**(1.0/n)|\nfor -val =\u003e real root -|val**(1.0/n)| when n is odd\nfor -val =\u003e first ccw complex root    when n is even\n\n9.root(2) =\u003e 3.0\n-32.root(5,3) =\u003e (-2.0+0.0i)\n73.root 6 =\u003e 2.04434322\n73.root 6,1 =\u003e (2.04434322+0.0i)\n(-100.43).root 6,6 =\u003e (1.86712994-1.07798797i)\nComplex(3,19).root 7,4 =\u003e (-1.47939161+0.37266673i)\n```\n\n**roots**\n```\nUse syntax:  val.roots(n,{opt})\nroots(n,opt=0) n is root 1/n exponent, integer \u003e 0\n               opt, optional string input, are:\n   0   : default (no input), return array of n ccw roots\n'c'|'C': complex, return array of complex roots\n'e'|'E': even, return array even numbered roots\n'o'|'O': odd , return array odd  numbered roots\n'i'|'I': imag, return array of imaginary roots\n'r'|'R': real, return array of real roots\nAn empty array is returned for an opt with no members.\n\n9348134943.roots(9); -89.roots(4,'real'); 2.2.roots 3,'Im'\nFor Ruby \u003e= 1.9 can also use a symbol as option: 384.roots 4,:r\n\nCan ask: How many complex roots of x: x.roots(n,'c').size\nWhat's the 3rd 5th root of (4+9i): Complex(4,9).root(5,3)\n\n8.roots 3 =\u003e [(2.0+0.0i), (-1.0+1.73205081i), (-1.0-1.73205081i)]\n```\n\n**Roots.digits_to_show**\n```\nWith version 1.1.0 this method was added to allow users to set\nand see the number of decimal digits displayed. If no input is\ngiven, the number of digits previously set is shown. The default\nvalue is 8. Providing an input value sets the number of digits to\ndisplay. An input value \u003c 1 will be set to a value of 1, to\ndisplay at least one decimal digit. An input greater than the\nmaximum digits shown for a given Ruby will display that maximum.\n\n\nRoots.digits_to_show =\u003e 8\n\n10.root 5 =\u003e 1.58489319\n\nRoots.digits_to_show 11 =\u003e 11\n\n10.root 5 =\u003e 1.58489319246\n\nRoots.digits_to_show 16 =\u003e 16\n\n10.root 5 =\u003e 1.5848931924611136\n\nRoots.digits_to_show 17 =\u003e 17\n\n10.root 5 =\u003e 1.5848931924611136\n\nRoots.digits_to_show 0 =\u003e 1\n\n10.root 5 =\u003e 1.6\n```\n\n## Mathematical Foundations\n\n```\nFor complex number (x+iy) = a*e^(i*arg) = a*[cos(arg) + i*sin(arg)]\n\nThe root values of a number are:\n\n1) root(n) = (x + iy)^(1/n)\n2) root(n) = (a*e^(i*arg))^(1/n)\n3) root(n,k) = (a*e^i*(arg + 2kPI))^(1/n)\n4) root(n,k) = a^(1/n)*(e^i*(arg + 2kPI))^(1/n)\n5) root(n,k) = |a^(1/n)|*e^i*(arg + 2kPI)/n\n6) root(n,k) = |a^(1/n)|*(cos(arg/n+2kPI/n) + i*sin(arg/n+2kPI/n))\n   define  mag = |a^(1/n)|, theta = arg/n, and delta = 2PI/n\n7) root(n,k)= mag*[cos(theta + k*delta) + i*sin(theta + k*delta)], k=0..n-1\n\nThus, there are n distinct roots (values).\n\nFor integer numbers:\n\nFor binary based (digital) computers (cpu), all integers are represented as\nbinary numbers. To find the root 'n' of an integer 'num' we can use the following\nprocess to find the largest integer nth 'root' such that root**n \u003c= num.\n\nFor an integer composed of 'b' bits an nth root 'n' will have at most (b/n + 1) bits.\n\nFor squareroots n = 2:\nFor 9 = 0b1001, it has b = 4 bits, and its squareroot has at most (4/2 + 1) = 3 bits.\nThe squareroot of 9 is 3 = 0b11, which is 2 bits.\n\nFor 100 = 0b1100100, b = 7, and its squareroot has at most (7/2 + 1) = 4 bits.\nThe squareroot of 100 is 10 = 0b1010, which is 4 bits.\n\nFor cuberoots n = 3:\nFor 8 = 0b1000, it has b = 4 bits, and its cuberoot has at most (4/3 + 1) = 2 bits.\nThe cuberoot of 8 is 2 = 0b10, which is 2 bits.\n\nFor 125 = 0b1111101, b = 7, and its cuberoot has at most (7/3 + 1) = 3 bits.\nThe cuberoot of 125 is 5 = 0b101, which is 3 bits.\n\nAlgorithm:\n           bits_shift = (num.bit_length)/n + 1   # determine max number of root bits\n           bitn_mask = 1 \u003c\u003c bits_shift           # set value for max bit position of root\n           root = 0                              # initialize the value for root\n           until bitn_mask == 0                  # step through all the bit positions for root\n             root |= bitn_mask                   # set current bit position to '1' in root\n             root ^= bitn_mask if root**n \u003e num  # set it back to '0' if root too large\n             bitn_mask \u003e\u003e= 1                     # set bitn_mask to next smaller bit position\n           end\n           root                                  # return exact integer value for root\n\nStarting with 2.1.0 Newton's method for squareroots is used instead of bbm.\nStarting with 2.2.0 Newton's method for general nth roots is used instead of bbm.\nhttps://en.wikipedia.org/wiki/Nth_root_algorithm\n```\n## Author\nJabari Zakiya\n\n## License\nGPL-2.0+\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjzakiya%2Froots","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjzakiya%2Froots","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjzakiya%2Froots/lists"}