Saturday, October 15, 2005

Physics 20 Reading List #4

This week you will be reading about the integrating powers of Mathematica, about passing functions as arguments in Python and C++, and about the basics of numerical integration.

1. Mathematica and integration

In the introduction to this week's assignment I mention Mathematica's Integrate[] function (see secs. 3.5.6--3.5.8 of the Mathematica manual) and its numerical cousin NIntegrate[]. Mathematica contains a very powerful algorithm to perform integrals analytically; so powerful, in fact, that Wolfram decided to show it off by allowing free web access to the Integrate[] function (can you come up with an integral that Mathematica cannot do?). While you're visiting that site, have a look at its brief history of integration, and at its description of the algorithm used internally by Mathematica. Also, learn a bit more about the Risch algorithm.

2. Passing functions as arguments:
  1. Python

    To complete this week's assignment, if you are using Python, you need to know about Python functions: read about them in your favorite Python manual, in Guido van Rossum's Python Tutorial, in How to Think Like a Computer Scientist, or in the Python Grimoire.

    Make attention in particular at how functions are primitive objects in Python (in fact, everything is an object in Python). Thus, we could define a function evalinzero(f) which returns the value of another function for x = 0:

    >>> def evalinzero(f):
    >>> return f(0)

    we then have

    >>> import math
    >>> evalinzero(math.exp)
    1.0

    which works also for home-grown functions,

    >>> def xplusone(x):
    >>> return x+1.0
    >>>
    >>> evalinzero(xplusone)
    1.0

    and even for lambda functions,

    >>> evalinzero(lambda x: x+1.0)
    1.0


  2. C++

    Passing function names as arguments to other functions in C++ takes a bit more effort; this is because C++ insists on knowing the types of all arguments to all functions, just like it insists that you declare all variables. While this strong typing may seem annoying at times, it helps greatly in preventing bugs.

    The easiest way to pass a function as an argument to another function in C++ is to pass a reference to the function. For those C programmers among you, a reference is sort of like a pointer that is allowed to point to only one thing during its lifetime; in C++ you should avoid pointers unless you really must use them, since pointers easily lead to bugs. Here's how you pass a function reference to another function, using as an example the same 'evalinzero' function that evaluates an arbitrary function at x=0:

    #include <iostream>
    #include <cmath>
    // The function 'evalinzero' takes one argument, which is declared as double (&f)(double).
    // This means 'a reference to a function with local name f that takes a double and returns
    // a double'.
    // Likewise double (&g) (int) would mean 'a reference to a function with local name g that
    // takes an int and returns a double'.
    double evalinzero(double (&f)(double)) {
    return f(0);
    };
    // Here is a test function.
    double func(const double x) {
    return exp(2.0*x)+3.0;
    };
    // Here is the main code.
    int main() {
    std::cout << evalinzero(func) << std::endl;
    };

    Running this code should produce '4.0' as output.


3. Numerical integration

After reading the introduction to numerical integration in this week's assignment, have a look at Secs. 4.0 and 4.1 in Numerical Recipes in C (we also have several copies of this book in the lab).

If you wish to try your hand at the final, optional item in the assignment, read also Sec. 4.3 on Romberg Integration.

0 Comments:

Post a Comment

<< Home