Supported operators of .math()
Expression syntax
This page describes the syntax of expression parser of Mathlion. It describes how to work with the available data types, functions, operators, variables, and more.
Operators
The expression parser has operators for all common arithmetic operations such as addition and multiplication. The expression parser uses conventional infix notation for operators: an operator is placed between its arguments. Round parentheses can be used to override the default precedence of operators.
The following operators are available:
Operator | Name | Syntax | Associativity | Example | Result |
---|---|---|---|---|---|
( , ) |
Grouping | (x) |
None | 2 * (3 + 4) |
14 |
[ , ] |
Matrix, Index | [...] |
None | [[1,2],[3,4]] |
[[1,2],[3,4]] |
{ , } |
Object | {...} |
None | {a: 1, b: 2} |
{a: 1, b: 2} |
, |
Parameter separator | x, y |
Left to right | max(2, 1, 5) |
5 |
. |
Property accessor | obj.prop |
Left to right | obj={a: 12}; obj.a |
12 |
; |
Statement separator | x; y |
Left to right | a=2; b=3; a*b |
[6] |
; |
Row separator | [x, y] |
Left to right | [1,2;3,4] |
[[1,2],[3,4]] |
\n |
Statement separator | x \n y |
Left to right | a=2 \n b=3 \n a*b |
[2,3,6] |
+ |
Add | x + y |
Left to right | 4 + 5 |
9 |
+ |
Unary plus | +y |
Right to left | +4 |
4 |
- |
Subtract | x - y |
Left to right | 7 - 3 |
4 |
- |
Unary minus | -y |
Right to left | -4 |
-4 |
* |
Multiply | x * y |
Left to right | 2 * 3 |
6 |
.* |
Element-wise multiply | x .* y |
Left to right | [1,2,3] .* [1,2,3] |
[1,4,9] |
/ |
Divide | x / y |
Left to right | 6 / 2 |
3 |
./ |
Element-wise divide | x ./ y |
Left to right | [9,6,4] ./ [3,2,2] |
[3,3,2] |
% , mod |
Modulus | x % y |
Left to right | 8 % 3 |
2 |
^ |
Power | x ^ y |
Right to left | 2 ^ 3 |
8 |
.^ |
Element-wise power | x .^ y |
Right to left | [2,3] .^ [3,3] |
[9,27] |
' |
Transpose | y' |
Left to right | [[1,2],[3,4]]' |
[[1,3],[2,4]] |
! |
Factorial | y! |
Left to right | 5! |
120 |
& |
Bitwise and | x & y |
Left to right | 5 & 3 |
1 |
~ |
Bitwise not | ~x |
Right to left | ~2 |
-3 |
| |
Bitwise or | x | y |
Left to right | 5 | 3 |
7 |
^| |
Bitwise xor | x ^| y |
Left to right | 5 ^| 2 |
6 |
<< |
Left shift | x << y |
Left to right | 4 << 1 |
8 |
>> |
Right arithmetic shift | x >> y |
Left to right | 8 >> 1 |
4 |
>>> |
Right logical shift | x >>> y |
Left to right | -8 >>> 1 |
2147483644 |
and |
Logical and | x and y |
Left to right | true and false |
false |
not |
Logical not | not y |
Right to left | not true |
false |
or |
Logical or | x or y |
Left to right | true or false |
true |
xor |
Logical xor | x xor y |
Left to right | true xor true |
false |
= |
Assignment | x = y |
Right to left | a = 5 |
5 |
? : |
Conditional expression | x ? y : z |
Right to left | 15 > 100 ? 1 : -1 |
-1 |
: |
Range | x : y |
Right to left | 1:4 |
[1,2,3,4] |
to , in |
Unit conversion | x to y |
Left to right | 2 inch to cm |
5.08 cm |
== |
Equal | x == y |
Left to right | 2 == 4 - 2 |
true |
!= |
Unequal | x != y |
Left to right | 2 != 3 |
true |
< |
Smaller | x < y |
Left to right | 2 < 3 |
true |
> |
Larger | x > y |
Left to right | 2 > 3 |
false |
<= |
Smallereq | x <= y |
Left to right | 4 <= 3 |
false |
>= |
Largereq | x >= y |
Left to right | 2 + 4 >= 6 |
true |
Since in mathlion every variable is an array the operators *
,/
,^
are converted in background to .*
,./
,.^
to allow for a more intuitive writing of the equations.
Precedence
The operators have the following precedence, from highest to lowest:
Operators | Description |
---|---|
(...) [...] {...} |
Grouping Matrix Object |
x(...) x[...] obj.prop : |
Function call Matrix index Property accessor Key/value separator |
' |
Matrix transpose |
! |
Factorial |
^ , .^ |
Exponentiation |
+ , - , ~ , not |
Unary plus, unary minus, bitwise not, logical not |
x unit |
Unit |
* , / , .* , ./ , % , mod |
Multiply, divide, modulus, implicit multiply |
+ , - |
Add, subtract |
: |
Range |
to , in |
Unit conversion |
<< , >> , >>> |
Bitwise left shift, bitwise right arithmetic shift, bitwise right logical shift |
== , != , < , > , <= , >= |
Relational |
& |
Bitwise and |
^| |
Bitwise xor |
| |
Bitwise or |
and |
Logical and |
xor |
Logical xor |
or |
Logical or |
? , : |
Conditional expression |
= |
Assignment |
, |
Parameter and column separator |
; |
Row separator |
\n , ; |
Statement separators |
Functions
Functions are called by entering their name, followed by zero or more arguments enclosed by parentheses.
('sqrt(25)'); // 5
('log(1000, 3 + 7)'); // 4
('sin(pi / 4)'); // 0.7071067811865475
New functions can be defined using the function
keyword. Functions can be
defined with multiple variables. Function assignments are limited: they can
only be defined on a single line.
('f(x) = x ^ 2 - 5');
('f(2)'); // -1
('f(3)'); // 4
('g(x, y) = x ^ y');
('g(2, 3)'); // 8
Constants and variables
Mathlion has a number of built-in constants such as pi
and e
.
// use constants
('pi'); // 3.141592653589793
('e ^ 2'); // 7.3890560989306495
('log(e)'); // 1
('e ^ (pi * i) + 1'); // ~0 (Euler)
Variables can be defined using the assignment operator =
, and can be used
like constants.
// define variables
('a = 3.4'); // 3.4
('b = 5 / 2'); // 2.5
// use variables
('a * b'); // 8.5
Data types
The expression parser supports booleans, numbers, complex numbers, units, strings, matrices, and objects.
Booleans
Booleans true
and false
can be used in expressions.
// use booleans
('true'); // true
('false'); // false
('(2 == 3) == false'); // true
Booleans can be converted to numbers and strings and vice versa using the
functions number
and boolean
, and string
.
// convert booleans
('number(true)'); // 1
('string(false)'); // "false"
('boolean(1)'); // true
('boolean("false")'); // false
Numbers
The most important and basic data type in Mathlion are numbers. Numbers use a point as decimal mark. Numbers can be entered with exponential notation. Examples:
// numbers in Mathlion
('2'); // 2
('3.14'); // 3.14
('1.4e3'); // 1400
('22e-3'); // 0.022
A number can be converted to a string and vice versa using the functions
number
and string
.
// convert a string into a number
('number("2.3")'); // 2.3
('string(2.3)'); // "2.3"
Mathlion uses regular JavaScript numbers, which are floating points with a limited precision and limited range.
('1e-325'); // 0
('1e309'); // Infinity
('-1e309'); // -Infinity
When doing calculations with floats, one can very easily get round-off errors:
// round-off error due to limited floating point precision
('0.1 + 0.2'); // 0.30000000000000004
When outputting results, the function math.format
can be used to hide
these round-off errors when outputting results for the user:
var ans = ('0.1 + 0.2'); // 0.30000000000000004
math.format(ans, {precision: 14}); // "0.3"
BigNumbers
Mathlion supports BigNumbers for calculations with an arbitrary precision.
BigNumbers are slower but have a higher precision. Calculations with big numbers are supported only by arithmetic functions.
BigNumbers can be created using the bignumber
function:
('bignumber(0.1) + bignumber(0.2)'); // BigNumber, 0.3
The default number type of the expression parser can be changed at instantiation of Mathlion. The expression parser parses numbers as BigNumber by default:
// Configure the type of number: 'number' (default), 'BigNumber', or 'Fraction'
math.config({number: 'BigNumber'});
// all numbers are parsed as BigNumber
('0.1 + 0.2'); // BigNumber, 0.3
BigNumbers can be converted to numbers and vice versa using the functions
number
and bignumber
. When converting a BigNumber to a Number, the high
precision of the BigNumber will be lost. When a BigNumber is too large to be represented
as Number, it will be initialized as Infinity
.
Complex numbers
Complex numbers can be created using the imaginary unit i
, which is defined
as i^2 = -1
. Complex numbers have a real and complex part, which can be
retrieved using the functions re
and im
.
var parser = math.parser();
// create complex numbers
('a = 2 + 3i'); // Complex, 2 + 3i
('b = 4 - i'); // Complex, 4 - i
// get real and imaginary part of a complex number
('re(a)'); // Number, 2
('im(a)'); // Number, 3
// calculations with complex numbers
('a + b'); // Complex, 6 + 2i
('a * b'); // Complex, 11 + 10i
('i * i'); // Number, -1
('sqrt(-4)'); // Complex, 2i
Mathlion does not automatically convert complex numbers with an imaginary part
of zero to numbers. They can be converted to a number using the function
number
.
// convert a complex number to a number
var parser = math.parser();
('a = 2 + 3i'); // Complex, 2 + 3i
('b = a - 3i'); // Complex, 2 + 0i
('number(b)'); // Number, 2
('number(a)'); // Error: 2 + i is no valid number
Strings
Strings are enclosed by double quotes ". Strings can be concatenated using the
function concat
(not by adding them using +
like in JavaScript). Parts of
a string can be retrieved or replaced by using indexes. Strings can be converted
to a number using function number
, and numbers can be converted to a string
using function string
.
// create a string
('"hello"'); // String, "hello"
// string manipulation
('a = concat("hello", " world")'); // String, "hello world"
('size(a)'); // Number, 11
('a[1:5]'); // String, "hello"
('a[1] = "H"'); // String, "Hello"
('a[7:12] = "there!"'); // String, "Hello there!"
// string conversion
('number("300")'); // Number, 300
('string(300)'); // String, "300"
Strings can be used in the eval
function, to parse expressions inside
the expression parser:
('eval("2 + 3")'); // 5
Matrices
Matrices can be created by entering a series of values between square brackets,
elements are separated by a comma ,
.
A matrix like [1, 2, 3]
will create a vector, a 1-dimensional matrix with
size [3]
. To create a multi-dimensional matrix, matrices can be nested into
each other. For easier creation of two-dimensional matrices, a semicolon ;
can be used to separate rows in a matrix.
// create a matrix
('[1, 2, 3]'); // Matrix, size [3]
('[[1, 2, 3], [4, 5, 6]]'); // Matrix, size [2, 3]
('[[[1, 2], [3, 4]], [[5, 6], [7, 8]]]'); // Matrix, size [2, 2, 2]
// create a two dimensional matrix
('[1, 2, 3; 4, 5, 6]'); // Matrix, size [2, 3]
Another way to create filled matrices is using the functions zeros
, ones
,
eye
, and range
.
// initialize a matrix with ones or zeros
('zeros(3, 2)'); // Matrix, [[0, 0], [0, 0], [0, 0]], size [3, 2]
('ones(3)'); // Matrix, [1, 1, 1], size [3]
('5 * ones(2, 2)'); // Matrix, [[5, 5], [5, 5]], size [2, 2]
// create an identity matrix
('eye(2)'); // Matrix, [[1, 0], [0, 1]], size [2, 2]
// create a range
('1:4'); // Matrix, [1, 2, 3, 4], size [4]
('0:2:10'); // Matrix, [0, 2, 4, 6, 8, 10], size [6]
A subset can be retrieved from a matrix using indexes and a subset of a matrix
can be replaced by using indexes. Indexes are enclosed in square brackets, and
contain a number or a range for each of the matrix dimensions. A range can have
its start and/or end undefined. When the start is undefined, the range will start
at 1, when the end is undefined, the range will end at the end of the matrix.
There is a context variable end
available as well to denote the end of the
matrix.
// create matrices
('a = [1, 2; 3, 4]'); // Matrix, [[1, 2], [3, 4]]
('b = zeros(2, 2)'); // Matrix, [[0, 0], [0, 0]]
('c = 5:9'); // Matrix, [5, 6, 7, 8, 9]
// replace a subset in a matrix
('b[1, 1:2] = [5, 6]'); // Matrix, [[5, 6], [0, 0]]
('b[2, :] = [7, 8]'); // Matrix, [[5, 6], [7, 8]]
// perform a matrix calculation
('d = a * b'); // Matrix, [[19, 22], [43, 50]]
// retrieve a subset of a matrix
('d[2, 1]'); // 43
('d[2, 1:end]'); // Matrix, [[43, 50]]
('c[end - 1 : -1 : 2]'); // Matrix, [8, 7, 6]
Objects
Objects in Mathlion work the same as in languages like JavaScript and Python.
An object is enclosed by square brackets {
, }
, and contains a set of
comma separated key/value pairs. Keys and values are separated by a colon :
.
Keys can be a symbol like prop
or a string like "prop"
.
('{a: 2 + 1, b: 4}'); // {a: 3, b: 4}
('{"a": 2 + 1, "b": 4}'); // {a: 3, b: 4}
Objects can contain objects:
('{a: 2, b: {c: 3, d: 4}}'); // {a: 2, b: {c: 3, d: 4}}
Object properties can be retrieved or replaced using dot notation or bracket notation. Unlike JavaScript, when setting a property value, the whole object is returned, not the property value
var scope = {
obj: {
prop: 42
}
};
// retrieve properties
('obj.prop', scope); // 42
('obj["prop"]', scope); // 42
// set properties (returns the whole object, not the property value!)
('obj.prop = 43', scope); // {prop: 43}
('obj["prop"] = 43', scope); // {prop: 43}
scope.obj; // {prop: 43}
Multi-line expressions
An expression can contain multiple lines, and expressions can be spread over
multiple lines. Lines can be separated by a newline character \n
or by a
semicolon ;
. Output of statements followed by a semicolon will be hidden from
the output, and empty lines are ignored. The output is returned as a ResultSet
,
with an entry for every visible statement.
// a multi-line expression
('1 * 3 \n 2 * 3 \n 3 * 3'); // ResultSet, [3, 6, 9]
// semicolon statements are hidden from the output
('a=3; b=4; a + b \n a * b'); // ResultSet, [7, 12]
// single expression spread over multiple lines
('a = 2 +\n 3'); // 5
('[\n 1, 2;\n 3, 4\n]'); // Matrix, [[1, 2], [3, 4]]
The results can be read from a ResultSet
via the property ResultSet.entries
which is an Array
, or by calling ResultSet.valueOf()
, which returns the
array with results.
Implicit multiplication
The expression parser supports implicit multiplication. Implicit multiplication
has the same precedence as explicit multiplications and divisions, so 3/4 mm
is evaluated as (3 / 4) * mm
.
Parentheses are parsed as a function call when there is a symbol or accessor on
the left hand side, like sqrt(4)
or obj.method(4)
. In other cases the
parentheses are interpreted as an implicit multiplication.
Implicit multiplication can be tricky as there is ambiguity on how an expression is evaluated. Use it carefully.
Here some examples:
Expression | Evaluated as | Result |
---|---|---|
(1 + 3) pi | (1 + 3) * pi | 12.566370614359172 |
(4 - 1) 2 | (4 - 1) * 2 | 6 |
3 / 4 mm | (3 / 4) * mm | 0.75 mm |
2 + 3 i | 2 + (3 * i) | 2 + 3i |
(1 + 2) (4 - 2) | (1 + 2) * (4 - 2) | 6 |
sqrt(4) (1 + 2) | sqrt(4) * (1 + 2) | 6 |
Comments
Comments can be added to explain or describe calculations in the text. A comment
starts with a sharp sign character #
, and ends at the end of the line. A line
can contain a comment only, or can contain an expression followed by a comment.
var parser = math.parser();
('# define some variables');
('width = 3'); // 3
('height = 4'); // 4
('width * height # calculate the area'); // 12