import { create, factory, all, MathJsFunctionName, fractionDependencies, addDependencies, divideDependencies, formatDependencies, } from 'mathjs'; /* Basic usage examples */ { const math = create(all); // functions and constants math.round(math.e, 3); math.round(100.123, 3); math.atan2(3, -3) / math.pi; math.log(10000, 10); math.sqrt(-4); math.pow([[-1, 2], [3, 1]], 2); const angle = 0.2; math.add(math.pow(math.sin(angle), 2), math.pow(math.cos(angle), 2)); // expressions math.evaluate('1.2 * (2 + 4.5)'); // chained operations const a = math.chain(3).add(4).multiply(2).done(); // 14 // mixed use of different data types in functions math.add(4, [5, 6]); // number + Array, [9, 10] math.multiply(math.unit('5 mm'), 3); // Unit * number, 15 mm math.subtract([2, 3, 4], 5); // Array - number, [-3, -2, -1] math.add(math.matrix([2, 3]), [4, 5]); // Matrix + Array, [6, 8] } /* Bignumbers examples */ { // configure the default type of numbers as BigNumbers const math = create(all, { number: 'BigNumber', precision: 20, }); { math.add(math.bignumber(0.1), math.bignumber(0.2)); // BigNumber, 0.3 math.divide(math.bignumber(0.3), math.bignumber(0.2)); // BigNumber, 1.5 } } /* Chaining examples */ { const math = create(all, {}); const a = math.chain(3).add(4).multiply(2).done(); // 14 // Another example, calculate square(sin(pi / 4)) const b = math.chain(math.pi).divide(4).sin().square().done(); // toString will return a string representation of the chain's value const chain = math.chain(2).divide(3); const str: string = chain.toString(); // "0.6666666666666666" chain.valueOf(); // the function subset can be used to get or replace sub matrices const array = [ [1, 2], [3, 4], ]; const v = math.chain(array).subset(math.index(1, 0)).done(); // 3 const m = math.chain(array).subset(math.index(0, 0), 8).multiply(3).done(); // filtering math .chain([-1, 0, 1.1, 2, 3, 1000]) .filter(math.isPositive) .filter(math.isInteger) .filter((n) => n !== 1000) .done(); // [2, 3] } /* Simplify examples */ { const math = create(all); math.simplify("2 * 1 * x ^ (2 - 1)"); math.simplify("2 * 3 * x", { x: 4 }); const f = math.parse("2 * 1 * x ^ (2 - 1)"); math.simplify(f); math.simplify("0.4 * x", {}, { exactFractions: true }); math.simplify("0.4 * x", {}, { exactFractions: false }); } /* Complex numbers examples */ { const math = create(all, {}); const a = math.complex(2, 3); // create a complex number by providing a string with real and complex parts const b = math.complex('3 - 7i'); // read the real and complex parts of the complex number { const x: number = a.re; const y: number = a.im; // adjust the complex value a.re = 5; } // clone a complex value { const clone = a.clone(); } // perform operations with complex numbers { math.add(a, b); math.multiply(a, b); math.sin(a); } // create a complex number from polar coordinates { const p: math.PolarCoordinates = { r: math.sqrt(2), phi: math.pi / 4 }; const c: math.Complex = math.complex(p); } // get polar coordinates of a complex number { const p: math.PolarCoordinates = math.complex(3, 4).toPolar(); } } /* Expressions examples */ { const math = create(all, {}); // evaluate expressions { math.evaluate('sqrt(3^2 + 4^2)'); } // evaluate multiple expressions at once { math.evaluate(['f = 3', 'g = 4', 'f * g']); } // get content of a parenthesis node { const node = math.parse('(1)'); const innerNode = node.content; } // scope can contain both variables and functions { const scope = { hello: (name: string) => `hello, ${name}!` }; math.evaluate('hello("hero")', scope); // "hello, hero!" } // define a function as an expression { const scope: any = { a: 3, b: 4, }; const f = math.evaluate('f(x) = x ^ a', scope); f(2); scope.f(2); } { const node2 = math.parse('x^a'); const code2: math.EvalFunction = node2.compile(); node2.toString(); } // 3. using function math.compile // parse an expression { // provide a scope for the variable assignment const code2 = math.compile('a = a + 3'); const scope = { a: 7 }; code2.evaluate(scope); } // 4. using a parser const parser = math.parser(); // get and set variables and functions { parser.evaluate('x = 7 / 2'); // 3.5 parser.evaluate('x + 3'); // 6.5 parser.evaluate('f(x, y) = x^y'); // f(x, y) parser.evaluate('f(2, 3)'); // 8 const x = parser.get('x'); const f = parser.get('f'); const y = parser.getAll(); const g = f(3, 3); parser.set('h', 500); parser.set('hello', (name: string) => `hello, ${name}!`); } // clear defined functions and variables parser.clear(); } /* Fractions examples */ { // configure the default type of numbers as Fractions const math = create(all, { number: 'Fraction', }); const x = math.fraction(0.125); const y = math.fraction('1/3'); math.fraction(2, 3); math.add(x, y); math.divide(x, y); // output formatting const a = math.fraction('2/3'); } /* Matrices examples */ { const math = create(all, {}); // create matrices and arrays. a matrix is just a wrapper around an Array, // providing some handy utilities. const a: math.Matrix = math.matrix([1, 4, 9, 16, 25]); const b: math.Matrix = math.matrix(math.ones([2, 3])); b.size(); // the Array data of a Matrix can be retrieved using valueOf() const array = a.valueOf(); // Matrices can be cloned const clone: math.Matrix = a.clone(); // perform operations with matrices math.sqrt(a); math.factorial(a); // create and manipulate matrices. Arrays and Matrices can be used mixed. { const a = [ [1, 2], [3, 4], ]; const b: math.Matrix = math.matrix([ [5, 6], [1, 1], ]); b.subset(math.index(1, [0, 1]), [[7, 8]]); const c = math.multiply(a, b); const f: math.Matrix = math.matrix([1, 0]); const d: math.Matrix = f.subset(math.index(1, 0)); } // get a sub matrix { const a: math.Matrix = math.diag(math.range(1, 4)); a.subset(math.index([1, 2], [1, 2])); const b: math.Matrix = math.range(1, 6); b.subset(math.index(math.range(1, 4))); } // resize a multi dimensional matrix { const a = math.matrix(); a.resize([2, 2, 2], 0); a.size(); a.resize([2, 2]); a.size(); } // can set a subset of a matrix to uninitialized { const m = math.matrix(); m.subset(math.index(2), 6, math.uninitialized); } // create ranges { math.range(1, 6); math.range(0, 18, 3); math.range('2:-1:-3'); math.factorial(math.range('1:6')); } // map matrix { math.map([1, 2, 3], function (value) { return value * value; }); // returns [1, 4, 9] } // filter matrix { math.filter([6, -2, -1, 4, 3], function (x) { return x > 0; }); // returns [6, 4, 3] math.filter(['23', 'foo', '100', '55', 'bar'], /[0-9]+/); // returns ["23", "100", "55"] } // concat matrix { math.concat([[0, 1, 2]], [[1, 2, 3]]); // returns [[ 0, 1, 2, 1, 2, 3 ]] math.concat([[0, 1, 2]], [[1, 2, 3]], 0); // returns [[ 0, 1, 2 ], [ 1, 2, 3 ]] } } /* Sparse matrices examples */ { const math = create(all, {}); // create a sparse matrix const a = math.identity(1000, 1000, 'sparse'); // do operations with a sparse matrix const b = math.multiply(a, a); const c = math.multiply(b, math.complex(2, 2)); const d = math.matrix([0, 1]); const e = math.transpose(d); const f = math.multiply(e, a); } /* Units examples */ { const math = create(all, {}); // units can be created by providing a value and unit name, or by providing // a string with a valued unit. const a = math.unit(45, 'cm'); // 450 mm const b = math.unit('0.1m'); // 100 mm // creating units math.createUnit('foo'); math.createUnit('furlong', '220 yards'); math.createUnit('furlong', '220 yards', { override: true }); math.createUnit('testunit', { definition: '0.555556 kelvin', offset: 459.67 }); math.createUnit('testunit', { definition: '0.555556 kelvin', offset: 459.67 }, { override: true }); math.createUnit('knot', { definition: '0.514444 m/s', aliases: ['knots', 'kt', 'kts'] }); math.createUnit('knot', { definition: '0.514444 m/s', aliases: ['knots', 'kt', 'kts'] }, { override: true }); math.createUnit( 'knot', { definition: '0.514444 m/s', aliases: ['knots', 'kt', 'kts'], prefixes: 'long', }, { override: true } ); math.createUnit( { foo_2: { prefixes: 'long', }, bar: '40 foo', baz: { definition: '1 bar/hour', prefixes: 'long', }, }, { override: true, } ); // use Unit as definition math.createUnit('c', { definition: b }); math.createUnit('c', { definition: b }, { override: true }); // units can be added, subtracted, and multiplied or divided by numbers and by other units math.add(a, b); math.multiply(b, 2); math.divide(math.unit('1 m'), math.unit('1 s')); math.pow(math.unit('12 in'), 3); // units can be converted to a specific type, or to a number b.to('cm'); math.to(b, 'inch'); b.toNumber('cm'); math.number(b, 'cm'); // the expression parser supports units too math.evaluate('2 inch to cm'); // units can be converted to SI math.unit('1 inch').toSI(); // units can be split into other units math.unit('1 m').splitUnit(['ft', 'in']); } /* Expression tree examples */ { const math = create(all, {}); // Filter an expression tree const node: math.MathNode = math.parse('x^2 + x/4 + 3*y'); const filtered: math.MathNode[] = node.filter((node: math.MathNode) => node.isSymbolNode && node.name === 'x'); const arr: string[] = filtered.map((node: math.MathNode) => node.toString()); // Traverse an expression tree const node1: math.MathNode = math.parse('3 * x + 2'); node1.traverse((node: math.MathNode, path: string, parent: math.MathNode) => { switch (node.type) { case 'OperatorNode': return node.type === 'OperatorNode'; case 'ConstantNode': return node.type === 'ConstantNode'; case 'SymbolNode': return node.type === 'SymbolNode'; default: return node.type === 'any string at all'; } }); } /* Function floor examples */ { const math = create(all, {}); // number input math.floor(3.2); // returns number 3 math.floor(-4.2); // returns number -5 // number input // roundoff result to 2 decimals math.floor(3.212, 2); // returns number 3.21 math.floor(-4.212, 2); // returns number -4.22 // Complex input const c = math.complex(3.24, -2.71); // returns Complex 3 - 3i math.floor(c); // returns Complex 3 - 3i math.floor(c, 1); // returns Complex 3.2 - 2.8i //array input math.floor([3.2, 3.8, -4.7]); // returns Array [3, 3, -5] math.floor([3.21, 3.82, -4.71], 1); // returns Array [3.2, 3.8, -4.8] } /* JSON serialization/deserialization */ { const math = create(all, {}); const data = { bigNumber: math.bignumber('1.5'), }; const stringified = JSON.stringify(data); const parsed = JSON.parse(stringified, math.json.reviver); parsed.bigNumber === math.bignumber('1.5'); // true } /* Extend functionality with import */ declare module 'mathjs' { interface MathJsStatic { testFun(): number; value: number; } } { const math = create(all, {}); const testFun = () => 5; math.import( { testFun, value: 10, }, {} ); math.testFun(); const a = math.value * 2; } /* Renamed functions from v5 => v6 */ { const math = create(all, {}); math.typeOf(1); math.variance([1, 2, 3, 4]); math.evaluate('1 + 2'); // chained operations math.chain(3).typeOf().done(); math.chain([1, 2, 3]).variance().done(); math.chain('1 + 2').evaluate().done(); } /* Factory Test */ { // create a factory function const name = 'negativeSquare'; const dependencies: MathJsFunctionName[] = ['multiply', 'unaryMinus']; const createNegativeSquare = factory(name, dependencies, (injected) => { const { multiply, unaryMinus } = injected; return function negativeSquare(x: number): number { return unaryMinus(multiply(x, x)); }; }); // create an instance of the function yourself: const multiply = (a: number, b: number) => a * b; const unaryMinus = (a: number) => -a; const negativeSquare = createNegativeSquare({ multiply, unaryMinus }); negativeSquare(3); } /** * Dependency map typing test from mathjs official document: * https://mathjs.org/docs/custom_bundling.html#using-just-a-few-functions */ { const config = { // optionally, you can specify configuration }; // Create just the functions we need const { fraction, add, divide, format } = create( { fractionDependencies, addDependencies, divideDependencies, formatDependencies, }, config ); // Use the created functions const a = fraction(1, 3); const b = fraction(3, 7); const c = add(a, b); const d = divide(a, b); console.log('c =', format(c)); // outputs "c = 16/21" console.log('d =', format(d)); // outputs "d = 7/9" } /** * Custom parsing functions * https://mathjs.org/docs/expressions/customization.html#customize-supported-characters */ { const math = create(all, {}); const isAlphaOriginal = math.parse.isAlpha; math.parse.isAlpha = (c, cPrev, cNext) => { return isAlphaOriginal(c, cPrev, cNext) || c === "\u260E"; }; // now we can use the \u260E (phone) character in expressions const result = math.evaluate("\u260Efoo", { "\u260Efoo": 42 }); // returns 42 console.log(result); } /** * Util functions * https://mathjs.org/docs/reference/functions.html#utils-functions */ { const math = create(all, {}); // hasNumericValue function math.hasNumericValue(2); // returns true math.hasNumericValue('2'); // returns true math.isNumeric('2'); // returns false math.hasNumericValue(0); // returns true math.hasNumericValue(math.bignumber(500)); // returns true math.hasNumericValue([2.3, 'foo', false]); // returns [true, false, true] math.hasNumericValue(math.fraction(4)); // returns true math.hasNumericValue(math.complex('2-4i')); // returns false }