Sei sulla pagina 1di 18

Hubble’s Law and Model Fitting

Computational Physics

Physics is a natural science which attempts to describe the Unive rse in terms of a few basic concepts such

as time, space, mass, and electric charge. These quantities can be assi gned numerical values that every

physicist can agree upon. Nature is complex, so physicists choose to s tudy natural phenomena that appear

to be as simple as possible and can be reproduced reliably by other phy sicists.

Most physicists specialize in one of three types of activity. Exper imental physicists observe these phenomena, measure their properties using instruments, and attem pt to discover simple laws describe these observations: experimental physics is based on technology. Theoretic al physicists invent mathematical models that relate measured properties and construct theories which organize and unify these models:

theoretical physics is based on mathematics. Computational physicist s 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 mathemati cal theories and equations, and make predictions that can be verified or falsified by experiment. Comp utationalists design algorithms to solve equations or analyze data, write and debug computer programs that impl ement 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 characteri stic 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 an d speed of a galaxy are examples

of natural phenomena that astronomers have attempted to measure. Fig. 1 s hows 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 per iod of a few days. Its absolute

luminosity can be predicted from its period. Its apparent luminosi ty 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 spe ctral 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 longitud e α and latitude δ , and K, X, Y, Z are constants. Fig. 3 shows the results of his analysis. He concluded th at K 500 km /s /Mpc, which is considerably larger that the current best value of Hubbl e’s constant H ( t 0 ) 72 km / s / Mpc.

1

Figure 1: Hubble lists Barnard’s Galaxy NGC 6822, see http://antwrp.gsfc.nasa.gov/apod/ap020123. html , at a distance

Figure 1: Hubble lists Barnard’s Galaxy NGC 6822, see http://antwrp.gsfc.nasa.gov/apod/ap020123. html, at a distance r = 0. 214 Mpc (1 Mega-parsec = 3. 086 × 10 19 km) moving towards us with speed v = 130 km/s.

General-Relativistic Theory of Cosmology

General Relativity is a mathematical theory that relates the properti es of time and space to the energy density measured at each point in space and instant of time. The mathemat ical equations of General Relativity can be written

R µν 1 2 g µν R = 8πG N T µν g µν Λ

c

4

(2)

where G N is Newton’s 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 th e stress-energy tensor T µ,ν represents the energy and momentum density of matter and radiation.

This complex set of nonlinear partial differential equations is extrem ely challenging to solve. Analytic solutions exist only for very simple distributions of matter and radiat ion. The simplest cosmological model assumes that spacetime is homogeneous and isotropic and described by the Robertson-Walker metric

ds 2

=0 g µν dx µ dx ν = c 2 dt 2 R 2 ( t )

µ =0 ν

3

3

2

1 dr kr 2 + r 2 ( 2 + sin 2 θdφ 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 li ke uniform perfect fluid with density ρ and pressure p . This leads to the Friedmann-Lamaˆıtre equations

H 2

˙

R

R 2 = 8πG N ρ kc 2 + Λ c 2

3

R

2

3

,

¨

R

R

= 4πG N

3

( ρ + 3 p ) + Λ c 2 .

3

(4)

H

( t ) is the Hubble parameter and its value at the present time t 0 is Hubble’s constant

H

( t 0 ) = 72 km / s / Mpc.

2

Figure 2: Table 1 from Hubble’s paper [1]. 3

Figure 2: Table 1 from Hubble’s paper [1].

3

Figure 3: A Figure from Hubble’s paper [1]. 4

Figure 3: A Figure from Hubble’s paper [1].

4

We will study these differential equations later in the course. For t his lecture all we need to know is how to relate them galaxy redshifts in an expanding universe. Suppose R 1 is the scale factor when light of frequency ν 1 was emitted from a distant galaxy, and R 2 is the scale factor when this light is observed on Earth with frequency ν 2 , then the redshift z is given by

z + 1 = ν 1 = R 2 1 + v 12 ,

ν

2

R

1

c

(5)

where v 12 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 ,

real numbers x i , y i . For example, n is the number of observed galaxies, and x i and y i are their radial distances and velocities.

We would like to summarize this data set using a model equation that r elates the two real variables x, y , for example a linear model

, n 1. Each point consists of two

y ( x ) = a + bx ,

with intercept a and slope b .

(6)

Least-squares algorithm

The least-squares algorithm determines the model parameters a, b by minimizing the function

f ( a, b)

n 1

i =0

( y i a bx i ) 2 .

(7)

This procedure tends to make the deviation of y i from the point y ( x i ) = a + bx i on the straight line as small as possible. The derivatives of f vanish at its minimum

∂f

∂a

= 2

n

1

i

=0

( y i a bx i ) = 0 ,

and

f ∂b = 2

n

1

i

=0

x i ( y i a bx i ) = 0 .

(8)

These two equations can be solved simultaneously for the two unknown s a, b. Define the following sums:

s x

n

1

i

=0

x i ,

s y

n

1

i

=0

y i ,

s xx

n

1

i

=0

x

2

i

,

s xy

n

1

i

=0

x i y i .

(9)

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

a = s xx s y s x s xy ns xx s

2

x

,

b = ns xy s x s y ns xx s

2

x

.

(10)

Uncertainty estimates

The number of degrees of freedom of the fit is the number of data points mi nus the number of parameters:

ν = n 2. An estimate of the variance of the data set from the model prediction is

σ 2 f ( a, b)

1

=

ν

n 2

5

n

1

i =0

( y i y ( x i )) 2 .

(11)

The standard deviation σ is an estimate of the error bar in each y i . These error estimates can be propagated to the parameters a, b considered as functions of y i :

2

σ a =

n

1

i

=0

σ

i 2

∂a

∂y

=

σ 2 s xx

ns xx s

2

x

,

σ

2

b =

n

1

i

=0

σ

∂b i 2 = ∂y

σ 2 n ns xx s

2

x

.

Programming in C++

The simplest C++ program consists of 12 characters:

(12)

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 [ 2 31

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.

2 31 1].

#include <iostream>

int main()

{

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

// 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 strin g 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 valu e std::cout. The resulting expression (std::cout<<std::endl) then prints a newline on the display buffer and flushes the buffer t o the physical display.

To make the program more readable by human beings, comments, spaces and emp ty lines have been added:

all of these are ignored by the C++ compiler. There are two types of comme nts: 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 includ e 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 represent ed 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()

<< ’\t’

<< "min(int)

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

<< ’\n’

<< "max(double) = " << numeric_limits<double>::max() << ’\t’ << "min(double) = " << numeric_limits<double>::min() << endl;

int digits = 6;

// 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; cout.precision(digits);

// read using standard input stream // 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 si mpler linear equation with two parameters

v ( r ) = a + br ,

(13)

to determine Hubble’s 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;

8

// 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"

<< " Hubble’s 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, b lows off its outer envelope, and

collapses into a dense core of free electrons and nuclei that is suppor ted against further gravitational

collapse by the Pauli exclusion principle, which forbids the elec trons 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 surr ounding gas that it becomes

unstable. The explosion takes place in seconds and the mostly carbon-ox ygen core is converted into a gas

of heavier elements that is blown off into interstellar space. This debris remains visible as a supernova

remnant.

9

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

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

Supernovae and Hubble’s constant

A plot of light intensity emitted as a function of time is called the li ght curve of the supernova explosion. Type Ia supernovae have characteristic light curves from which th e 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 Ce pheid variable stars. Because supernova explosions are billions of times brighter than typical star s they can be observed at much greater distances from Earth. Their distances and redshifts can be used to m easure 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 appar ent and absolute magnitudes

µ m M = 5 log 10 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 se t 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

z

mu

mu_err

b013

0.4260

41.98

0.23

d033

0.5310

42.96

0.17

10

Figure 5: From reference [2]. 11

Figure 5: From reference [2].

11

d083

0.3330

40.71

0.14

d084

0.5190

42.95

0.29

We will write a program to fit this data to a straight line and estimate Hub ble’s constant. According to Eq. 14, Supernova b013 is 248.9 Mpc from Earth, and the relativistic Dopple r formula

1 + z =

1 + v c 1 − v 2 c 2
1 + v
c
1 − v 2
c
2

(15)

gives its speed to be v = 0. 341 c . At these cosmological distances and relativistic velocities the eq uations of general relativity must be used to relate the general relativistic r edshift

z = R ( t 0 )

R

( t )

1 ,

(16)

to the distance modulus. For distant supernovae the relation can be ap proximated as follows:

µ = 25 + 5 log 10 H cz 0 + 1 . 086(1 q 0 ) z +

(17)

where c is measured in km /s and H 0 in km /s /Mpc. This equation follows from a Taylor expansion of the cosmic scale factor

R ( t ) = R ( t 0 ) 1 + ( t t 0 ) H 0 1 2 ( t t 0 ) 2 q 0 H +

2

0

where t is the time of emission of light from the supernova and

H 0

˙

R

( t 0 )

R ( t 0 ) ,

and

q 0 ≡ − R ( t 0 )

˙

R

¨

R

( t 0 )

2 ( t 0 )

 

,

(18)

,

(19)

are Hubble’s constant and the deceleration parameter at the present cosm ological time t 0 . See Chapter 14 § 6 of Weinberg[3] for a detailed derivation of these formulas.

Chi-square Fitting to a Straight Line

Hubble’s 1929 paper did not quote error bars on the data values, although we can f airly safely assume that he quoted values with an appropriate number of significant digits. To fit Hu bble’s data we used a simple least-squares fit and estimated the error bar in the data set from the d eviations 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

χ 2 ( a, b)

n

1

i

=0

y i a bx i

σ

i

2

.

(20)

In this expression, data values with small error bars are given more wei ght than data points with large error bars.

The parameters a, b are determined by minimizing this function. The following formu las are discussed in detail in Numerical Recipes[5]:

b = 1

S

tt

n

1

i

=0

t

i y i

σ

i

,

a = S y S x b S

,

12

σ

2

a =

S 1 +

1

2

SS tt ,

S

x

σ

2

b =

1

S tt .

(21)

Here

and

S =

t i = 1 i x i S x ,

σ

S

n

1

i

=0

1

σ

2

i

,

S x =

n

1

i

=0

x

i

σ

2

i

,

S tt =

n 1

i =0

S y =

t

2

i

n

,

1

i

=0

y

i

σ

2

i

 

(22)

.

(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 incom plete Gamma function, we will use the simpler criterion that the χ 2 per degree of freedom is close to unity:

χ 2 / d.o.f

1

n 2

n

1

i

=0

y i a bx i

σ

i

2

1 .

(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 ar e 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 bet ter 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 wi th error bars and plot them using Gnuplot from a C++ program.

#include <cmath> #include <cstdlib> #include <fstream> #include <iostream> #include <string>

using namespace std;

/* defines abs() */ /* defines rand() and system() */ /* defines ofstream object for writing to a file */

/* defines string objects */

// 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] th at includes y-error bars. The data is fitted to a linear function using the chi-square merit func tion. 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 p rogram file. The supernova data set is much larger, so the program will read th e 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 b e 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 call ing 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>

// C++ std template vector type

z_data,

// redshift - column 2 in data file

mu_data,

// distance modulus - column 3

mu_err_data;

// 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,

// makes a linear chi-square fit // vector of x values - input // vector of y values - input

const vector<double>& err, // vector of y error values - input

double& a, double& b, double& sigma_a, double& sigma_b, double& chi_square

// 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; while (getline(data_file, line)) {

// string object to hold current 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;

}

// name of supernova in column 1 // columns 2, 3, 4 // string stream object to read line // read successive column entries

// if a read error occurs

// 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,

// makes a linear chi-square fit // vector of x values - input // vector of y values - input

const vector<double>& err, // vector of y error values - input

double& a, double& b, double& sigma_a,

// 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 = 0, S_x = 0, S_y = 0; for (int i = 0; i < n; i++) {

 

S

+= 1 / err[i] / err[i];

S_x += x[i] / err[i] / err[i]; S_y += 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 re ference 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., Phy s. 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 E SSENCE 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++ Beginner’s Guide”, http://msdn.microsoft.com/en-us/beginner/cc305129.aspx , Chapter 1: C++ Fundamentals,

http://go.microsoft.com/?linkid=8310946.

18