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>|</code> | Bitwise or | <code>x | y</code> | Left to right | <code>5 | 3</code> | `7` 81 <code>^|</code> | Bitwise xor | <code>x ^| y</code> | Left to right | <code>5 ^| 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>^|</code> | Bitwise xor 122 <code>|</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 ```