Académique Documents
Professionnel Documents
Culture Documents
Computational Physics
Physics is a natural science which attempts to describe the Universe in terms of a few basic concepts such
as time, space, mass, and electric charge. These quantities can be assigned numerical values that every
physicist can agree upon. Nature is complex, so physicists choose to study natural phenomena that appear
to be as simple as possible and can be reproduced reliably by other physicists.
Most physicists specialize in one of three types of activity. Experimental physicists observe these
phenomena, measure their properties using instruments, and attempt to discover simple laws describe these
observations: experimental physics is based on technology. Theoretical physicists invent mathematical
models that relate measured properties and construct theories which organize and unify these models:
theoretical physics is based on mathematics. Computational physicists use digital computers to analyze
experimental data and explore the properties of models and theories: computational physics is based on
computer science an numerical analysis.
Experimentalists spend most of their time designing and building instruments, and in collecting and
analyzing experimental data. Theorists work primarily with mathematical theories and equations, and
make predictions that can be verified or falsified by experiment. Computationalists design algorithms to
solve equations or analyze data, write and debug computer programs that implement algorithms, and run
simulations to explore theories and compare with experimental data.
(1)
where r, v are the measured distance and speed of the galaxy located at galactic longitude and latitude ,
and K, X, Y, Z are constants. Fig. 3 shows the results of his analysis. He concluded that
K 500 km/s/Mpc, which is considerably larger that the current best value of Hubbles constant
H(t0 ) 72 km/s/Mpc.
dr2
2
2
2
2
+ r (d + sin d ) ,
ds
g dx dx = c dt R (t)
1 kr2
=0 =0
2
(3)
where R is the cosmological scale factor, r, , are spherical-polar coordinates, and the curvature constant
k = 0, 1 signifies a flat, open, or closed universe.
The simplest assumption about matter and radiation is that it behaves like uniform perfect fluid with
density and pressure p. This leads to the Friedmann-Lamatre equations
2
R
R
!2
c2
8GN kc2
2 +
,
3
R
3
R
4GN
c2
=
( + 3p) +
.
R
3
3
H(t) is the Hubble parameter and its value at the present time t0 is Hubbles constant
H(t0 ) = 72 km/s/Mpc.
(4)
We will study these differential equations later in the course. For this lecture all we need to know is how to
relate them galaxy redshifts in an expanding universe. Suppose R1 is the scale factor when light of
frequency 1 was emitted from a distant galaxy, and R2 is the scale factor when this light is observed on
Earth with frequency 2 , then the redshift z is given by
z+1=
R2
v12
1
,
=
1+
2
R1
c
(5)
where v12 is the speed of the distant galaxy relative to the observer.
Least-squares algorithm
The least-squares algorithm determines the model parameters a, b by minimizing the function
f (a, b)
n1
X
i=0
(yi a bxi ) .
(7)
This procedure tends to make the deviation of yi from the point y(xi ) = a + bxi on the straight line as
small as possible. The derivatives of f vanish at its minimum
n1
X
f
= 2
(yi a bxi ) = 0 ,
a
i=0
and
n1
X
f
= 2
xi (yi a bxi ) = 0 .
b
i=0
(8)
These two equations can be solved simultaneously for the two unknowns a, b. Define the following sums:
sx
n1
X
xi ,
sy
i=0
n1
X
yi ,
i=0
sxx
n1
X
i=0
x2i ,
sxy
n1
X
x i yi .
(9)
i=0
sxx sy sx sxy
,
nsxx s2x
b=
nsxy sx sy
.
nsxx s2x
(10)
Uncertainty estimates
The number of degrees of freedom of the fit is the number of data points minus the number of parameters:
= n 2. An estimate of the variance of the data set from the model prediction is
2
n1
1 X
f (a, b)
2
(yi y(xi )) .
=
n 2 i=0
(11)
The standard deviation is an estimate of the error bar in each yi . These error estimates can be
propagated to the parameters a, b considered as functions of yi :
a2
n1
X
i=0
yi
2
2 sxx
=
,
nsxx s2x
b2
n1
X
i=0
yi
2
2 n
.
nsxx s2x
(12)
Programming in C++
The simplest C++ program consists of 12 characters:
int main(){}
Every C++ program must define a unique main function, which can have either no arguments as defined
here by empty parentheses (), or two arguments usually written (int argc, char *argc[]). The return
value of the function is of type int, which usually represents a 32-bit integer in the range [231 ..231 1].
Note the required space between int and main. The body of the function in braces {} is empty: the
function does nothing except to return the integer 0 (zero) by default.
The following program prints a message on the display.
#include <iostream>
int main()
// main function returns 0 on successful completion
{
std::cout << "Hello, world!" << std::endl;
}
The preprocessor directive #include is used to import object and function definitions from the C++
standard iostream library and make them available to the program. A standard library name is
conventionally enclosed in angle brackets < >. These objects and functions belong to a namespace called
std .
The main function contains a single executable statement, which is an expression terminated by a
semicolon. The expression is built using the binary operator << which takes a left operand and a right
operand and associates from left to right. The message is coded as a string literal, which is a sequence of
characters enclosed in double quotes "". The object std::cout is defined in the iostream library and
handles printing information on the display. The object std::endl prints a newline character and then
flushes the stream buffer. The expression is interpreted as
((std::cout<<"Hello, world!")<<std::endl). The sub-expression (std::cout<<"Hello, world!")
prints the message string on the display buffer and returns the value std::cout. The resulting expression
(std::cout<<std::endl) then prints a newline on the display buffer and flushes the buffer to the physical
display.
To make the program more readable by human beings, comments, spaces and empty lines have been added:
all of these are ignored by the C++ compiler. There are two types of comments: C-style comments are
6
started by the two characters /* and ended by the two characters */ and can extend over more than
one line. C++-style comments are started by the two characters // and extend to the end of the line.
numbers like 2 and that require an infinite number of decimal digits to express exactly. Integers that
are not too large in magnitude can be represented in C++ by quantities of type int and rational
fractions and real numbers that are not too large or too small can represented by quantities of type
double with approximately 15 decimal digits of precision.
#include <cmath>
#include <iostream>
#include <limits>
int main () {
cout <<
<<
<<
<<
<<
int digits = 6;
<<
<<
<<
<<
\t
\n
\t
endl;
do {
cout << "The double value of pi = " << pi << \n
<< "The exact value of pi = 3.1415926535897932384626433832795..."
<< " ..." << endl;
cout << "\nEnter number of decimal places for pi (or 0 to quit): ";
cin >> digits;
// read using standard input stream
cout.precision(digits);
// reset number of digits printed by cout
} while (digits > 0);
}
The standard cmath header defines various useful mathematical functions such as atan which returns
the principal arc tangent of its double argument in the interval [/2, /2] radians.
The standard limits header defines a parametrized (template) type numeric_limits which takes
7
types like int or double as parameters. The type has static member functions, such as min and
max, which return limiting values.
The program uses the do { } while (condition); control structure: the block of statements in braces
{ } is executed repeatedly while the logical expression condition evaluates to true.
#include <cmath>
#include <iostream>
using namespace std;
const int n = 24;
double r[n] = {
// distances in Mpc
0.032, 0.034, 0.214, 0.263, 0.275, 0.275, 0.45, 0.5, 0.5, 0.63, 0.8, 0.9,
0.9,
0.9,
0.9,
1.0,
1.1,
1.1,
1.4, 1.7, 2.0, 2.0, 2.0, 2.0
};
double v[n] = {
// velocities in km/s
+170, +290, -130, -70, -185, -220, +200, +290, +270, +200, +300, -30,
+650, +150, +500, +920, +450, +500, +500, +960, +500, +850, +800, +1090
};
int main() {
// declare and initialize various sums to be computed
double s_x = 0, s_y = 0, s_xx = 0, s_xy = 0;
// compute the sums
for (int i = 0; i < n; i++) {
s_x += r[i];
s_y += v[i];
s_xx += r[i] * r[i];
s_xy += r[i] * v[i];
}
// evaluate least-squares fit forumlas
double denom = n * s_xx - s_x * s_x;
double a = (s_xx * s_y - s_x * s_xy) / denom;
double b = (n * s_xy - s_x * s_y) / denom;
To store the 24 values of r, an array of double values that cannot be changed is declared
const double r[n] and initialized with a list of 24 real numbers. In C++ an array with n elements
is indexed from 0 to n-1. Thus r[0] is the first element of the array, r[1] the second, and r[23]
the last.
To compute the various sums needed the for (initializer; condition; increment) { } control structure
is used. The initializer expression is evaluated first. The condition expression is then tested: if it evalutes
to true then the sequence of (1) statements in the block { } followed by (2) the increment expression,
followed by (3) the condition expression, is repeatedly executed until the condition evaluates to false.
(14)
Columns
SN= supernova identifier
z = redshift
mu= distance modulus
mu_err = error in distance modulus
SN
b013
d033
z
0.4260
0.5310
mu
41.98
42.96
mu_err
0.23
0.17
10
11
d083
d084
0.3330
0.5190
40.71
42.95
0.14
0.29
We will write a program to fit this data to a straight line and estimate Hubbles constant. According to
Eq. 14, Supernova b013 is 248.9 Mpc from Earth, and the relativistic Doppler formula
1 + vc
1+z = q
2
1 vc2
(15)
gives its speed to be v = 0.341 c. At these cosmological distances and relativistic velocities the equations of
general relativity must be used to relate the general relativistic redshift
z=
R(t0 )
1,
R(t)
(16)
to the distance modulus. For distant supernovae the relation can be approximated as follows:
cz
+ 1.086(1 q0 )z + . . .
= 25 + 5 log10
H0
(17)
where c is measured in km/s and H0 in km/s/Mpc. This equation follows from a Taylor expansion of the
cosmic scale factor
1
R(t) = R(t0 ) 1 + (t t0 )H0 (t t0 )2 q0 H02 + . . . ,
(18)
2
where t is the time of emission of light from the supernova and
H0
0)
R(t
,
R(t0 )
and
q0
0)
R(t0 )R(t
,
2
R (t0 )
(19)
are Hubbles constant and the deceleration parameter at the present cosmological time t0 . See Chapter 14
6 of Weinberg[3] for a detailed derivation of these formulas.
Here
1
ti =
i
and
S=
n1
X
i=0
Sx
xi
S
1
,
i2
Sx =
n1
X
i=0
Stt =
n1
X
t2i ,
(22)
i=0
xi
,
i2
Sy =
n1
X
i=0
yi
.
i2
(23)
The goodness of fit can be computed as the probability Q that the value of 2 should be greater than or
equal to its computed value. Because this involves computing an incomplete Gamma function, we will use
the simpler criterion that the 2 per degree of freedom is close to unity:
2
n1
1 X yi a bxi
/d.o.f
1.
n 2 i=0
i
2
(24)
Because the fit has two parameters a, b, the number of degrees of freedom is = n 2. Two data points
can be fit exactly with two parameters. If 2 n 2, then the terms in the sum have average magnitude
close to one. This implies that the deviations from the straight line are consistent with the error bars. If
2 /d.o.f 1 the fit is too good to be true; and if it is much larger than unity, data cannot be
approximated by a straight line.
#include
#include
#include
#include
#include
<cmath>
<cstdlib>
<fstream>
<iostream>
<string>
/* defines abs() */
/* defines rand() and system() */
/* defines ofstream object for writing to a file */
/* defines string objects */
ofstream plot_file(plot_file_name.c_str());
for (int i = 0; i < 50; i++) {
double x = 0.2 * i;
double random_error = 0.2 * (-1 + 2.0 * rand() / (RAND_MAX + 1.0));
double y = sin(x) + random_error;
double error_bar = abs(random_error);
plot_file << x << \t << y << \t << error_bar << \n;
}
plot_file.close();
ofstream script_file("script.gnu");
script_file << "set title \gnuplot.cpp\\n"
<< "set xlabel \x\\n"
<< "set ylabel \y(x)\\n"
<< "set yrange [-1.5:1.5]\n"
<< "set grid\n";
script_file << "plot \plot.data\ with errorbars, sin(x)\n";
script_file << "pause mouse\n";
script_file.close();
string command(gnuplot + " script.gnu");
system(command.c_str());
}
This program uses C++ string objects to hold and manipulate character strings. The member function
c_str() converts a string object to a character string.
A file can be opened for writing by creating an ofstream object. The << operator can then be used to
write objects to the stream. The member function close() flushes the stream and closes the connection to
the file.
The function rand() returns an integer between 0 and RAND_MAX. The function abs() returns the absolute
value of its argument. The function system() issues its argument as a command to the operating system.
#include <cmath>
#include <fstream>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
using namespace std;
// ---------------- declare global variables ---------------string url("http://dark.dark-cosmology.dk/~tamarad/SN/");
string data_file_name("Davis07_R07_WV07.dat");
vector<double>
z_data,
mu_data,
mu_err_data;
//
//
//
//
void chi_square_fit(
const vector<double>& x,
const vector<double>& y,
const vector<double>& err,
double& a,
double& b,
double& sigma_a,
double& sigma_b,
double& chi_square
);
//
//
//
//
//
//
//
//
//
// to use mu = a + b log_10(z)
string SN;
double z, mu, mu_err;
istringstream is(line);
is >> SN >> z >> mu >> mu_err;
//
//
//
//
if (is.fail()) {
cerr << "error reading line: "
<< line << endl;
continue;
}
//
//
//
//
//
//
//
16
double& sigma_b,
double& chi_square)
{
int n = x.size();
double S
for (int
S += 1
S_x +=
S_y +=
}
= 0, S_x = 0, S_y = 0;
i = 0; i < n; i++) {
/ err[i] / err[i];
x[i] / err[i] / err[i];
y[i] / err[i] / err[i];
vector<double> t(n);
for (int i = 0; i < n; i++)
t[i] = (x[i] - S_x/S) / err[i];
double S_tt = 0;
for (int i = 0; i < n; i++)
S_tt += t[i] * t[i];
b = 0;
for (int i = 0; i < n; i++)
b += t[i] * y[i] / err[i];
b /= S_tt;
a = (S_y - S_x * b) / S;
sigma_a = sqrt((1 + S_x * S_x / S / S_tt) / S);
sigma_b = sqrt(1 / S_tt);
chi_square = 0;
for (int i = 0; i < n; i++) {
double diff = (y[i] - a - b * x[i]) / err[i];
chi_square += diff * diff;
}
}
The chi_square_fit function uses reference objects and variables for its arguments. A reference variable
is declared by appending an ampersand & to its type. The function works on the original object or
variable, so any changes it makes persist after it returns. If instead ordinary variables are used, then the
function makes a copy. For a const input variable copying can waste time and memory, especially the
object is very large. If the function modifies a non-const variable, the changes are made to the copy and
are lost when the function returns.
References
[1] Edwin Hubble, A relation between distance and radial velocity among extra-galactic nebulae, Proc.
Natl. Acad. Sci. USA 15, 168 (1929), http://www.pnas.org/content/15/3/168.full.pdf.
17
[2] K.A. Olive and J.A. Peacock, Big-bang cosmology, in C. Amsler et al., Phys. Lett. B667, 1 (2008),
http://pdg.lbl.gov/2009/reviews/rpp2009-rev-bbang-cosmology.pdf.
[3] S. Weinberg, Gravitation and Cosmology (Wiley, 1972).
[4] T.M. Davis et al., Scrutinizing Exotic Cosmological Models Using ESSENCE Supernova Data
Combined with Other Cosmological Probes, Ap. J. 666 716 (2007),
http://arxiv.org/abs/astro-ph/0701510. Data can be downloaded from
http://dark.dark-cosmology.dk/~tamarad/SN/.
[5] W.H. Press, S.A. Teukolsky, W.T. Vetterling and B.P. Flannery, Numerical Recipes in C (Cambridge
University Press 1992), 15.2 Fitting Data to a Straight Line,
http://www.nrbook.com/a/bookcpdf/c15-2.pdf.
[6] Herbert Schildt, C++ Beginners Guide,
http://msdn.microsoft.com/en-us/beginner/cc305129.aspx, Chapter 1: C++ Fundamentals,
http://go.microsoft.com/?linkid=8310946.
18