I want continue my explorations of Mathematica. Or rather, I have to since I started to blog about it, and the trial time is slowly ticking away. I am already a bit tired of this program. It may have a lot of features, but I doubt that it is a good tool for me personally. The basic things just seem to be too cumbersome. And the sources for errors are too frequent.
I tried to start programming Mathematica. A very ambitious project would be the Game of Life. I have done this in Java for teaching purposes and in other languages, but never in Euler.
First, I found the cellular automaton of Mathematica, and the example below.
I can guess how to works. The plot, first of all, is a mean value of cell states during the run of the game. I have no idea if this is using an infinite field. Nor do I know any other details of this function or its parameters. The explanation in the documentation is sparse to say the least. The code of the cellular automaton is probably in C.
So I tried a less ambitious idea, the Towers of Hanoi. There is a nice recursive algorithm for this. You move n-1 discs from A to C, then the biggest disc from A to B, and then n-1 discs from C to B.
Towers[n_, a_, b_, via_] := If [n > 0, ( Towers[n - 1, a, via, b]; Print["Move from ", a, " to ", b]; Towers[n - 1, via, b, a] ) ]
There is a nice introduction into this kind of programming on a Wolfram page. The example with the sinc function on that page contains a trivial error and should read „If[x==0,1,sin(x)/x]“, by the way.
Here is the result of my Tower function.
Towers[3, "A", "B", "C"]; Move from A to B Move from A to C Move from B to C Move from A to B Move from C to A Move from C to B Move from A to B
Since Mathematica programming is all done with the idea of pattern matching, the procedural example above is not a good example. You may be tempted to try to define some functions recursively, e.g., the Chebyshev polynomials. It is well known that this is not a good idea, since the recursion has 2 terms
\(T_{n+1}(x) = 2x T_n(x) – T_{n-1}(x)\)
To evaluate this takes a computing time which approximatelygrows like the n-th Fibonacci number, since all values are computed many times. Maxima can remember the intermediate results using
Tf[0, x_] := 1.0 Tf[1, x_] := x Tf[n_, x_] := (Tf[n, x] = 2.0*x*Tf[n - 1, x] - Tf[n - 2, x])
With this, you can plot the 20-th Chebyshev polynomial. Note that I defined Tf with double numbers, which should be faster.
In Maxima via Euler you can do the same. The function needs to be defined as a macro for the indexed variable T, and the values for n=0 and n=1 as variable values. In the compatibility mode of Euler this looks as follows.
>:: function T[n,x] := 2*x*T[n-1,x] - T[n-2,x]; >:: T[0,x] := 1; >:: T[1,x] := x; >&T[20,x]|expand 20 18 16 14 524288 x - 2621440 x + 5570560 x - 6553600 x 12 10 8 6 4 2 + 4659200 x - 2050048 x + 549120 x - 84480 x + 6600 x - 200 x + 1
Of course, it might be better to define this in a loop. In Mathematica, this would be the following.
Clear[T]; T[n_, x_] := If [n == 0, 1, If [n == 1, x, (a = 0; b = x; For [i = 2, i <= n, i++, {a, b} = {b, 2*x*b - a}]; b) ] ]
It took me quite a while to figure this out. The main problem was that my code was faulty and resulted in an eternal loop. I did not notice this and tried to fix it, which is impossible while a loop is running. Later I saw the highlighted bracket indicating the running program and stopped it with Alt-dot. And of course, such kind of spaghetti code is never nice to fix. I got to learn more ways to group commands than the simple (…) with the result b at the end.
It also does not help that Maxima hides the error of commands. You see the yellow color indicating an error, but you need to open a small + sign to see an explanation.