Real Number Symbolic Differentiator


In addition to simply building and evaluating an expression as in Arithmetica, you should allow the user a new command: to differentiate an expression. Symbolic differentiation finds the derivative of a given expression with respect to a given variable, producing a new expression as its output. In general, symbolic mathematics programs manipulate formulas to produce new formulas, rather than performing numeric calculations based on formulas. In a sense, symbolic manipulation programs are more powerful: a formula provides answers to a class of problems, while a numeric answer applies only to a single problem.

For example, if the given expression is ax2 + bx + c and the variable to differentiate with respect to is x, the command should return 2ax + b. Symbolic differentiation is of special historical because it was one of the motivating examples behind the development of a class of computer languages specifically design for symbol manipulation. Furthermore, it marked the beginning of the line of research that led to the development of powerful systems for symbolic mathematical work, which are currently being used by a growing number of applied mathematicians and physicists.

Differentiation of any such expression can be carried out by applying the following reduction rules; the notation used is d/dx[form] where x is the variable with respect to which the derivative is taken and form is the formula whose derivative is desired; the operator ^ is used to denote raising to a power, e.g. x^2 = x*x.

  1. d/dx[c] = 0 , where c is a numeric constant.
  2. d/dx[x] = 1
  3. d/dx[v] = 0 , where v is a variable other than x.
  4. d/dx[u + v] = d/dx[u] + d/dx[v]
  5. d/dx[u - v] = d/dx[u] - d/dx[v]
  6. d/dx[-v] = - d/dx[v]
  7. d/dx[u * v] = u * d/dx[v] + v * d/dx[u]
  8. d/dx[u / v] = (v * d/dx[u] - u * d/dx[v]) / v^2
  9. d/dx[u^c] = c * u^(c - 1) * d/dx[u] , where c is constant.
  10. d/dx[sqrt(u)] = (1/2) * d/dx[u] / sqrt(u)
  11. d/dx[log(u)] = (d/dx[u]) / u
  12. d/dx[exp(u)] = exp(u) * d/dx[u]
  13. d/dx[sin(u)] = cos(u) * d/dx[u]
  14. d/dx[cos(u)] = - sin(u) * d/dx[u]
  15. d/dx[tan(u)] = (1 + tan(u)^2) * d/dx[u]

Observe that a number of the rules are recursive in nature. That is, to obtain the derivative of a sum we first find the derivatives of the terms and add them. Each of the terms may in turn be an expression that needs to be decomposed. Decomposing into smaller and smaller pieces will eventually produce pieces that are either constants or variables, whose derivatives will be either 0 or 1.

Although many of the operators are similar to Arithmetica, you will also be supporting functions that produce real number values. Thus your version of this program should use double values as its data type instead of int.

Your program should recognize the following expressions:
expression
syntax
semantics
examples
Constant
<any real number>
[0-9]+(.[0-9]+)?
a real number constant
87
13.5
0.432
Variable
<any string>
[a-zA-z]+
an expression represented by a word
a
bugs
totalSquished
Assignment
var = expr
assigns an expression to a variable
a = 87
bugs = 12.12 * a
a = b
Unary Operator
op expr
prefixes an expression 
-   // negation
-13
-(a + b * c)
-bugs
Binary Operator
expr op expr
combines two expressions into a single expression (in precedence order)
*   // times
/   // divide
+   // plus
-   // minus
^   // exponentiation
a + b
a / 2
a + 10 ^ c
Unary Functions
fun(expr)
a function that takes an expression as its single argument
sin    // sine in radians
cos    // cosine in radians
tan    // tangent in radians
sqrt   // square root 
sin(a * b)
sqrt(x) - y ^ 2
Binary Functions
fun(expr,...)
a function that takes two arguments; the first of which is an expression and the second is shown below
log(expr, constant) // log base constant
d(expr, variable)   // derivative w.r.t. variable
f(expr, var=value)  // evaluate expr with var=value 
d(x^2, x)
Parentheses
(expr)
raises an expression's precedence
(a + b) * 3
3 * (bugs + t)

Operators have the following precedence from left to right (listed from highest to lowest):

() parentheses
- unary operators
^ power operators
*, /, % arithmetic operators
+, - arithmetic operators
= assignment

Extra Credit

The program produces answers that are correct; however, they are not simplified. For example:

d(x * y, x) = x * 0 + 1 * y

but we would like the program to know that x * 0 = 0 and 1 * y = y. Thus simplifying the answer above to just y. Although, it is easy to catch some common cases at the point of generation. In general, algebraic simplifiers may be very complex.

Resources


Comments?