# Why does Expand not work within a function?

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.

-
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. –  Sjoerd C. de Vries Apr 23 '12 at 14:33
Audrey, you might want to take a look at this question, which gives better methods for implementing multiparameter recursive functions. –  Ｊ. Ｍ. Apr 27 '12 at 14:25

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.

-
oh, right, thanks. –  Audrey Apr 23 '12 at 14:09
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. –  whuber Apr 23 '12 at 16:02
@Artes, what exactly is defective? –  user21 Apr 24 '12 at 5:56
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. – Artes Apr 24 '12 at 6:07 @Artes, no, no messages for me. – user21 Apr 24 '12 at 6:18 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 *).

-