simple-squiggle

A restricted subset of Squiggle
Log | Files | Refs | README

syntax.md (29121B)


      1 # Expression syntax
      2 
      3 This page describes the syntax of expression parser of math.js. It describes
      4 how to work with the available data types, functions, operators, variables,
      5 and more.
      6 
      7 ## Differences from JavaScript
      8 
      9 The expression parser of math.js is aimed at a mathematical audience,
     10 not a programming audience. The syntax is similar to most calculators and
     11 mathematical applications. This is close to JavaScript as well, though there
     12 are a few important differences between the syntax of the expression parser and
     13 the lower level syntax of math.js. Differences are:
     14 
     15 - No need to prefix functions and constants with the `math.*` namespace,
     16   you can just enter `sin(pi / 4)`.
     17 - Matrix indexes are one-based instead of zero-based.
     18 - There are index and range operators which allow more conveniently getting
     19   and setting matrix indexes, like `A[2:4, 1]`.
     20 - Both indexes and ranges and have the upper-bound included.
     21 - There is a differing syntax for defining functions. Example: `f(x) = x^2`.
     22 - There are custom operators like `x + y` instead of `add(x, y)`.
     23 - Some operators are different. For example  `^` is used for exponentiation,
     24   not bitwise xor.
     25 - Implicit multiplication, like `2 pi`, is supported and has special rules.
     26 - Relational operators (`<`, `>`, `<=`, `>=`, `==`, and `!=`) are chained, so the expression `5 < x < 10` is equivalent to `5 < x and x < 10`.
     27 - Multi-expression constructs like `a = 1; b = 2; a + b` or
     28   `"a = 1;\n cos(a)\n sin(a)"` (where `\n` denotes newline)
     29   produce a collection ("ResultSet") of values. Those expressions
     30   terminated by `;` are evaluated for side effect only and their values
     31   are suppressed from the result.
     32 
     33 ## Operators
     34 
     35 The expression parser has operators for all common arithmetic operations such
     36 as addition and multiplication. The expression parser uses conventional infix
     37 notation for operators: an operator is placed between its arguments.
     38 Round parentheses can be used to override the default precedence of operators.
     39 
     40 ```js
     41 // use operators
     42 math.evaluate('2 + 3')       // 5
     43 math.evaluate('2 * 3')       // 6
     44 
     45 // use parentheses to override the default precedence
     46 math.evaluate('2 + 3 * 4')   // 14
     47 math.evaluate('(2 + 3) * 4') // 20
     48 ```
     49 
     50 The following operators are available:
     51 
     52 Operator    | Name                       | Syntax      | Associativity | Example               | Result
     53 ----------- | -------------------------- | ----------  | ------------- | --------------------- | ---------------
     54 `(`, `)`    | Grouping                   | `(x)`       | None          | `2 * (3 + 4)`         | `14`
     55 `[`, `]`    | Matrix, Index              | `[...]`     | None          | `[[1,2],[3,4]]`       | `[[1,2],[3,4]]`
     56 `{`, `}`    | Object                     | `{...}`     | None          | `{a: 1, b: 2}`        | `{a: 1, b: 2}`
     57 `,`         | Parameter separator        | `x, y`      | Left to right | `max(2, 1, 5)`        | `5`
     58 `.`         | Property accessor          | `obj.prop`  | Left to right | `obj={a: 12}; obj.a`  | `12`
     59 `;`         | Statement separator        | `x; y`      | Left to right | `a=2; b=3; a*b`       | `[6]`
     60 `;`         | Row separator              | `[x; y]`    | Left to right | `[1,2;3,4]`           | `[[1,2],[3,4]]`
     61 `\n`        | Statement separator        | `x \n y`    | Left to right | `a=2 \n b=3 \n a*b`   | `[2,3,6]`
     62 `+`         | Add                        | `x + y`     | Left to right | `4 + 5`               | `9`
     63 `+`         | Unary plus                 | `+y`        | Right to left | `+4`                  | `4`
     64 `-`         | Subtract                   | `x - y`     | Left to right | `7 - 3`               | `4`
     65 `-`         | Unary minus                | `-y`        | Right to left | `-4`                  | `-4`
     66 `*`         | Multiply                   | `x * y`     | Left to right | `2 * 3`               | `6`
     67 `.*`        | Element-wise multiply      | `x .* y`    | Left to right | `[1,2,3] .* [1,2,3]`  | `[1,4,9]`
     68 `/`         | Divide                     | `x / y`     | Left to right | `6 / 2`               | `3`
     69 `./`        | Element-wise divide        | `x ./ y`    | Left to right | `[9,6,4] ./ [3,2,2]`  | `[3,3,2]`
     70 `%`         | Percentage                 | `x%`        | None          | `8%`                  | `0.08`
     71 `%`         | Addition with Percentage   | `x + y%`    | Left to right | `100 + 3%`            | `103`
     72 `%`         | Subtraction with Percentage| `x - y%`    | Left to right | `100 - 3%`            | `97`
     73 `%` `mod`   | Modulus                    | `x % y`     | Left to right | `8 % 3`               | `2`
     74 `^`         | Power                      | `x ^ y`     | Right to left | `2 ^ 3`               | `8`
     75 `.^`        | Element-wise power         | `x .^ y`    | Right to left | `[2,3] .^ [3,3]`      | `[8,27]`
     76 `'`         | Transpose                  | `y'`        | Left to right | `[[1,2],[3,4]]'`      | `[[1,3],[2,4]]`
     77 `!`         | Factorial                  | `y!`        | Left to right | `5!`                  | `120`
     78 `&`         | Bitwise and                | `x & y`     | Left to right | `5 & 3`               | `1`
     79 `~`         | Bitwise not                | `~x`        | Right to left | `~2`                  | `-3`
     80 <code>&#124;</code>  | Bitwise or     | <code>x &#124; y</code>   | Left to right | <code>5 &#124; 3</code>  | `7`
     81 <code>^&#124;</code> | Bitwise xor    | <code>x ^&#124; y</code>  | Left to right | <code>5 ^&#124; 2</code> | `7`
     82 `<<`        | Left shift                 | `x << y`    | Left to right | `4 << 1`              | `8`
     83 `>>`        | Right arithmetic shift     | `x >> y`    | Left to right | `8 >> 1`              | `4`
     84 `>>>`       | Right logical shift        | `x >>> y`   | Left to right | `-8 >>> 1`            | `2147483644`
     85 `and`       | Logical and                | `x and y`   | Left to right | `true and false`      | `false`
     86 `not`       | Logical not                | `not y`     | Right to left | `not true`            | `false`
     87 `or`        | Logical or                 | `x or y`    | Left to right | `true or false`       | `true`
     88 `xor`       | Logical xor                | `x xor y`   | Left to right | `true xor true`       | `false`
     89 `=`         | Assignment                 | `x = y`     | Right to left | `a = 5`               | `5`
     90 `?` `:`     | Conditional expression     | `x ? y : z` | Right to left | `15 > 100 ? 1 : -1`   | `-1`
     91 `:`         | Range                      | `x : y`     | Right to left | `1:4`                 | `[1,2,3,4]`
     92 `to`, `in`  | Unit conversion            | `x to y`    | Left to right | `2 inch to cm`        | `5.08 cm`
     93 `==`        | Equal                      | `x == y`    | Left to right | `2 == 4 - 2`          | `true`
     94 `!=`        | Unequal                    | `x != y`    | Left to right | `2 != 3`              | `true`
     95 `<`         | Smaller                    | `x < y`     | Left to right | `2 < 3`               | `true`
     96 `>`         | Larger                     | `x > y`     | Left to right | `2 > 3`               | `false`
     97 `<=`        | Smallereq                  | `x <= y`    | Left to right | `4 <= 3`              | `false`
     98 `>=`        | Largereq                   | `x >= y`    | Left to right | `2 + 4 >= 6`          | `true`
     99 
    100 
    101 ## Precedence
    102 
    103 The operators have the following precedence, from highest to lowest:
    104 
    105 Operators                         | Description
    106 --------------------------------- | --------------------
    107 `(...)`<br>`[...]`<br>`{...}`     | Grouping<br>Matrix<br>Object
    108 `x(...)`<br>`x[...]`<br>`obj.prop`<br>`:`| Function call<br>Matrix index<br>Property accessor<br>Key/value separator
    109 `'`                               | Matrix transpose
    110 `!`                               | Factorial
    111 `^`, `.^`                         | Exponentiation
    112 `+`, `-`, `~`, `not`              | Unary plus, unary minus, bitwise not, logical not
    113 See section below                 | Implicit multiplication
    114 `*`, `/`, `.*`, `./`, `%`, `mod`  | Multiply, divide, percentage, modulus
    115 `+`, `-`                          | Add, subtract
    116 `:`                               | Range
    117 `to`, `in`                        | Unit conversion
    118 `<<`, `>>`, `>>>`                 | Bitwise left shift, bitwise right arithmetic shift, bitwise right logical shift
    119 `==`, `!=`, `<`, `>`, `<=`, `>=`  | Relational
    120 `&`                               | Bitwise and
    121 <code>^&#124;</code>              | Bitwise xor
    122 <code>&#124;</code>               | Bitwise or
    123 `and`                             | Logical and
    124 `xor`                             | Logical xor
    125 `or`                              | Logical or
    126 `?`, `:`                          | Conditional expression
    127 `=`                               | Assignment
    128 `,`                               | Parameter and column separator
    129 `;`                               | Row separator
    130 `\n`, `;`                         | Statement separators
    131 
    132 
    133 ## Functions
    134 
    135 Functions are called by entering their name, followed by zero or more
    136 arguments enclosed by parentheses. All available functions are listed on the
    137 page [Functions](../reference/functions.md).
    138 
    139 ```js
    140 math.evaluate('sqrt(25)')           // 5
    141 math.evaluate('log(10000, 3 + 7)')  // 4
    142 math.evaluate('sin(pi / 4)')        // 0.7071067811865475
    143 ```
    144 
    145 New functions can be defined by "assigning" an expression to a function call
    146 with one or more variables. Such function assignments are limited: they can
    147 only be defined on a single line.
    148 
    149 ```js
    150 const parser = math.parser()
    151 
    152 parser.evaluate('f(x) = x ^ 2 - 5')
    153 parser.evaluate('f(2)')     // -1
    154 parser.evaluate('f(3)')     // 4
    155 
    156 parser.evaluate('g(x, y) = x ^ y')
    157 parser.evaluate('g(2, 3)')  // 8
    158 ```
    159 
    160 Note that these function assignments do _not_ create closures; put another way,
    161 all free variables in mathjs are dynamic:
    162 
    163 ```js
    164 const parser = math.parser()
    165 
    166 parser.evaluate('x = 7')
    167 parser.evaluate('h(y) = x + y')
    168 parser.evaluate('h(3)')         // 10
    169 parser.evaluate('x = 3')
    170 parser.evaluate('h(3)')         // 6, *not* 10
    171 ```
    172 
    173 It is however possible to pass functions as parameters:
    174 
    175 ```js
    176 const parser = math.parser()
    177 
    178 parser.evaluate('twice(func, x) = func(func(x))')
    179 parser.evaluate('twice(square, 2)')    // 16
    180 parser.evaluate('f(x) = 3*x')
    181 parser.evaluate('twice(f, 2)')         // 18
    182 
    183 // a simplistic "numerical derivative":
    184 parser.evaluate('eps = 1e-10')
    185 parser.evaluate('nd(f, x) = (f(x+eps) - func(x-eps))/(2*eps)')
    186 parser.evaluate('nd(square,2)')        // 4.000000330961484
    187 ```
    188 
    189 Math.js itself heavily uses typed functions, which ensure correct inputs and
    190 throws meaningful errors when the input arguments are invalid. One can create
    191 a [typed-function](https://github.com/josdejong/typed-function) in the
    192 expression parser like:
    193 
    194 ```js
    195 const parser = math.parser()
    196 
    197 parser.evaluate('f = typed({"number": f(x) = x ^ 2 - 5})')
    198 ```
    199 
    200 
    201 ## Constants and variables
    202 
    203 Math.js has a number of built-in constants such as `pi` and `e`.
    204 All available constants are listed on he page
    205 [Constants](../reference/constants.md).
    206 
    207 ```js
    208 // use constants
    209 math.evaluate('pi')                 // 3.141592653589793
    210 math.evaluate('e ^ 2')              // 7.3890560989306495
    211 math.evaluate('log(e)')             // 1
    212 math.evaluate('e ^ (pi * i) + 1')   // ~0 (Euler)
    213 ```
    214 
    215 Variables can be defined using the assignment operator `=`, and can be used
    216 like constants.
    217 
    218 ```js
    219 const parser = math.parser()
    220 
    221 // define variables
    222 parser.evaluate('a = 3.4')      // 3.4
    223 parser.evaluate('b = 5 / 2')    // 2.5
    224 
    225 // use variables
    226 parser.evaluate('a * b')        // 8.5
    227 ```
    228 
    229 Variable names must:
    230 
    231 - Begin with an "alpha character", which is:
    232   - A latin letter (upper or lower case). Ascii: `a-z`, `A-Z`
    233   - An underscore.                        Ascii: `_`
    234   - A dollar sign.                        Ascii: `$`
    235   - A latin letter with accents.          Unicode: `\u00C0` - `\u02AF`
    236   - A greek letter.                       Unicode: `\u0370` - `\u03FF`
    237   - A letter-like character.              Unicode: `\u2100` - `\u214F`
    238   - A mathematical alphanumeric symbol.   Unicode: `\u{1D400}` - `\u{1D7FF}` excluding invalid code points
    239 - Contain only alpha characters (above) and digits `0-9`
    240 - Not be any of the following: `mod`, `to`, `in`, `and`, `xor`, `or`, `not`, `end`. It is possible to assign to some of these, but that's not recommended.
    241 
    242 It is possible to customize the allowed alpha characters, see [Customize supported characters](customization.md#customize-supported-characters) for more information.
    243 
    244 
    245 ## Data types
    246 
    247 The expression parser supports booleans, numbers, complex numbers, units,
    248 strings, matrices, and objects.
    249 
    250 
    251 ### Booleans
    252 
    253 Booleans `true` and `false` can be used in expressions.
    254 
    255 ```js
    256 // use booleans
    257 math.evaluate('true')               // true
    258 math.evaluate('false')              // false
    259 math.evaluate('(2 == 3) == false')  // true
    260 ```
    261 
    262 Booleans can be converted to numbers and strings and vice versa using the
    263 functions `number` and `boolean`, and `string`.
    264 
    265 ```js
    266 // convert booleans
    267 math.evaluate('number(true)')       // 1
    268 math.evaluate('string(false)')      // "false"
    269 math.evaluate('boolean(1)')         // true
    270 math.evaluate('boolean("false")')   // false
    271 ```
    272 
    273 
    274 ### Numbers
    275 
    276 The most important and basic data type in math.js are numbers. Numbers use a
    277 point as decimal mark. Numbers can be entered with exponential notation.
    278 Examples:
    279 
    280 ```js
    281 // numbers in math.js
    282 math.evaluate('2')        // 2
    283 math.evaluate('3.14')     // 3.14
    284 math.evaluate('1.4e3')    // 1400
    285 math.evaluate('22e-3')    // 0.022
    286 ```
    287 
    288 A number can be converted to a string and vice versa using the functions
    289 `number` and `string`.
    290 
    291 ```js
    292 // convert a string into a number
    293 math.evaluate('number("2.3")')    // 2.3
    294 math.evaluate('string(2.3)')      // "2.3"
    295 ```
    296 
    297 Math.js uses regular JavaScript numbers, which are floating points with a
    298 limited precision and limited range. The limitations are described in detail
    299 on the page [Numbers](../datatypes/numbers.md).
    300 
    301 ```js
    302 math.evaluate('1e-325')   // 0
    303 math.evaluate('1e309')    // Infinity
    304 math.evaluate('-1e309')   // -Infinity
    305 ```
    306 
    307 When doing calculations with floats, one can very easily get round-off errors:
    308 
    309 ```js
    310 // round-off error due to limited floating point precision
    311 math.evaluate('0.1 + 0.2')  // 0.30000000000000004
    312 ```
    313 
    314 When outputting results, the function `math.format` can be used to hide
    315 these round-off errors when outputting results for the user:
    316 
    317 ```js
    318 const ans = math.evaluate('0.1 + 0.2')  //  0.30000000000000004
    319 math.format(ans, {precision: 14})       // "0.3"
    320 ```
    321 
    322 Numbers can be expressed as binary, octal, and hexadecimal literals:
    323 
    324 ```js
    325 math.evaluate('0b11')  //  3
    326 math.evaluate('0o77')  //  63
    327 math.evaluate('0xff')  //  255
    328 ```
    329 
    330 A word size suffix can be used to change the behavior of non decimal literal evaluation:
    331 
    332 ```js
    333 math.evaluate('0xffi8')         // -1
    334 math.evaluate('0xffffffffi32')  //  -1
    335 math.evaluate('0xfffffffffi32') //  SyntaxError: String "0xfffffffff" is out of range
    336 ```
    337 
    338 Non decimal numbers can include a radix point:
    339 ```js
    340 math.evaluate('0b1.1')         // 1.5
    341 math.evaluate('0o1.4')         // 1.5
    342 math.evaluate('0x1.8')         // 1.5
    343 ```
    344 
    345 Numbers can be formatted as binary, octal, and hex strings using the `notation` option of the `format` function:
    346 
    347 ```js
    348 math.evaluate('format(3, {notation: "bin"})')    //  '0b11'
    349 math.evaluate('format(63, {notation: "oct"})')   //  '0o77'
    350 math.evaluate('format(255, {notation: "hex"})')  //  '0xff'
    351 math.evaluate('format(-1, {notation: "hex"})')   //  '-0x1'
    352 math.evaluate('format(2.3, {notation: "hex"})')  //  '0x2.4cccccccccccc'
    353 ```
    354 
    355 The `format` function accepts a `wordSize` option to use in conjunction with the non binary notations:
    356 
    357 ```js
    358 math.evaluate('format(-1, {notation: "hex", wordSize: 8})')   //  '0xffi8'
    359 ```
    360 
    361 The functions `bin`, `oct`, and `hex` are shorthand for the `format` function with `notation` set accordingly:
    362 
    363 ```js
    364 math.evaluate('bin(-1)')     // '-0b1'
    365 math.evaluate('bin(-1, 8)')  // '0b11111111i8'
    366 ```
    367 
    368 ### BigNumbers
    369 
    370 Math.js supports BigNumbers for calculations with an arbitrary precision.
    371 The pros and cons of Number and BigNumber are explained in detail on the page
    372 [Numbers](../datatypes/numbers.md).
    373 
    374 BigNumbers are slower but have a higher precision. Calculations with big
    375 numbers are supported only by arithmetic functions.
    376 
    377 BigNumbers can be created using the `bignumber` function:
    378 
    379 ```js
    380 math.evaluate('bignumber(0.1) + bignumber(0.2)') // BigNumber, 0.3
    381 ```
    382 
    383 The default number type of the expression parser can be changed at instantiation
    384 of math.js. The expression parser parses numbers as BigNumber by default:
    385 
    386 ```js
    387 // Configure the type of number: 'number' (default), 'BigNumber', or 'Fraction'
    388 math.config({number: 'BigNumber'})
    389 
    390 // all numbers are parsed as BigNumber
    391 math.evaluate('0.1 + 0.2')  // BigNumber, 0.3
    392 ```
    393 
    394 BigNumbers can be converted to numbers and vice versa using the functions
    395 `number` and `bignumber`. When converting a BigNumber to a Number, the high
    396 precision of the BigNumber will be lost. When a BigNumber is too large to be represented
    397 as Number, it will be initialized as `Infinity`.
    398 
    399 
    400 ### Complex numbers
    401 
    402 Complex numbers can be created using the imaginary unit `i`, which is defined
    403 as `i^2 = -1`. Complex numbers have a real and complex part, which can be
    404 retrieved using the functions `re` and `im`.
    405 
    406 ```js
    407 const parser = math.parser()
    408 
    409 // create complex numbers
    410 parser.evaluate('a = 2 + 3i')   // Complex, 2 + 3i
    411 parser.evaluate('b = 4 - i')    // Complex, 4 - i
    412 
    413 // get real and imaginary part of a complex number
    414 parser.evaluate('re(a)')        // Number,  2
    415 parser.evaluate('im(a)')        // Number,  3
    416 
    417 // calculations with complex numbers
    418 parser.evaluate('a + b')        // Complex, 6 + 2i
    419 parser.evaluate('a * b')        // Complex, 11 + 10i
    420 parser.evaluate('i * i')        // Number,  -1
    421 parser.evaluate('sqrt(-4)')     // Complex, 2i
    422 ```
    423 
    424 Math.js does not automatically convert complex numbers with an imaginary part
    425 of zero to numbers. They can be converted to a number using the function
    426 `number`.
    427 
    428 ```js
    429 // convert a complex number to a number
    430 const parser = math.parser()
    431 parser.evaluate('a = 2 + 3i')   // Complex, 2 + 3i
    432 parser.evaluate('b = a - 3i')   // Complex, 2 + 0i
    433 parser.evaluate('number(b)')    // Number,  2
    434 parser.evaluate('number(a)')    // Error: 2 + i is no valid number
    435 ```
    436 
    437 
    438 ### Units
    439 
    440 math.js supports units. Units can be used in the arithmetic operations
    441 add, subtract, multiply, divide, and exponentiation.
    442 Units can also be converted from one to another.
    443 An overview of all available units can be found on the page
    444 [Units](../datatypes/units.md).
    445 
    446 Units can be converted using the operator `to` or `in`.
    447 
    448 ```js
    449 // create a unit
    450 math.evaluate('5.4 kg')                     // Unit, 5.4 kg
    451 
    452 // convert a unit
    453 math.evaluate('2 inch to cm')               // Unit, 5.08 cm
    454 math.evaluate('20 celsius in fahrenheit')   // Unit, ~68 fahrenheit
    455 math.evaluate('90 km/h to m/s')             // Unit, 25 m / s
    456 
    457 // convert a unit to a number
    458 // A second parameter with the unit for the exported number must be provided
    459 math.evaluate('number(5 cm, mm)')           // Number, 50
    460 
    461 // calculations with units
    462 math.evaluate('0.5kg + 33g')                // Unit, 0.533 kg
    463 math.evaluate('3 inch + 2 cm')              // Unit, 3.7874 inch
    464 math.evaluate('3 inch + 2 cm')              // Unit, 3.7874 inch
    465 math.evaluate('12 seconds * 2')             // Unit, 24 seconds
    466 math.evaluate('sin(45 deg)')                // Number, 0.7071067811865475
    467 math.evaluate('9.81 m/s^2 * 5 s to mi/h')   // Unit, 109.72172512527 mi / h
    468 ```
    469 
    470 
    471 ### Strings
    472 
    473 Strings are enclosed by double quotes " or single quotes '. Strings can be concatenated using the
    474 function `concat` (not by adding them using `+` like in JavaScript). Parts of
    475 a string can be retrieved or replaced by using indexes. Strings can be converted
    476 to a number using function `number`, and numbers can be converted to a string
    477 using function `string`.
    478 
    479 When setting the value of a character in a string, the character that has been
    480 set is returned. Likewise, when a range of characters is set, that range of
    481 characters is returned.
    482 
    483 
    484 ```js
    485 const parser = math.parser()
    486 
    487 // create a string
    488 parser.evaluate('"hello"')                        // String, "hello"
    489 
    490 // string manipulation
    491 parser.evaluate('a = concat("hello", " world")')  // String, "hello world"
    492 parser.evaluate('size(a)')                        // Matrix [11]
    493 parser.evaluate('a[1:5]')                         // String, "hello"
    494 parser.evaluate('a[1] = "H"')                     // String, "H"
    495 parser.evaluate('a[7:12] = "there!"')             // String, "there!"
    496 parser.evaluate('a')                              // String, "Hello there!"
    497 
    498 // string conversion
    499 parser.evaluate('number("300")')                  // Number, 300
    500 parser.evaluate('string(300)')                    // String, "300"
    501 ```
    502 
    503 Strings can be used in the `evaluate` function, to parse expressions inside
    504 the expression parser:
    505 
    506 ```js
    507 math.evaluate('evaluate("2 + 3")')  // 5
    508 ```
    509 
    510 
    511 ### Matrices
    512 
    513 Matrices can be created by entering a series of values between square brackets,
    514 elements are separated by a comma `,`.
    515 A matrix like `[1, 2, 3]` will create a vector, a 1-dimensional matrix with
    516 size `[3]`. To create a multi-dimensional matrix, matrices can be nested into
    517 each other. For easier creation of two-dimensional matrices, a semicolon `;`
    518 can be used to separate rows in a matrix.
    519 
    520 ```js
    521 // create a matrix
    522 math.evaluate('[1, 2, 3]')                                // Matrix, size [3]
    523 math.evaluate('[[1, 2, 3], [4, 5, 6]]')                   // Matrix, size [2, 3]
    524 math.evaluate('[[[1, 2], [3, 4]], [[5, 6], [7, 8]]]')     // Matrix, size [2, 2, 2]
    525 
    526 // create a two dimensional matrix
    527 math.evaluate('[1, 2, 3; 4, 5, 6]')                       // Matrix, size [2, 3]
    528 ```
    529 
    530 Another way to create filled matrices is using the functions `zeros`, `ones`,
    531 `identity`, and `range`.
    532 
    533 ```js
    534 // initialize a matrix with ones or zeros
    535 math.evaluate('zeros(3, 2)')      // Matrix, [[0, 0], [0, 0], [0, 0]],  size [3, 2]
    536 math.evaluate('ones(3)')          // Matrix, [1, 1, 1],                 size [3]
    537 math.evaluate('5 * ones(2, 2)')   // Matrix, [[5, 5], [5, 5]],          size [2, 2]
    538 
    539 // create an identity matrix
    540 math.evaluate('identity(2)')      // Matrix, [[1, 0], [0, 1]],          size [2, 2]
    541 
    542 // create a range
    543 math.evaluate('1:4')              // Matrix, [1, 2, 3, 4],              size [4]
    544 math.evaluate('0:2:10')           // Matrix, [0, 2, 4, 6, 8, 10],       size [6]
    545 ```
    546 
    547 A subset can be retrieved from a matrix using indexes and a subset of a matrix
    548 can be replaced by using indexes. Indexes are enclosed in square brackets, and
    549 contain a number or a range for each of the matrix dimensions. A range can have
    550 its start and/or end undefined. When the start is undefined, the range will start
    551 at 1, when the end is undefined, the range will end at the end of the matrix.
    552 There is a context variable `end` available as well to denote the end of the
    553 matrix.
    554 
    555 *IMPORTANT: matrix indexes and ranges work differently from the math.js indexes
    556 in JavaScript: They are one-based with an included upper-bound, similar to most
    557 math applications.*
    558 
    559 ```js
    560 parser = math.parser()
    561 
    562 // create matrices
    563 parser.evaluate('a = [1, 2; 3, 4]')       // Matrix, [[1, 2], [3, 4]]
    564 parser.evaluate('b = zeros(2, 2)')        // Matrix, [[0, 0], [0, 0]]
    565 parser.evaluate('c = 5:9')                // Matrix, [5, 6, 7, 8, 9]
    566 
    567 // replace a subset in a matrix
    568 parser.evaluate('b[1, 1:2] = [5, 6]')     // Matrix, [[5, 6], [0, 0]]
    569 parser.evaluate('b[2, :] = [7, 8]')       // Matrix, [[5, 6], [7, 8]]
    570 
    571 // perform a matrix calculation
    572 parser.evaluate('d = a * b')              // Matrix, [[19, 22], [43, 50]]
    573 
    574 // retrieve a subset of a matrix
    575 parser.evaluate('d[2, 1]')                // 43
    576 parser.evaluate('d[2, 1:end]')            // Matrix, [[43, 50]]
    577 parser.evaluate('c[end - 1 : -1 : 2]')    // Matrix, [8, 7, 6]
    578 ```
    579 
    580 ## Objects
    581 
    582 Objects in math.js work the same as in languages like JavaScript and Python.
    583 An object is enclosed by curly brackets `{`, `}`, and contains a set of
    584 comma separated key/value pairs. Keys and values are separated by a colon `:`.
    585 Keys can be a symbol like `prop` or a string like `"prop"`.
    586 
    587 ```js
    588 math.evaluate('{a: 2 + 1, b: 4}')         // {a: 3, b: 4}
    589 math.evaluate('{"a": 2 + 1, "b": 4}')     // {a: 3, b: 4}
    590 ```
    591 
    592 Objects can contain objects:
    593 
    594 ```js
    595 math.evaluate('{a: 2, b: {c: 3, d: 4}}')  // {a: 2, b: {c: 3, d: 4}}
    596 ```
    597 
    598 Object properties can be retrieved or replaced using dot notation or bracket
    599 notation. Unlike JavaScript, when setting a property value, the whole object
    600 is returned, not the property value
    601 
    602 ```js
    603 let scope = {
    604   obj: {
    605     prop: 42
    606   }
    607 }
    608 
    609 // retrieve properties
    610 math.evaluate('obj.prop', scope)          // 42
    611 math.evaluate('obj["prop"]', scope)       // 42
    612 
    613 // set properties (returns the whole object, not the property value!)
    614 math.evaluate('obj.prop = 43', scope)     // {prop: 43}
    615 math.evaluate('obj["prop"] = 43', scope)  // {prop: 43}
    616 scope.obj                                 // {prop: 43}
    617 ```
    618 
    619 
    620 ## Multi-line expressions
    621 
    622 An expression can contain multiple lines, and expressions can be spread over
    623 multiple lines. Lines can be separated by a newline character `\n` or by a
    624 semicolon `;`. Output of statements followed by a semicolon will be hidden from
    625 the output, and empty lines are ignored. The output is returned as a `ResultSet`,
    626 with an entry for every visible statement.
    627 
    628 ```js
    629 // a multi-line expression
    630 math.evaluate('1 * 3 \n 2 * 3 \n 3 * 3')    // ResultSet, [3, 6, 9]
    631 
    632 // semicolon statements are hidden from the output
    633 math.evaluate('a=3; b=4; a + b \n a * b')   // ResultSet, [7, 12]
    634 
    635 // single expression spread over multiple lines
    636 math.evaluate('a = 2 +\n  3')               // 5
    637 math.evaluate('[\n  1, 2;\n  3, 4\n]')      // Matrix, [[1, 2], [3, 4]]
    638 ```
    639 
    640 The results can be read from a `ResultSet` via the property `ResultSet.entries`
    641 which is an `Array`, or by calling `ResultSet.valueOf()`, which returns the
    642 array with results.
    643 
    644 
    645 ## Implicit multiplication
    646 
    647 *Implicit multiplication* means the multiplication of two symbols, numbers, or a grouped expression inside parentheses without using the `*` operator. This type of syntax allows a more natural way to enter expressions. For example:
    648 
    649 ```js
    650 math.evaluate('2 pi')         // 6.283185307179586
    651 math.evaluate('(1+2)(3+4)')   // 21
    652 ```
    653 
    654 Parentheses are parsed as a function call when there is a symbol or accessor on
    655 the left hand side, like `sqrt(4)` or `obj.method(4)`. In other cases the
    656 parentheses are interpreted as an implicit multiplication.
    657 
    658 Math.js will always evaluate implicit multiplication before explicit multiplication `*`, so that the expression `x * y z` is parsed as `x * (y * z)`. Math.js also gives implicit multiplication higher precedence than division, *except* when the division matches the pattern `[unaryPrefixOp]?[number] / [number] [symbol]` or `[unaryPrefixOp]?[number] / [number] [left paren]`. In that special case, the division is evaluated first:
    659 
    660 ```js
    661 math.evaluate('20 kg / 4 kg')   // 5      Evaluated as (20 kg) / (4 kg)
    662 math.evaluate('20 / 4 kg')      // 5 kg   Evaluated as (20 / 4) kg
    663 ```
    664 
    665 The behavior of implicit multiplication can be summarized by these operator precedence rules, listed from highest to lowest precedence:
    666 
    667 - Function calls: `[symbol] [left paren]`
    668 - Explicit division `/` when the division matches this pattern: `[+-~]?[number] / [+-~]?[number] [symbol]` or `[number] / [number] [left paren]`
    669 - Implicit multiplication
    670 - All other division `/` and multiplication `*`
    671 
    672 Implicit multiplication is tricky as there can appear to be ambiguity in how an expression will be evaluated. Experience has shown that the above rules most closely match user intent when entering expressions that could be interpreted different ways. It's also possible that these rules could be tweaked in future major releases.  Use implicit multiplication carefully. If you don't like the uncertainty introduced by implicit multiplication, use explicit `*` operators and parentheses to ensure your expression is evaluated the way you intend.
    673 
    674 Here are some more examples using implicit multiplication:
    675 
    676 Expression      | Evaluated as        | Result
    677 --------------- | ------------------- | ------------------
    678 (1 + 3) pi      | (1 + 3) * pi        | 12.566370614359172
    679 (4 - 1) 2       | (4 - 1) * 2         | 6
    680 3 / 4 mm        | (3 / 4) * mm        | 0.75 mm
    681 2 + 3 i         | 2 + (3 * i)         | 2 + 3i
    682 (1 + 2) (4 - 2) | (1 + 2) * (4 - 2)   | 6
    683 sqrt(4) (1 + 2) | sqrt(4) * (1 + 2)   | 6
    684 8 pi / 2 pi     | (8 * pi) / (2 * pi) | 4
    685 pi / 2 pi       | pi / (2 * pi)       | 0.5
    686 1 / 2i          | (1 / 2) * i         | 0.5 i
    687 8.314 J / mol K | 8.314 J / (mol * K) | 8.314 J / (mol * K)
    688 
    689 
    690 ## Comments
    691 
    692 Comments can be added to explain or describe calculations in the text. A comment
    693 starts with a sharp sign character `#`, and ends at the end of the line. A line
    694 can contain a comment only, or can contain an expression followed by a comment.
    695 
    696 ```js
    697 const parser = math.parser()
    698 
    699 parser.evaluate('# define some variables')
    700 parser.evaluate('width = 3')                              // 3
    701 parser.evaluate('height = 4')                             // 4
    702 parser.evaluate('width * height   # calculate the area')  // 12
    703 ```