Skip to main content
Top

2012 | Book

Guide to Scientific Computing in C++

insite
SEARCH

About this book

This easy-to-read textbook/reference presents an essential guide to object-oriented C++ programming for scientific computing. With a practical focus on learning by example, the theory is supported by numerous exercises. Features: provides a specific focus on the application of C++ to scientific computing, including parallel computing using MPI; stresses the importance of a clear programming style to minimize the introduction of errors into code; presents a practical introduction to procedural programming in C++, covering variables, flow of control, input and output, pointers, functions, and reference variables; exhibits the efficacy of classes, highlighting the main features of object-orientation; examines more advanced C++ features, such as templates and exceptions; supplies useful tips and examples throughout the text, together with chapter-ending exercises, and code available to download from Springer.

Table of Contents

Frontmatter
1. Getting Started
Abstract
This introductory chapter discusses some of the features of C++ in terms of object-orientation and other “buzzwords”, such as polymorphism and inheritance, that are used to describe the language, and also in terms of its strengths and weaknesses. Methods for editing, compiling and running a simple C++ program are introduced, followed by basic information on declaring and using variables and arrays, and on input and output. Sadly, a large amount of the time that a programmer claims to be “programming” may actually be more accurately described as “debugging”: the chapter concludes with tips about simple ways that a novice C++ programmer might go about debugging a program, thus minimising the time spent on the excruciatingly frustrating process of hunting for errors in a code.
Joe Pitt-Francis, Jonathan Whiteley
2. Flow of Control
Abstract
In almost any computer program written for a scientific computing application we need to allow the computer to execute a collection of statements if—and only if—some criterion is met. For example, if we were writing a program to control the motion of a spacecraft travelling to Mars, the program would include lines of code that would control the safe landing of the spacecraft. It is imperative that the lines of code that instruct the motors to cut out are executed at exactly the right time. As with most programming languages, conditional branching may be achieved in C++ programs by using an if statement. Similarly we may use a while statement to execute a collection of statements until a specified condition is met, and a for loop to execute a collection of statements a specified number of times. This flow of control often depends on relations between operators (such as greater than) and on combinations of expressions (such as two conditions both being true). In this chapter we explain how to utilise these features of the C++ language.
Joe Pitt-Francis, Jonathan Whiteley
3. File Input and Output
Abstract
Being able to transfer data between applications is an essential requirement of most scientific computing software. For example, data defining the boundary of an object may be generated from an image processing application. This data may subsequently be used by many applications written by a variety of users. To allow exchange of data between applications in this manner requires us to store data in a clearly specified format. Reading and writing files to a given specification therefore plays a key role in scientific computing applications. Although C++ offers an extremely large number of commands for writing to, and reading from, file, almost all file formats can be achieved by using a very small subset of these commands. In this chapter we focus on the commands that allow file input and output to any reasonable specification for scientific computing software.
Joe Pitt-Francis, Jonathan Whiteley
4. Pointers
Abstract
One of the key features of the C++ language is the concept of a pointer. As we demonstrate in this chapter, pointers are extremely useful for allocating memory for arrays whose sizes are not known when the code is compiled. We will see in the next chapter that they also have use when writing functions that allow us to repeat the same operation on different variables. Before we may use these features we first need to understand what a pointer is. This chapter therefore begins by introducing pointers through explaining how they relate to the storage of variables in the computer’s memory. Understanding this concept then makes utilising pointers for useful purposes a much simpler task.
Joe Pitt-Francis, Jonathan Whiteley
5. Blocks, Functions and Reference Variables
Abstract
The code developed up to this point has been largely restricted to code that may be placed inside a single set of curly brackets. Readers with previous programming experience will be aware of the limitations this places when writing code. For example, if we were to apply the same operations in different places in the code we would have to repeat the lines of code that performed these operations everywhere in the code where they were required. This would result in a lengthy, unwieldy program where we would have to maintain identical fragments of code. It would be much more convenient if we could write a function that we could call whenever we wanted to perform these operations. This chapter introduces the C++ machinery for writing functions. We also introduce reference variables: these are an attractive feature of the C++ programming language that simplifies the writing of functions.
Joe Pitt-Francis, Jonathan Whiteley
6. An Introduction to Classes
Abstract
One of the key features of the C++ programming language is that it is object-oriented. Up until now we have largely ignored this feature, making only passing reference to it in earlier chapters. In this chapter we discuss in more detail three properties of object-orientation: modularity; abstraction; and encapsulation. This allows us to motivate the need for developing classes: entities where the data, and the operations on the data, are stored in one place. Access privileges to the members of a class are introduced: these prevent a user of a class from inadvertently corrupting the data or functionality of the class. We conclude the chapter by developing a class of complex numbers. This allows us to introduce operator overloading: a feature that permits us to define what we mean by addition, subtraction, multiplication and division of complex numbers, allowing much more natural looking C++ code to be written when performing these operations on complex numbers.
Joe Pitt-Francis, Jonathan Whiteley
7. Inheritance and Derived Classes
Abstract
Suppose we have developed a class for a specific application. If we want to extend the software based on this class to do something slightly different we could modify the class already written. This, however, may not be an ideal solution as we may introduce conflicts with the functionality of the original class. A more suitable approach is to derive a new class that has the features of the original class (modified if required) together with any new features required. This is known as inheritance, and is a very powerful feature of the C++ language. One particularly useful feature of inheritance is that of polymorphism: we may apply the same functionality to instances of both the original class and the derived class, with the correct operations “under the hood” being chosen by the computer based on whether the instance of the class is the original or derived class.
Joe Pitt-Francis, Jonathan Whiteley
8. Templates
Abstract
If we want to write a function that returns the larger of two numbers, and we want this function to be used for both integer variables and double precision floating point variables, then we could write two functions: one for integer variables and the other for double precision floating point variables. Both of these functions would require only a few lines of code, and it would not be difficult to maintain both functions. For larger functions maintaining more than one function to do the same operations may be problematic. This may be avoided by the use of templates, a feature of the C++ language that allows very general code to be written. We begin this chapter by discussing templates and the flexibility that they permit. One library associated with C++ is the Standard Template Library (STL): we conclude this chapter by giving a brief survey of this library.
Joe Pitt-Francis, Jonathan Whiteley
9. Errors and Exceptions
Abstract
Until this point we have used assert statements to ensure that a condition required by the code to generate correct output is met. For example, we might check that a number that we were going to take the square root of is non-negative, and trip an assertion if this condition were not met. Whilst this approach is very useful as it pinpoints errors, it is rather inflexible as it terminates the code at the instant that an assertion is tripped. We would much rather the code instead made some attempt to fix the problem itself, if that were possible, warned us of the possible effects of the fix if necessary, and then carried on executing. This is possible through the use of exceptions, which are the focus of this chapter.
Joe Pitt-Francis, Jonathan Whiteley
10. Developing Classes for Linear Algebra Calculations
Abstract
Linear algebra calculations—i.e. operations on vectors and matrices—are at the heart of many scientific computing application codes. In this chapter we will apply the ideas introduced earlier in this book to begin to develop a collection of classes that allow us to perform these calculations. We will describe the design of a class of vectors in the body of this chapter. Appropriate constructors and destructors will ensure that memory is managed correctly, and operator overloading will allow operations between vectors and matrices (such as addition, subtraction and multiplication) to be coded in a natural manner. The exercises at the end of the chapter will focus on developing this class further, developing a companion class of matrices, and developing a linear system class that allows us to solve matrix equations.
Joe Pitt-Francis, Jonathan Whiteley
11. An Introduction to Parallel Programming Using MPI
Abstract
The most common type of high-performance parallel computer is a distributed memory computer: a computer that consists of many processors, each with their own individual memory, that can only access the data stored by other processors by passing messages across a network. This chapter serves as an introduction to the Message Passing Interface (MPI), which is a widely used library of code for writing parallel programs on distributed memory architectures. Although the MPI libraries contain many different functions, basic code may be written using only a very small subset of these functions. By providing a basic guide to these commonly used functions you will be able to write simple MPI programs, edit MPI programs written by other programmers, and understand the function calls when using a scientific library built on MPI.
Joe Pitt-Francis, Jonathan Whiteley
12. Designing Object-Oriented Numerical Libraries
Abstract
Having developed classes that underpin linear algebra operations in an earlier chapter, we now demonstrate how to construct object-oriented libraries for scientific computing applications that utilise the functionality of these classes. We use the specific example of developing a library that uses the finite difference method to solve boundary value, second order, constant coefficient differential equations. We begin by considering ordinary differential equations. We state the theory that underpins the finite difference method for these equations, and then describe the classes that we will develop to allow this theory to be applied. We then briefly discuss how to develop a library for the solution of Poisson’s equation, an elliptic partial differential equation, in two spatial dimensions.
Joe Pitt-Francis, Jonathan Whiteley
Backmatter
Metadata
Title
Guide to Scientific Computing in C++
Authors
Joe Pitt-Francis
Jonathan Whiteley
Copyright Year
2012
Publisher
Springer London
Electronic ISBN
978-1-4471-2736-9
Print ISBN
978-1-4471-2735-2
DOI
https://doi.org/10.1007/978-1-4471-2736-9

Premium Partner