Physics 20 Reading List #2
For some of you, this is your first encounter with
Mathematica. This is a powerful tool, but it sometimes
has inconsistent or counterintuitive behavior, and you may sometimes wonder
what is the best way to achieve certain things.
In particular, see below for some more hints about the homework
assignment due Monday Jan 16.
~~~
Some confusion can easily arise from the fact that Mathematica
allows several different programming styles.
Your first short reading is from a section of
the Mathematica manual describing these styles.
At the end this page, Wolfram technical writers show you how to define
the factorial function in twelve different ways (although some of them
are clearly the same way repeated with slightly different syntax).
What power! What confusion!
You may have noticed that functional programming tends to be very
effective in Mathematica. This method 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. (Optional) If you would like to foray
into the realm of more advanced functional programming, take a look at
this section of the Mathematica manual.
~~~
One thing that is troublesome to deal with in Mathematica is the evaluation (or non-evaluation) of expressions. For example, the difference between = and := is that only the former evaluates the right-hand side. See this site for some examples.
An even more troublesome occurrence is when evaluations occur (or do
not occur) 'automatically' in a way different from what you might expect. You may encounter this problem in the last part of the homework assignment, if you try to use a function like FindRoot[] on a function that requires some of its arguments to be numeric, like NDSolve. Notice that NDSolve[] works only if everything except for the independent variable is numerical, so
NDSolve[{y''[t]==-9.8, y'[0]==0, y[0]==0}, y, {t,0,10}]
will work, but
NDSolve[{y''[t]== g, y'[0]==0, y[0]==0}, y, {t,0,10}]
will not work unless g has been assigned a numerical value.
Why is this a problem? Well, suppose you have a function
and you want to pass this function into FindRoot[], iterating over values of g to find a zero. The problem is that
FindRoot[myfunction[g],{g,-5,-20}]
will try to evaluate myfunction before it tries different values of g, and this evaluation is done with a symbolic value of g, so then NDSolve will fail.
There are at least two solutions to this problem. (If you find more, feel free to post a comment!) The first is to use the Hold[] function, which tells Mathematica not to evaluate the function until later:
FindRoot[Hold[myfunction[g]],{g,-5,-20}]
In this case, myfunction[g] is evaluated only after the FindRoot function plugs in numerical values.
Another (in my opinion, better) solution is to define myfunction[] only for numerical arguments:
In this case the Hold[] in the FindRoot[] function is no longer necessary. The ?NumericQ tells Mathematica that the definition you have typed in is valid only for numeric values of g. (If you had previously defined myfunction[] with a general value of g, the new restrictive definition will be added to the original one, but will not replace it. Then calling myfunction[] with non-numeric g will still use the old definition, resulting in an error from NDSolve[]. You should use Clear[] to fix this).
Here are some more links to learn about the standard Mathematica
evaluation process, and about those functions that have nonstandard evaluation rules.
(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.
Mathematica. This is a powerful tool, but it sometimes
has inconsistent or counterintuitive behavior, and you may sometimes wonder
what is the best way to achieve certain things.
In particular, see below for some more hints about the homework
assignment due Monday Jan 16.
Some confusion can easily arise from the fact that Mathematica
allows several different programming styles.
Your first short reading is from a section of
the Mathematica manual describing these styles.
At the end this page, Wolfram technical writers show you how to define
the factorial function in twelve different ways (although some of them
are clearly the same way repeated with slightly different syntax).
What power! What confusion!
You may have noticed that functional programming tends to be very
effective in Mathematica. This method 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. (Optional) If you would like to foray
into the realm of more advanced functional programming, take a look at
this section of the Mathematica manual.
One thing that is troublesome to deal with in Mathematica is the evaluation (or non-evaluation) of expressions. For example, the difference between = and := is that only the former evaluates the right-hand side. See this site for some examples.
An even more troublesome occurrence is when evaluations occur (or do
not occur) 'automatically' in a way different from what you might expect. You may encounter this problem in the last part of the homework assignment, if you try to use a function like FindRoot[] on a function that requires some of its arguments to be numeric, like NDSolve. Notice that NDSolve[] works only if everything except for the independent variable is numerical, so
NDSolve[{y''[t]==-9.8, y'[0]==0, y[0]==0}, y, {t,0,10}]
will work, but
NDSolve[{y''[t]== g, y'[0]==0, y[0]==0}, y, {t,0,10}]
will not work unless g has been assigned a numerical value.
Why is this a problem? Well, suppose you have a function
myfunction[g_] := ( sol=NDSolve[{y''[t]== g, y'[0]==25, y[0]==0},y,{t,0,10}];
y[5] /. sol[[1]]);
and you want to pass this function into FindRoot[], iterating over values of g to find a zero. The problem is that
FindRoot[myfunction[g],{g,-5,-20}]
will try to evaluate myfunction before it tries different values of g, and this evaluation is done with a symbolic value of g, so then NDSolve will fail.
There are at least two solutions to this problem. (If you find more, feel free to post a comment!) The first is to use the Hold[] function, which tells Mathematica not to evaluate the function until later:
FindRoot[Hold[myfunction[g]],{g,-5,-20}]
In this case, myfunction[g] is evaluated only after the FindRoot function plugs in numerical values.
Another (in my opinion, better) solution is to define myfunction[] only for numerical arguments:
myfunction[g_?NumericQ] := ( sol=NDSolve[{y''[t]== g, y'[0]==25, y[0]==0},y,{t,0,10}];
y[5] /. sol[[1]]);
In this case the Hold[] in the FindRoot[] function is no longer necessary. The ?NumericQ tells Mathematica that the definition you have typed in is valid only for numeric values of g. (If you had previously defined myfunction[] with a general value of g, the new restrictive definition will be added to the original one, but will not replace it. Then calling myfunction[] with non-numeric g will still use the old definition, resulting in an error from NDSolve[]. You should use Clear[] to fix this).
Here are some more links to learn about the standard Mathematica
evaluation process, and about those functions that have nonstandard evaluation rules.
(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