# Coffeequate

A computer algebra system for JavaScript. ## Algebra in the browser

No matter how hard you try, `-webkit-calc()` is not going to be able to solve an equation. Neither is JavaScript. That's where Coffeequate comes in. Coffeequate is a computer algebra system (CAS) for JavaScript. It can manipulate algebraic expressions, and solve and simplify equations.

## Features

• Solve quadratic and linear equations.
• Simplify most algebraic expressions.
• Propagate uncertainties in an expression.
• Substitute numbers and other expressions into existing expressions.
• Handle variables, constants, and symbolic constants (like π or G).

## Usage

### Installation

To include Coffeequate on your page, just use a script tag: ``` <script type="text/javascript" src="coffeequate.min.js"></script> ``` You can also load it with an AMD loader like RequireJS. ``` define(["lib/coffeequate.min"], function (CQ) { // Use Coffeequate here! }); ```

If you really want, you can play around with Coffeequate in development by using this site's version of Coffeequate, CDN style. Obviously, this is not a good idea for production. ``` <script src="http://matthewja.com/Coffeequate/coffeequate.min.js"></script> ```

### Using Coffeequate

Coffeequate gives you a `CQ` function (or `coffeequate` if you'd prefer). This function converts strings to Coffeequate expressions, which you can then operate on with methods. ``` equ = CQ("Ek = 1/2 * m * v**2"); m = equ.solve("m"); // 2 * Ek * v**-2 expr = CQ("m * c**2"); expr = expr.sub({"m": CQ("F * a**-1"), "c": 10}); // 100 * F * a**-1 ``` Valid terminals are variables, which are alphanumeric strings that begin with a letter; constants, which are numbers as digits which may include decimal points, or scientific notation (e.g. `2e-3`); or symbolic constants, which are variables preceded by a backslash. A list of known symbolic constants is located here. The methods of an expression are listed below.

• `expr.solve(variable, equivalencies)` - Takes the name of a variable as a string, and returns the expression solved for this variable as an array of solutions. Expressions are automatically equated to zero.
• `expr.simplify(equivalencies)` - Return a simplified version of the expression.
• `expr.expand()` - Return an expanded version of the expression.
• `expr.sub(substitutions, equivalencies, substituteUncertainties, evaluateSymbolicConstants)` - Takes an object mapping variable names to values, and returns a new expression with each variable replaced by its value. Values can be numbers, other variables, or even other expressions. If substituteUncertainties is true (default is false), then instead of substituting the values into variables, the values will be substituted into the uncertainties of those variables instead. If evaluateSymbolicConstants is true (default is false), known symbolic constants will be evaluated.
• `expr.differentiate(variable, equivalencies)` - Takes the name of a variable as a string, and returns the expression solved for this variable as an array of solutions. Expressions are automatically equated to zero.
• `expr.getAllVariables()` - Returns an array of labels of variables that are in the expression.
• `expr.mapOverVariables(fun)` - Maps the function `fun` over all variables, replacing those variables with the return value of `fun(variable)`. Returns a new expression.
• `expr.getUncertainty()` - Returns an expression representing the uncertainty of this expression.
• `expr.toMathML()` - Returns a MathML string of the expression.
• `expr.toLaTeX()` - Returns a LaTeX string of the expression.
• `expr.toFunction(variables..., equivalencies)` - Takes multiple variable labels and returns a JavaScript function that takes values for those variables in order, and then substitutes them into the expression.
• `expr.copy()` - Recursively deep-copy the expression.

`equivalencies` is an object mapping variable labels to an array of variable labels that that variable is equivalent to - for example, if `x` and `y` are equivalent, then you could have `equivalencies = {"x":["x", "y"], "y":["x", "y"]}`. Equivalencies is always an optional parameter.

If you find yourself in need of checking the type of a CQ expression node, or you want to monkeypatch CQ, the raw nodes are provided in `CQ.raw`: `{Add, Mul, Pow, Terminal, Variable, Constant, SymbolicConstant, Uncertainty}`.

## Examples and REPL

### REPL

Here's a JS REPL with Coffeequate v1.2.0 already loaded. Try it out!

### Examples

Here are some examples of Coffeequate in use.

#### Finding freefall speed

``` kineticEnergy = CQ("Ek = 1/2 * m * v**2"); potentialEnergy = CQ("Ep = m * g * h"); // Substitute the potential energy into the kinetic energy. // Then solve for v. v = kineticEnergy.sub({Ek: potentialEnergy.solve("Ep")}).solve("v"); v.toString(); // -1*sqrt(g*h*m)/sqrt(m/2), sqrt(g*h*m)/sqrt(m/2) ```

#### Finding freefall time

``` projectile = CQ("s = u * t + 1/2 * a * t**2"); freefall = projectile.sub({u: 0, a: CQ("g")}); time = freefall.solve("t"); time.toString(); // -1*sqrt(s)/sqrt(g/2),sqrt(s)/sqrt(g/2) ```

#### Time dilation

``` dilation = function(v) {   var td = CQ("Δt * (1 + -v**2 * c**-2)**(-1/2)");   return td.sub({"Δt": 1, "c": 3e8, "v": v}); }; dilation(10).toString(); // 1 dilation(1000000000).toString(); // 0.287348 dilation(CQ("v")).toString(); // 1 + 1.11111e-17*v**2**-1/2 ```

#### Peak of projectile flight

``` s = CQ("u*t + 0.5*a*t**2"); // Vertical position as a function of time. maxT = s.differentiate("t").solve("t"); // Differentiate and equate to zero to find times where s is maximal or minimal. s.sub({"t":maxT}).toString(); // -((0.5*u**2)/a) ```
This project is maintained by Matthew Alger and Buck Shlegeris.