6

I was trying to get Mathematica to simplify some moderately ugly sums and I ran into some pretty weird behaviour, which I tracked down to the following example. I'm working with Christoffel-Darboux-type sums of Hermite polynomials, which are known to simplify nicely, a fact of which Mathematica is aware:

Sum[(HermiteH[k, x] HermiteH[k, y])/(2^k k!), {k, 0, n}]

Out[1]= (2^(-1 - n) (HermiteH[n, y] HermiteH[1 + n, x] - 
HermiteH[n, x] HermiteH[1 + n, y]))/((x - y) n!)

So far so good. However, even simple changes to the above expression make Mathematica output a far more complex answer which is not what I'm looking for in general and which in this case is evidently rather wrong:

Sum[(HermiteH[k, -x] HermiteH[k, y])/(2^k k!), {k, 0, n}]

enter image description here

The problem is somewhat related to this question on Simplify, but I can't see why Mathematica would think the code above is in any way simpler than just

-(2^(-1 - n) (HermiteH[n, y] HermiteH[1 + n, -x] - 
HermiteH[n, -x] HermiteH[1 + n, y]))/((x + y) n!)

Can anyone share some insight? or is this some kind of bug?

Emilio Pisanty
  • 10,255
  • 1
  • 36
  • 69

1 Answers1

3

Before I answer your question, I would like to share some results. Since there was no guarantee that the Christoffel–Darboux formula would be invariant under such a change of variables, I did a simple check:

In[25]:= Sum[(HermiteH[k, -x] HermiteH[k, y])/(2^k k!), {k, 0, 3}]

Out[25]= 1 - 2 x y + 1/8 (-2 + 4 x^2) (-2 + 4 y^2) 
       + 1/48 (12 x - 8 x^3) (-12 y + 8 y^3)

In[26]:= Sum[(HermiteH[k, x] HermiteH[k, y])/(2^k k!), 
             {k, 0,n}] /. {x -> -x, n -> 3}

Out[26]= ((12 - 48 x^2 + 16 x^4) (-12 y + 8 y^3) - (12 x - 
8 x^3) (12 - 48 y^2 + 16 y^4))/(96 (-x - y))

In[34]:= (-1/96)(PolynomialReduce[Numerator@%26, {x + y}, {x, y}])[[1, 1]] 
        == %25 // Expand

Out[34]= True

And, it works at higher values of n, also. Similarly,

In[39]:= Sum[(HermiteH[k, -x] HermiteH[k, y])/(2^k k!), {k, 0, n}];
         (% /. n -> 3) == %25 // Expand

Out[40]= True

This leads me to believe that the answer you're given is absolutely correct, just not in its simplest form.

As to why Mathematica does not recognize the simplification, the answer is simply because it does not know everything, and while such a variable transformation seems easy to us, it is not necessarily straightforward to program.

Edit: Sum behaves this way because the form

Sum[(HermiteH[k, x] HermiteH[k, y])/(2^k k!), {k, 0,n}]

is recognized and the substitution can be made immediately. To allow for the more complex simplification that you wish, we need to create a custom rule for it, as follows

Unprotect[Sum]
Sum[(HermiteH[k_, x_] HermiteH[k_, y_])/(2^k_ (k_)!), {k_, 0, n_}] := 
 (2^(-1 - n) (HermiteH[n, y] HermiteH[1 + n, x] 
  - HermiteH[n, x] HermiteH[1 + n, y]))/((x - y) n!)
Protect[Sum]

which when used with

Sum[(HermiteH[k, -x] HermiteH[k, y])/(2^k k!), {k, 0, n}]

gives the desired result.

A couple of words of caution, though. This is deliberately overriding the built-in behavior of Sum and may affect its behavior in uncertain ways. So, if you decide to take this route, make the substitutions as specific as possible, so that you do not run into unintended behavior.

Sjoerd C. de Vries
  • 65,815
  • 14
  • 188
  • 323
rcollyer
  • 33,976
  • 7
  • 92
  • 191
  • I don't doubt that it is a correct expression, but for symbolic manipulation it is quite useless, since I am trying to get simple algebraic expressions for more complicated quantities than the ones shown here (i.e. sums that I can't do by hand like this one and would like to know whether they simplify or not in "known mathematics"). The question is, why exactly does Mathematica think its answer is simpler than mine, and can this be changed? – Emilio Pisanty Apr 13 '12 at 10:38
  • @episanty I answered the question of why it thinks its form is simpler: it does not know about the alternatives. Also, there may be cases where the alternative explicitly does not work, so then Mathematica's answer would be the correct one. It is those cases you have to be careful of before you attempt to alter its behavior. That said, I added a method to do exactly that in my answer. – rcollyer Apr 13 '12 at 14:40
  • Wouldn't it be safer to create a set of rules ? – b.gates.you.know.what Apr 13 '12 at 14:44
  • @b.gatessucks on the surface, yes. But, the form Sum[...] /. ... doesn't work in this case because the simplification occurs first. The Sum has to be held. So, while not quite as safe as a rule, this was the most straightforward method to accomplish the task automatically. – rcollyer Apr 13 '12 at 14:50
  • @rcollyer Yes, this works for this specific instance, but the scope of the changes is really quite limited. Isn't there a way to prohibit the use of DifferenceRoot, so that hopefully MM will try to explore other avenues? – Emilio Pisanty Apr 13 '12 at 15:36
  • @episanty there are two problems here. First, if you turned it off, Sum won't magically know about how to perform the simplification you want because it doesn't know about it now. Second, as these simplifications are handled internally, turning off this specific simplification would be difficult, and likely would require turning them all off. To turn them off, wrap the code in a Block[{Sum}, <hand coded simplifications>; Sum[...]]. When Block finishes executing the old definition will take over, and any Sum remaining will use the built-in simplifications. – rcollyer Apr 13 '12 at 15:54
  • @episanty Note, within the Block you still have to Unprotect[Sum] to be able to change its definitions. – rcollyer Apr 13 '12 at 15:55
  • @rcollyer I think you misunderstand me - I would like to make the simplification engine assign a prohibitively large weight to DifferenceRoot so that sums MM cannot simplify are returned as is, and hopefully so that all other possible simplifications will be carried out. – Emilio Pisanty Apr 14 '12 at 19:18
  • @episanty no, I did not misunderstand. The difficulty is when the simplification occurs. If this occurred while using Simplify, I'd suggest using either of the options ComplexityFunction or TransformationFunctions to accomplish what you want. But, the simplification occurs before Simplify has a chance to work. So, we need to rely on other means to force Sum to do what you wish. – rcollyer Apr 15 '12 at 01:10
  • @episanty cont'd, hence, the idea of using a custom transformation rule which would do exactly what you wish. But, to stop the use of DifferenceRoot would be difficult, at best, to accomplish as its use is buried deep enough that it is out of user control. I understand your frustration; getting Mathematica to put an expression in a particular form is very difficult, most of the time. I'd argue that it works best as a guide in this particular endeavor, and is ultimately incapable of doing what you want without a lot of manual intervention. – rcollyer Apr 15 '12 at 01:18
  • 1
    @rcollyer hmmmm. Looks like a problem without any reasonable solution, then. Thanks! – Emilio Pisanty Apr 15 '12 at 02:50