4

I'm working on a side project for my calc class that differentiates simple functions like y=x^2 in Javascript. To do that, I parsed the expression into an Abstract Syntax Tree, and then hardcoded derivative rules like product rule and chain rule.

The only functions that will be put into this are AP Calculus/first year calculus problems, so trig, logs, exponents are all in play

My program takes the derivative just fine, but what I end up with is the function written in a ridiculously unsimplified way.

For example, differentiating x^2 gives (2*(x^(2-1))), which is technically correct, but could be written much easier as 2*x. So far, I have a basic simplifier which basically repeatedly analyzes the tree, and applies a few basic rules.

The general procedure I have is to analyze it with recursive descent.

If the current tree has no variables, evaluate it and replace the current node with the result.

Otherwise, apply a mass of if statements to simplify it. This includes stuff like

  • If you are multiplying by zero, replace the expression with zero
  • If you are multiplying by one, replace the expression with the other operand
  • If you are raising to the power of zero, replace the expression with one.

And so on and so forth. If I actually want to get any real simplification going, like combining like terms, this will quickly spiral out of control. Also, if I want to determine if any two expressions are equivalent, the best solution I have is to simply generate random numbers in the domain of the function, and see if they are equal. This, however, doesn't seem very efficient.

How can I more efficiently determine the equality of two different expressions (A simple example would be x+2 and 2+x), and is there a way to simplify functions without a mass of if statements?

scrblnrd3
  • 7,228
  • 9
  • 33
  • 64
  • 2
    I have a feeling that determining whether two expressions are equal might be the hardest problem in the world. If you had an efficient equality checker, couldn't you could plug in `are_equal(theory_I_want_to_prove, True)`, and prove/disprove any theory you want? – Kevin Mar 21 '14 at 14:02
  • For equality, what I really want is something that will recognize when terms are out of order, like 2+x+x^2, and x^2+2+x – scrblnrd3 Mar 21 '14 at 14:05
  • 4
    @scrblnrd3 why not implement some kind of sort for rule for _commutative operators_ where you order the variables e.g. alphabetically, by exponent with scalars in front – Paul S. Mar 21 '14 at 14:18
  • You can replace x/y by x*y^-1 and x-y by x + (-1)*y. Then you only have times and plus to worry about, you don't need divide and minus. – Robert Dodier Mar 21 '14 at 16:48

2 Answers2

0

I am actually developing a Computer Algebra System which uses a binary tree. It has a comparison function to determine if two expressions (trees) are mathematically equal in order to factorize them. For example:

  • sin(x+1) + sin(1+x) = 2*sin(x+1)
  • sin(x-1) and sin(1-x) cannot be added
  • x + x^2 = x*(1+x)

The algorithm is like this:

Each node have asigned a side (left or right). Search for each operator in the tree, if it is + or * the sides of the childs doesn't matter. But if the operator is /, ^ or - the sides of the childs matter. In the division, who is in the numerator and who is in the denominator. So with this algorithm, x+2 will be equal to 2+x.

Sorry for my bad English :P

gab06
  • 578
  • 6
  • 23
0

I would address the problem in a series of steps on the lines of

  1. Write all polynomial nodes in a "canonical" way
    • For instance, by sorting their monomials using lexicographic order and degree (so that 1 + x gets always represented as x + 1, etc.)
  2. Write all rational nodes in a "canonical" way
    • A rational expression is the quotient of two polynomials, so you would be using 1 above here.
  3. Have a list of identities for every particular function
    • For example, ln(xy) = ln(x) + ln(y), etc.
  4. Have a list of injectivity reductions
    • For example, sin x = sin y if, and only if, x = y + 2*k*Pi for some integer value of k or ln(x) = ln(y) iff x = y, etc.
  5. Etc.

These are just some few ideas to get you started. The project is ambitious enough.

Leandro Caniglia
  • 14,495
  • 4
  • 29
  • 51