Nerdamer
a symbolic math expression evaluator for javascript
Install / Use
/learn @jiggzson/NerdamerREADME
Nerdamer
As 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.
UPDATE
April, 2025 Nerdamer 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
March, 2026 The TS port is mostly complete. The work is ongoing depending on available time.
Note: The Together-science project decided to pick up the banner where Nerdamer left off. See Nerdamer-Prime.
Getting started with Nerdamer
Load the library in your html page
<!-- assuming you've saved the file in the root of course -->
<!-- This the core and the only file needed if all you'll be doing is evaluating expresssions -->
<script src="nerdamer.core.js"></script>
<!-- LOAD ADD-ONS. These files contain extended functions. See documentation -->
<!-- again assuming you've saved the files in root -->
<script src="Algebra.js"></script>
<script src="Calculus.js"></script>
<script src="Solve.js"></script>
<script src="Extra.js"></script>
Or import everything
<script src="all.min.js"></script>
<!-- assuming you've saved the file in the root -->
If you're using node.js install it using npm i nerdamer and then
// const cannot be used since nerdamer gets modified when other modules are loaded
var nerdamer = require('nerdamer');
// Load additional modules. These are not required.
require('nerdamer/Algebra');
require('nerdamer/Calculus');
require('nerdamer/Solve');
require('nerdamer/Extra');
Or do a single import to import everything
const nerdamer = require('nerdamer/all.min');
Some functions have dependencies from other add-ons.
You can see nerdamer in action at http://nerdamer.com/demo
For full documentation go to http://nerdamer.com/documentation
All operations are done using the 'nerdamer' object.
To add an expression just add it to the nerdamer object which will return a Expression object.
var e = nerdamer('x^2+2*(cos(x)+x*x)');
console.log(e.text());
//result:
//2*cos(x)+3*x^2
It 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:
var ans = nerdamer.expand('(x-1)^5');
console.log(ans.text());
// -1-10*x^2-5*x^4+10*x^3+5*x+x^5
var sol = nerdamer.solve('x^2-4', 'x');
console.log(sol.text());
// [2,-2]
You can also pass in an object with known values as the second parameter.
var e = nerdamer('x^2+2*(cos(x)+x*x)', { x: 6 });
console.log(e.text());
//result:
//108+2*cos(6)
As you can see only the substitution is performed. To evaluate the result just call evaluate. Note that evaluate returns a text string or a number not an object.
var e = nerdamer('x^2+2*(cos(x)+x*x)', { x: 6 }).evaluate();
console.log(e.text());
//result:
//109.9203405733006
To get back the text as a fraction, call the text method and pass in the string 'fractions'.
var e = nerdamer('x^2+2*(cos(x)+x*x)', { x: 6 }).evaluate();
console.log(e.text('fractions'));
//result:
//429607273/3908351
You can get your expression back as LaTeX by calling the toTeX method
var LaTeX = nerdamer('x^2+2*(cos(x)+x*x)', { x: 0.25 }).toTeX();
console.log(LaTeX);
//result:
//2 \cdot \mathrm{cos}\left(\frac{1}{4}\right)+\frac{3}{16}
To have numbers returned as decimals pass in the string 'decimals' to the toTeX method
var LaTeX = nerdamer('x^2+2*(cos(x)+x*x)', { x: 0.25 }).toTeX('decimal');
console.log(LaTeX);
//result:
//2 \cdot \mathrm{cos}\left(0.25\right)+0.1875
Alternatively 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.
var e = nerdamer('x^2+2*(cos(x)+x*x)', { x: 'x^2+1' });
console.log(e.text());
//result:
//2*cos(1+x^2)+3*(1+x^2)^2
Every time you parse an expression it's stored in nerdamer. To get a list of all the expressions you just call nerdamer.expressions().
var knownValues = { x: 'x^2+1' };
nerdamer('x^2+2*(cos(x)+x*x)').evaluate(knownValues);
nerdamer('sin(x)^2+cos(x)^2').evaluate(knownValues);
console.log(nerdamer.expressions());
//result:
//[ 46.692712758272776, 1 ]
You can request it as an object as well by passing in true. This can be convenient in some situations as the numbering starts at 1;
var knownValues = { x: 'x^2+1' };
nerdamer('x^2+2*(cos(x)+x*x)', knownValues);
nerdamer('sin(x)^2+cos(x)^2', knownValues);
console.log(nerdamer.expressions(true));
//{ '1': '2*cos(1+x^(2))+3*(1+x^(2))^(2)',
//'2': 'cos(1+x^(2))^(2)+sin(1+x^(2))^(2)' }
Functions aren't always immediately parsed to numbers. For example
var result = nerdamer('cos(x)', { x: 6 });
console.log(result.text());
//cos(6)
will only subsitute out the variable name. To change this behaviour numer should be passed in as the 3rd argument.
var result = nerdamer('cos(x)', { x: 6 }, 'numer');
console.log(result.text());
//0.960170286650366
or alternatively
var result = nerdamer('cos(x)').evaluate({ x: 6 });
console.log(result.text());
//0.960170286650366
The difference however is that the first option directly substitutes the variables while the second first evaluates the 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.
var result = nerdamer('sqrt(x)*sqrt(x)-2', { x: 2 });
console.log(result.text());
//0
The above expample now returns zero whereas in previous version the result would be 4.440892098500626e-16. Same goes for 0.1+0.2.
An expression can be replaced directly by passing in the index of which expression to override. For example
nerdamer('cos(x)', { x: 6 }, 'numer');
nerdamer('sin(x)+y', { x: 6 }, null, 1);
console.log(nerdamer.expressions());
//[ 'sin(6)+y' ]
If multiple modifier options need to be passed into nerdamer you can do so using an array. For example ...
var e = nerdamer('cos(x)+(y-x)^2', { x: 7 }, ['expand', 'numer']);
console.log(e.text());
//-14*y+y^2+49.7539022543433
If you need the code as LaTeX you can pass in true as the second parameter when requesting the expressions.
nerdamer('x^2+2*(cos(x)+x*x)');
nerdamer('sin(x)^0.25+cos(x)^0.5');
var asObject = true;
var asLaTeX = true;
console.log(nerdamer.expressions(asObject, asLaTeX));
/*{ '1': '2 \\cdot \\mathrm{cos}\\left(x\\right)+3 \\cdot x^{2}',
'2': '\\sqrt{\\mathrm{cos}\\left(x\\right)}+\\mathrm{sin}\\left(x\\right)^{\\frac{1}{4}}' }*/
You can specify a particular location when adding an expression, which is specified with the third parameter.
nerdamer('x^2+2*(cos(x)+x*x)');
nerdamer('sin(x)^0.25+cos(x)^0.5');
nerdamer('expr-override', undefined, 2);
var asObject = false;
var asLaTeX = true;
console.log(nerdamer.expressions(asObject, asLaTeX));
/* [ '2 \\cdot \\mathrm{cos}\\left(x\\right)+3 \\cdot x^{2}',
'\\sqrt{\\mathrm{cos}\\left(x\\right)}+\\mathrm{sin}\\left(x\\right)^{\\frac{1}{4}}',
'expr-override' ]
*/
Here's an example of reserved variable and function names.
var reserved = nerdamer.reserved();
console.log(reserved);
//result:
/* 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 */
//or as an array
var reserved = nerdamer.reserved(true);
console.log(reserved);
//result:
/* [ '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' ] */
Most 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
var e = nerdamer('diff(x^2+2*(cos(x)+x*x),x)');
console.log(e.text());
//result:
//-2*sin(x)+6*x
Nerdamer can also handle runtime functions. To do this use the method setFunction. The runtime functions do have symbolic capabilities and support for imaginary numbers. The setfunction method is used as follows:
nerdamer.setFunction( function_name, parameter_array, function_body )
For Example:
//generate some points
var f = function (x) {
return 5 * x - 1;
};
console.log(f(1)); //4
console.log(f(2)); //9 - value to be found
console.log(f(7)); //34
nerdamer.setFunction('interpolate', ['y0', 'x0', 'y1', 'x1', 'x'], 'y0+(y1-y0)*((x-x0)/(x1-x0))');
var answer = nerdamer('interpolate(4,1,34,7,2)').evaluate();
console.log(answer);
//result: 9
Custom functions alternatively be set in following manner.
nerdamer('hyp(a, b) := sqrt(a^2 + b^2) ');
var result = nerdamer('hyp(
Related Skills
node-connect
336.2kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
frontend-design
82.8kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
openai-whisper-api
336.2kTranscribe audio via OpenAI Audio Transcriptions API (Whisper).
commit-push-pr
82.8kCommit, push, and open a PR
