Formula (MathObject Class)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

The Formula Class

A Formula object represents an expression whose result is one of the MathObject types defined above. These act like functions in that you can evaluate them at different values of the variables that they use, or substitute other expressions for the variables (to form compositions).

```   \$f = Formula("2x^2+3x-5");

\$a = random(2,5,1);
\$b = random(5,9,1);
\$f = Formula("x^2 + \$a x + \$b");
```

The variables used in a Formula must be declared in the Context. The Numeric Context has `x` pre-defined, but you can add more, as in the following example:

```   Context("Numeric");

\$f = Formula("x^2 + 2xy + y^2");
```

Formulas can be added, subtracted, multiplied, etc, to obtain new Formula objects, and functions like `sin()`, `sqrt()`, and so on will return Formula objects when their arguments are formulas:

```   \$x = Formula("x");
\$f = 3* \$x**2 - 2 * \$x + 5;    # same as Formula("3x^2 - 2x + 5");
\$g = \$x - 5;
\$h = \$f / \$g;                  # same as Formula("(3x^2 - 2x + 5) / (x - 5)");
\$g1 = sin(\$g)                  # same as Formula("sin(x-5)");
```

Formulas can produce any type of MathObject as its result, including points, vectors, intervals, etc. For example,

```   Context("Vector");
\$f1 = Formula("<2x+1,1-x,x^2>");           # a vector-valued formula

\$f2 = Formula("(1,3,-2) + t <4,-1,2>");    # a parametric line

Context("Interval");
\$f3 = Formula("(x,2x+1]");                 # an interval-valued formula
```

If you substitute values as coefficients in a formula, you may end up with things like `1 x^2 + -3 x + 0`, but Formulas have a `reduce` method that can be used to remove coefficients of 1, simplify addition of negatives, remove sums or products of 0, and so forth. E.g.,

```   \$f = Formula("1 x^2 + -3 x + 0")->reduce;  # same as Formula("x^2 - 3x");
```

There are a number of reduction rules, and you can enable or disable them individually (reference needed). Note, however, that MathObjects is not a full computer algebra system, and the reduction rules are mainly geared toward improving the output, not solving equations or performing algebraic manipulations to simplify the expression.

Given a Formula, you may want to evaluate the Formula at a particular value of its variable; that can be accomplished by the `eval()` method. The arguments to `eval()` assign values to all the variables of the Formula, and it returns the value of the Formula for those inputs. For example:

```   \$f = Formula("x^2 + 2x + 1");
\$a = \$f->eval(x=>2);            # f at x=2, or Real(9)

\$g = Formula("xy + x + y");
\$b = \$g->eval(x=>2,y=>3);       # g at (x,y) = (2,3), or Real(11);
```

The `substitute()` method is similar to `eval()`, but in this case, the specified variables are replaced by the values that are given. The values need not be constants; they could be Formulas, in which case the result is the composition of the two Formulas. Note that not all the variables need to be substituted (unlike with `eval()`, where all variables must be given a value).

```   \$f = Formula("x^2 + 2x + 1");
\$g1 = \$f->substitute(x => "y");            # same as Formula("y^2 + 2y + 1");
\$g2 = \$f->substitute(x => "2x-1");         # same as Formula("(2x-1)^2 + 2(2x-1) + 1");

\$h = Formula("xy + x + y");
\$h1 = \$h->substitute(x => "y");            # same as Formula("y*y + y + y") or Formula("y^2 + 2y");
\$h2 = \$h->substitute(x => 2, y => "3x");   # same as Formula("2(3x) + 2 + 3x");
```

If you need to evaluate a Formula multiple times (for example, to produce a graph), it is not very efficient to use `eval()`. Instead, you can use the `perlFunction` method to generate a native Perl function that you can call to evaluate the Formula. If given no arguments, `perlFunction()` returns an anonymous code reference to a subroutine that evaluates the Formula; the parameters to the subroutine are the values of the variables (in alphabetical order). If a single argument is given, it is the name to give to the subroutine; if two arguments are given, the second is an array reference that lists the order of the variables to use for the arguments to the subroutine.

```   \$f = Formula("x^2+y");

\$F = \$f->perlFunction;            # anonymous subroutine reference
\$a = &{\$F}(2,3);                  # value of \$f for x=2 and y=3, i.e., Real(7)
```
```   \$f->perlFunction("F");            # subroutine named F
\$a = F(2,3);                      # again, Real(y)
```
```   \$f->perlFunciton("G",["y","x"]);  # change order of variables in arguments to G
\$a = \$G(2,3);                     # value of \$f for y=2 and x=3, i.e.,  Real(11);
```

You can obtain the derivative of a Formula using the `D()` method. If the Formula has more than one variable, then you need to indicate which one to differentiate by; you do this by giving the variable name as an argument to the method. You can get second or third derivatives (or higher) either by using `D()` a second time or third time, or by including more variable names in the call to `D()`. For example:

```   \$f = Formula("3x^2-5x+2");
\$df = \$f->D('x');                    # same as Formula("3*(2x)-5");
\$df_4 = \$df->eval(x=>4);             # f'(4), i.e., Real(19);
\$ddf = \$df->D('x');                  # same as Formula("6");
\$ddf = \$f->D('x','x');               # same as above

\$f = Formula("x^2 + 4xy^2 + y^3");
\$fx = \$f->D('x');                    # same as Formula("2x+4y^2");
\$fxy = \$fx->D('y');                  # same as Formula("4*(2y)");
\$fxy = \$f->D('x','y');               # same as above
```

See the Using Math Obejcts POD documentation for more information about Formula objects and how to use them.