{"name":"math","intro":"`math` is SymPy behind the leftbrain contract. Answers come back in exact form *and* decimal form *and* LaTeX together, so the caller never rounds, re-derives or re-types anything. Expressions are parsed in a locked-down namespace — no builtins, no attribute access, no imports — and run under a timeout.\n\nThat namespace is an allowlist, not all of SymPy: `isprime` and `factorint` are in, `primepi` and `nextprime` are not. Every function it will evaluate is listed under **Functions** below, and a rejected name comes back with the near misses and the whole accepted set rather than only what failed.\n\n**Batching.** There is no list mode, but predicates return booleans that coerce to 1 and 0 inside an expression, so `is_prime(11) + is_prime(12) + is_prime(13)` counts how many hold in one call. For a bounded run of primes or squares, `numbers.sequence` takes `start` and `end`.","when_to_use":["Before stating any number: percentages, fractions, powers, roots, interest, ratios.","Trigonometry — and always pass `angle`, because `sin(30)` means two different things.","Algebra and calculus: `solve`, `diff`, `integrate`, `limit`, `series`, `ode`.","Linear algebra (`matrix`) and exact descriptive statistics (`stats`).","Not for dates or unit conversion: use `datetime` and `convert` instead."],"network":false,"related":"[`numbers`](/docs/tools/numbers) for rounding rules, locale formatting and exact allocation · [`convert`](/docs/tools/convert) for units · [`scale`](/docs/tools/scale) for proportional scaling.","docs_url":"/docs/tools/math","modes":[{"name":"eval","purpose":"Evaluate an expression to exact, decimal and LaTeX form.","description":"The default entry point. Parses and evaluates an arithmetic or symbolic expression, simplifying symbolic results and expanding numeric ones. Human notation is understood: `15% of 200`, `12^2`, `×`, `÷`, `√`, `π`, `∞`, `3∠45` for a phasor, `°` for degrees, and `8,45,000` or `845,000` for grouped digits (inside a call, commas still separate arguments). A decimal literal is the rational it prints as, so `0.1 + 0.2 - 0.3` is `0`. The result carries `exact`, `decimal`, `latex` and — for rationals — `numerator` and `denominator`; complex results add modulus and argument. When the exact form would run to more digits than can be returned, as `(1 + 1/10^6)^(10^6)` does, only the decimal is returned and `warnings` says so.","parameters":[{"name":"percent","type":"string","required":false,"doc":"How to read a `%` between two values: `modulus` for the remainder, `percent` for a percentage of what follows. Only asked for when the expression has one; `mod` is the spelling that never needs it.","default":null},{"name":"expr","type":"string","required":true,"doc":"The expression to evaluate.","default":null},{"name":"angle","type":"string","required":false,"doc":"Mandatory whenever the expression contains trigonometry.","default":null},{"name":"vars","type":"object \\| string[]","required":false,"doc":"Values substituted before evaluating, e.g. `{'a': 3}`.","default":null},{"name":"precision","type":"integer","required":false,"doc":"Significant digits in the decimal form.","default":"15"},{"name":"timeout","type":"number","required":false,"doc":"Seconds before the computation is abandoned.","default":"20"}],"examples":[{"mode":"eval","expr":"1/0"},{"mode":"eval","expr":"15% of 2400"},{"mode":"eval","expr":"sin(30) + cos(60)","angle":"deg"},{"mode":"eval","expr":"sqrt(a^2 + b^2)","vars":{"a":3,"b":4}},{"mode":"eval","expr":"(3 + 4i) * (1 - 2i)"},{"mode":"eval","expr":"sin(30)"},{"mode":"eval","expr":"foo(2) + 1"},{"mode":"eval","expr":"__import__(1)"},{"mode":"eval","expr":"9^9^9^9"}]},{"name":"exact","purpose":"Evaluate without ever showing a decimal.","description":"Same parsing as `eval`, but the result is forced through `nsimplify` and the decimal form is dropped. Use it when a decimal would be a lie — recovering `3/10` from `0.1 + 0.2`, or keeping a radical as a radical. An exact form too big to return is refused as `too_large` before it is built; `eval` with `precision` gives the decimal.","parameters":[{"name":"percent","type":"string","required":false,"doc":"How to read a `%` between two values: `modulus` for the remainder, `percent` for a percentage of what follows. Only asked for when the expression has one; `mod` is the spelling that never needs it.","default":null},{"name":"expr","type":"string","required":true,"doc":"The expression to evaluate.","default":null},{"name":"angle","type":"string","required":false,"doc":"Mandatory whenever the expression contains trigonometry.","default":null},{"name":"vars","type":"object \\| string[]","required":false,"doc":"Values substituted before evaluating.","default":null},{"name":"precision","type":"integer","required":false,"doc":"Significant digits used internally.","default":"15"}],"examples":[{"mode":"exact","expr":"0.1 + 0.2"},{"mode":"exact","expr":"1/3 + 1/6"},{"mode":"exact","expr":"sqrt(50)"},{"mode":"exact","expr":"2 +"},{"mode":"exact","expr":"tan(45)"}]},{"name":"simplify","purpose":"Reduce an expression to its simplest equivalent form.","description":"Runs SymPy's `simplify` over the parsed expression. Trigonometric identities, cancelling factors and collected terms all come out. `angle` defaults to `rad` here because a symbolic identity does not depend on the unit.","parameters":[{"name":"expr","type":"string","required":true,"doc":"The expression to simplify.","default":null},{"name":"angle","type":"string","required":false,"doc":"Interpretation of trig arguments.","default":"`rad`"},{"name":"precision","type":"integer","required":false,"doc":"Significant digits in the decimal form.","default":"15"}],"examples":[{"mode":"simplify","expr":"(x^2 - 1)/(x - 1)"},{"mode":"simplify","expr":"sin(x)^2 + cos(x)^2"},{"mode":"simplify","expr":"x^^2"}]},{"name":"expand","purpose":"Multiply out products and powers.","description":"Distributes products over sums, expands integer powers, and applies the trigonometric sum and multiple-angle identities (`sin(2x)` becomes `2 sin(x) cos(x)`). The inverse of `factor`; use it to get a polynomial in standard form before comparing two expressions. A logarithm of a product is left alone, since `log(ab) = log(a) + log(b)` needs positive arguments, and `assumptions` says so; an expression that was already expanded says that too.","parameters":[{"name":"expr","type":"string","required":true,"doc":"The expression to expand.","default":null},{"name":"angle","type":"string","required":false,"doc":"Interpretation of trig arguments.","default":"`rad`"},{"name":"precision","type":"integer","required":false,"doc":"Significant digits in the decimal form.","default":"15"}],"examples":[{"mode":"expand","expr":"(x + 1)^3"},{"mode":"expand","expr":"(a + b)*(a - b)"},{"mode":"expand","expr":"(x + 1"}]},{"name":"factor","purpose":"Factorise a polynomial over the rationals, or an integer into primes.","description":"Factors a polynomial into irreducible factors over the rationals. Returns the factored form in `value` and LaTeX; if nothing factors, the input comes back unchanged and `assumptions` says it is irreducible. A bare integer is factorised into primes: `12` gives `2**2*3` with the exponents in `factors`. It takes an expression, not an equation — `x^2 - 5x + 6`, without the `= 0`.","parameters":[{"name":"expr","type":"string","required":true,"doc":"The expression to factor.","default":null},{"name":"angle","type":"string","required":false,"doc":"Interpretation of trig arguments.","default":"`rad`"},{"name":"precision","type":"integer","required":false,"doc":"Significant digits in the decimal form.","default":"15"}],"examples":[{"mode":"factor","expr":"x^2 - 5*x + 6"},{"mode":"factor","expr":"a^3 - b^3"},{"mode":"factor","expr":"x; y"}]},{"name":"solve","purpose":"Solve equations, systems and inequalities.","description":"Solves one equation or a system of them. Write equations as strings with a single `=` (`x^2 - 5*x + 6 = 0`); relational operators produce an inequality solution set instead. If there are more unknowns than equations the tool refuses to guess which to solve for and returns `needs.options`. `domain` narrows the search to real, integer or positive solutions — with no domain, variables are complex. When no closed form exists — a degree-40 polynomial, say — the roots are found numerically instead, said so in `assumptions`; “no solutions found” was the one answer that could not be true. An equation with no solutions in the domain is still `ok`, with an empty list and a line in `assumptions` saying how many roots exist elsewhere: `x^2 + 1 = 0` over the reals reports its two complex roots and how to see them.","parameters":[{"name":"equations","type":"string[]","required":false,"doc":"The equations. A single string is accepted.","default":null},{"name":"expr","type":"string","required":false,"doc":"Alternative to `equations` for one equation.","default":null},{"name":"vars","type":"object \\| string[]","required":false,"doc":"Which unknowns to solve for. Required when there are more unknowns than equations.","default":null},{"name":"domain","type":"string","required":false,"doc":"Assumption applied to every unknown.","default":"`complex`"},{"name":"precision","type":"integer","required":false,"doc":"Significant digits in the decimal forms.","default":"15"}],"examples":[{"mode":"solve","equations":["x^2 - 5*x + 6 = 0"]},{"mode":"solve","equations":["x + y = 10","x - y = 2"]},{"mode":"solve","equations":["x^2 + 1 = 0"],"domain":"real"},{"mode":"solve","equations":["x^2 - 4 > 0"],"vars":["x"]},{"mode":"solve","equations":["x + y = 10"]},{"mode":"solve","equations":["x = 1"],"domain":"quaternion"}]},{"name":"diff","purpose":"Differentiate, optionally evaluated at a point.","description":"Differentiates `expr` with respect to `var`, `order` times, and simplifies the result. Pass `at` to also evaluate the derivative at a point. With several free symbols and no `var`, the tool refuses to guess and lists the candidates.","parameters":[{"name":"expr","type":"string","required":true,"doc":"The expression to differentiate.","default":null},{"name":"var","type":"string","required":false,"doc":"The variable. Inferred when the expression has exactly one free symbol.","default":null},{"name":"order","type":"integer","required":false,"doc":"How many times to differentiate.","default":"1"},{"name":"at","type":"string \\| number","required":false,"doc":"Also evaluate the derivative at this point.","default":null},{"name":"angle","type":"string","required":false,"doc":"Interpretation of trig arguments.","default":"`rad`"}],"examples":[{"mode":"diff","expr":"x^3 + 2*x"},{"mode":"diff","expr":"x^3","var":"x","order":2,"at":4},{"mode":"diff","expr":"x^2*y + y^3","var":"y"},{"mode":"diff","expr":"x*y"}]},{"name":"integrate","purpose":"Definite and indefinite integrals.","description":"With `lower` and `upper`, computes a definite integral; without them, an indefinite one (the result carries an explicit `+ C`). If no closed form exists, the definite case falls back to a numeric value and says so in `warnings`. Passing only one bound is an error, not a guess.","parameters":[{"name":"expr","type":"string","required":true,"doc":"The integrand.","default":null},{"name":"var","type":"string","required":false,"doc":"The variable of integration. Inferred when unambiguous.","default":null},{"name":"lower","type":"string \\| number","required":false,"doc":"Lower bound. Required together with `upper`.","default":null},{"name":"upper","type":"string \\| number","required":false,"doc":"Upper bound. Required together with `lower`.","default":null},{"name":"precision","type":"integer","required":false,"doc":"Significant digits in the decimal form.","default":"15"}],"examples":[{"mode":"integrate","expr":"x^2","var":"x"},{"mode":"integrate","expr":"sin(x)","var":"x","lower":0,"upper":"pi"},{"mode":"integrate","expr":"x^2","var":"x","lower":0}]},{"name":"limit","purpose":"Limits, one-sided or two-sided.","description":"Evaluates the limit of `expr` as `var` approaches `point`. Without `side` the limit is two-sided; when the two sides disagree the response stays `ok` but reports `exists: false` together with both one-sided limits. `point` accepts `oo` for infinity.","parameters":[{"name":"expr","type":"string","required":true,"doc":"The expression.","default":null},{"name":"var","type":"string","required":false,"doc":"The variable. Inferred when unambiguous.","default":null},{"name":"point","type":"string \\| number","required":false,"doc":"The point approached; `oo` for infinity.","default":"0"},{"name":"side","type":"string","required":false,"doc":"One-sided limit.","default":"two-sided"}],"examples":[{"mode":"limit","expr":"sin(x)/x","var":"x","point":0},{"mode":"limit","expr":"1/x","var":"x","point":0,"side":"+"},{"mode":"limit","expr":"1/x","var":"x","point":0},{"mode":"limit","expr":"1/x","var":"x","point":0,"side":"up"}]},{"name":"series","purpose":"Taylor / Laurent series expansion.","description":"Expands `expr` about `at` up to `order`. The response carries both the series with its `O(...)` term (in `value`) and the bare polynomial (in `polynomial`), so the caller can use whichever it needs.","parameters":[{"name":"expr","type":"string","required":true,"doc":"The expression to expand.","default":null},{"name":"var","type":"string","required":false,"doc":"The variable. Inferred when unambiguous.","default":null},{"name":"at","type":"string \\| number","required":false,"doc":"Point to expand about.","default":"0"},{"name":"order","type":"integer","required":false,"doc":"Order of the expansion.","default":"6"}],"examples":[{"mode":"series","expr":"exp(x)","var":"x","order":5},{"mode":"series","expr":"log(1 + x)","var":"x","at":0,"order":4},{"mode":"series","expr":"exp(x*y)","order":3}]},{"name":"ode","purpose":"Solve an ordinary differential equation.","description":"Solves an ODE written in ordinary notation: primes (`y'`, `y''`) and `dy/dx` are both understood, with or without a `*` after a coefficient (`y'' + 4y' + 4y = 0`). `func` names the unknown function and its independent variable. Initial conditions go in `ics` keyed by `y(0)` / `y'(0)`. The response includes SymPy's classification of the equation.","parameters":[{"name":"equation","type":"string","required":true,"doc":"The differential equation, e.g. `y'' + y = 0`.","default":null},{"name":"func","type":"string","required":false,"doc":"The unknown function, `y` or `y(x)`.","default":"`y(x)`"},{"name":"ics","type":"object","required":false,"doc":"Initial conditions, e.g. `{'y(0)': 1, \"y'(0)\": 0}`.","default":null},{"name":"precision","type":"integer","required":false,"doc":"Significant digits in the decimal form.","default":"15"}],"examples":[{"mode":"ode","equation":"y' = y","func":"y(x)"},{"mode":"ode","equation":"y'' + y = 0","func":"y(x)","ics":{"y(0)":1,"y'(0)":0}},{"mode":"ode","equation":"y' = y","func":"2x"},{"mode":"ode","equation":"y' = y","func":"y(x)","ics":{"y0":1}}]},{"name":"matrix","purpose":"Linear algebra: determinant, inverse, eigenvectors, solving.","description":"One matrix operation per call, chosen with `op`: `det`, `inv`, `transpose`, `rank`, `trace`, `rref`, `nullspace`, `eig`, `solve`, `mul`, `add`, `sub`, `pow`. Matrices are nested lists (a flat list is read as a single row). Entries may be numbers or expressions, and everything stays exact — no floating-point drift in a determinant.","parameters":[{"name":"op","type":"string","required":false,"doc":"The operation.","default":"`det`"},{"name":"A","type":"array \\| string","required":true,"doc":"The matrix.","default":null},{"name":"B","type":"array","required":false,"doc":"Second matrix, for `mul`, `add`, `sub`.","default":null},{"name":"b","type":"array","required":false,"doc":"Right-hand side, for `op: solve`.","default":null},{"name":"n","type":"integer","required":false,"doc":"Exponent, for `op: pow`.","default":"2"},{"name":"precision","type":"integer","required":false,"doc":"Significant digits in the decimal forms.","default":"15"}],"examples":[{"mode":"matrix","op":"det","A":[[1,2],[3,4]]},{"mode":"matrix","op":"inv","A":[[4,7],[2,6]]},{"mode":"matrix","op":"eig","A":[[2,1],[1,2]]},{"mode":"matrix","op":"solve","A":[[2,1],[1,3]],"b":[5,10]},{"mode":"matrix","op":"det","A":[[1,2,3],[4,5,6]]},{"mode":"matrix","op":"inv","A":[[1,2],[2,4]]},{"mode":"matrix","op":"mul","A":[[1,2],[3,4]],"B":[[1,2,3]]},{"mode":"matrix","op":"eigenfrobnicate","A":[[1,0],[0,1]]}]},{"name":"stats","purpose":"Exact descriptive statistics and regression.","description":"Statistics over a list of numbers, computed with exact rationals rather than floats. `op` selects the statistic: `describe`, `sum`, `mean`, `median`, `mode`, `stdev`, `pstdev`, `variance`, `pvariance`, `min`, `max`, `range`, `percentile`, `quartiles`, `zscore`, `geometric_mean`, `harmonic_mean`, `weighted_mean`, `cumsum`, `corr`, `covariance`, `regress`. `describe` returns both the sample (n−1) and population (n) spread so nobody has to guess which one was used.","parameters":[{"name":"op","type":"string","required":false,"doc":"The statistic to compute.","default":"`describe`"},{"name":"data","type":"array","required":true,"doc":"The sample.","default":null},{"name":"y","type":"array","required":false,"doc":"Second series, for `corr`, `covariance`, `regress`.","default":null},{"name":"weights","type":"array","required":false,"doc":"Weights, for `weighted_mean`.","default":null},{"name":"percentile","type":"number","required":false,"doc":"0..100, for `op: percentile`.","default":null},{"name":"value","type":"string \\| number \\| integer","required":false,"doc":"The observation, for `op: zscore`.","default":null},{"name":"predict","type":"number","required":false,"doc":"An x-value to predict, for `op: regress`.","default":null}],"examples":[{"mode":"stats","op":"describe","data":[2,4,4,4,5,5,7,9]},{"mode":"stats","op":"regress","data":[1,2,3,4],"y":[2,4,6,9],"predict":5},{"mode":"stats","op":"percentile","data":[1,2,3,4,5,6,7,8,9,10],"percentile":90},{"mode":"stats","op":"stdev","data":[5]},{"mode":"stats","op":"vibe","data":[1,2,3]},{"mode":"stats","op":"corr","data":[1,2,3],"y":[1,2]}]},{"name":"convert_form","purpose":"Re-present one value: polar, rectangular, fraction, scientific, LaTeX.","description":"Takes one expression and returns it in a different representation, chosen with `form`: `polar`, `rect`, `latex`, `decimal`, `fraction`, `scientific`, `percent`. This is a presentation change, not a computation — the value is unchanged.","parameters":[{"name":"expr","type":"string","required":true,"doc":"The value to re-present.","default":null},{"name":"form","type":"string","required":false,"doc":"Target form.","default":"`decimal`"},{"name":"significant","type":"integer","required":false,"doc":"Significant digits, for `form: scientific`.","default":"6"},{"name":"tolerance","type":"number","required":false,"doc":"Rounding tolerance, for `form: fraction`.","default":null},{"name":"precision","type":"integer","required":false,"doc":"Significant digits in the decimal forms.","default":"15"}],"examples":[{"mode":"convert_form","expr":"3 + 4i","form":"polar"},{"mode":"convert_form","expr":"0.375","form":"fraction"},{"mode":"convert_form","expr":"0.000123456","form":"scientific","significant":3},{"mode":"convert_form","expr":"3 + 4i","form":"scientific"},{"mode":"convert_form","expr":"2","form":"binary"}]},{"name":"plot_points","purpose":"Sample a function into (x, y) pairs for charting.","description":"Evaluates `expr` at `n` evenly spaced points across `range` and returns the pairs plus the observed y-extent. Points where the function is undefined or non-real are skipped and counted in `warnings` rather than silently returned as nulls.","parameters":[{"name":"expr","type":"string","required":true,"doc":"The function to sample.","default":null},{"name":"var","type":"string","required":false,"doc":"The variable. Inferred when unambiguous.","default":null},{"name":"range","type":"number[]","required":false,"doc":"Start and end of the sampled interval.","default":"`[-10, 10]`"},{"name":"n","type":"integer","required":false,"doc":"Number of samples, 2..10000.","default":"50"}],"examples":[{"mode":"plot_points","expr":"x^2","var":"x","range":[-2,2],"n":5},{"mode":"plot_points","expr":"1/x","var":"x","range":[-1,1],"n":5},{"mode":"plot_points","expr":"x^2","range":[0]},{"mode":"plot_points","expr":"x^2","n":1}]}]}