Minima

advertisement
1 MINIMISATION PROBLEMS
This practical introduces the following:




Potential energy and stable equilibrium
The use of functions in C programming.
Using GNUPLOT to draw graphs
The Newton-Raphson method for finding the zeroes of a mathematical function.
1.1 Potential energy and stable equilibrium
In mechanics you have met the potential energy V of a particle, which in general varies with the
particle's position. Consider a particle moving along the x axis - the force on it in the x direction
at the point x is the negative gradient (slope) of the potential energy function at that point,
Fx ( x )  
dV
. Therefore the force is zero at a stationary point of the function V(x). Close to a
dx
potential minimum the force is always towards the bottom of the potential well, while near a
maximum the force is away from the top of the potential 'hill'. So the bottom of a potential well
is a point of stable equilibrium, while a maximum of the potential is a point of unstable
equilibrium from which the particle tends to move away under the slightest perturbation. A point
of inflection is also a point of unstable equilibrium.
It is important to identify the states of stable equilibrium of particles or systems of particles, and
this involves finding the minima of potential energy functions. For one-dimensional problems
this means we must find the points where the slope of V(x) is zero, and its second derivative is
positive.
1.2 Functions in C
This section introduces the use of functions in C through an example. For further information on
functions in C, see Manual IV section 1.
The program root.c (provided electronically as well as on page 3) uses a very simple algorithm
to find a root of a quadratic function, f(x) = ax2 + bx + c.
The method used (the algorithm) is as follows:
1. Choose two values of x: x1 for which f(x1)<0 and x2 for which f(x2)>0.
2. Calculate f(x3) where x3=( x1+ x2)/2.
3. If f(x3)<0, then repeat steps 1 and 2 using x1=x3 and x2. If f(x3)>0, then repeat steps 1
and 2 using x1 and x2=x3.
4. Repeat the process until f(x3) equals zero to within the desired accuracy. Then this
value of x3 is a root of f(x).
1
A do-while loop has been used in the program to implement this algorithm. One way to write
the loop is the following:
do{
x3 = (x1 + x2)/2;
f=a*x3*x3+b*x3+c;
if (f>0){
x2=x3;
}
else {
x1=x3;
}
} while(fabs(f)>min);
(The values of x1, x2, a, b, c and min are defined earlier in the program.) Notice the while
condition - the loop is repeated as long as the absolute value of f(x3) is greater than some value
min. If we asked the program to stop when f(x3) =0 it might never stop! Instead it stops when
f(x3) is less than or equal to some value min which is set to a small number, for example 10-3,
which determines the accuracy to which the root is calculated.
Now compare the loop in root.c with the loop above. The form of f(x) does not appear. Instead
you see the statement f=func(x3, a, b, c); This is a call to the C function named func, which is
a separate subprogram, located after the brace } which closes main(). The call includes the
values of the parameters needed to evaluate f, enclosed between brackets. These parameters
are the values of a, b and c which are set earlier in the program, and the current value of x3. This
statement shifts operation to func(), where the appropriate value for f is calculated and returned
to the loop. Next time round, the function is called again with the same values of a, b and c but a
new value for x3.
Next look at the function func(x, a, b, c). First there is a heading (the function header):
double func(double x, double a, double b, double c)
This is of the form type name(parameters), where type refers to the number which this
function returns to main (a double in this case), name is the function name (func in this case),
and parameters are the numbers sent from main: a, b and c identify the precise quadratic
function we are dealing with, and the value of x at which the function is to be evaluated.
All statements in the function func(x, a, b, c) are placed between an opening brace { and a
closing brace }, just as all the statements in main() are between opening and closing braces. In
fact main is itself a function with the header main(). Since all C programs must include a main
function, the default type is usually assumed for it, and it is not essential to state its type. Often
there are no parameters to be fed in from outside, so there is nothing between the brackets ( ).
The types of the parameters (a, b, c and x) on which the function func depends are declared in
the function header (as double) and do not need to be declared again inside the function.
However the variable fvalue, which will contain the value to be returned, must be declared. The
following line calculates the appropriate value of fvalue, and the final statement returns this
value to the point in main() from which it was called.
The function itself must be declared before it is used, just like any variable. However since the
function is a separate subprogram outside main, the declaration must also be outside main.
Consequently the first statement after the include statements is a declaration of the function:
2
double func(double x, double a, double b, double c);
This is called the function prototype. Notice that it includes the type of the function itself, as
well as the list of parameters and their types. In fact the prototype looks just like the function
header except that there is a semicolon at the end - it is a declaration statement, not a header.
/* root.c
A simple iteration method for finding the zeroes of a quadratic function
# include <stdio.h>
# include <math.h>
*/
/* necessary for use of abs() */
double func(double x, double a, double b, double c);
/* function prototype */
main()
/* header for function main() */
{
/* start of main() */
double x1, x2, x3, f, f1, f2, a, b, c, min;
int step;
printf("\nEnter values for a, b and c, separated by spaces or carriage returns:\n");
scanf("%lf %lf %lf", &a, &b, &c);
printf("Enter a value of x for which f(x) is negative:\n");
scanf("%lf", &x1);
while (func(x1, a, b, c) >=0) {
printf("f(x) is not negative for this x. Choose another value:\n");
scanf("%lf", &x1);
}
printf("Enter a value of x for which f(x) is positive:\n");
scanf("%lf", &x2);
while(func(x2, a, b, c) <=0) {
printf("f(x) is not positive for this x. Choose another value:\n");
scanf("%lf", &x2);
}
step=1;
min=0.0001;
do{
x3 = (x1 + x2)/2;
f=func(x3, a, b, c);
if (f>0){
x2=x3;
}
else {
x1=x3;
}
step++;
} while(fabs(f)>min);
/* stops loop when f is sufficiently close to 0 */
printf("\nf(x) is zero at x=%0.3lf\n", x3);
printf("Number of steps = %d\n", step);
}
3
/* prints x to 2 places of decimals */
/* end of main() */
double func(double x, double a, double b, double c)
/* function header */
{
/* start of func() */
double fvalue;
fvalue = a*x*x + b*x + c;
return fvalue;
}
/* end of func() */
EXERCISES 1
1. Run the program root.c for a set of values a, b and c which will give 2 real roots.
(N.B. To enter a negative value: for example, -2 for a, enter 0-2.)
It may help you to identify suitable initial values x1 and x2 if you draw a rough graph of f(x),
or plot the function using GNUPLOT as explained in section 1.3.
Check the answer analytically, and note the number of steps taken.
To understand exactly how the program works, do the calculation yourself in the same way
as the computer, and make a list of the values of x1, x2 and x3 at the end of each step. Plot a
graph to show how the value of x3 approaches a root.
2. Investigate how you can obtain a second root of the function by changing the values of x1
and x2 that you enter.
3. Decrease the value of min and investigate how this affects the number of steps taken.
Make the program print the root to an appropriate number of decimal places.
1.3 Using GNUPLOT to draw graphs
When you run the program root.c you are asked to enter two values of x, one for which f(x) is
negative, and the other for which it is positive. To choose such values it will help you to look at
a graph of the function. GNUPLOT is a simple plotting program, described in more detail in
Manual IV section 2.2. Instructions for using it to plot a simple function are given here:

Launch GNUPLOT by typing gnuplot<RETURN>

At the prompt gnuplot> type in the function you wish to plot. For example, for the quadratic
function, type f(x)=a*x*x+b*x+c and press <RETURN>. The multiplication and division
signs and conventions are exactly the same as in C. (You don't need to type in numerical
values for a, b and c at this stage. )

Type in values for the constants followed by <RETURN>, one equation per line. E.g.
a=1
b=3
c= -2
(Each new line starts with the gnuplot prompt.)
4

Type
plot f(x)
followed by <RETURN>
A new window opens up, with the graph of your function. If you want to change the range of x
or y values displayed, go back to the GNUPLOT window, and click on the Axes button in the bar
at the very top. This provides a menu which includes X Range and Y Range. To change the x
range, click on X Range, and fill in the initial and final values of x in the dialog boxes which pop
up. Then at the gnuplot prompt type replot to plot your previous function using the new x range.
1.4 The Newton-Raphson method
A better method of finding the zeroes of a function is the Newton-Raphson method. This is
based on the approximation
f ( x n 1 )  f ( x n )  ( x n 1  x n ) f ' ( x n )
(1)
where f '(xn) is the derivative of the function f(x) evaluated at the point x = xn. (This
approximation consists of the first two terms of the Taylor expansion for f(xn+1) about the point
xn). We wish to find the value xn+1 for which the function is zero. So equating the right hand
side of equation (1) to zero will give an approximate value for a root:
x n 1  x n 
f ( xn )
f ' ( xn )
(2)
Unless the initial value of xn is very close to a root, this will not be a good approximation, so the
calculation must be repeated, and successive approximations to the root obtained.
The Newton-Raphson algorithm is as follows:
1. Choose an initial value x1.
2. Calculate f(x1) and f '(x1).
3. Calculate an approximation to the root, x2, using equation (2).
4. Repeat steps 2 and 3 using x2 instead of x1 to get a new approximation x3.
Loop through steps 1 and 2 until the value of f(x) is sufficiently close to zero.
EXERCISES 2
1.
Write a program which uses the Newton-Raphson method to minimise a function f (x):

Use the program root.c as a model and edit the algorithm, introducing a second
function which calculates the derivative f '(x) (=2ax+b in the quadratic case).
Make sure you have added any new declarations that are needed.

Since there may be places where the derivative vanishes, add an if-else statement
to prevent a division by zero error when the program is run. This statement
should cause the program to terminate if f '(x)=0, and print a message stating
what has happened, the value of x for which this occurs, and the number of steps
taken. To make the program terminate, use the statement exit(1). The function
exit() is defined in the header file <stdlib.h>.
5

2.
Compare the performance of the Newton-Raphson program with that of root.c.
For the same values of a, b and c and the same accuracy, compare the number of
steps taken to produce an answer.
The interaction potential between the Na+ and Cl ions in a molecule of NaCl can be
approximated by
V (r )  
e2
  e r / 
r
(3)
The first term is the Coulomb attraction between the ions treated as point charges
separated by a distance r. The second results from the distribution of the electron within
the molecule. Suitable values for the parameters are:
=1.09x103 eV, =0.033 nm, e2/(4)= 1.44 eV nm. (1 nm = 109 m).
The bond length in the NaCl molecule is the value of the separation r of the ions at the
minimum of the potential (3).

Use your Newton-Raphson program to find where the derivative of this potential
vanishes, and thus where the potential has either a minimum or a maximum.

How can you tell that you have found a minimum of the potential rather than a
maximum? Add a statement which will make your program identify when the
answer corresponds to a minimum.

What is the value for the bond length of the NaCl molecule?

Use GNUPLOT to plot the potential (3), and identify the minimum found using
your program.
6
SUPPLEMENT TO MINIMISATION PROBLEMS
1.5 Equilibrium of a particle in more than one dimension
For a particle moving in two or more dimensions the potential energy may be a function of
several variables, e.g. V(x,y). In this case, the components of the force in the x and y directions
are determined by the corresponding partial derivatives:
Fx ( x , y )  
V
V
, Fy ( x , y )  
x
 y
(4)
The vector form of this equation is
 V  V 
F( x, y)  V ( x, y)   
i
j
 x  y 
(5)
V(x,y) is the gradient vector of the potential energy function, and the force is in the opposite
direction to the gradient.
For equilibrium each component of the force must vanish separately, and for a minimum the
slope of V(x,y) must be positive in any direction. So all the second partial derivatives must be
positive:
 2V
 2V
 2V
 2V
,
,
and

0

0

0
 x y  y x
 x2
 y2
(6)
Similarly for a maximum, all second partial derivatives must be negative.
In two dimensions, however, there is another type of stationary point, where the function is a
minimum along one axis but a maximum along the other. Imagine a function which represents
the height of a landscape: a pass between two mountains would be an example of an extremum
of this type. This is called a saddle point.
1.6 Method of steepest descent
Suppose that you are standing on a hillside and wish to descend to a valley below by the quickest
route but that you are unable to see far enough into the distance to plan a route from where you
are standing. The simplest approach that you could adopt for getting to the valley would be to
take steps in the direction where the downward slope of the hill is steepest, viewed from where
you are standing. This is the essence of the steepest descent method for finding the minimum of
a function of two variables V(x,y).
The gradient V of a function V(x,y) is a vector perpendicular to the surface V=constant. In the
hillside analogy, V corresponds to the vertical height, and V is in the direction where the slope
of V is largest, i.e. in the direction where the ground slopes upward most steeply from the point
where you are standing. Moving in the opposite direction to this gradient will take you downhill
7
most rapidly. So in the case of the particle moving in a potential V(x,y), the opposite direction to
the gradient at any point is the direction in which the potential decreases most steeply.
According to equation (6), this direction is also the direction of the force at that point.
So to use the steepest descent method, choose some starting point (xo,yo) and compute the
gradient vector of the potential function at that point. The first step is taken in the opposite
direction to this vector with a certain step length, , which ends at the point (x1,y1). If the step
length is too long then the step may overshoot the minimum of the function. This is because you
are guessing at the value of the function a steplength away using a linear approximation. If the
step length is too short then the programme will be inefficient. In fact, the optimum step length
will depend on the actual size of the local gradient of the function. The steepest descent method
applied to a function of two variables takes the form
x i 1  x i  
V
x
y i 1  y i  
V
 y
(7)
where (xi,yi) is the ith iterate of the starting point (xo,yo). To search for a maximum instead of a
minimum, the minus sign in equation (7) is replaced by a plus sign.
EXERCISES 3
1. Edit your minimisation program to find the stationary points of a function using the iterative
method given in equation (7).
2. Use your program to find the stationary points of the functions f(x,y), g(x,y) and h(x,y):
f ( x, y) 
1 2
(x  y2 ) ,
2
g( x, y) 
1 2
(x  y2 ) ,
2
h( x , y )  10 
1 2
(x  y2 )
2
You must choose a stepsize,. (0.01 might be a suitable value).
 For the functions f and h you should find that the stationary point is reached in
approximately the same number of steps no matter what starting point (xo,yo) you
choose so long as those points are the same distance from the stationary point.
Explain why.
 For the function g you will find rather different behaviour depending on the starting
point you choose. Choose the minus sign in the iterated equation to find a minimum
value and observe the trajectories of the iterated points when you use (0,1), (1,1),
(1,0) and (1,0.01) as starting points. Explain why you might expect to find the
behaviour you actually observe.
3. Three electrons are confined to move on a ring of radius R as shown below. Find the
equilibrium positions of the electrons.
8
y
2
3



R
1
x
It is convenient to think of one charge as fixed on the x axis, and identify the
positions of the other two by their polar coordinates (R ,1) and (R ,2). The
potential energy associated with each pair is inversely proportional to the separation
of the two charges. For example, the potential energy of the 1st and 2nd electrons is
V12  
e2
4
0
1
e2

r12
4
1
0
2 R sin( 1 / 2)
where r12 = 2R | sin (/2)| is the distance between the two electrons, which is a
positive number. Note that the separation of the 2nd and 3rd electrons is
(2R) |sin (( )/2)|. Write down an expression for the total potential energy V of
the three electrons.

The gradient operator in polar coordinates has radial and transverse components

1 
and
respectively. In this case the radial distance R of each electron is
r
r
fixed. Calculate the gradient of V12 (treating as the variable).

In this case the two variables on which the potential V depends are the two angles
and. Calculate the gradient of V, and use your program to minimise the total
potential energy of the three electrons. What are their relative angular positions in
this minimum energy configuration? Give a physical explanation of why this
configuration leads to a minimum potential energy.
9
Download