You are on page 1of 6

James Lamb

Computer Programming and Numerical Methods


Assessed Problems

For the longer assessed problems my first


task was to find the value of using Monte-Carlo integration of a
circle within a square. Monet-Carlo integration is a numerical
method of evaluating an integral. In one dimension, it takes a
sample of random points over an area containing a function. It then
takes the ratio of the number of points under the function to the
total number of points, and multiplies it by the area the points are
sampled over. This gives an estimate to the total area below the
function and hence the value of the integral.
In order to get an estimate to the value of then the integral of a
circle of radius 1 can be taken, as the area of this circle is . The
function for a circle is r=x 2 + y 2 . X and y coordinates are produced
by a random number generator in the code, giving values between 0
and 1. To get values that cover the area of the square, these are
multiplied by 2, then 1 is subtracted to give values between -1 and
1. These are then compared to the function to see whether they lie
inside or outside of the circle. If x 2+ y 2 is greater than r (where
r=1) then they lie outside, and if it is less than or equal to r they lie
inside. The total count of the number of points within the function is
given by the variable ratio in the code, and for every value of
x 2+ y 2 1 , 1 is added to the value of ratio. Then the final value of
ratio divided by the total number of points generated multiplied by
the area of the square (2x2=4) gives the estimate of .
The random numbers are generated using functions written into
fortran. The random number generator is initiated by calling the sub
program RANDOM_SEED. Now the subprogram RANDOM_NUMBER
can be called to generate a random number. The problem with this
is that each time the program is run the random numbers generated
are exactly the same, so will not be truly random. In order to
compensate for this, the code uses the system clock to assign a
value for the initial seed. As the clock is constantly changing it
generates a different initial seed each time the program is run, and
therefore a new set of random numbers.
Clearly the more random points you generate the more accurate the
estimate of the integral will be, as the ratio will better represent the

James Lamb
area under the function. The next task was to see how the value of
the estimate changes with the total number of points (N). The first
program asks you to input N at the beginning, and it was seen that
results gets closer to the larger the value of N. The calculation
took longer as N increased however, so the CPU_TIME sub program
was used to time the calculation to help compare.
The second program instead takes a starting value of N=10, and
then runs through the same algorithm as the first program 30 times,
doubling N each time. The graph below shows how the estimate
changes, converging towards the red line ( ) as N increases.

Zooming in on the values above 10,000,000 shows a similar


convergence pattern, just over a smaller range for the values of the
estimate, and by 108<N<109 we know to 4 decimal places
(3.1416).

James Lamb

The next part of the project involved modifying this code so it can
be used on an integral between specified limits, in both one and two
dimensions. The one-dimensional code was developed first, as
described below, and then this was further modified to allow twodimensional integrals to be calculated.
The first modification was to allow the user to input the limits the
integral is calculated between, a for the lower limit and b for the
upper. This was done in the same way as reading the users input
for N. When calculating , because r=x 2 + y 2 then r is always
positive for any value of x or y as they are both squared. In reality a
function can be negative as well. When calculating the net integral,
then the value should be the area above y=0 minus the area below
y=0. Therefore I calculate two integrals, int_plus for the total area
above y=0 and int_minus for the total area below y=0. This means I
need to calculate N_plus and ratio_plus for the total number of
points and the number of points within the function for y>0, and
similarly N_minus and ratio_minus for y<0.
These then need to be multiplied by the area that contains the
function above and below y=0. We have the width of the rectangles
as specified by a and b, but we need the heights. To do this I sample
20 points along the function and determine the maximum and
minimum values of the function within the specified limits. As this
cannot definitely give the exact max/minimum, I multiply both by 2
to find an area that completely contains the function. Although this
is still not certain to contain the whole function, for most
applications it should work. The area above the curve is then given
by (b-a)*y_max, and below by (b-a)*y_min. If the minimum value is
above y=0, then y_min must be set to 0 so the area encloses all

James Lamb
values above y=0, similarly if y_max is below 0 then it must be set
to 0 for the same reasoning.
The random number generator works in exactly the same way as for
the program calculating . To get the range of x values specified
by the limits then the random number is multiplied by (b-a) and
then a is added. To get the range of y values that contain the
function then the random number is multiplied by (y_max-y_min)
and then y_min is added. Then for each x value the function is
calculated, and a series of if statements decides whether ratio_plus
or ratio_minus is increased, with N_plus or N_minus increasing each
time the algorithm is run.
The values of the area above and below the curves is then
evaluated, and the net integral then calculated as the area above area below: integral=int_plus-int_minus. This was done for various
types of functions to test its applicability, and done for 3 values of N
to see how the number of points effects the result. I have tried to
incorporate the most common functions we would potentially use;
quadratic (which is used to represent any polynomial type),
exponential, logarithmic, Gaussian and sinusoidal. The codes are
exactly the same just with different equations. The only difference is
in the logarithmic code, where there is a condition on the possible
values for the limits so that the log of a negative number or 0 does
not occur. This would again be different if the equation contained
negative coefficients inside the log, but the adjustments to be made
would be simple. The results are as follows:
Limits
Function
x^2 + 2x +
1

-3

e^(2x + 1)

-2

Number of steps
10000000
10000
1000000
0
23.65440 24.00864
0
0
24.005002
75.27515 74.53071
4
4
74.241391
20.39234 20.26955
4
8
20.266000

Mathematic
a
24
74.1817

2ln(x^2+4)
1
5
20.2672
e^[-((x 1)^2)/2]
-2
4 2.461200 2.502924 2.500104
2.49986
4sin((x2)^2+2)
-3
3 4.189269 4.121586 4.120763
4.11871
These are all compared to the value Mathematica gives for the
integral. As with as N increases the value gets more accurate.
This code was then further modified to allow integration in two
dimensions. The user is able to enter the limits for both the x and y
axis now. The value of the function is evaluated over the area
enclosed by these limits to find z_max and z_min similarly to the
one-dimensional code. These are then doubled or set to 0 as before.

James Lamb

In the algorithm for the calculation of int_plus and int_minus, an


extra random number is generated for the z coordinate. This is the
compared to the function at the same x and y coordinates to see
whether ratio_plus or ratio_minus is increased, again with N_plus or
N_minus increasing every time. Int_plus and int_minus are
calculated slightly differently, as the ratio needs to be multiplied by
the volume the random points are sampled from - (b-a)*(dc)*z_max/min*ratio/N.
The integral is calculated in the same way as the one-dinemsional
code though (integral=int_plus-int_minus). Just as before this was
then tested for a range of functions with varying N. Again, the only
difference was the equation used in the calculations and the
condition preventing the log of a negative number or 0. The results
are as follows:
Limits
Function
x^2 + 2y^2 - 7xy
+x+1
2e^(-2x + y) + 2
ln(3x + y + 2)
E^(-((x-3)^2 + (y1)^2)/5)
-3sin(4x + y^2)

a
3
1

b c
3 3
1 1

1
3
3

5 1
3 3
3 3

3
1

Number of steps
1000000
10000
1000000
00
312.1306 358.7425 360.0261
79
75
73
24.18932 24.93086 25.04236
8
4
8
40.90067 41.68861 41.63904
4
8
2

Mathemati
ca

360
25.0492
41.6382

3 7.156872

7.016393

7.003003

6.99955

3 0.843718

1.156977

1.235367

1.24522

As can be seen both sets of results clearly show that as N increases


the value gets closer to the real integral, and by 10 8 the values are
very close to those obtained using Mathematica.
The submitted programs are named as follows:
Pi.f90 this is the first part of the project which is just the program
to evaluate pi.
PiChanges.f90 this is the modified version of Pi.f90 which does the
same calculation for an increasing value of N.
1D-log.f90 this is the one-dimensional integration code. The
logarithmic one is chosen as this is the only one to have the
constraint on the limits input by the user. The other codes are
exactly the same just with different equations in the calculations
within the program and no constraint on the limits.

James Lamb

2D_log.f90 this is the two-dimensional version, again the log code


is submitted due to the addition code in order to apply the
constraint.

You might also like