Vous êtes sur la page 1sur 18

Hubbles Law and Model Fitting

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.

The Expanding Universe


A galaxy is a collection of several billion stars. Galaxies have characteristic shapes and are separted from
one another by empty space. More than 10,000 galaxies have been identified and cataloged, and Earth
receives light from more than a hundred billion galaxies. The location and speed of a galaxy are examples
of natural phenomena that astronomers have attempted to measure. Fig. 1 shows a typical galaxy studied
by Edwin Hubble[1] and his collaborator Milton Humason.

Cepheid Variables as Standard Candles


A Cepheid variable is a type of star whose luminosity varies with a period of a few days. Its absolute
luminosity can be predicted from its period. Its apparent luminosity observed on Earth can therefore be
used to infer its distance.
The speed of a galaxy can be inferred from the shift in wavelength of spectral lines in the light it emits.
Lines from distant galaxies are generally redshifted, which indicates that they are receding from us.
Hubble analyzed the data in Fig. 2 using the relation
rK + X cos cos + Y sin cos + Z sin = v ,

(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.

Figure 1: Hubble lists Barnards Galaxy NGC 6822, see http://antwrp.gsfc.nasa.gov/apod/ap020123.


html, at a distance r = 0.214 Mpc (1 Mega-parsec = 3.086 1019 km) moving towards us with speed v = 130
km/s.

General-Relativistic Theory of Cosmology


General Relativity is a mathematical theory that relates the properties of time and space to the energy
density measured at each point in space and instant of time. The mathematical equations of General
Relativity can be written
1
8GN
R g R =
T g
(2)
2
c4
where GN is Newtons gravitational constant, c is the speed of light, and is the cosmological constant.
The other quantities in the equation are functions of the time-space 4-vector x = {ct,~r}. The metric
tensor g (x) describes the geometry of spacetime, the Ricci tensor R and curvature scalar R are
functions of the metric tensor and its spacetime derivatives, and the stress-energy tensor T, represents
the energy and momentum density of matter and radiation.
This complex set of nonlinear partial differential equations is extremely challenging to solve. Analytic
solutions exist only for very simple distributions of matter and radiation. The simplest cosmological model
assumes that spacetime is homogeneous and isotropic and described by the Robertson-Walker metric
3 X
3
X


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)

Figure 2: Table 1 from Hubbles paper [1].

Figure 3: A Figure from Hubbles paper [1].

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.

Algorithm for fitting data to a straight line


Consider a data set with n data points labeled by an index i = 0, 1, . . . , n1. Each point consists of two
real numbers xi , yi . For example, n is the number of observed galaxies, and xi and yi are their radial
distances and velocities.
We would like to summarize this data set using a model equation that relates the two real variables x, y,
for example a linear model
y(x) = a + bx ,
(6)
with intercept a and slope b.

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

Then the least-squares values of the parameters are given by


a=

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>

/* standard C++ input output stream header */

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.

Computing with integers and real numbers


Physical quantities
are represented real numbers, which include integers, rational fractions, and real

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>

/* defines arc-tangent function atan */


/* defines cout, cin and endl */
/* defines numeric_limits */

using namespace std;

// import included std objects into global namespace

const double pi = 4 * atan(1.0);

// pi in radians from arc-tangent function

int main () {
cout <<
<<
<<
<<
<<

"\nLimiting values of int and double\n"


"max(int)
= " << numeric_limits<int>::max()
"min(int)
= " << numeric_limits<int>::min()
"max(double) = " << numeric_limits<double>::max()
"min(double) = " << numeric_limits<double>::min()

int digits = 6;

<<
<<
<<
<<

\t
\n
\t
endl;

// number of decimal digits printed by default

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.

Computing the Hubble Constant


Hubble used Eq. 1 with 4 parameters to model his data. We will use a simpler linear equation with two
parameters
v(r) = a + br ,
(13)
to determine Hubbles constant as the slope b using the linear least-squares algorithm.

#include <cmath>
#include <iostream>
using namespace std;
const int n = 24;

// number of galaxies in Table 1

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;

// estimate the variance in the data set


double sum = 0;
for (int i = 0; i < n; i++) {
double v_of_r_i = a + b * r[i];
double error = v[i] - v_of_r_i;
sum += error * error;
}
double sigma = sqrt(sum / (n - 2));
// estimate of error bar in v
// estimate errors in a and b
double sigma_a = sqrt(sigma * sigma * s_xx / denom);
double sigma_b = sqrt(sigma * sigma * n / denom);
// print results
cout.precision(4);
cout << " Least-squares fit of " << n << " data points\n"
<< " -----------------------------------\n"
<< " Hubbles constant slope
b = " << b
<< " +- " << sigma_b << " km/s/Mpc\n"
<< " Intercept with r axis
a = " << a
<< " +- " << sigma_a << " km/s\n"
<< " Estimated v error bar sigma = " << sigma << " km/s" << endl;
}

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.

Type Ia Supernovae as Standard Candles


A white dwarf is a star that has exhausted its supply of hydrogen fuel, blows off its outer envelope, and
collapses into a dense core of free electrons and nuclei that is supported against further gravitational
collapse by the Pauli exclusion principle, which forbids the electrons from getting too close to one another.
A Type Ia supernova is a catastrophic thermonuclear explosion of this core. This can happen when the
white dwarf accretes so much matter from a neighboring star or the surrounding gas that it becomes
unstable. The explosion takes place in seconds and the mostly carbon-oxygen core is converted into a gas
of heavier elements that is blown off into interstellar space. This debris remains visible as a supernova
remnant.

Figure 4: Remnant of the Type Ia supernova SN 1604 http://en.wikipedia.org/wiki/SN_1604 observed


by Johannes Kepler.

Supernovae and Hubbles constant


A plot of light intensity emitted as a function of time is called the light curve of the supernova explosion.
Type Ia supernovae have characteristic light curves from which the their absolute luminosities can be
inferred. Their distances from Earth can then be calculated from the observed apparent luminosities.
Thus Type Ia supernovae can be used as standard candles, just like Cepheid variable stars. Because
supernova explosions are billions of times brighter than typical stars they can be observed at much greater
distances from Earth. Their distances and redshifts can be used to measure the Hubble parameter, see
Fig. 5.
Astronomers measure the brightness of an object in the sky using a unit called the magnitude. The
absolute magnitude of the object is denoted by M and the apparent magnitude by m. The absolute
magnitude is defined to be the apparent magnitude observed at a distance of 10 parsecs from the object.
The distance modulus is defined as the difference between the apparent and absolute magnitudes
m M = 5 log10 r 5 ,

(14)

where r is the distance in parsecs of the object from Earth.


Davis et al.[4] study redshift and distance modulus data using a set of 192 Type Ia supernovae with large
redshifts. This data set is available as a file giving redshift z, distance modulus and the error in for
each object, as shown by the following snippet:
;
;
;
;
;
;
;

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

Figure 5: From reference [2].

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.

Chi-square Fitting to a Straight Line


Hubbles 1929 paper did not quote error bars on the data values, although we can fairly safely assume that
he quoted values with an appropriate number of significant digits. To fit Hubbles data we used a simple
least-squares fit and estimated the error bar in the data set from the deviations of the data points from the
fitted straight line. It is not possible to estimate the reliability of the least-squares fit in the absence of
error bars on the data.
If the error bars i are available on the y values of the set, then it is possible to take them into account by
minimizing the chi-square sum, which is defined as
n1
X  yi a bxi 2
.
(20)
2 (a, b)
i
i=0
In this expression, data values with small error bars are given more weight than data points with large
error bars.
The parameters a, b are determined by minimizing this function. The following formulas are discussed in
detail in Numerical Recipes[5]:


n1
1 X ti y i
1
S2
1
Sy Sx b
b=
,
b2 =
1+ x
,
a2 =
,
a=
.
(21)
Stt i=0 i
S
S
SStt
Stt
12

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.

C++ strings, files and Gnuplot


A good way of visualizing a data set is to plot it. If you do not have a better plotting program available
you should download and install Gnuplot from http://gnuplot.info/ and learn how to use it.
The following simple program shows how to simulate some data points with error bars and plot them using
Gnuplot from a C++ program.

#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 */

using namespace std;


// path to gnuplot executable - change if located somewhere else
#ifdef _MSC_VER
/* this variable is defined by Visual C++ */
string gnuplot("C:\\gnuplot\\bin\\wgnuplot.exe");
#else
/* Linux or Macintosh */
string gnuplot("/usr/bin/gnuplot");
#endif
int main() {
string plot_file_name("plot.data");
13

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.

C++ Program to fit supernova data


The following program estimates the Hubble constant from a data set[4] that includes y-error bars. The
data is fitted to a linear function using the chi-square merit function. The goodness of the fit is estimated
by computing the chi-square per degree of freedom.
The program hubble.cpp used static arrays to store the data, which were coded by hand in the program
file. The supernova data set is much larger, so the program will read the data directly from the data file.
The program uses template std::vector objects from the C++ standard template library to hold the
data. A std::vector is very convenient to use because the number of elements need not be constant.
Starting with empty vectors, the program adds one data point to the end of the vector for each line in the
data file using the push_back member function. The number of elements can be determined by calling the
size member function.
The program uses std::string and std::stringstream objects to read and parse each line in the data
file.
14

#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;

//
//
//
//

C++ std template vector type


redshift - column 2 in data file
distance modulus - column 3
error in distance modulus - column 4

// ---------------- function declarations ---------------void read_data();

// opens and reads the data file

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
);

//
//
//
//
//
//
//
//
//

makes a linear chi-square fit


vector of x values - input
vector of y values - input
vector of y error values - input
fitted intercept - output
fitted slope - output
estimated error in intercept - output
estimated error in slope - output
minimized value of chi-square sum - output

// ---------------- function definitions ---------------int main() {


cout << " Chi-square fit of supernova data to a straight line\n"
<< " Reference: " << url << endl;
read_data();
int n = z_data.size();
vector<double> logz_data(n);
for (int i = 0; i < n; i++)
logz_data[i] = log10(z_data[i]);

// to use mu = a + b log_10(z)

double intercept, slope, intercept_err, slope_err, chisqr;


chi_square_fit(logz_data, mu_data, mu_err_data,
15

intercept, slope, intercept_err, slope_err, chisqr);


cout.precision(4);
cout << " slope = " << slope << " +- " << slope_err << "\n"
<< " intercept = " << intercept << " +- " << intercept_err << "\n"
<< " chi-square/d.o.f = " << chisqr / (n - 2) << endl;
}
void read_data() {
// create an input file stream object and open the data file
ifstream data_file(data_file_name.c_str());
if (data_file.fail())
cerr << "sorry, cannot open " << data_file_name << endl;
// read the data file one line at a time
string line;
// string object to hold current line
while (getline(data_file, line)) {
// std::getline defined in <string>
if (line[0] == ;)
continue;

// skip lines starting with semicolon

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;
}

// if a read error occurs

name of supernova in column 1


columns 2, 3, 4
string stream object to read line
read successive column entries

// print an error message

// store the data values in the data vectors


z_data.push_back(z);
mu_data.push_back(mu);
mu_err_data.push_back(mu_err);
}
cout << " read " << z_data.size() << " data values" << endl;
data_file.close();
}
void chi_square_fit(
const vector<double>& x,
const vector<double>& y,
const vector<double>& err,
double& a,
double& b,
double& sigma_a,

//
//
//
//
//
//
//

makes a linear chi-square fit


vector of x values - input
vector of y values - input
vector of y error values - input
fitted intercept - output
fitted slope - output
estimated error in intercept - output

16

double& sigma_b,
double& chi_square)

// estimated error in slope - output


// minimized value of chi-square sum - output

{
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

Vous aimerez peut-être aussi