{"id":13438126,"url":"https://github.com/jiggzson/nerdamer","last_synced_at":"2025-05-14T20:09:43.107Z","repository":{"id":10278913,"uuid":"12394395","full_name":"jiggzson/nerdamer","owner":"jiggzson","description":"a symbolic math expression evaluator for javascript","archived":false,"fork":false,"pushed_at":"2025-04-04T17:40:46.000Z","size":12805,"stargazers_count":523,"open_issues_count":80,"forks_count":84,"subscribers_count":24,"default_branch":"master","last_synced_at":"2025-04-14T16:53:24.771Z","etag":null,"topics":["algebra","calculus","differentiation","equation","expressions","fraction","fractions","integration","javascript","latex","math","solve-equations","solver","substitutions","symbolic"],"latest_commit_sha":null,"homepage":"http://www.nerdamer.com","language":"JavaScript","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/jiggzson.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"license.txt","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":"CITATION.cff","codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2013-08-27T01:59:14.000Z","updated_at":"2025-04-09T09:37:09.000Z","dependencies_parsed_at":"2024-01-16T01:27:47.490Z","dependency_job_id":"e6782304-fba0-4050-aa58-d7d86d8384ef","html_url":"https://github.com/jiggzson/nerdamer","commit_stats":null,"previous_names":[],"tags_count":35,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jiggzson%2Fnerdamer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jiggzson%2Fnerdamer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jiggzson%2Fnerdamer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jiggzson%2Fnerdamer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jiggzson","download_url":"https://codeload.github.com/jiggzson/nerdamer/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254219374,"owners_count":22034397,"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":["algebra","calculus","differentiation","equation","expressions","fraction","fractions","integration","javascript","latex","math","solve-equations","solver","substitutions","symbolic"],"created_at":"2024-07-31T03:01:03.075Z","updated_at":"2025-05-14T20:09:43.086Z","avatar_url":"https://github.com/jiggzson.png","language":"JavaScript","readme":"[![Build Status](https://travis-ci.org/jiggzson/nerdamer.svg?branch=master)](https://travis-ci.org/jiggzson/nerdamer)\r\n\r\nNerdamer\r\n========\r\n\r\nAs of version 0.5.0, the library is split into the core and optional add-ons which can be loaded after the core has been loaded.\r\n\r\n## UPDATE\r\nNerdamer is currently being ported to TypeScript. This will have substantial breaking changes. A full list of changes will be published with the official release. You can track the TypeScript port [here](https://github.com/jiggzson/nerdamer/tree/2.0)\r\n\r\n---\r\n\r\nNote: The Together-science project decided to pick up the banner where Nerdamer left off. See [Nerdamer-Prime](https://github.com/together-science/nerdamer-prime).\r\n\r\nGetting started with Nerdamer\r\n\r\nLoad the library in your html page\r\n\r\n```html\r\n\u003c!-- assuming you've saved the file in the root of course --\u003e\r\n\u003c!-- This the core and the only file needed if all you'll be doing is evaluating expresssions --\u003e\r\n\u003cscript src=\"nerdamer.core.js\"\u003e\u003c/script\u003e \r\n\u003c!-- LOAD ADD-ONS. These files contain extended functions. See documentation --\u003e\r\n\u003c!-- again assuming you've saved the files in root --\u003e\r\n\u003cscript src=\"Algebra.js\"\u003e\u003c/script\u003e\r\n\u003cscript src=\"Calculus.js\"\u003e\u003c/script\u003e\r\n\u003cscript src=\"Solve.js\"\u003e\u003c/script\u003e\r\n\u003cscript src=\"Extra.js\"\u003e\u003c/script\u003e\r\n```\r\nOr import everything\r\n```html\r\n\u003cscript src=\"all.min.js\"\u003e\u003c/script\u003e  \u003c!-- assuming you've saved the file in the root --\u003e\r\n```\r\nIf you're using node.js install it using `npm i nerdamer` and then\r\n\r\n```javascript\r\n// const cannot be used since nerdamer gets modified when other modules are loaded  \r\nvar nerdamer = require('nerdamer'); \r\n// Load additional modules. These are not required.  \r\nrequire('nerdamer/Algebra'); \r\nrequire('nerdamer/Calculus'); \r\nrequire('nerdamer/Solve'); \r\nrequire('nerdamer/Extra');\r\n```\r\nOr do a single import to import everything\r\n```javascript\r\nconst nerdamer = require(\"nerdamer/all.min\")\r\n```\r\n\r\nSome functions have dependencies from other add-ons. \r\n\r\nYou can see nerdamer in action at http://nerdamer.com/demo\r\n\r\nFor full documentation go to http://nerdamer.com/documentation\r\n\r\nAll operations are done using the 'nerdamer' object. \r\n\r\nTo add an expression just add it to the nerdamer object which will return a `Expression` object.\r\n\r\n```javascript             \r\nvar e = nerdamer('x^2+2*(cos(x)+x*x)');\r\nconsole.log(e.text());\r\n\r\n//result: \r\n//2*cos(x)+3*x^2\r\n```            \r\nIt is also possible to use `nerdamer` functions directly within the need for string manipulation of the input. The input will be parsed and the output will of type `Expression`. For example:\r\n```javascript\r\nvar ans = nerdamer.expand('(x-1)^5');\r\nconsole.log(ans.text());\r\n// -1-10*x^2-5*x^4+10*x^3+5*x+x^5\r\n\r\nvar sol = nerdamer.solve('x^2-4', 'x');\r\nconsole.log(sol.text())\r\n// [2,-2]\r\n```\r\n\r\nYou can also pass in an object with known values as the second parameter.\r\n\r\n```javascript             \r\nvar e = nerdamer('x^2+2*(cos(x)+x*x)',{x:6});\r\nconsole.log(e.text());\r\n\r\n//result:\r\n//108+2*cos(6)\r\n```            \r\n        \r\n\r\nAs you can see only the substitution is performed. To evaluate the result just call evaluate. \r\nNote that evaluate returns a text string or a number not an object.\r\n\r\n```javascript             \r\nvar e = nerdamer('x^2+2*(cos(x)+x*x)',{x:6}).evaluate();\r\nconsole.log(e.text());\r\n\r\n//result:\r\n//109.9203405733006\r\n```            \r\nTo get back the text as a fraction, call the text method and pass in the string 'fractions'.\r\n\r\n```javascript             \r\nvar e = nerdamer('x^2+2*(cos(x)+x*x)',{x:6}).evaluate();\r\nconsole.log(e.text('fractions'));\r\n\r\n//result:\r\n//429607273/3908351\r\n```    \r\nYou can get your expression back as LaTeX by calling the toTeX method\r\n```javascript             \r\nvar LaTeX = nerdamer('x^2+2*(cos(x)+x*x)',{x:0.25}).toTeX();\r\nconsole.log(LaTeX);\r\n\r\n//result:\r\n//2 \\cdot \\mathrm{cos}\\left(\\frac{1}{4}\\right)+\\frac{3}{16}\r\n```   \r\n\r\nTo have numbers returned as decimals pass in the string 'decimals' to the toTeX method\r\n\r\n```javascript             \r\nvar LaTeX = nerdamer('x^2+2*(cos(x)+x*x)',{x:0.25}).toTeX('decimal');\r\nconsole.log(LaTeX);\r\n\r\n//result:\r\n//2 \\cdot \\mathrm{cos}\\left(0.25\\right)+0.1875\r\n```   \r\n\r\nAlternatively you can pass an object containing known values into evaluate method instead. The values passed in don't have to be number they can be another expression if needed.\r\n\r\n```javascript             \r\nvar e = nerdamer('x^2+2*(cos(x)+x*x)',{x:'x^2+1'});\r\nconsole.log(e.text());\r\n\r\n//result:\r\n//2*cos(1+x^2)+3*(1+x^2)^2\r\n```            \r\n\r\nEvery time you parse an expression it's stored in nerdamer. To get a list of all the expressions you just call \r\nnerdamer.expressions().\r\n\r\n```javascript             \r\nvar knownValues = {x:'x^2+1'};\r\nnerdamer('x^2+2*(cos(x)+x*x)').evaluate(knownValues);\r\nnerdamer('sin(x)^2+cos(x)^2').evaluate(knownValues);\r\n\r\nconsole.log(nerdamer.expressions());\r\n\r\n//result:\r\n//[ 46.692712758272776, 1 ]\r\n```            \r\n\r\nYou can request it as an object as well by passing in true. This can be convenient in some \r\nsituations as the numbering starts at 1;\r\n\r\n```javascript             \r\nvar knownValues = {x:'x^2+1'};\r\nnerdamer('x^2+2*(cos(x)+x*x)', knownValues );\r\nnerdamer('sin(x)^2+cos(x)^2', knownValues );\r\n\r\nconsole.log(nerdamer.expressions(true));\r\n\r\n//{ '1': '2*cos(1+x^(2))+3*(1+x^(2))^(2)',\r\n//'2': 'cos(1+x^(2))^(2)+sin(1+x^(2))^(2)' }\r\n```            \r\n        \r\nFunctions aren't always immediately parsed to numbers. For example\r\n\r\n```javascript\r\nvar result = nerdamer('cos(x)',{x:6});\r\nconsole.log(result.text());\r\n//cos(6)\r\n```\r\nwill only subsitute out the variable name. To change this behaviour numer should be passed in as the 3rd argument.\r\n\r\n```javascript\r\nvar result = nerdamer('cos(x)',{x:6}, 'numer');\r\nconsole.log(result.text());\r\n//0.960170286650366\r\n```\r\nor alternatively\r\n\r\n```javascript\r\nvar result = nerdamer('cos(x)').evaluate({x:6});\r\nconsole.log(result.text());\r\n//0.960170286650366\r\n```\r\nThe difference however is that the first option directly substitutes the variables while the second first evaluates\r\nthe expression and then makes the substitutions. This library utilizes native javascript functions as much as possible. As a result it inherits whatever rounding errors they possess. One major change with version 0.6.0 however, is dealing with floating point issues.\r\n\r\n```javascript\r\nvar result = nerdamer('sqrt(x)*sqrt(x)-2', {x: 2});\r\nconsole.log(result.text());\r\n//0\r\n```\r\nThe above expample now returns zero whereas in previous version the result would be 4.440892098500626e-16. Same goes for 0.1+0.2.\r\n\r\nAn expression can be replaced directly by passing in the index of which expression to override. For example\r\n\r\n```javascript\r\nnerdamer('cos(x)',{x:6}, 'numer');\r\nnerdamer('sin(x)+y',{x:6}, null, 1);\r\nconsole.log(nerdamer.expressions());\r\n//[ 'sin(6)+y' ]\r\n```\r\n\r\nIf multiple modifier options need to be passed into nerdamer you can do so using an array. For example ...\r\n\r\n```javascript\r\nvar e = nerdamer('cos(x)+(y-x)^2', {x:7}, ['expand', 'numer']);\r\nconsole.log(e.text());\r\n//-14*y+y^2+49.7539022543433\r\n```\r\n\r\nIf you need the code as LaTeX you can pass in true as the second parameter when requesting the expressions.\r\n\r\n```javascript             \r\nnerdamer('x^2+2*(cos(x)+x*x)');\r\nnerdamer('sin(x)^0.25+cos(x)^0.5' );\r\nvar asObject = true;\r\nvar asLaTeX = true;\r\nconsole.log(nerdamer.expressions(asObject, asLaTeX));\r\n\r\n/*{ '1': '2 \\\\cdot \\\\mathrm{cos}\\\\left(x\\\\right)+3 \\\\cdot x^{2}',\r\n  '2': '\\\\sqrt{\\\\mathrm{cos}\\\\left(x\\\\right)}+\\\\mathrm{sin}\\\\left(x\\\\right)^{\\\\frac{1}{4}}' }*/\r\n```            \r\n        \r\n\r\nYou can specify a particular location when adding an expression, which is specified with the third parameter.\r\n\r\n```javascript \r\nnerdamer('x^2+2*(cos(x)+x*x)');\r\nnerdamer('sin(x)^0.25+cos(x)^0.5' );\r\nnerdamer('expr-override', undefined, 2 );\r\nvar asObject = false;\r\nvar asLaTeX = true;\r\nconsole.log(nerdamer.expressions(asObject, asLaTeX));\r\n\r\n/* [ '2 \\\\cdot \\\\mathrm{cos}\\\\left(x\\\\right)+3 \\\\cdot x^{2}',\r\n  '\\\\sqrt{\\\\mathrm{cos}\\\\left(x\\\\right)}+\\\\mathrm{sin}\\\\left(x\\\\right)^{\\\\frac{1}{4}}',\r\n  'expr-override' ]\r\n */\r\n```\r\n\r\nHere's an example of reserved variable and function names.\r\n\r\n```javascript \r\nvar reserved = nerdamer.reserved();\r\nconsole.log(reserved);\r\n//result:\r\n/* csc, sec, cot, erf, fact, mod, GCD, QGCD, LCM, pow, PI, E, cos, sin, tan, acos, asin, atan, sinh, cosh, tanh, asinh, acosh, atanh, exp, min, max, floor, ceil, round, vector, matrix, parens, sqrt, log, expand, abs, invert, transpose, dot */\r\n\r\n//or as an array\r\n\r\nvar reserved = nerdamer.reserved(true);\r\nconsole.log(reserved);\r\n//result:\r\n/* [ 'csc', 'sec', 'cot', 'erf', 'fact', 'mod', 'GCD', 'QGCD', 'LCM', 'pow', 'PI', 'E', 'cos', 'sin', 'tan', 'acos', 'asin', 'atan', 'sinh', 'cosh', 'tanh', 'asinh', 'acosh', 'atanh', 'exp', 'min', 'max', 'floor', 'ceil', 'round', 'vector', 'matrix',\r\n  'parens', 'sqrt', 'log', 'expand', 'abs', 'invert', 'transpose', 'dot' ]  */\r\n```            \r\n\r\nMost math functions are passed in as part of the expression. If you want to differentiate for instance you just use the function diff which is located in the Calculus add-on as of version 0.5.0\r\n\r\n```javascript             \r\nvar e = nerdamer('diff(x^2+2*(cos(x)+x*x),x)');\r\n\r\nconsole.log(e.text());\r\n\r\n//result: \r\n//-2*sin(x)+6*x\r\n```\r\n        \r\n\r\nNerdamer can also handle runtime functions. To do this use the method setFunction. \r\nThe runtime functions do have symbolic capabilities and support for imaginary numbers. \r\nThe setfunction method is used as follows:\r\n\r\nnerdamer.setFunction( function_name, parameter_array, function_body ) \r\n\r\nFor Example:\r\n\r\n```javascript             \r\n//generate some points\r\nvar f = function(x) { return 5*x-1; }\r\nconsole.log(f(1)); //4\r\nconsole.log(f(2)); //9 - value to be found\r\nconsole.log(f(7)); //34\r\n\r\nnerdamer.setFunction('interpolate',['y0','x0','y1','x1','x'],'y0+(y1-y0)*((x-x0)/(x1-x0))')\r\nvar answer = nerdamer('interpolate(4,1,34,7,2)').evaluate();\r\n\r\nconsole.log(answer);\r\n\r\n//result: 9\r\n```\r\n\r\nCustom functions alternatively be set in following manner.\r\n\r\n```javascript\r\nnerdamer('hyp(a, b) := sqrt(a^2 + b^2) ');\r\nvar result = nerdamer('hyp(3, 4)').evaluate().text();\r\nconsole.log(result);\r\n//result: 5\r\n```\r\n\r\n\r\nIf you need to add a constant use the setConstant method\r\n\r\n```javascript             \r\nnerdamer.setConstant( 'g', 9.81);\r\nvar weight = nerdamer('100*g').text();\r\nconsole.log(weight);\r\n//result:\r\n//981\r\n```            \r\n        \r\nTo delete just set it to delete\r\n\r\n```javascript             \r\nnerdamer.setConstant( 'g', 9.81);\r\nvar weight = nerdamer('100*g').text();\r\nconsole.log(weight);\r\n//981\r\nnerdamer.setConstant( 'g', 'delete');\r\nvar weight = nerdamer('100*g').text();\r\nconsole.log(weight);\r\n//100*g\r\n```        \r\n\r\nYou also have the option of exporting your function to a javascript function which can be useful if you need some \r\nfiltering from user input. Do keep in mind that the parameters are sorted alphabetically for more than one \r\nparameter. To use it add the expression to nerdamer and use the buildFunction method.\r\n\r\n```javascript             \r\nvar f = nerdamer('x^2+5').buildFunction();\r\nconsole.log(f(9));\r\n\r\n//result:\r\n//86\r\n```            \r\nIf you have a particular order in which you need the parameters to be set, then you pass in an array with the variables in the order in which you want them for instance:\r\n\r\n ```javascript\r\nvar f = nerdamer('z+x^2+y').buildFunction(['y', 'x', 'z']);\r\n console.log(f(9,2,1));\r\n //result\r\n //14\r\n ```\r\n\r\nEvery time you add an expression to nerdamer it's stored. To list the expressions currently in nerdamer call \r\nthe 'expressions' method. To delete an expression use the 'clear' method and pass in the expression you want to delete. \r\nTo clear everything pass in the string 'all'.\r\n\r\n```javascript            \r\nnerdamer('n*R*T/v');\r\nnerdamer('mc^2');\r\nnerdamer('G*m1*m2/d^2');\r\n\r\nnerdamer.clear(2);\r\n\r\nconsole.log(nerdamer.expressions(true));\r\n\r\n//result:\r\n//{ '1': 'R*T*n*v^(-1)', '2': 'G*d^(-2)*m1*m2' }\r\n\r\nnerdamer.clear('all');\r\nconsole.log(nerdamer.expressions(true));\r\n//result:\r\n//{}\r\n```            \r\n     \r\nIf you need go get the variables of an expression use the variables method. This method can be called after\r\nnerdamer was provided an expression. For example\r\n\r\n```javascript\r\nvar variables = nerdamer('csc(x*cos(y))-no_boring_x').variables();\r\nconsole.log(variables);\r\n//result:\r\n//[ 'no_boring_x', 'x', 'y' ]\r\n```\r\n\r\nThe order in which the variables appear require a little bit of knowledge of how nerdamer organizes symbols. For the\r\nsake of simplicity we'll just assume that there is no particular order   \r\n\r\n----------------------------------------------------------------------------------------------------------------------\r\n\r\nUsing the solver\r\n===============\r\nTo solve equations first load Solve.js. Just remember that Solve also required Algebra.js and Calculus.js to be loaded. You can then solve equations using nerdamer. Important: State the variable for which you are trying to solve.\r\n```javascript\r\nvar sol = nerdamer.solveEquations('x^3+8=x^2+6','x');\r\nconsole.log(sol.toString());\r\n//1+i,-i+1,-1\r\n```\r\n\r\nNotice that we use toString rather than text as this returns a javascript array.\r\n\r\nYou can also solve an expression\r\n```javascript\r\nvar e = nerdamer.solveEquations('x^2+4-y', 'y');\r\nconsole.log(e[0].text());\r\n//4+x^2\r\n```\r\n\r\nYou can also solve multivariate equations\r\n```javascript\r\nvar sol = nerdamer.solveEquations('x^2+8+y=x+6','x');\r\nconsole.log(sol.toString());\r\n//0.5*((-4*y-7)^0.5+1),0.5*(-(-4*y-7)^0.5+1)\r\n```\r\nYou can do up to 3rd order polynomials for multivariate polynomials\r\n\r\nAdditionally you can try for equations containing functions. This is more of a hit or miss approach unlike single variable polynomials (which uses Mr. David Binner's Jenkins-Traub port - http://www.akiti.ca/PolyRootRe.html) but it's there if you want to give it a try.\r\n\r\n```javascript\r\nvar sol = nerdamer.solveEquations('cos(x)+cos(3*x)=1','x');\r\nconsole.log(sol.toString());\r\n//5.7981235959208695,0.4850617112587174\r\n```\r\nTo solve a system of linear equations pass them in as an array. For example\r\n\r\n```javascript\r\nvar sol = nerdamer.solveEquations(['x+y=1', '2*x=6', '4*z+y=6']);\r\nconsole.log(sol);\r\n//[ [ 'x', 3 ], [ 'y', -2 ], [ 'z', 2 ] ]\r\n```\r\nIn version 0.7.2 and up the solver can additionally be used in the following way\r\n```javascript\r\n//first parse the equation\r\nvar x = nerdamer('x^2+2=y-7*a');\r\n//You can make substitutions to the equation\r\nx = x.evaluate({a: 'x^2-3'});\r\nconsole.log(x.toString()); //2+x^2=-7*x^2+21+y\r\nvar solutions = x.solveFor('x');\r\nconsole.log(solutions.toString()); //(1/16)*sqrt(32*y+608),(-1/16)*sqrt(32*y+608)\r\n```\r\n","funding_links":[],"categories":["JavaScript"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjiggzson%2Fnerdamer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjiggzson%2Fnerdamer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjiggzson%2Fnerdamer/lists"}