7
$\begingroup$

I'm writing this fairly simple function:

hermite[0, x] = 1;
hermite[1, x] = 2 x;
hermite[n_, x_] := (
  hermite[n, x] = 2 x*hermite[n - 1, x] - 2 (n - 1) hermite[n - 2, x];
  Expand[hermite[n, x]]
  )

But the Expand command is ignored.

Yet, when I do

Expand[hermite[10, x]]

The result is expanded like I wish.

Why is it not working when I put the same command inside a function? I'd like to do it in the function; it would be cleaner.

$\endgroup$
2
  • 5
    $\begingroup$ You forgot the underscore after x in the first two definitions. Now, these functions only work if you provide them with the symbol x as argument. Overall I'd say this is a bit messy definition. I have no Mathematica at hand at the moment, but I think the second time you evaluate this with the same arguments you already have stored a definition for these arguments which is then executed and you'll never get to the Expand. It looks like you have been incorrectly modifying a memoizing definition of hermite. $\endgroup$ Apr 23, 2012 at 14:33
  • $\begingroup$ Audrey, you might want to take a look at this question, which gives better methods for implementing multiparameter recursive functions. $\endgroup$ Apr 27, 2012 at 14:25

2 Answers 2

14
$\begingroup$

To implement what you intended to do, I suggest to take a look at this approach :

hermite[0, x_] := 1
hermite[1, x_] := 2 x
hermite[n_Integer /; n >= 2, x_] :=
    hermite[n, x] = Expand[2 x*hermite[n - 1, x] - 2 (n - 1) hermite[n - 2, x]]

Now you shouldn't have problems anymore.

Recalling that there are in Mathematica the Hermite polynomials $H_{n}(x)$ since the version 1, namely HermiteH function, we can check if the above is correctly implemented :

And @@ SameQ @@@ ({hermite[#, x], HermiteH[#, x]} & /@ Range[100])
True

e.g.

hermite[10, x]
-30240 + 302400 x^2 - 403200 x^4 + 161280 x^6 - 23040 x^8 + 1024 x^10

The problem with your approach appears with so-called memoization of

2 x*hermite[n - 1, x] - 2 (n - 1) hermite[n - 2, x] 

but not Expand[hermite[n, x]], so there you had i.e.

hermite[5, x]
2 x (12 - 48 x^2 + 16 x^4) - 8 (-8 x + 2 x (-2 + 4 x^2))

instead of

120 x - 160 x^3 + 32 x^5

We solved the problem by remembering

Expand[ 2 x*hermite[n - 1, x] - 2 (n - 1) hermite[n - 2, x] ]

To avoid another possible problems with the variable n, I included a condition in the definition of hermite[n, x]. In your approach you had i.e. hermite[1, x] = 2 x; and so evaluating i.e.

Plot[{hermite[0, x], hermite[1, x]}, {x, -5, 5}]     (* A *)

a message is generated $RecursionLimit::reclim of exceeded $RecursionLimit (by default its value is 256). To avoid this problem you have do this :

 Plot[ Evaluate @ {hermite[0, x], hermite[1, x]}, {x, -5, 5}]  (* B *)

With my approach you needn't evaluate the functions, so you can choose (* A *).

$\endgroup$
5
$\begingroup$

For me, both return the same result. Quit the kernel and restart or, use

ClearAll[hermite]
hermite[0, x] = 1;
hermite[1, x] = 2 x;
hermite[n_,x_] := 
   (hermite[n, x] =  2 x*hermite[n - 1, x] - 2 (n - 1) hermite[n - 2, x];
    Expand[hermite[n, x]]
   )

As suggested in the comments here is the version you are likely after:

ClearAll[hermite]
hermite[0, x] = 1;
hermite[1, x] = 2 x;
hermite[n_, x_] := 
 hermite[n, x] = 
  Expand[2 x*hermite[n - 1, x] - 2 (n - 1) hermite[n - 2, x]]

In the comments it was suggested to mention that in functions that have attribute Hold you are better of to call Evaluate as in

Plot[Evaluate[{hermite[0, x], hermite[1, x]}], {x, -5, 5}]

to avoid recursion.

$\endgroup$
8
  • $\begingroup$ oh, right, thanks. $\endgroup$
    – Audrey
    Apr 23, 2012 at 14:09
  • 3
    $\begingroup$ By memoizing the unexpanded version of hermite you create a subtle bug. E.g, the first call to hermite[3, x] returns the expanded version -12 x + 8 x^3 whereas all subsequent calls will return the unexpanded version -8 x + 2 x (-2 + 4 x^2). The solution, of course, is to change the order of operations so that the the expanded version is stored. $\endgroup$
    – whuber
    Apr 23, 2012 at 16:02
  • $\begingroup$ @Artes, what exactly is defective? $\endgroup$
    – user21
    Apr 24, 2012 at 5:56
  • $\begingroup$ Haven't you got any messages $RecursionLimit::reclim ? Here it luckily works, even with them, but in general it is not recommended, e.g. for taking too much memory. $\endgroup$
    – Artes
    Apr 24, 2012 at 6:07
  • $\begingroup$ @Artes, no, no messages for me. $\endgroup$
    – user21
    Apr 24, 2012 at 6:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.