Monday, April 04, 2005

Physics 20 Reading List #2

For some of you, last week marked your first encounter with Mathematica. I think you have gotten a good feeling for the power of this tool, but you might also have been puzzled by its sometimes inconsistent or counterintuitive behavior, and you might have wondered what is the best way to achieve certain things. The readings for this week are sure to help you. (In particular, part 3 below should help with item 5 of this week's assignment.)

Please remember that the weekly readings are a required part of your ph20 experience. While you may not end up reading carefully everything that I propose every week, be sure to have a look at everything and see what could be most useful for your learning process.

1. Part of your Mathematica(l) confusion may arise from the fact that this environment allows several different programming styles, listed in the Mathematica manual (this link leads you to your first, short reading for this week). You might not be familiar with some of the styles, which I repeat below (I add links to interesting webpages about various languages, when I know of any; the links are there for your curiosity, but are not required or suggested reading).

- Procedural (or imperative) programming requires you to distill your purpose into a series of operations on data objects, to be executed consecutively (but according to flow-control statements such as ''if'' and ''for''). Operations are organized at various levels in modules. Think C.

- List-based programming formulates most operations as manipulations of lists, which may contain eterogeneous data, and sometimes commands (seen as a special type of data that defines an operation). Think LISP, or Scheme.

- Functional programming organizes tasks around the definition and application of expressions (i.e., functions) rather than the execution of commands. It discourages side effects (as the assignment of permanent values to variables) and encourages the reuse and composition of functions. Haskell is a standard model functional language, but the various LISP dialects are also considered functional.

- Rule-based (or logic) programming uses rules to create statements about our knowledge of a system or problem; the rules are then applied recursively to produce a result. Typical applications are to expert systems and to the automated proving of theorems. The canonical language is Prolog.

- Object-oriented programming endows data structures (i.e., objects) with properties (attributes) and behaviors (methods). The same method can be defined in different ways for different objects (polymorphism), and objects can sit in a hierarchy united by inheritance relationships. Think C++.

- String-based programming. Not very interesting.

At the end of the page suggested for your reading, Wolfram technical writers show you how to define the factorial function in twelve different ways. What power, but what confusion!

2. Your second reading: a 1993 interview of Stephen Wolfram, Mathematica's creator. He recounts why the software was created, and how it gained widespread acceptance in the industrial and educational community by appearing at the time when workstations (as opposed to mainframes) powerful enough to run it were beginning to be available.

I agree with Wolfram when he points out that Mathematica contains a much broader variety of programming notions and constructs than most other languages, and therefore can be very useful to teach computation to beginners. As I hinted above, the price for this is a lack of elegance and beauty. In this lab we care about beauty as a defense from complexity! With Mathematica, it can be very easy to build byzantine structures that encode very sophisticated mathematics and numerical analysis, but debugging them can be very troublesome.

Wolfram makes another good point about the blending of mathematics and computation in Mathematica, allowing a ''gentle start'', and harking back to the times when computer science was being developed by eminent mathematicians such as von Neumann and Turing. Again, I agree. It is not by chance that this computational physics laboratory begins with Mathematica.

3. Item 5 of this week's assignment presents you with a Mathematica conundrum. You are asked to define a series of functions that take certain parameters as input (such as the initial velocity of the grapefruit) and then feed it to specific numerical Mathematica functions (such as NDSolve[], or FindRoot[]), which will fail if their input is symbolic, rather than numeric. For instance, NDSolve[] can only solve differential equations where everything (except for the unknown functions of time) is spelled out as numbers, so it will return a good solution for
NDSolve[{y''[t] == -9.8, y'[0] == 0, y[0] == 0}, y[t], {t,0,10}]

but it will fail for
NDSolve[{y''[t] == -g, y'[0] == 0, y[0] == 0}, y[t], {t,0,10}]

where g has not been assigned as a number.

Why is this a problem? Well, you may want to have FindRoot (say) call NDSolve repeatedly, trying many values for the parameter (say) g until a certain criterion is satisfied. But because of the way FindRoot evaluates its arguments initially, it may call NDSolve once without assigning any value to g, which will cause NDSolve to fail.

The solution is to mark the argument list of any user-defined function that uses NDSolve, FindRoot, etc., so that it will be evaluated only if it is called with numerical parameters. For instance,

mysolver[g_?NumericQ] := (
sol = NDSolve[{y''[t] == -g, y'[0] == 0, y[0] == 0}, y, {t, 0, 10}];
y[5] /. sol[[1]]
);

will only try to solve the differential equation (and return the value of the solution at time 5) if it is called with a numerical value. The ?NumericQ clause serves to test the type of the argument. (If you had previously defined mysolver[] with a generic argument, the new restrictive definition would be added to the general one, but would not replace it. Thus, calling mysolver[] with a non-numeric argument would still use the more general definition, resulting in an error. Clear[] is useful in these situations.)

You can find more about Mathematica's tests and more generally about its pattern matching capabilities in the Mathematica manual.

4. Let's close this reading session with a few places where you can go if you want to dig deeper into the inner workings of Mathematica.

- You may occasionally wonder what is the difference between set (=) and set-delayed (:=)? (Many other useful tricks can be found on the same website.) Learn about the evaluation process in Mathematica, and then go on to the nonstandard evaluation of commands like Plot[].

- (Optional) Functional programming, mentioned above, is an especially efficient way to program in Mathematica, and perhaps the way that is most faithful to the Mathematica spirit of blending mathematics and computer science. The relevant Mathematica commands are Function[], Map[], Apply[], Fold[], Nest[], and others. Read the chapter on functional programming in the Mathematica manual. Stop when you feel that your incremental learning function has flattened out.

- (Optional) Richard Gaylord has an interesting tutorial on the Fundamentals of Mathematica Programming. This material is not elementary: check it out if you are interested in the internal organization of Mathematica.

0 Comments:

Post a Comment

<< Home