0% found this document useful (0 votes)
23 views

Computational Physics

This document is a teacher's manual for a computer programming and numerical analysis course. It covers topics like the Linux operating system, C programming language basics, variables, loops, functions, operators, mathematical functions in C, graphics using Gnuplot, and finite and infinite series. For each topic, it provides explanations, examples, and problems. It is intended to guide teachers in teaching the course and students in learning the content.

Uploaded by

2000jeptha
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
23 views

Computational Physics

This document is a teacher's manual for a computer programming and numerical analysis course. It covers topics like the Linux operating system, C programming language basics, variables, loops, functions, operators, mathematical functions in C, graphics using Gnuplot, and finite and infinite series. For each topic, it provides explanations, examples, and problems. It is intended to guide teachers in teaching the course and students in learning the content.

Uploaded by

2000jeptha
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 165

Computer Programming & Numerical

Analysis- Teacher's Manual

Version 2.01
Last modi ed on August 17, 2017
Contents
Note to the Reader 2
1 Introduction 5
1.1 General Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
1.1.1 Operating System . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
1.1.1.1 Linux Operating System . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
1.1.2 Compiler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
1.1.3 Editors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
1.1.3.1 Edit/Write your own program . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
1.1.4 Programming Language . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
1.2 Introduction to GNU C . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
1.2.1 Create your rst C program . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
1.2.2 Compile/Run/Execute your rst C program . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
1.2.2.1 Run your rst C program . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
1.2.3 Variables in C . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
1.2.4 Loops in C . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
1.3 Functions in C . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
1.3.1 Decision Making in C . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
1.3.2 Function Prototypes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
1.4 Operators in C . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
1.4.1 Arithmetic Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
1.4.2 Assignment Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
1.4.3 Relational Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
1.4.4 Logical Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
1.5 Mathematical Functions in C . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
1.6 Storing the results of the program in a data le . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
1.7 Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
1.8 Advanced Topic: Pointers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
1.9 QUESTIONS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
1.10 PROBLEMS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
2 Graphics Using GNUPLOT 58
2.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
2.2 Plotting with inbuilt functions of GNUPLOT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
2.2.1 Interactive plotting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
2.3 Saving Plots . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
2.4 Plotting using script . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
2.4.1 Customization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
2.5 Plotting using data from a le . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
2.6 Periodic Function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65
2.7 PROBLEMS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68

1
CONTENTS COMPUTER PROGRAMMING-2017

3 Finite & In nite Series 78


3.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78
3.2 Finite Series . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78
3.3 In nite Series . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82
3.4 Questions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87
3.5 Problems . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88
4 Root Finding 97
4.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97
4.2 Bisection Method . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98
4.3 Secant Method . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101
4.4 Newton-Raphson Method . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103
4.5 Questions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106
4.6 Problems . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106
5 Ordinary Di erential Equations 116
5.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 116
5.2 Euler's Formula . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117
5.3 Runge-Kutta methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117
5.4 Simultaneous Equations of First-Order . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121
5.5 Problems . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125
6 Integration 136
6.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 136
6.2 Methods Based on Intervals of Equal Width . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 136
6.2.1 Trapezoidal Rule . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 136
6.2.2 Simpson's Rule . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138
6.3 Methods Based on Intervals of Unequal Width . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 140
6.3.1 Gauss Quadrature . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 140
6.3.2 Gauss-Laguerre Quadrature . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143
6.3.3 Gauss-Hermite Quadrature . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143
6.3.4 General Considerations & Programming Tips . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143
6.4 Problems . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 146
7 Matrices 154
7.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 154
7.2 Arrays in C . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 154
7.2.1 Declaration of Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155
7.2.2 Initializing & Using Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155
7.3 The Function matalloc . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 158
7.4 Problems . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 161

Page 2 of 164;
CONTENTS COMPUTER PROGRAMMING-2017

A Note to the Reader

This Manual is intended for use in the Computer Programming & Numerical Analysis class. The
Manual does not assume any familiarity with either the C programming language which is used or the
techniques of numerical analysis. However, if the reader is familiar with these then it would be of help.

The book is organised into 7 Chapters and they are best gone through in sequence. Chapter 1 is
an introduction to programming in general and to the C programming language in particular. This
Chapter may be skipped by readers who already are familiar with the language though it may help to
go through it once to familiarize themselves with the notation etc. It also has some sample programs
to illustrate the use of various C progamming constructs like loops and conditional statements etc.

Chapter 2 is an introduction to Gnuplot, an open source graphics package which we use to gener-
ate graphics in this course. Once again it is self contained and does not assume any previous familiarity
with Gnuplot.

Chapter 3 uses the programming and graphics fundamentals from the earlier Chapters to nd the
sum of nite and in nite series.

Chapter 4 discusses various methods to nd roots of equations. The methods discussed are the
Bisection method, Secant method and the Newton-Raphson method.

Chapter 5 is an introduction to solving ordinary di erential equations using Euler's formula and
4 order Runge-Kutta method.
th

Chapter 6 discusses integration by various methods. Methods using intervals of equal and unequal
width are discussed here. The Trapezoidal and Simpson's rule are discussed as examples of methods
using intervals of equal width and Gauss-Legendre, Gauss-Hermite and Gauss-Lagauerre quadratures
as examples of methods which use unequal intervals.

Chapter 7 is a short discussion of matrices and how to manipulate and use them in C. Here we use
arrays and pointers to do various matrix operations.

Each Chapter has several sample programs so that the reader can get an idea of how to write his/her
own programs. In addition, each Chapter has some questions and problems at the end which the reader
should certainly attempt to answer and solve.

Page 3 of 164;
CONTENTS COMPUTER PROGRAMMING-2017

For students who own computers at home, the chances are that you are using a Windows OS based
machine. This programming language used in this course is C and the compiler used is gcc which
comes with a Linux OS. In addition, the graphics package Gnuplot also comes with the Linux OS. For
Windows users, there is a simple way to emulate a Linux environment.

Go to https://www.cygwin.com/ and download and install the program Cygwin. This will come
in two versions- Cygwin32 and Cygwin64. If you have a 64-bit computer then install Cygwin64, else
install Cygwin32. Once installed, run the program as you run any windows program, that is by double
clicking on the icon. This will open a small window. In this type startx. This will open a terminal
on your screen, exactly like the one you see in the laboratory on the Linux machines. It is as if, your
Windows machine has turned into a Linux machine. You can run all the Linux OS programs like Gnu-
plot, gcc, emacs etc. in this terminal. Once you are nished, just type exit and you will return to
your Windows environment.

We would very much like to get your suggestions regarding how to improve this Manual. In addition,
if there are any errors or misprints that are spotted in the Manual, we would like to hear from you.
Please send a mail with the suggestions/errors etc. to [email protected] making sure
you quote the version number of the Manual as well as the Modi cation date of the Manual you are
using. The version number and date are on the title page of the Manual.

Page 4 of 164;
Chapter 1

Introduction
This course on Computer Programming is meant to introduce students to both computer programming
as well as to numerical analysis. Although it expects students not to have forgotten what they learnt
about numerical methods in their undergraduate course, it makes no great demands on them in this
respect.

1.1 General Introduction


Most of you would be familiar with using the computer for browsing the Internet. So what is a com-
puter? We can divide a computer into Hardware and Software. Hardware consists of devices, like
the computer itself, the monitor, keyboard, printer, mouse and speakers. These are called Input/Out-
put (IO) devices. However, the real bits of hardware lie inside the computer. These are the various
chips to perform all the operations, store commands and data etc. The main processing chip is called
the Central Processing Unit (CPU). Apart from this there are specialised chips for functions like
storing data and instructions (Random Access Memory), graphic interface, ethernet connectivity
etc. There could also be storage devices for data like a Hard Disk, CD-ROM, SD card etc.

Software is the name given to the programs that you install on the computer to perform certain
types of activities. The rst thing we need in a computer is an Operating System (OS). You are all
familiar with the various Operating Systems- Windows, Linux, Apple iOS and of course Android. Yes,
Android is an operating system for mobile platforms like your phone. Software also includes all the other
programs which allow us to use the computer- word processing software like MS Word, Spreadsheet
software like MS Excel, games, email software etc. All these are called Application software.

1.1.1 Operating System


Of course we all know that at the most basic level, the computer works by manipulating electric charge
and the language it uses is the language of 0 and 1. The manipulation of electric charge is done by

5
Introduction COMPUTER PROGRAMMING-2017

an enormously complicated set of electrical circuits comprising of millions of microscopic transistors,


capacitors and resistors etc. To give you an idea, the Qualcomm Snapdragon chip in your Android
phone has more than a billion transistors!
Obviously, to make the computer useful, it is important to be able to communicate with it not in the
language of 0s and 1s but in ordinary language. An operating system (OS) is a software that, after
being initially loaded into the computer by a boot program, manages all other programs in a computer
and provides programmers/users with an interface used to access those resources. An OS processes sys-
tem data and user input, and responds by allocating and managing tasks and internal system resources
as a service to users and programs of the system. Thus we can say that an OS is a translator and a
manager which allows us to use the computer.

RIn this course we shall use the Linux OS.


For students who own computers at home, the chances are that you are using a Windows OS based
machine. This programming language used in this course is C and the compiler used is gcc which
comes with a Linux OS. In addition, the graphics package Gnuplot also comes with the Linux OS. For
Windows users, there is a simple way to emulate a Linux environment.

Go to https://www.cygwin.com/ and download and install the program Cygwin. This will come
in two versions- Cygwin32 and Cygwin64. If you have a 64-bit computer then install Cygwin64, else
install Cygwin32. Once installed, run the program as you run any windows program, that is by double
clicking on the icon. This will open a small window. In this type startx. This will open a terminal
on your screen, exactly like the one you see in the laboratory on the Linux machines. It is as if, your
Windows machine has turned into a Linux machine. You can run all the Linux OS programs like Gnu-
plot, gcc, emacs etc. in this terminal. Once you are nished, just type exit and you will return to
your Windows environment.

1.1.1.1 Linux Operating System


The name Linux was coined in 1991 by Linus Torvalds after his own name and is supposed to indicate
any open sourced operating system based on a Unix platform. The word open source implies that
typically all underlying source codes can be freely modi ed, used, and redistributed by anyone. The
system's utilities and libraries usually come from the GNU operating system, announced in 1983 by
Richard Stallman.
There are several distributions (popularly referred to as distros) of the Linux OS eg. Red Hat, SUSE
Linux (Novell) and Debian; and other derived distros like Fedora, Ubuntu (Canonical Ltd.), Gentoo,
PCLinuxOS, CentOS, etc. Broadly speaking, the mother distros (Red Hat, SuSE, Debian) di er mostly
in the areas they specialize or otherwise their focus.

Page 6 of 164;
Introduction COMPUTER PROGRAMMING-2017

RIn this course we shall use Scienti c Linux.


Since most of you may not be very familiar with working on the Linux operating system, it is useful
to get familiar with the commands so that it is easier to manipulate your les and programs. A few
commonly used commands are given below.

A FEW GENERAL LINUX COMMANDS


Some useful linux commands are given here (you don't have to type $, which shows the
command prompt).

$pwd
print working directory. The command tells you what is your present work directory.

$ls
lists les in a given directory. There are many options available with ls, which you can nd using
the command man ls or ls {help. In fact, if you are not sure of all the options for any command,
you can use this, that is man command where `command' is the command you want more
information on. Thus, man cd, man mv etc. can be used.

$cd
change directory. To see what is stored in any subdirectory, we must rst of all change the current
directory by using the cd command. Suppose we wish to change to the include directory. The
required command then is
$cd include
This when followed by the ls command will display the les and subdirectories stored in the include
directory. To return to the main directory we must execute
$cd ..
Here .. means the parent directory (or one directory up).

$mkdir mydirectory
creates a directory with the name mydirectory
$ls [option(s)]
If you run ls without any additional parameters or options, the program will list the contents of the
current working directory in short form.
The options can be

Page 7 of 164;
Introduction COMPUTER PROGRAMMING-2017

$ls -l
This will give you a detailed list of the directory contents
$ls -a
This will also display hidden les
$ls -al
This will list all les in the current working directory in long listing format showing permissions,
ownership, size, and time and date stamp.

$cp lename1.c lename2.c


copies one le to another le. Original copy lename1.c will also exist after the operation.

$mv -i lename1.c lename2.c


moves one le to another le. Original copy lename1.c will NOT exist after the operation. The
ag -i ensures that the computer asks (something like Do you want to proceed?) before executing
the command.

$rm -i lename1.c
deletes/removes a le. Once again the ag -i ensures a check before the command is executed.

R You should familiarise yourself with all these commands since you might be
using them extensively throughout this course. By default your present working di-
rectory will be your home area. Please create all your programs etc. in this directory.
Please do not create a directory on the desktop since it would be dicult subsequently
to copy les from it in case there is a server problem and you might lose all your
work.Subsequently, if you want to organise the directory into various sub-directories
with di erent topics, you can always do that using the commands above.

GETTING STARTED:

Each of you has been given a userid and a password. Enter userid and the password

Page 8 of 164;
Introduction COMPUTER PROGRAMMING-2017

EXACTLY as you have been given. This will then allow you to log into the system.
When you log in, you are working in your area. The desktop has a directory by the
name of HOME. By default, all your work is stored in this directory.

Almost all the work that one does in this lab is done in the terminal mode.To open
a terminal, use the mouse and click on (shown as circled on the gure) Applications
! System Tools ! Terminal. This will open a terminal as shown in the gure. The
cursor will be on the command prompt [userid@localhost ]$, where userid is your user
name.

Figure 1.1: Screen Shot of opening screen after logging in

1.1.2 Compiler
For our purposes, we would be using the computer to solve problems. For this purpose we need to learn
a programming language. There are many programming languages like C, C++, Fortran, APL etc.
After one writes a program to do a speci c task, say nd the sum of the rst 10 digits, one inputs the
program into the computer. For this purpose we need to use an Editor. We shall discuss the various
editors below.
Once the program is entered and stored in the computer, one would need to run it. Here there is
a problem- the computer, as we are aware only understands a language which is called a lower level
language (e.g. Assembly language or Machine language) while our porgram is a set of instructions in
English. To translate our instructions into a language which the computer understands, we need a
program called a Compiler. The name\compiler" is primarily used for programs that translate source
codes from a high-level programming language (like C, C++, Fortran, etc.) to a lower level language
(e.g., assembly language or machine language). The original sequence is usually called the source code
and the output the object code. The most common reason for wanting to translate source codes is to
create an executable program. In this course, we would be using C programming language

Page 9 of 164;
Introduction COMPUTER PROGRAMMING-2017

and hence the native compiler with Linux, which is GNU C.

1.1.3 Editors
As we saw above, we need a text editor to type and save our program. A text editor is a computer
program that allows you to input, modify and assemble text. For instance, in MS Windows, you may be
familiar with the NOTEPAD or WORDPAD. A text editor is di erent from a Word Processing program
(like MS WORD) in that it has limited capabilities of formatting and processing text. In Linux there are
several editors, like gedit, emacs, vim etc. You can use any one of these to make your rst program.
Emacs and gedit are all menu based and so it is easy to nd commands much like you are used to in
Notepad and Wordpad. However, if you are interested, there are many tutorials available on the Internet
for learning to use these editors eciently. For instance, (http://www.jesshamrick.com/2012/09/10/absolute-
beginners-guide-to-emacs/ ) is a comprehensive guide to using Emacs.

Similarly, for using gedit, (https://help.gnome.org/users/gedit/stable/ ) is a good guide.

1.1.3.1 Edit/Write your own program


Here, we are showing you how to make your rst program using emacs, but it can be done using any
of your favorite editors. On the command prompt of a terminal, type

$emacs &

This will open a new screen. Using keyboard, type the following program:

Program 1.1
/  This program prints ` `My First C programme ' '  /

#i n c l u d e < stdio .h>


#i n c l u d e < math . h >
main ( )

f
p r i n t f ( "My First C program n n" ) ;

After writing this program, click on the taskbar item

File ! Save

Page 10 of 164;
Introduction COMPUTER PROGRAMMING-2017

This will open a window with the Save File As option. Enter the desired name of the program, like
rst.c in the New File Name and click OK.

R Most students nd gedit somewhat simpler to use for editing programs. You
should try to use both of them and see which one you prefer and then use it. Just
make sure that the programs are properly saved.

1.1.4 Programming Language


The computer language that we shall use is C, distributed by GNU. The reasons for this choice are
threefold:
1. C is a scienti c language much like Fortran or C++ or Pascal in structure, but has certain advan-
tages on syntax
2. C has features that allow the programmer to organize programs in a clear, easy, logical way. For
example, C allows meaningful names for variables without any loss of eciency, yet it gives a
complete freedom of programming style, including exible ways of making decisions, and a set of
exible commands for performing tasks repetitively (for, while, do). Also it has a vast library of
mathematical functions that can be harnessed to extensive computations.
3. C is useful not only in scienti c computations but is also used by computer scientists who focus
more on machine level programming or web designing. This is obviously a great advantage both
in an academic as well as in a non-academic world.

1.2 Introduction to GNU C


On the command prompt of a terminal, type

$gcc -- version

This will type the version of the compiler you are using. Note that this compiler will compile programs
written in C.

The language C is case sensitive. For example, the variable lower case x is di erent from
the variable upper case X in C.

1.2.1 Create your rst C program


This is a three step process:

Page 11 of 164;
Introduction COMPUTER PROGRAMMING-2017

1. First, you need to write and save your program in a text le using a TEXT EDITOR
2. Then you compile this program le using the gcc compiler to create an executable le.
3. Finally, you can EXECUTE or RUN the executable le created in step 2 to get the output

1.2.2 Compile/Run/Execute your rst C program


Now that you have a program written in C programming language which you have named rst.c, let
us see how we can run the program to get the results. You can call the program by ANY name as
long as the extension is .c. However, it helps to name programs in such a way so that later on you
know by looking at the name what it might do. Also avoid very long names and those with too many
special characters like etc. Compilation is necessary since the computer obviously does not understand
the English language in which you have written the program. Further, compilation also takes all the
header les (see below) like stdio.h, math.h etc and "attaches" them to the program you have written.
These header les have prede ned functions and routines which make it easier to use the programming
language.
Compilation and Executing or running a program is a two step process.

1. First one has to compile the program to create an executable le


2. Second the compiled executable le has to be run.
Let us see how this is done for our program rst.c.

In order to compile and create an executable, type

$ gcc <program lename.c> -o <executable lename>


So, in our case, for example,

$ gcc rst.c {o output.x

will compile the program saved in the text le with the name rst.c and create an executable out-
put.x in the same directory. The extension (.c) is meant to indicate the nature of this le. You can
give the command ls to check if output.x is created. Now we have created an executable le, in our
case output.x which can be executed or run by the machine.

1.2.2.1 Run your rst C program


In order to run the executable le produced above, type at the command prompt,

Page 12 of 164;
Introduction COMPUTER PROGRAMMING-2017

$ ./output.x

Note that := is necessary before output.x to make sure that the le output.x in the current directory
is executed.

Important: If you dont give a name to the output le (like we have given above (out-
put.x), then the compiler, uses a default name. The default name is a.out. So for instance,
instead of typing as above, if you compiled your rst.c program as

$ gcc rst.c

then the executable le created will be a.out and NOT output.x. This can be run by
typing the following at the command prompt:

$ ./a.out

If everything goes ne, then it will print \This is my rst C program" on the screen and will return
back to the command prompt.

CONGRATULATIONS! You are successful in writing, compiling and executing your


rst C program.

R As pointed out above, there is no need to name the executable les and clutter
up your area. An executable le can not be read or edited and so there is no reason to
have di erent executable les in your directory. PLEASE DON'T CREATE ANY
EXECUTABLE FILES EXCEPT THE DEFAULT ONE that is a.out. This way
your directory will not be lled with useless les. In any case, if you want to run a
program, all you need to do is to compile it again and run the freshly created new
a.out.
Although you have written a simple program which prints out some text, we don't really know what
the meaning of each of the commands is. The rst thing one has to understand about a programming
language is that the rules of any programming language are very precise and strict. One has to follow
them exactly otherwise the program will not work. In this respect, a computer programming language
is unlike natural languages that we speak. In our spoken language for instance, even if we use a gram-
matically incorrect expression, most of the times the listener can understand what we are trying to say.
In the case of programming languages, there is no such margin- the compiler , which is what translates

Page 13 of 164;
Introduction COMPUTER PROGRAMMING-2017

our program into machine language will not understand if the program is written incorrectly even in
a small way and return an error. In other words, natural languages have a fair degree of redundancy
while a programming language has none.

To start learning how C programming language works, let us write another program, this time
something which is a little bit more complex than our rst program.

Program 1.2- sinx.c , Version 1


/  sinx . c This program calculates sin (x)  /

# include < stdio .h >


# include < math . h >
main ()

f
float x,y;

p r i n t f ( " Supply the value of x in radians n n" ) ;

s c a n f ( "%f " ,& x ) ;

y = sin (x );

p r i n t f ( "%f , %f n n" , x,y);

After keying in the program above and saving it to a text le sinx.c, compile/execute and run your
programme. Before you compile delete le \a.out" if it already exists. In any case, the compiler will
overwrite any existing a.out le and replace it with the new one. Then type,

$ gcc sinx.c {lm

The program with the name sinx.c will compile and create the default executable a.out in the same
directory. You can use the command ls to check if a.out is created. Why did we have to add {lm
while compiling this program while we did not add this in compiling the rst program? The reason
for this is that this program has a statement #include <math.h>. We need this because we want
the program to compute the value of sin(x) and this function is available in the le math.h as you
will see below. Whenever we want to include the le math.h in any program, during compilation, we
need to add the quali er {lm. Since every single program that you write in this course would be using
some pre-de ned mathematical function, one will always have to include the le math.h. Therefore,
please remember to always add this quali er whenever you compile any program.

Page 14 of 164;
Introduction COMPUTER PROGRAMMING-2017

In order to run the executable le,

$ ./a.out

If every thing goes well the message in the seventh line will be printed on the screen that is

$ Supply the value of x in radians

and the cursor will begin ashing in the next line prompting you for input. If you now key in
the number 3:14159 (thereby wanting to compute sin()) and press < ENTER >, the numbers
3:14159: ; 0:000000 will ash on the screen for an instant; after that the screen returns to the COM-
MAND PROMPT.

Hints for understanding the above program:

1. The rst line in the above program is a comment and it is not part of the program in the sense
that it is not compiled. You can give a comment anywhere in the program using the format /*
(Comment) */. Any line in the program which begins with /* and ends with */ is not read by the
compiler. Another way to write comments is to start the line with //. Anything between /* and
*/ is only for your convenience. It makes no di erence to the program. Similarly, any line starting
with // is not read by the compiler. The comments are very useful in making programs more
readable and self- explanatory. You will nd them of great use when you write longer programs
and when you try to look at programs that you wrote earlier and whose details you would have
forgotten. Writing comments is good programming practice since then anyone who looks at the
program can understand it easily.
2. The next two lines beginning with #include append two header les to the programme. # is
called a preprocessor directive. stdio stands for standard input output while the le extension
.h indicates that it is a header le. These header les are there in the compiler directory of the
computer. The stdio.h le governs the input via scanf statement and output via the printf
statement. There are other means of input/output about which you will learn later. The math.h
header le contains declarations of in-built mathematical functions like sin, cos, etc. Header les,
as we mentioned, are les containing previously de ned functions or routines which allow us to
simplify the program. Thus, for instance, in the absence of math.h, every time that one wanted
to nd the cosine of an angle, or the square root of a number etc., one would have to write out
explicit instructions to do it. The header les make it convenient for us to use various well known
functions and operations. Again, please remember that the syntax of how to use these prede ned
routines and functions is xed and one cannot change it.

Page 15 of 164;
Introduction COMPUTER PROGRAMMING-2017

3. The 4th line indicates the start of the main program. Every program must have the function
main(). The 5th line is an open brace (f) which signals the beginning of the main program.
Correspondingly the last line contains a close brace (g) which signals the end of the
program EVERY C-program has to have these features.
4. The sixth line contains the declaration that the variables x and y are oating point numbers.
Each variable in a C program has to be declared in accordance with its nature such as oating
point, integer, character, long integer, double oat etc. An integer variable, i, is declared as int
i; similarly, a oat variable x is declared as oat x. All these declarations must be made at
the very beginning of the main program. It is good programming practice to initialize
the variables to some nominal values (usually 0). For a detailed discussion of variables, see
below.
Note the semicolon at the end of the statement. All executable statements in C have to
end with a semicolon. To save space, one can write more than one statement in a line, each
separated by a semi-colon but it is not advisable. Proper indentation of programs is crucial as it
can often help us avoid common syntax errors.
5. The seventh statement prints the message "Supply the value of x in radians" on the screen and
the nn in inverted commas causes the cursor to go to the beginning of the next line. Any matter
appearing within the inverted commas in a printf statement appears as it is on the
screen except for the special characters such as nn, %f, %d, %6.2f etc. The meaning of these
special characters will be explained as we go along. The messages such as the one in line 7 in the
above program are used as prompts, in this case to ask the user to input the value of x (in radians)
to the program. The program now waits for you to supply the value of x.
6. Once you supply the value, the eighth statement is the input statement requiring you to supply
the value of the variable x. If you have declared x as a oating point number, then it is best to
supply x as a decimal fraction (For example x = 2.0 instead of x = 2). scanf is a function
which will take the value of the input you have given on the screen and stores it in the memory.
The &x in this statement corresponds to the pointer to the memory address of the variable
x. (If you do not understand the pointers at this stage, do not worry, it would become clear
later. It must be noted, though, that the pointer feature is a major advantage of C over other
advanced languages like Fortran). The next statement computes sin(x) by making use of math.h
and assigns it to the variable y. For details of assignment of variables etc. see below the section
on Variables in C.
7. The next statement prints the value of two numbers x and y. In this statement %f describes the
nature of the variable viz., x is a oating point variable denoted by f in %f. For integers we would
use %d. The nn once again is to bring the cursor to the next line though it is not required in this
case.

Page 16 of 164;
Introduction COMPUTER PROGRAMMING-2017

8. The nal line, as in ALL C programs is a closing brace indicating to the compiler the end of the
program.

R Variables and constants in C can be given any name. However, the compiler
will only take the rst letters as meaningful and ignore all the others. As
8
mentioned earlier, C treats variables or constants in small case (like x, a, pi etc.)
di erently than those in upper case (like X, A, PI etc.). So please be careful. Also,
by convention, lower case letters are normally used to denote variables while upper
case letters are used to denote constants.

1.2.3 Variables in C
There are di erent kinds of variables in C. Single precision Floating point (usually just called oating
point), double precision Floating point (usually called double), integers, long integers, character vari-
ables. These are all di erent and to see the di erence, one must understand how the computer stores
these numbers.

Let us start with the simplest kind, that is intger variables. An int variable can store values from
32768 to +32767, that is from 2 to 2
15 15
1. What happens when we declare a variable, say a as
int a in the program? The compiler on reading this line in the program tells the computer memory
to allocate 16 bits (or 2 bytes) of memory space to the variable and call it in its address location as
a. (Why is the value of the number stored as int only 15 bits while we need 16 bits to store it? ). The
format speci er for an integer variable is %d.

Now, later on in the program, suppose you give a value of 156 to the variable a, you would typically
write

a = 156;
in the program. The character \=" in C is used for assignment and NOT as an equality
What this statement will do will be to tell the computer that the memory in the address location called
a , should store the number 156. That is important because it allows one to use the same variables
repeatedly. Thus, in ordinary mathematics, a statement like

x = x + 10;
will make no sense. In C, it simply means: Take the value stored in the memory location called x, add

Page 17 of 164;
Introduction COMPUTER PROGRAMMING-2017

10 to it and nally, store the result in the same memory location, that is now the value in the memory
location of x is the new value, which is the old value plus 10. You can see how this makes a program
much easier to write or else everytime we wanted to do an operation on a variable, we would need to
de ne a new variable.

While in most compilers, the integer variable is 16 bits or 2 bytes long, there are some compilers
where it is 32 bits or 4 bytes long. In most compilers, there is another variable class de ned which can
take care of longer integers. This is called the long integer which is 32 bits long and therefore can take
values from 2147483647 to +2147483647, that is from 2 to 2 31
1. The format speci er for long
31

integer is %ld.

Similarly, the next kind of variables is the single precision oating point variable. These vari-
ables have a precision of 6 digits and range from 10 to 10 and unlike the integer variable, it needs
36 36

32 bits (or 4 bytes) of memory space to be stored. Now it is clear that it would be dicult to store this
many numbers in 32 bits. So what the computer does is to store it as a number between 1 and 2 scaled
with a power of 2. Thus, for instance, 1:0 is stored as +1:0  2 and 5:0 is stored as 1:25  2 etc.
0 2

So we see that we need appropriate storage for three things:

1. The sign of the number which means 1 bit of storage.


2. The exponent of 2 which uses 8 bits of storage.
3. The mantissa, that is the number which multiplies the power of 2 therefore has 23 bits of storage
left. Now since there is little point in storing 1, and the mantissa will always be less than 2, the
1 is ignored and the rest of the mantissa after the decimal point is stored as an integer variable of
23 bits.
This way we can store very large and very small numbers. In our case, this will be sucient. The
format speci er for single precision oating point variable is %f.

However, in certain cases, more precision is required and so there is another class of oating point
variables, called double precision oating point variables. These have 14 digits of precision and
can range from 10 303
to 10 . They are stored just like the single precision oating point variables
303

but with the exponent having 11 bits instead of 8 bits and the mantissa having 52 bits. The sign bit
remains the same. Thus to store a double precision oating point number we need 64 bits or 8 bytes.
The format speci er for double precision oating point variable is also %f.

Then there are character variables where one can store a single character. It is 1 byte long. The
format speci er for character variable is %c.

Page 18 of 164;
Introduction COMPUTER PROGRAMMING-2017

Example 1.3- sinxtab.c (Version 1)

Now let us try to run a variant of the previous program which will tabulate the value of sin(x) at
twenty equally spaced values of x lying between x1 and x2 that you would specify. The listing of this
program is as follows:

Program 1.3- sinxtab.c , Version 1


/  sinxtab . c tabulates values of sin x  /

# include < stdio .h >


# include < math . h >
main ( )

f
float x, x1 , x2 , y, dx , pi ;

int i , n =20;

pi = 4.0  atan ( 1 . 0 ) ;

p r i n t f ( " Supply x1 and x2 in units of pi n n" ) ;

s c a n f ( "%f , %f " , &x1 , &x 2 ) ;

x1 = x1  pi ;

x2 = x2  pi ;

dx = ( x2 x1 ) / ( float )(n );

for ( i =0; i <


= n; i ++)

f x = x1 + i  dx ;

y = sin (x );

p r i n t f ( " %6.2 f %6.2 f n n" , x, y);

g
g

Hints for understanding the above program:

1. As in the case of oating point variables, integer variables must also be explicitly declared
in the beginning. It is possible to assign values to integers in the declaration statement itself,
as is done for n in the above program.
2. The atan function evaluates arc tangent (arctan) of its argument.
3. The for statement sets a sequence i = 0 to n in unit steps. i++ increments i by one and is identical
to i = i + 1. All statements after the braces on the next line until the closing braces (in the 14th
line) are executed for every value of i in the sequence de ned above. This procedure is called
looping. NOTE that there is no semicolon after the for statement.
4. %6.2f is a format symbol which stands for a oating point number of total eld of six spaces with
two places after decimal.

Page 19 of 164;
Introduction COMPUTER PROGRAMMING-2017

5. The space between %6.2f and the second %6.2f is to separate the numbers adequately when
printed on the screen.

1.2.4 Loops in C
Frequently we would like to repeat some operation for a speci ed number of steps. In this case, the
for loop in C is very useful. A for loop is a repetition control structure that allows you to eciently
write a loop that needs to execute a speci c number of times. The syntax for a for loop is as follows:

for ( init ; condition ; increment ) f


statement ( s ) ;

g
The init step is executed rst, and only once. This step allows you to declare and initialize any
loop control variables. You are not required to put a statement here, as long as a semicolon appears.

Next, the condition is evaluated. If it is true, the body of the loop is executed. If it is false, the
body of the loop does not execute and the ow of control jumps to the next statement just after the
for loop.

After the body of the for loop executes, the ow of control jumps back up to the increment state-
ment. This statement allows you to update any loop control variables. This statement can be left
blank, as long as a semicolon appears after the condition.

The condition is now evaluated again. If it is true, the loop executes and the process repeats itself
(body of loop, then increment step, and then again condition). After the condition becomes false, the
for loop terminates.

Thus, in our example above, the for loop is


for <
( i =0; i =n ; i ++)

f
x = x1 + i dx ;

y = sin (x );

p r i n t f ( " %6.2 f %6.2 f n n" , x, y);

g
The init step is i=0, that is the variable i which is an integer variable is initialised to 0. The the
condition, that is i <= n is evaluated. If it is true, which it will be at rst since n = 20, the body
of the loop, that is the statements contained within the curly braces are executed. After this is done
once, the ow goes back to the increment statement, which in this case is i + +. Now, recall that
the initial value of i was i = 0. The statement i + + tells the computer to take the value stored in the
memory location addressed by i, and whatever the value is there, increment or increase it by 1 and then

Page 20 of 164;
Introduction COMPUTER PROGRAMMING-2017

store the new value in the same memory location. After the increment, the condition, that is i <= n
is evaluated again and since it would be found to be true, since the value of i after the rst run is now
i = 1, the process repeats itself. This continues till the time the condition becomes false when the
loop terminates.

Looping or recursion is a very important part of programming and there are many ways in which one
can use the various looping structures available in C. Remember that the for loop is best used when
we want to perform certain statements for a known number of steps.

Another kind of looping structure is the do-while loop.

Frequently, when we want to repeat certain steps in a program, we do not know how many times we
have to repeat the steps, but we do know what the nal value of a particular parameter or variable we
want. Then it is best to use the do-while loop. The structure of a do-while loop is as follows:

do f
statement ( s ) ;

g while ( condition );

Here statements are the steps you want the computer to repeat and condition is the statement
which if true means that the steps keep on repeating. Thus in the previous example, we could replace
the for loop with
i =0; n =20;

do
f x = x1 + i  dx ;

y = sin (x );

p r i n t f ( " %6.2 f %6.2 f n n" , x, y);

i ++;

g while < (i =n ) ;

The structure and the meaning of the various lines should be obvious in this loop construction.

Another useful loop structure is the while loop. The structure of the while loop is as follows:

while ( condition ) f
statement ( s ) ;

g
Notice that this is almost exactly like the do-while loop except one very important di erence. In
this loop structure, like the for loop, the condition is checked at the top of the loop. In the do-while
loop, the condition is checked after the loop has been executed atleast once, that is the condition is
checked at the bottom of the loop. This is a very important di erence. In our example above, we could

Page 21 of 164;
Introduction COMPUTER PROGRAMMING-2017

write the same loop with a while loop as follows:

i =0; n =20;

while < (i =n )

f x = x1 + i  dx ;

y = sin (x );

p r i n t f ( " %6.2 f %6.2 f n n" , x, y);

i ++;

g
We can also have nested loops that is one or more loops inside a loop. The nested loops do not have
to be of the same kind, that is one can have for loops inside a do-while loop etc. The only thing one
has to be careful of is that the loops are completely nested. That means that the inner
loops should close before the outer loop closes. This is extremely important and you must
remember this.

Change of Type (typecasts)

Very often one has to change a variable from one type to another; for example int to oat, oat to
double, oat to int etc. Thus oat(n) OR ( oat)(n) converts the value of n into oat type.
Note that whereas n remains of the type int and its value in the above example remains
20, the value of ( oat)(n) becomes 20:0. Similarly, the statement (int)(x*y+0.1*exp(x)) will, for
example, evaluate the expression (x*y+0.1*exp(x)), which is of the type oat and then convert it into
type int. Thus we may have a statement like

i = (int)(x*y+0.1*exp(x));

Of course i must already have been declared as an int variable. If the expression on the RHS evaluates
to 3:7, the integer i will have the value 3; if it evaluates to 3:8, i will have the value 3.

R Whenever we divide by a oating point number with an integer, we should


always as good programming practice, change the type of the integer in the denomi-
nator to oat. Otherwise there is a chance that the program will do integer division
and give strange results.

Example 1.3 (version 2)

Page 22 of 164;
Introduction COMPUTER PROGRAMMING-2017

An alternative program

Program 1.3- sinxtab.c , Version 2


/  sinxtab ver2 . c tabulates values of sin x  /

# include < stdio .h >


# include < math . h >
main ( )

f
float x , x1 , x2 , y , dx , p i ;

int i , n =20;

pi = 4.0  atan ( 1 . 0 ) ;

p r i n t f ( " Supply x1 and x2 in units of pi n n" ) ;

s c a n f ( "%f ,% f " ,& x1 ,& x 2 ) ;

x1 = x1  pi ;

x2 = x2  pi ;

dx = ( x2 x1 ) / ( float )(n );

for ( x=x 1 ; x < = x2 ; x+ = dx )

f y = sin (x );

p r i n t f ( " %6.2 f %6.2 f n n" , x , y ) ;

g
g

to set up the sequence: x=x1, x1+dx, ...x2 (=x1+n*dx). Here x+=dx is an abbreviation for
x = x + dx. Similarly x*=(expression) implies x = x * expression, etc. Note that the
integer variable i is no longer required in the program; therefore it may be deleted from the declaration
statement int i, n = 20. Rerun the program. The results of these two programs should be identical.

or
R The ability of a programming language to do this recursion, that is
 is amongst the most powerful things in programming. Of course, as a
x = x dx
x = x + dx

mathematical statement it makes no sense. But if we understand how a computer


works, then it will be clear. When we de ne a variable, say x as a oating point
variable, the computer assigns a memory space which typically is 4 bytes or 32 bits.
This memory space is labelled x. Now whenever we have a value of the variable x
in the program, it stores that value in this memory location. Now imagine what
happens when the program encounters a statement like x = x + 1:6. It takes the value
of the variable x stored in the memory labelled x and adds 1:6 to the number. The
new number is again stored in the same memory location and labelled as x. Now
after this step, whenever the variable x is called in the program, it will return the
new value of x. This kind of recursion allows programs to be very versatile and

Page 23 of 164;
Introduction COMPUTER PROGRAMMING-2017

exible.

1.3 Functions in C
You have already used library functions like sin; cos, atan, etc. To be able to appreciate the modular
structure of C language, it is essential for you to learn how to make your own function routine which
performs a speci c computation when called by the main program. In this manner, the main program
will simply become a calling program and call various functions to perform their respective computa-
tions.

A function is a group of statements that together perform a task. Every C program has
at least one function as we have seen. This is the function main(). One can divide up one's code into
separate functions. How one divides up one's code among di erent functions is up to you, but logically
the division is such that each function performs a speci c task. Think of a function as a blackbox
which sits inside the main program, which incidentally is also a function! When the function is called
by the main program or any other function, then the blackbox is supplied with some input values or
parameters. The blackbox performs certain operations on the input values according to how you have
de ned the function and then returns the value computed to the main program.

A function declaration tells the compiler about a function's name, return type, and parameters. A
function de nition provides the actual body of the function. We already know that the C standard
library provides numerous built-in functions that your program can call. For example,printf(), scanf(),
and many more functions. In C Language, a function is the same as a method or a sub-routine or a
procedure, etc. In some languages these are not the same.

The general form of a function de nition in C is as follows


return type function name ( parameter list )

f
body of the function

g
A function de nition in C, as we have seen, consists of a function header and a function body. Here
return type, function name and parameter list are the components of the function header. Here
return type tells the compiler what kind of function it is that one is de ning. A function may or may
not return a value. The return type is the data type of the value the function returns, that is if the
function returns a oating point variable, then the return type is oat, if an integer then int and so
on. However, it is not always the case that a function has to return a value. Some functions perform

Page 24 of 164;
Introduction COMPUTER PROGRAMMING-2017

the desired operations without returning a value. In this case, the return type is the keyword void.
Remember that printing something does not count as returning a value. We have already encountered
examples of such void functions- printf, scanf and even main() are examples of such functions.
function name is basically the name by which the function is going to be called or addressed in the
program. parameter list is essentially what goes into the function or the blackbox. Whenever we
call the function in the main program, we need to specify the input parameters. The parameter list
thus has the type, order, and number of the parameters of a function. However, just like one can
have functions which do not return Parameters are optional; that is, a function may contain no parame-
ters. Finally, the function body contains a collection of statements that de ne what the function does.

To see how all this works, let us consider an example.

Example 1.4

For example if you wish to compute the function

f (x) = x  x  x + sin x  log x


in your program, you can do so in two ways.

# include < stdio .h >


# include < math . h >
/ 
Function with name f of type float and has one

argument which is of type float

 /

float f ( float x)

f
float z ;

z = x  x x + sin (x)  log (x ) ;

return (z );

g
/  Main function which will call above function  /

main ( )

f
float y;

float f ( float x); /  function declaration  /

Page 25 of 164;
Introduction COMPUTER PROGRAMMING-2017

p r i n t f ( ` ` Supply the value for which you want to evaluate the function n n" ) ;

s c a n f ( "%f " ,& y ) ;

p r i n t f ( " %6.2 f %6.2 f n n" , y, f (y ) ) ;

Here return type is oat since the function is going to return a oating point number. The func-
ton name is simply f and the parameter list is x. Note that we need to de ne the kind of variable
the parameter x is, in this case oat. This method of writing a function returns to the calling program
the value of the function for the speci ed argument x. Alternatively, we could de ne the expression as
follows:

oat f( oat x)
f
return (x*x*x + sin(x)*log(x));
g
Note that in this case we did not use the local oat variable z to rst calculate the result and then
return the value. A local variable within the function is one which has no relevance outside the function.
Note that in this case, x, the input variable is not local but is passed into the function. Similarly the
value of the function is passed out but stored locally as z.

R The global variables of the function (in our example the variable x) need
to be supplied whenever the function is called. Of course though the variable is
called x in the function de nition, one can call the function in the main program
for any variable or even a constant. Thus in the above example, we saw that the
function f(x) was called for the variable y which was supplied to the program by
the user. Alternatively, we could have asked the program to print f(1.7) instead of
f(y). Remember that the function of more than one variable, whenever it is called
in the main program, should have exactly the same number of and type of variables
speci ed in exactly the same order.

Since this is a simple one-line function, we can also use an alternative way to de ne it. This is called
preprocessor directive. The syntax would be

#de ne f(x) ((x)*(x)*(x) + sin(x)*log(x))

Page 26 of 164;
Introduction COMPUTER PROGRAMMING-2017

There must be

(a) A space between #de ne and f(x) and between f(x) and the beginning of the function.

(b) The argument of the function should always be within brackets wherever it appears
and the entire function should also be enclosed within brackets.

The return type of inline functions (int/ oat etc.) is decided by the argument x. The complete
program may look like the following:

#include < stdio .h >


#include < math . h >
#define f (x) ((x)  (x)  (x) + sin (x)  log (x )) /  inline function  /

/  Main function which will call above function  /

main ( )

f
float y;

p r i n t f ( " Supply the value for which you want to evaluate the function n n" ) ;

s c a n f ( "%f " , &y ) ;

p r i n t f ( " %6.2 f %6.2 f n n" , y, f (y ) ) ;

R It is ALWAYS a good idea to declare function prototypes in the main program


except for the inline functions. Notice that both these styles of functions have NO
semicolon at the end of the line. ALWAYS remember to enclose ALL variables in
an inline function in parenthesis.

We have just seen an example of de ning functions in C. However, the above example was fairly
simple and did not really need a function to work. We could as well have written a variable z and then
printed the values of z for di erent values of x. The following example will bring out the real utility of
functions in C.

Example 1.5

Let us take another example: We wish to evaluate the function

Page 27 of 164;
Introduction COMPUTER PROGRAMMING-2017

f (x; n) = xn 1 + ex for x  0:0


= xn log(1 + x) for x > 0:0

where n is an integer. Obviously, such a function can not be written in the inline style easily.
However, in the rst style it may be written as:
float f ( float x, int n)

f
float y , z =1.0;

int i ;

for ( i =1; i < =n ; i ++)

f

z =x ;

g
if (x < 0.0)

f
y = z 1 + exp ( x ) ;

g
else
f
y = z l o g (1+ x ) ;

g
return (y );

g
and the full program may look like the following:

# include < stdio .h >


# include < math . h >
/ 
Function with name f of type float and has two

arguments , one of type float and other of type int .

 /

float f ( float x, int n)

f
float y , z =1.0;

int i ;

for ( i =1; i <=n ; i ++) f



z =x ;

Page 28 of 164;
Introduction COMPUTER PROGRAMMING-2017

if (x < 0.0) f
y = z 1 +e x p ( x ) ;

g
else f
y = z l o g (1+ x ) ;

g
return (y );

g
/  global function declaration  /

float f ( float x, int n);

/  main function will call f  /

main ( )

f
float q;

int j ;

p r i n t f ( " Supply the value of x( float ) , n( int ) n n" ) ;

s c a n f ( "%f , %d " , &q , &j ) ;

p r i n t f ( " x=%6.2 f n=%d f =%6.2 f n n" , q , j , f (q , j ) ) ;

Note that here we have de ned a function of two variables, one of which, x, is a oat variable and the
other, n, is an integer variable. We can, in fact, de ne in the same way functions of several variables.

1.3.1 Decision Making in C


You would have realised by now that a C-program is basically the encoding of an algorithm in the C-
programming language. An algorithm is essentially a step by step method to solve a particular problem.
We use algorithms all the time without realising it. Thus, for instance, suppose you want to wake up
exactly at 4am. Then typically you would need to set an alarm for 4am. The algorithm then can
simply be
1. Pick up mobile
2. Open Alarm App
3. Check time of existing alarm
4. If Alarm already set for 4am, go to 6
5. Else Set alarm for 4am
6. Shut the Alarm App on your mobile

Page 29 of 164;
Introduction COMPUTER PROGRAMMING-2017

Now this might seem trivial and obvious, but notice that this is exactly what you do. Basically, any
particular task can be broken up into discrete steps and the set of these steps to complete a task is
called an algorithm.

In the above algorithm, notice that there is a decision to be made. The decision is to check the time
of the existing alarm. Then, if the alarm is already set for 4am, then one does nothing and shuts the
Alarm App. Else one sets the alarm for 4am. It is these decision structures that we need to implement
in C.

Decision making structures require that the programmer speci es one or more conditions to be eval-
uated or tested by the program, along with a statement or statements to be executed if the condition
is determined to be true, and optionally, other statements to be executed if the condition is determined
to be false. There are many kinds of decision making structures in C.

The simplest one is the if statement. The structure


if ( boolean f
expression )

statements to be executed if boolean expression is true

g
Thus for instance, we could have the following program
#include < > stdio .h

main ()

f
int a = 17;

if ( a < 100)

f
p r i n t f ( "a is less than 100 n n" );

g
p r i n t f ( " value of a is : %d n n" , a );

g
The boolean expression in this program is \ if a < 100". The statements inside the curly braces
following if will be executed only if the expression is true. If not, the control will pass to the line
immediately after the if structure. In the above case, since a = 10, and therefore the boolean expression
is true, the program will execute the statements inside the if and print \ a is less than 100". After this
it will go as usual to the next line after the if block and print \ value of a is : 17".

The most commonly used decision structure is the if....else structure.


if ( boolean expression )

f
statement ( s ) will execute if the boolean expression is true

Page 30 of 164;
Introduction COMPUTER PROGRAMMING-2017

g
else
f
statement ( s ) will execute if the boolean expression is false

g
In the program above, we could also use this structure as follows.
#include < > stdio .h

main ()

f
int a = 179;

if ( a < 100 )

f
p r i n t f ( "a is less than 100 n n" );

g
else
f
p r i n t f ( "a is not less than 100 n n" );

g
p r i n t f ( " value of a is : %d n n" , a );

g
Here in the if part of the structure, a boolean expression is checked. In this case since the variable
a = 179, the boolean expression a < 100 is clearly false. Therefore the statements inside the if are
not executed. Instead, the control goes to the else part of the structure. Notice that here there is
no condition and therefore if the boolean expression in the if is false, then the statements within the
else structure are always executed. In this case, the statement is a simple printing of \a is not less
than 100". Note again that one can have as many statements within the if and else structures. Also
note that if the boolean expression in if is true, then the statements within the else structure are not
executed.

Another decision structure which is used frequently is the if...else if...else if......else.Basically, one
can use an if statement followed by an optional else if...else statement. This is very useful to test
various conditions using single if...else if statement. The syntax is as follows

if ( boolean expression 1)

f
Statements that are executed when the boolean expression 1 is true

g
else if ( boolean expression 2)

Page 31 of 164;
Introduction COMPUTER PROGRAMMING-2017

f
Statements executed when the boolean expression 2 is true

g
else if ( boolean expression 3)

f
Statements executed when the boolean expression 3 is true

g
else
f
Statements executed when the none of the above condition is true

g
There are several things one must keep in mind when using the if...else if....else structure.
1. An if can have zero or one else and it must come after any else if's.
2. An if can have zero to many else if 's and they must come before the else.
3. Once an else if succeeds, that is the boolean statement corresponding to it is true, then none of
the remaining else if 's or else will be tested.
So for instance, we can use this construct in the program above as follows.
#include < > stdio .h

main ()

f
int a = 179;

if ( a < 100 )

f
p r i n t f ( "a is less than 100 n n" );

g
else if (a < 150)

f
p r i n t f ( "a is less than 150 n n" );

g
else if (a < 175)

f
p r i n t f ( "a is less than 175 n n" );

g
else
f
p r i n t f ( "a is not less than 175 n n" );

g
p r i n t f ( " value of a is : %d n n" , a );

Page 32 of 164;
Introduction COMPUTER PROGRAMMING-2017

In this case, since the value of the variable a is 179, the boolean statement corresponding to if and
the two else if s is false and therefore the statement in the else will be executed and we will get \ a is
not less than 175" and then the \value of a = 179".

Once again, we can always use nested if... else statements or even nested if...else if...else state-
ments. However, one should be careful that the loops are completely nested.

Finally, there is another kind of decision making structure called the switch statement. This used
when a variable is to be tested for equality against a list of values. Each value is called a case, and the
variable being switched on is checked for each switch case. The syntax is as follow:

switch ( expression ) f
case constant expression :

statement ( s ) ;

break ; / This is optional  /

case constant expression :

statement ( s ) ;

break ; / This is optional  /

/  you can have an y number of case statements  /

default : /  This is Optional  /

statement ( s ) ;

g
There are several things to keep in mind when one uses this structure.

1. The expression used in a switch statement must have an integral or enumerated type.
2. One can have any number of case statements within a switch. Each case has to be followed by the
value to be compared to and a colon.
3. The constant-expression for a case must be the same data type as the variable in the switch, and
it must be a constant.
4. When the variable being switched on is equal to a case, the statements following that case will
execute until a break statement is reached.
5. When a break statement is reached, the switch terminates, and the program goes to the next line
following the switch statement.
6. Not every case needs to contain a break. If no break appears, the program will go through to the
subsequent cases until a break is reached.

Page 33 of 164;
Introduction COMPUTER PROGRAMMING-2017

7. A switch statement can have an optional default case, which must appear at the end of the switch.
The default case can be used for performing a task when none of the cases is true. No break is
needed in the default case.
As an example of this statement, consider the following program to convert a set of marks between
0 and 4 into grades. 0 marks is an F grade, 1 is D, 2 is C, 3 is B and 4 is A.
#include < >
stdio .h

main ()

int marks ;

marks =2;

switch ( marks )

f
case 0 :

p r i n t f ( " Your grade is F n n" );

break ;

case 1 :

p r i n t f ( " Your grade is D n" n );

break ;

case 2:

p r i n t f ( " Your grade is C n n" );

break ;

case 3:

p r i n t f ( " Your grade is B n n" );

break ;

case 4 :

p r i n t f ( " Your grade is A n" n );

break ;

default :

printf (" Invalid grade n n" );

g
g
As you can see, if the value of the switch expression that is marks is 3, the statements corresponding
to the case 3 will be executed and we will get \ Your grade is C" as the output.

If a statement becomes too long, it can be continued in the next line by using n . A
generalization to functions of many variables is obvious. There are also functions that do not return
any value to the calling program but perform many other tasks. In fact, most of the work in C is done
through such functions. Examples are scanf, printf. Even main () itself is one such function. We

Page 34 of 164;
Introduction COMPUTER PROGRAMMING-2017

will come across many more examples of such functions in future.

N.B. The function subprogram can be de ned either before or after the main program. If it is
de ned after the main program, it has to be identi ed in the main program eg.

#include < stdio .h >


#include < math . h >
main ()

f
float f ( float x, int n);

g
float f ( float x, int n)

f
y=x ;

return (y );

1.3.2 Function Prototypes


Every user-de ned subroutine/function must be declared in the caller function via a function proto-
type. If a function is to be used in many other functions, its prototype must be declared in each one
of them. Alternately, one may make a global declaration of the function prototype by declaring it
outside all functions. For example

float f1 ( float x, float y)

f
. . .

. . .

. . .

g
void f2 ( float x, int i )

f
float f1 ( float a , float b);

. . .

. . .

. . .

g
main ( )

Page 35 of 164;
Introduction COMPUTER PROGRAMMING-2017

float f1 ( float x, float y);

void float
f2 ( a , int j );

. . .

. . .

. . .

g
Here we have two user-de ned functions, f1 of return-type oat depending on two input argu-
ments, both of type oat, and f2 of return-type void depending on two input arguments, the rst of
type oat and the second of type void. The prototype of f1 has been declared in f2 as well as in main;
so the function f1 can be used in both of them. However, the prototype of f2 has been declared only in
main and not in f1. Hence, f2 can be used only in main. In general it is best to make a global
prototype declaration:

oat f1( oat x, oat y);


void f2( oat x, int n);

immediately after the inclusion of header and other les. Now the two functions can be used in
main as well as in all other programs. Note that the type of the function and the type and the number
of arguments on which the function depends, must match with the prototype declaration; the names of
the arguments can be anything or may not even be included. For example, the function prototype in
the above example could have been

oat f1( oat , oat );


void f2( oat , int );

Note on function names: You must always give meaningful function names to user-de ned
functions to improve the readability of your code. Try to avoid giving single alphabet
function names.

1.4 Operators in C
An operator in C is a symbol that tells the compiler to perform speci c mathematical or logical func-
tions. There are several kinds of operators in C like Arithmetic Operators , Assignment Operators,
Relational Operators, Logical Operators etc.

Page 36 of 164;
Introduction COMPUTER PROGRAMMING-2017

1.4.1 Arithmetic Operators

Operator Meaning
+ Addition
- Subtraction
* Multiplication
/ Division
% remainder after division or modulo division

Table 1.1: Arithmetic Operators in C

The meaning of the operators +, - and * computes addition, subtraction and multiplication respectively
as we know. However, one has to be careful in division. If both the dividend and divisor are de ned
as integers, say 6 and 4 that is 6=4 , then the result (which should be 1:5 ordinarily) will be 1 instead
since the compiler thinks that this is integer division. If one wants to divide integers, one should rst
change the typecast as discussed above before dividing. The only unfamiliar operator is %, or modulo
division. This is an operator which can only be used by integers and gives us the remainder after the
division. Thus, 6%4 will give us 2.

Another useful class of operators is the increment and decrement operators. These are the ++ and
the operators which increase or decrease the value of a variable or constant by 1. Remember that
these are so called unary operators and so operate on a single operand. A simple example is
int main ( )

f
int a = 3, b = 15;

float c = 1.5 , d = 12.5;

p r i n t f ( "++a = %d , b=%d , ++c =%f , d=%f " , ++a , b,++c , d);

g
This program will give us an output of 4; 14; 2:5; 11:5.

1.4.2 Assignment Operators


As the name suggests, assignment operators are used to assign a value to a variable.

Page 37 of 164;
Introduction COMPUTER PROGRAMMING-2017

Operator Usage Meaning


= x=y x=y
+= x +=y x=x+y
-= x -=y x=x-y
*= x *=y x=x*y
/= x /=y x = x/y
%= x %=y x = x%y

Table 1.2: Assignment Operators in C

The usage and the meaning should be clear from the table above.

1.4.3 Relational Operators


A relational operator as the name suggests, checks the relationship between two operands. This oper-
ator returns only two values, 1 and 0. If the relation is true, it returns 1 and if the relation is false, it
returns value 0.

Operator Usage Meaning


== Equal to 3==10 will return 0
> Greater than 3>10 will return 0
< less than 3<10 returns 1
!= Not equal to 3!=10 returns 1
>= Greater than or Equal to 3>=10 returns 0
<= Less than or Equal to 3<=10 returns 1

Table 1.3: Relational Operators in C

Relational operators are very useful in decision making and also in loops.

1.4.4 Logical Operators


Logical operators are those which if used in an expression return either 0 or 1 depending on whether
the expression is true or false. Once again, these are used frequently in decision making in C.

Suppose x = 3 and y = 10. Then


Operator Usage Meaning
&& (Logical AND) True only if all operands are true Then ((x == 3)&&(y > 100)) is equal to 0
jj (Logical OR) True only if either one is true Then ((x == 3)jj(y > 100)) is equal to 1
! (Logical NOT) True only if the operand is 0 Then !(x == 3) is equal to 0

Table 1.4: Logical Operators in C

Page 38 of 164;
Introduction COMPUTER PROGRAMMING-2017

1.5 Mathematical Functions in C


These are functions which are in-built in C and are declared in the header le < math.h>. Therefore
to use these, we must include this header le.
Wherever the argument in these mathematical functions is a double (double precision variable or con-
stant), it can be replaced by a oat variable or constant but should be avoided. The single precision
counterparts of these functions usually have f appended at the end of their names. For example the
single precision counterpart of sin() function declared in < math:h > is sinf() and so on. The choice
of using single precision ( oat) or double precision (double) variables for computation depends on the
nature of the problem and accuracy desired. However, if the argument is an integer, it cannot be re-
placed by a oat or double.

The trigonometric functions, the inverse trigonometric and the hyperbolic functions are fairly obvi-
ous. Please remember that the arguments of the trigonometric functions and the results
of the inverse functions are always in radians and NOT degrees. The commonly used trigono-
metric functions are sin, cos, tan, asin, acos, atan, sinh, cosh, tanh. Remember that each of these
functions is a type double precision oating point and the arguments are also double precision.
The exponentiation and log functions are exp,log, log10,log2 where the logarithmic function log is
loge while log10 is log .
10

The square root and power functions are sqrt and pow. The syntax of the pow function is pow(a; b)
where a and b are both double precision and a >= 0. The sqrt function has a syntax sqrt(a) where
a >= 0.
The abs function returns the absolute value of an integer. The fabs function returns the absolute
value of a oating point number.
The fmod function has two double precision variables x; y as its argument. When used, it returns the
oating point remainder of x=y. Thus suppose x = 9:6; y = 2:7 then fmod(x,y) is the remainder
left by 9:6=2:7 and is equal to 1:5.

Finally, there are two functions which may not be very obvious. These are the ciel and oor functions
which both have single oating point arguments. The ciel function returns the smallest integer value
not less than the argument while the oor function returns the value of the largest integer not greater
than the argument. Thus if x = 9:4, then ciel(x) is 10 while oor(x) is 9. Some of the functions that
you might use in this course are collected in the table below (Table 1.5).

Page 39 of 164;
Introduction COMPUTER PROGRAMMING-2017

Function Description
double cos(double x) Returns the cosine of a radian angle x.
double acos(double x) Returns the arc cosine of x in radians.
double cosh(double x) Returns the hyperbolic cosine of x.
double atan(double x) Returns the arc tangent of x in radians.
double exp(double x) Returns the value of e raised to the xth power.
double log(double x) Returns the natural logarithm (base-e logarithm) of x.
double log10(double x) Returns the common logarithm (base-10 logarithm) of x.
double pow(double x, double y) Returns x raised to the power of y.
double sqrt(double x) Returns the square root of x.
double fabs(double x) Returns the absolute value of x.
double fmod(double x, double y) Returns the remainder of x divided by y.
double ceil(double x) Returns the smallest integer value greater than or equal to x.
double oor(double x) Returns the largest integer value less than or equal to x.

Table 1.5: Mathematical Functions in C

1.6 Storing the results of the program in a data le


Frequently, we would need to store the results of a program in a data le to be used by other programs.
Thus, for instance, you might have a program which calculates the orbit of a planet, which will give
you the position of a planet at various times. You might want to use this to plot the trajectory of the
planet using another graphics program. Or you might have some expression which generates some data
and you might want to use another program to do some statistical analysis on the data. C allows you
to store the results of the program in a data le as well as to read a data le in a program. We will
learn essential features of storing data le in C program. The functions that are used to do this are
very similar to the printf and scanf functions that we have already discussed. The relevant functions
are fprintf and fscanf. Also we need to tell the C program the name of the data le which we want to
write to or from which we want the data to be read. The following program will make clear the syntax
etc of using these constructs.

/  Program for evaluating a function & storing the results in two

data files , data1 . t x t and data2 . t x t  /

#include < stdio .h >


#include < math . h >
main ( )

f
float x,y, z ;

Page 40 of 164;
Introduction COMPUTER PROGRAMMING-2017

FILE  f p=NULL ;

FILE  f p 1=NULL ;

fp = fopen ( " data1 . t x t " , "w" ) ; /  open a file handle in write mode  /

fp1 = fopen ( " data2 . t x t " , "w" ) ; /  open a file handle in write mode  /

for ( x= 0; x <= 6; x+= 0.1)

f
y=s i n ( x ) ;

z=c o s ( x ) ;

f p r i n t f ( fp , "%f n t %f n n" , x, y); /  print line to the file  /

f p r i n t f ( f p 1 , "%f n t %f n n" , x , z ) ;

g
f c l o s e ( fp ) ; /  close the file handle  /

f c l o s e ( fp1 ) ;

COMMENTS

1. Include the header le <stdio.h> in the main program to use FILE pointers in the main program.

2. Open two new data les in \w" (write) mode with a call to fopen() function. Other modes of
opening a le are \a" for append, \r" for read, etc. One can open as many les as one wants but
they should have di erent names, in this case fp, fp1 etc.

3. In order to store data inside the le, use fprintf() function in the manner we used printf() earlier
for printing the output to the standard output (screen). \n t" corresponds to a tab space and \n
n" corresponds to new line. Note that fprintf() takes the rst argument as the le pointer fp
which points to the le opened earlier in the program.
4. Once data is stored in the le, close the data le using fclose() subroutine.

1.7 Examples
We give a few examples of programs to solve simple arithmetic problems. These programs will illustrate
the use of most of the concepts discussed above.

Example 1.6

Page 41 of 164;
Introduction COMPUTER PROGRAMMING-2017

Palindrome Numbers are those numbers which do not change when the order is reversed. Thus
11; 22; 33 etc. are palindrome numbers as are 121; 313; 212; 12321 etc. The problem is to write a pro-
gram to check whether a number is a palindrome number or not.
As with all programs, rst one has to think of the underlying algorithm that one would use to solve the
problem. Think of this as solving the problem without a computer in a sense. Once we have the al-
gorithm, the next step is to code the algorithm in C to make a program which implements the algorithm.

The algorithm for this is straightforward.


1. Supply the number
2. Reverse the digits
3. Compare with original number
4. If both are the same, then output number is a palindrome number
5. Else output number is not a palindrome number
The program below is one way to implement this algorithm.

/  Program to check whether a given number is a Palindrome Number  /

#include < stdio .h >



/ We don ' t need a math . h file since this program d o e s NOT u s e any predefined functions  /

main ( )

f
int n, rev = 0, tem ;

/  Note that all operations are on integers and result in integers .  /

/  So all variables are integer type  /

p r i n t f ( " Enter a number to check if it is a palindrome or not n n" ) ;

s c a n f ( "%d " ,& n ) ;

tem = n ;

while ( tem != 0 )

/  Use of a top checked while loop along with the logical NOT operator  /

f
rev = rev  10;

rev = rev + tem % 1 0 ; /  Use of the remainder operator  /

tem = tem / 1 0 ;

/  Note that since everything is integer , this is an integer division  /

g
/  Use of an if else structure  /

Page 42 of 164;
Introduction COMPUTER PROGRAMMING-2017

if ( n == rev )

/  Use of the Relational == operator to check if the two variables are equal  /

p r i n t f ( "%d is a palindrome number . n n" , n);

else
p r i n t f ( "%d is not a palindrome number . n n" , n);

Example 1.7
This example shows you how to tell whether a given year is a leap year. Recall that to check for leap
year, we must have three criteria
1. The year is evenly divisible by 4;
2. If the year can be evenly divided by 100, it is NOT a leap year, unless;
3. The year is also evenly divisible by 400. Then it is a leap year.
This is the algorithm that we need to implement. One way to do it is as follows:

/  Program to check for leap year  /

#include < stdio .h >


main ( )

f
int year ;

p r i n t f ( " Enter a year to check if it is a leap year n n" ) ;

s c a n f ( "%d " , &y e a r ) ;

/  We h a v e to check three conditions . So we will use a if .. else if . . . else structure  /

if ( y e a r %400 == 0)

p r i n t f ( "%d is a leap year . n n" , year ) ;

/  Since there is one statement after the if condition , there is no need for f g /

else if ( y e a r %100 == 0)

/  Recall that in the if .. else if .. else construction , if any of the conditions  /

/  is satisfied , control passes out and no other condition is checked  /

p r i n t f ( "%d is not a leap year . n n" , year ) ;

else if ( y e a r %4 == 0 )

p r i n t f ( "%d is a leap year . n n" , year ) ;

else

Page 43 of 164;
Introduction COMPUTER PROGRAMMING-2017

p r i n t f ( "%d is not a leap year . n n" , year ) ;

Example 1.8 To nd the HCF (Highest Common Factor) or GCD (Greatest Common Divisor) of
two numbers. Recall that the HCF of two numbers is the highest or largest common factor of the two.
Thus, the HCF of 24 and 16 is 8 since 24 = 8  3 and 16 = 8  2. We can implement this in many
ways. This is one of the simplest way to do it.

/  Simple Program for HCF / 


#include < stdio .h >
main ( )

f
int n1 , n2 , i , hcf ;

p r i n t f ( " Enter two integers : " );

s c a n f ( "%d %d " , &n1 , &n2 ) ;

for ( i =1; i < = n1 && i < = n2 ; ++i )

/  note that the condition in the for loop is that  /

/  the variable i has to be less than both n1 and n2  /

f
if ( n1%i ==0 && n2%i ==0)

/  we need to check if i is a factor of both n1 and n2  /

hcf = i ;

/  since i is being incremented in the for loop ,  /

/  it will check the divisibility t i l l the smaller of n1 and n2  /

g
p r i n t f ( "HCF of %d and %d is %d " , n1 , n2 , hcf ) ;

Example 1.9
A very ecient algorithm to nd the HCF of two positive integers is the Euclid algorithm. The al-
gorithm is simple. Let m and n , m < n be the two integers. Then if n is exactly divisible by m,

Page 44 of 164;
Introduction COMPUTER PROGRAMMING-2017

the HCF is m. Else, if p is the remainder of the division of n by m, then repeat the same procedure
with the pair (p; m). Keep doing this till either the smaller number in the pairs divides the larger num-
ber exactly, in which case the smaller number is the HCF or the remainder is 1 in which case the HCF is1.

The previous program was one way to determine the HCF of two numbers. We now will use Euclid's
algorithm in a program with a function.

/  Program to find HCF of two numbers using Euclid ' algorithm  /

#i n c l u d e < stdio .h >


int euclidhcf ( int x, int y)

f
if ( y == 0)

f
return x;

g
else if (x > = y && y > 0)

f
return euclidhcf (y , (x % y ) ) ;

g
g
main ( )

f
int euclidhcf ( int x, int y);

int num1 , num2 , hcf ;

printf (" n n Enter two numbers to find H.C. F . using Euclidean algorithm : " );

s c a n f ( "%d ,%d " , &num1 , &num2 ) ;

hcf = e u c l i d h c f ( num1 , num2 ) ;

if ( hcf !=0)

p r i n t f ( " The H . C . F . of %d and %d is %d n n" , num1 , num2 , hcf ) ;

else
printf (" n n Input Numbers not valid n n" ) ;

Example 1.10
Suppose one wants to nd the number of prime numbers upto a given number n. The following program
can be used.

Page 45 of 164;
Introduction COMPUTER PROGRAMMING-2017

/  Program to find the number of Prime Numbers upto a given number n  /

#include < stdio .h >


#include < math . h >
main ()

f
int n , m, i , j , k , f l a g , np ;

float x , xi ;

p r i n t f ( " input an integer greater than 3 " );

s c a n f ( "%d " ,& n ) ;

np = 0 ;

for ( i =3; i < =n ; i +=2)

f
x i= i ;

m=s q r t ( x i ) ;

j =3;

f l a g =0;

while < (j =m && flag ==0)

f
x=x i / ( ( float )( j ) ) ;

k= i / j ;

if ( x==k )

flag =1;

j +=2;

g
if ( flag ==0)

f p r i n t f ( "%d " , i );

np+=1;

g
g
printf (" n n The number of primes upto %d is %d " n , np ) ;

In the program above a few things are worth noting:

1. The use of integer division and oat division. In once case, since i; j; k are all integers, the division
of i and j will yield an integer. ON the other hand the division of oating point xi with the integer
j (which has been made oat), yields a oating point number. Of course, if j divides i exactly
without a remainder, then the two operations will yield the same result.
2. The use of logical equal to.

Page 46 of 164;
Introduction COMPUTER PROGRAMMING-2017

3. The use of a ag which can get incremented in case some condition is true and then checked for
its value.
p
4. Finally, the running of the checking for primes (that is exact divisibility) only till the xi. For
any number, it should be obvious that one only needs to check for divisibility till the square root
of that number.

R Some of the common errors that you should avoid.

1. Forgetting to include <math.h>.


2. Forgetting to add -lm while compiling a program with <math.h>.
3. Using a comma instead of a semi colon while writing a for loop
4. Putting a semi colon at the end of a for loop , do, while if statements
5. While dividing a oating point number by an integer, not changing the denomi-
nator to oat type
6. Using nested loops
7. Forgetting to put \ " when writing printf and scanf statements
8. Forgetting to use & while using scanf
9. Not stating the function prototype in the program
10. When using multiple if or for or do loops, making sure that the number of braces
fg match, that is the number of opening braces are the same as the closing braces.

1.8 Advanced Topic: Pointers


Pointers are an essential part of C programming language. They provide a very powerful and compact
way to doing programming. In fact, it is because of pointers that C programming language is used
extensively. C language uses pointers with arrays, structures and functions. Pointers are use in C to
access memory as well as to manipulate the address.

So what exactly is a pointer? A pointer is a variable whose value is the address of another
variable, i.e., direct address of the memory location. The other variable can be of any type.
Thus, we can see that pointers are appropriately named since they `point' to locations in memory. The
best way to think of this is to think of a row of lockers in a room. Now each locker has a number

Page 47 of 164;
Introduction COMPUTER PROGRAMMING-2017

associated with it to identify it. These numbers are like the memory addresses of variables. However,
what is inside the locker might vary from locker to locker and this is what corresponds to the value of
the variable stored. This much is easy and obvious. But what about a pointer? A pointer in this locker
room example would be anything in which the number of another locker is stored. So for instance,
you could store the number of your locker in another locker. This other locker, which stores only the
number of the actual locker with the valuables in it, would be a pointer.

There is usually some confusion about terms- the term pointer can refer either to a memory address
or to the variable that stores the memory address.
So what exactly is a pointer? A pointer is a variable whose value is the address of another
variable, i.e., direct address of the memory location. The other variable can be of any type.
There are two types of operations with pointers:

The reference operator & gives the \address of a variable".

The dereference operator  gives the \contents of an object pointed to by a pointer".


To declare a pointer to a variable do we write

type *name

Thus we can have pointers like int *ip (pointer to an integer), int *fp (pointer to a oating point
variable) etc. Note that pointer variables always point to the same type of data. Thus we cannot
declare a variable to be oat and then have an integer pointer pointing to it.

oat x;
int* px;
px=&x;

is wrong because there is a type mismatch.

You are already familiar with the use of pointers. Suppose one wants to input the value of a oating
point variable x. Then we know, we need to write

scanf("%f",&x)

We have used the reference operator & to get the address in the memory. To see the use of this,
consider the following program
#include < >
stdio .h

Page 48 of 164;
Introduction COMPUTER PROGRAMMING-2017

int main ( )

f
int x; /  A normal integer  /

int  p; /  A pointer to an integer ("  p" is an integer , so p

must be a pointer to an integer )  /

p = &x ; /  Assign the address of x to p  /

x =107;

printf ( " value of x= %d n n" ,  p ); /  Note the use of the  to get the value  /

g
If one compiles and runs this program, it will give you an output

value of x = 107

Note that though we are asking the printf statement to print the value of p, it prints the value
stored in x. To understand this, let us go through the code. We start with a regular integer variable
x. We then de ned a pointer to an integer as p. The next line stores the memory location of x in
the pointer since we are using the referencing operator &. In the locker room example, this is like
our looking at the number of a locker rather then inside it. We then give a value of x as 107. This
is stored obviously in the memory location of x. The printf command asks the machine to print p.
Remember that the dereferencing operator  looks at the address stored in the pointer p and goes to
that address and fetches the value stored in that address which as we have said before was the address
of the variable x. This is like opening one locker (the pointer) nding the number of another locker in
it (the variable x) and going to that locker to see what is inside that locker and returning it to the screen.

To see how all of this works, consider the following simple code:

#include < stdio .h >


int main ( )

f
int  pi ;

int i ;

i =220;

p r i n t f ( " Address of i :%d n n " ,& i ) ;

p r i n t f ( " Value of i :%d n n" , i ) ;

p i=&i ;

p r i n t f ( " Address of pointer p i :%d n n" , p i ) ;

p r i n t f ( " Content of pointer p i :%d n n" ,  pi ) ;

i =1110;

p r i n t f ( " Address of pointer p i :%d n n" , p i ) ;

p r i n t f ( " Content of pointer p i :%d n n n n" ,  pi ) ;

 p i =5;

Page 49 of 164;
Introduction COMPUTER PROGRAMMING-2017

p r i n t f ( " Address of i :%dn n " ,& i ) ;

p r i n t f ( " Value of i :%d n n


n n" , i ) ;

g
The output that one gets from running this program is as follows:

Address of i: 2686784
Value of i: 220
Address of pointer pi: 2686784
Content of pointer pi: 220
Address of pointer pi: 2686784
Content of pointer pi: 1110
Address of i: 2686784
Value of i: 5

Let us try and understand how we get this output.:

1. Declaration of pointer and variable, int *pi creates a pointer pi and int i creates an integer variable
i. Note that till now we have not devlared the values of pi and i and therefore pointer pi points
to either no address or a random address and the variable i is assigned an address but contains a
random value.
2. i=220; assigns 220 to the variable i, i.e.,220 is stored in the memory location of variable i.
3. Now when we print &i, we get a value of the address of i and when we print just the variable i, we
get its value.
4. pi=&i; assigns the address of variable to i to the pointer pi.
5. Therefore, when we print the address of the pointer, pi we get the same address as i and when we
print the value of pi that is *pi, we get the same value as that of i, that is 220.
6. i=1110; assigns 1110 to variable i.
7. Now when we print the address and value of the pointer pi, we see that the address is the same as
that of i and the value is the new value of i that is 1110.
8. *pi=5; changes the contents of the memory location pointed by pointer pi to 5. Since the memory
location pointed to by the pointer pi is the same as that of i, when we print the value of i, we get
the new value that is 5.
Although in our course, we dont really need to use pointers explicitly, they are extremely useful
in advanced programming, especially when one is dealing with linked lists and large amounts of data.

Page 50 of 164;
Introduction COMPUTER PROGRAMMING-2017

They provide a neat and ecient way for allocation of memory in the machine and are used extensively.
We will encounter them again when we study matrices and their manipulation.

1.9 QUESTIONS
1. Can we run a program without having function main()?
2. What header le must be included (#include) if you use printf and scanf statements in your
program? What is # in the #include statement?
3. Do we need to put a semicolon ; after #include statements?
4. What do you understand by typecasting? How will you convert an int variable into oat in an
arithmetic expression?
5. What are the di erent ways in which a function (other than main() ) can be written and called in
main() program?
6. Where do we use pointer in a simple code?
7. What will happen if a semicolon is put after the for statement? Will the program compile? If yes,
then what will be the di erence in the output?
8. What will happen if a semicolon is put after the do statement? Will the program compile? If yes,
what will be output?

1.10 PROBLEMS
1. Make a table of the trigonometric functions sin x; cos x, and tan x for 0  x   .
4

2. The function f (x; y) of two variables x; y is de ned by

Page 51 of 164;
Introduction COMPUTER PROGRAMMING-2017

f (x; y) = x + y for jxj > jyj


2 4

= x (x + 1) for jxj = jyj


2 2

= y +x for jxj < jyj


2 4

Make a table of the function f (x; y) for 1:0  x; y  1:0 at intervals of 0:25 for both x and y.

3. Pythagorean number are those integers which satisfy the relation

a +b =c
2 2 2

Write a program to nd all the distinct sets of Pythagorean numbers less than 100.

/  Pythogoras triplets  /

#include < stdio .h >


#include < math . h >

main ( )

f
int a ,b,c ,d, n;

p r i n t f ( " Enter the number upto which you want the Pythagoras triplets n n" ) ;

s c a n f ( "%d " , &n ) ;

for ( a =1; a <=n ; a++)

f for ( b=a + 1 ; b < =n ; b++)

f d=a  a+b  b;

c=s q r t ( ( float )(d ) ) ;

if  (c c==d & c < =n )

printf (" n n %d ,%d ,%d " , a , b , c ) ;

g
g
g

4. Some integers have a property that they are divisible by the sum of their digits. Thus, 84 is one
such number since it is divisible by 8 + 4 = 12. Let us call them Harshad numbers. Write a
program to nd all the Harshad numbers between 50 and 70 both inclusive.

Page 52 of 164;
Introduction COMPUTER PROGRAMMING-2017

/  Harshad Numbers  /

#include < stdio .h >


#include < math . h >

main ( )

f
int n , m, i , j , r , d ;

p r i n t f ( " Enter the n u m b e r s m and n n n" ) ;

s c a n f ( "%d ,%d " , &m,& n ) ;

for ( i =m; i < =n;++ i )

f j=i ;

d =0;

while > (j 9)

f r= j % 1 0 ;

j /=10;

d+=r ;

g
d+=j ;

if ( i%d==0)

p r i n t f ( "%d , %d , Harshad Number n n" , i , d ) ;

else
p r i n t f ( "%d , %d , Not a Harshad Number n n" , i , d ) ;

g
g

5. Fibonacci numbers are those which have the property that each member (apart from the rst two)
is the sum of the previous two numbers. Thus the Fibonacci numbers are 1; 2; 3; 5; 8;    . Write a
program to generate Fibonacci numbers till 200. Now modify the program to use a function which
can be called to generate the Fibonacci numbers till any integer entered by the user.

#include < stdio .h >


int int
fibo ( n)

f int next , f i , t 1 =0 , t 2 = 1 ;

next = t1 + t2 ;

while ( next < = n)

Page 53 of 164;
Introduction COMPUTER PROGRAMMING-2017

f
p r i n t f ( "%d , " , next ) ;

t1 = t2 ;

t2 = next ;

next = t1 + t2 ;

g
g

main ( )

f
int fibo ( int n);

int n;

p r i n t f ( " Enter a positive number : " );

s c a n f ( "%d " , &n ) ;

while ( f i b o ( n) < =n )

f p r i n t f ( "%f n n" , f i b o ) ; g

6. Write a program to calculate the factorial of a given integer. Your program should use a function
or subroutine which calculates the factorial.

#include < stdio .h >


int int
fact ( n)

f int i , f a c t o =1;

for <
( i =1; i =n ; ++i )

f
facto  = i ;

g
printf (" Factorial of %d = %d " , n, facto );

g
main ( )

f int fact ( int n);

int n, i ;

Page 54 of 164;
Introduction COMPUTER PROGRAMMING-2017

p r i n t f ( " Enter an integer : " );

s c a n f ( "%d " ,& n ) ;

p r i n t f ( " n=%d n n" , n ) ;

// show error if the user enters a negative integer

if (n < 0)

p r i n t f ( " Error ! Factorial of a negative number doesn ' t exist . " );

else
f
fact (n ) ;

7. Use the factorial subroutine that you have written for the previous problem to write a program
which calculates n Cr and n Pr for given values of n and r. (n Cr = n nr r and n Pr = nn r ) (
!
)! ! (
!
)!

/  Permutation & Combination  /

#include < stdio .h >


int int
fact ( n)

f int i , f a c t o =1;

for <
( i =1; i =n ; ++i )

f
facto  = i ;

g
// p r i n t f (" F a c t o r i a l of %d = %d " , n, facto );

return ( facto );

g
main ( )

f int fact ( int n);

int n, r ,c ,p;

p r i n t f ( " Enter the value of n and r n n" ) ;

s c a n f ( "%d ,%d " ,&n ,& r ) ;

p r i n t f ( " n=%d , r=%d , n r=%d n n" , n , r , n r );

p= f a c t ( n ) / ( ( f a c t ( n r )));

c=p / ( ( f a c t ( r ) ) ) ;

printf (" P = %d , C = %d n n" , p , c ) ;

Page 55 of 164;
Introduction COMPUTER PROGRAMMING-2017

8. We know that a quadratic equation of the form ax + bx + c = 0; a 6= 0; a; b; c real can be solved 2

easily. We also know that the determinant D is given by

D=b 2
4ac

If D  0 then the roots are real. Write a program to determine the roots of a quadratic equation.
Your program should rst determine if D  0 and then give the roots. It should report an error if
D < 0.

/  Quadratic Equation  /

#include < stdio .h >


#include < math . h >
main ( )

f
float a , b , c , d , r1 , r 2 ;

p r i n t f ( " Enter coefficients a , b and c : " );

s c a n f ( "%f ,% f ,% f " ,& a ,& b ,& c ) ;

d = b  b 4  
a c ;

// condition for real and different roots

if (d > 0)

f
// sqrt () function returns square root

r1 = ( b+s q r t ( d ) ) / ( 2  a );

r2 = ( b sqrt (d))/(2  a );

p r i n t f ( " root1 = %f and root2 = %f " , r 1 , r2 ) ;

g
// c o n d i t i o n for real and equal roots

else if ( d == 0)

f
r1 = r2 = b/(2  a );

p r i n t f ( " root1 = root2 = %f ; " , r1 ) ;

g
else
f printf (" The determinant is negative n n" ) ; g
g

Page 56 of 164;
Introduction COMPUTER PROGRAMMING-2017

Page 57 of 164;
Chapter 2

Graphics Using GNUPLOT


2.1 Introduction
GNUPLOT is a command-line program that can generate two- and three-dimensional plots of functions
and data. The program runs on all major computers and operating systems (Linux, UNIX, Windows,
Mac OSX...).

The software is copyrighted but freely distributed (i.e., you don't have to pay for it). It was originally
intended to function as a software for plotting mathematical functions and data but has outgrown its
credentials. It now supports many non-interactive uses, including web scripting and integration as a
plotting engine for third-party applications like Octave. Gnuplot has been supported and under devel-
opment since 1986.

Gnuplot supports many types of plots in either 2D and 3D. It can draw using lines, points, boxes, con-
tours, vector elds, surfaces, and various associated text. It also supports various specialized plot types.

Gnuplot supports many di erent types of output: interactive screen terminals (with mouse and
hotkey functionality), direct output to pen plotters or modern printers (including postscript and many
color devices), and output to many types of graphic le formats (eps, g, jpeg, LaTeX, metafont, pbm,
pdf, png, postscript, svg, ...). Gnuplot is easily con gurable to include new devices.

2.2 Plotting with inbuilt functions of GNUPLOT


We will rst demonstrate gnuplot using built-in functions.

58
Graphics Using GNUPLOT COMPUTER PROGRAMMING-2017

2.2.1 Interactive plotting


In the following example, we plot sin(x) between 2 < x < 2 with labels on x and y axis.

Open a terminal and type at the prompt

$gnuplot

You will see a screen like this

Figure 2.1: Screen Shot of opening GNUPLOT

On the gnuplot prompt type the following lines one by one (self explanatory)

gnuplot> set xlabel `x'


gnuplot> set ylabel `sin(x)'
gnuplot> set time
gnuplot> set grid
gnuplot> plot [-2*pi : 2*pi] sin(x) title \Sine Wave" with linespoints

You will get a plot like this

Page 59 of 164;
Graphics Using GNUPLOT COMPUTER PROGRAMMING-2017

Figure 2.2: Screen Shot of Sin(x)

To turn o the grid, you can \unset grid", to turn o the xlabel, you can type \set xlabel ' ' ". Type
set at the gnuplot prompt to see all of the options you can turn on and o . To turn on auto-scaling
(without any `x' or `y' labels: default), type \set auto" at gnuplot> prompt.

Note that many of the gnuplot keywords including: using, title, and with can be abbreviated with a
single alphabet as: u, t and w but should be avoided by beginners. Also, each line and point style has
an associated number.

In order to draw two plots on top of each other, you can replace the last line by

gnuplot>plot [-2*pi : 2*pi] sin(x) t \Sine Wave" with linespoints, cos(x) t \Cosine
Wave" with linespoints

Figure 2.3: Screen Shot of Sin(x) & Cosine(x)

You can exit from gnuplot by typing \exit" (or \quit") on the gnuplot prompt.

Page 60 of 164;
Graphics Using GNUPLOT COMPUTER PROGRAMMING-2017

gnuplot>exit

2.3 Saving Plots


To save the above image as an enhanced postscript le with \.eps" extension, instead of displaying it
to the screen, enter the following commands:

gnuplot> set terminal postscript enhanced color solid 22


gnuplot>set output `plot.eps'
gnuplot>set xlabel `x'
gnuplot>set ylabel `y'
gnuplot> plot [-2*pi : 2*pi] sin(x) title \Sine Wave" with linespoints
gnuplot>set term x11

This will create a postscript image le called \plot.eps" of the previous plot. It will be placed in the
same folder in which you are working. You can then use any postscript viewer program like \gv" (or
\evince") to open your saved graphics le. Remember, the plot will not appear on the screen when you
redirect the terminal type to postscript ( rst line of the example above), so it may appear as if nothing
has happened. Exit from gnuplot prompt, and then type on the terminal
$gv plot.eps &

Note: once you have nished plotting to a le, you need to set the terminal type back to
x11 (last line of the previous example) so as to view subsequent plots on the screen.

2.4 Plotting using script


You can also plot and save above-mentioned example by writing all the commands in a script. When
this script is executed in gnuplot, each line is executed in sequence beginning from the top. To do that,
open your favourite text editor (gedit, emacs, vi, nedit etc) and then type following lines (exactly the
same which you typed interactively at the gnuplot> prompt):

set terminal postscript enhanced color solid 22


set output `plot1.eps'
set xlabel `x'
set ylabel `y'
plot [-2*pi : 2*pi] sin(x) title \SineWave" with linespoints

Page 61 of 164;
Graphics Using GNUPLOT COMPUTER PROGRAMMING-2017

set term x11

and save it to the gnuplot script le plotscript.p Finally, to execute this script using gnuplot, on
the terminal prompt, type

$gnuplot ./plotscript.p

This will create .eps le plot1.eps. You can directly view this le using gv as in the above example.

2.4.1 Customization
Customization of the axis ranges, axis labels, and plot title, as well as many other features, are speci ed
using the set command. Speci c examples of the set command follow. (The numerical values used in
these examples are arbitrary.) To view your changes type: replot at the gnuplot> prompt at any time.

Action Command
Create a title: > set title "Force-De ection Data"
Put a label on the x-axis: > set xlabel "De ection (meters)"

Put a label on the y-axis: > set ylabel "Force (kN)"

Change the x-axis range: >set xrange [0.001:0.005]

Change the y-axis range: > set yrange [20:500]

Have Gnuplot determine ranges: > set autoscale

Put a label on the plot: > set label "yield point" at 0.003, 260

Remove all labels: > unset label

Plot using log-axes: > set logscale

Plot using log-axes on y-axis: > unset logscale; set logscale y

Change the tic-marks: > set xtics (0.002,0.004,0.006,0.008)

Return to the default tics: >unset xtics; set xtics auto

Other features which may be customized using the set command are: arrow, border, clip, contour,
grid, mapping, polar, surface, time, view, and many more. The best way to learn is by reading the
on-line help information, trying the command, and reading the Gnuplot manual.

Page 62 of 164;
Graphics Using GNUPLOT COMPUTER PROGRAMMING-2017

FUNCTION RETURNS
abs(x) absolute value of x, jxj
acos(x) arc-cosine of x
asin(x) arc-sine of x
atan(x) arc-tangent of x
cos(x) cosine of x, x is in radians.
cosh(x) hyperbolic cosine of x, x is in radians
erf(x) error function of x
exp(x) exponential function of x, base e
inverf(x) inverse error function of x
invnorm(x) inverse normal distribution of x
log(x) log of x, base e
log10(x) log of x, base 10
norm(x) normal Gaussian distribution function
rand(x) pseudo-random number generator
sgn(x) 1 if x > 0; 1 if x < 0; 0 if x = 0
sin(x) sine of x, x is in radians
sinh(x) hyperbolic sine of x, x is in radians
sqrt(x) the square root of x
tan(x) tangent of x, x is in radians
tanh(x) hyperbolic tangent of x, x is in radians

Table 2.1: Some Inbuilt Functions in Gnuplot

Bessel, gamma, beta, gamma, and gamma functions are also supported. Many functions can take
complex arguments. Binary and unary operators are also supported. The supported operators in Gnu-
plot are the same as the corresponding operators in the C programming language, except that most
operators accept integer, real, and complex arguments. The ** operator (exponentiation) is supported
as in FORTRAN. Parentheses may be used to change the order of evaluation. The variable names x, y,
and z are used as the default independent variables.

2.5 Plotting using data from a le


Create a data le, data1.txt, using your favourite text editor (say, gedit or emacs) and enter the follow-
ing data (there are three columns)

Page 63 of 164;
Graphics Using GNUPLOT COMPUTER PROGRAMMING-2017

#n n
2 n
3

1 1 1
2 4 8
3 9 27
4 16 64
5 25 125
6 36 216
7 49 343
8 64 512
9 81 729
10 100 1000

Again start gnuplot in a terminal by writing \gnuplot" on the terminal prompt and type the follow-
ing line

gnuplot> plot \data1.txt" u 1:2 with linespoints,\data1.txt" using 1:3 with linespoints

gnuplot ignores lines starting with # (comment lines.) Also, you can combine any number of plots in
one gure. Thus, in this example, we have plotted n vs n and n vs n by the command u 1:2 and
2 3

then again u 1:3. It should be clear that the 1 refers to the rst column of the data le and the 2 and
3 refer to the second and third column. Similarly, one can plot data from di erent data les in this
manner. The above command will create a plot like that in Fig 2.4.

Figure 2.4: Screen Shot of Plot using data le

You can modify these plots again using the x and y-labeling.

As we discussed in the previous chapter, one can store the results of any program in a data le by

Page 64 of 164;
Graphics Using GNUPLOT COMPUTER PROGRAMMING-2017

opening a le and writing to it using the command fprintf. Once we have the data le, then one can
use it as above to plot the results in gnuplot.
You can also save the above plot in a .eps le using the following commands:

gnuplot>set terminal postscript enhanced color solid 22


gnuplot>set output `plots2.eps'
gnuplot>plot \data1.txt" using 1:2 with linespoints, \data1.txt" using 1:3 with lines-
points
gnuplot> set terminal x11

Exit the gnuplot and then type gv plots2.eps on the terminal command prompt to see the output.

2.6 Periodic Function


Very often we need to plot a function which is periodic: y = f (x) = f (x + T ), where T is the period of
the function, over a range which covers many periods. The function may be given in an analytic form
over one period, say, from x = 0 to x = T . For example the periodic function

f (x) = 1 for 0  x  
f (x) = 1 for   x  2
f (x + 2) = f (x)

when plotted in the interval ( 6; 6) will generate a plot like the one shown in Fig 2.5.

Page 65 of 164;
Graphics Using GNUPLOT COMPUTER PROGRAMMING-2017

2
Periodic Function

1.5

0.5

y
-0.5

-1

-1.5

-2
-20 -15 -10 -5 0 5 10 15 20
x

Figure 2.5: Screen Shot of Plot of periodic function

How does one plot such a function? We only know the values in the interval 2  x  2 as given
above. Suppose we wish to nd the value at x = 4:7. We know from the de nition of the function that
it is periodic with a period 2. This means it repeats itself exactly after that interval. So we need to
nd the number of complete intervals of length 2 in this. This is easy to do. Recall from the function
int which when operating

on a oating point number returns the integer value of the number. So if we
use n = int :  we will get n = int (2.35) = 2. This means that there are 2 complete periods from
4 7
2

0 to 4:7. Now if we take the quantity x1 = 4:7 2n, its value will be x1 = 0:7 which is within the
range where the function is de ned. In this case, since x1 < , we have the value f (x) = 1. This way
we can nd the value at any arbitrary point. The program to implement this algorithm can be as follows:

#include< stdio .h >


#include< math . h >
#define pi 3.14159

main ( )

f
float x , y , z , x1 ; int n;

FILE  f p=NULL ;

f p=f o p e n ( " r e s 1 . t x t " , "w" ) ;

for ( x= (6  pi ) ; x < =(6.0  p i ) ; x=x + 0 . 0 0 1  pi )

f n = ( int )( x/(2.0  pi ) ) ;

x1 = x 2.0   pi n;

z=f a b s ( x 1 ) ;

if > (z =0 && z < pi )

f y =1; g
if > (z = pi && z <  2 pi )

f y= 1; g

Page 66 of 164;
Graphics Using GNUPLOT COMPUTER PROGRAMMING-2017

f p r i n t f ( f p , "%f n t %f n n" , x , y ) ;

g
g

Note the use of fabs in the above program since the range of x is from 6 to 6. Also note the
use of the operation (int) which just takes the integer part of the argument, which in this case is x . 2

After this program is run, you will have a le called "res1.txt" in your directory. Now if you can
plot the data in the le using gnuplot.

gnuplot >set terminal postscript


gnuplot >set output `periodic1.eps'
gnuplot >set xlabel `x'
gnuplot >set ylabel `y'
gnuplot >set yrange [-2:2]
gnuplot >plot \res1.txt" u 1:2 title \Periodic Function"
gnuplot >set term x11

This set of commands in gnuplot will generate a le periodic1.eps with the title Periodic Func-
tion in your directory. If you now open the le, you will see a plot like that in Figure 2.5.

R Some of the common errors & good practices while using gnuplot

1. In the plot statement, the name of the data le to be plotted should always be in
\ ".
2. Before you plot any data from a le, make sure you check the le and con rm
that it has the data that you expect. Thus, for instance, in case there is some
error in your program, it might give very large or very small numbers or even
NAN (Not A Number) which is typically the output when there is a division by
zero.

Page 67 of 164;
Graphics Using GNUPLOT COMPUTER PROGRAMMING-2017

3.Sometimes, because of an incorrect use of a loop structure, either your program


goes into an in nite loop, or more frequently will generate a huge data le. Please
remember that a typical page of text (which is what a data le is) has a size of 1
kilobyte. Thus, if your data le is of size much larger than a few kilobytes, there
is something wrong. In that case, please check and correct your program.
4. Always rst see the plot without any extra labels, titles etc. on your screen. If
it is of the form that you expect, then only go and add all the extra things like
labels, titles, legends etc and save as .eps le.
5. Do not use very long and complicated names for your data les or the graphic
les (.eps) since then there is a chance you will make a mistake when trying
to enter the names. Short, descriptive names are best. Thus, for example, if
you are plotting the graph for Problem No. 3 in the graphics chapter, then the
program name can be graphprob3.c, the eps le can be graphprob3.eps and the
data le can be a standard data.dat. Remember, that just as there is no need to
store and save the output or executable (.out) les for each program, similarly
there is no need to store the data les with di erent names. One can always
generate them when needed.

2.7 PROBLEMS
1. To learn more about how to use gnuplot and some of the concepts from the previous chapter, try
to make the following gures in gnuplot. You will have to write the programs to generate and save
the data les for these gures and then plot those data les in gnuplot.

(a) A right angled triangle with vertices at (0; 0); (4; 0) and (4; 3).
(b) A circle of radius 3 centered at (5; 5).
(c) A box with vertices at (1; 1); (5; 1); (5; 5) and (1; 5).

Page 68 of 164;
Graphics Using GNUPLOT COMPUTER PROGRAMMING-2017

/  Right Angled Triangle  /

#include< stdio .h >


#include< math . h >
main ( )

f
float x , y , r , t , x0 , y 0 ;

FILE  f p=NULL ;

f p=f o p e n ( " r e s 1 . t x t " , "w" ) ;

for ( x =0; x < =4;x +=.01)

f y =0;

fprintf ( fp , "%f n t %f n n" , x , y ) ; g


for ( y =0; y < =3;y +=.01)

f x =4;

fprintf ( fp , "%f n t %f n n" , x , y ) ; g


for ( x =4; x > =0;x =.01)

f y =0.75  x;

fprintf ( fp , "%f n t %f n n" , x , y ) ; g


g

/   Circle /

#include< stdio .h >


#include< math . h >
#define pi 3.14159

main ( )

f
float x , y , r , t , x0 , y 0 ;

FILE  f p=NULL ;

f p=f o p e n ( " r e s 1 . t x t " , "w" ) ;

printf ( " Supply the values of the center coordinates and radius n n" ) ;

scanf ( "%f ,% f ,% f " ,& x0 ,& y0 ,& r ) ;

p r i n t f ( "%f ,% f ,% f n n " , x0 , y0 , r ) ;

for ( t =0; t < 


=2 pi ; t+=p i / 1 0 0 . 0 )

f y = y 0+r  sin ( t ) ;

x = x 0+r  cos ( t ) ;

fprintf ( fp , "%f n t %f n n" , x , y ) ;

g
g

Page 69 of 164;
Graphics Using GNUPLOT COMPUTER PROGRAMMING-2017

8
"res1.txt" u 1:2

5
y

2
2 3 4 5 6 7 8
x"

Figure 2.6: Problem 1

/   Box /

#include< stdio .h >


#include< math . h >
#define pi 3.14159

main ( )

f
float x , y , r , t , x0 , y 0 ;

FILE  f p=NULL ;

f p=f o p e n ( " r e s 1 . t x t " , "w" ) ;

for ( x =1; x < =5;x +=.01)

f y =1;

fprintf ( fp , "%f n t %f n n" , x , y ) ; g


for ( y =1; y < =5;y +=.01)

f x =5;

fprintf ( fp , "%f n t %f n n" , x , y ) ; g


for ( x =5; x > =1;x =.01)

f y =5;

fprintf ( fp , "%f n t %f n n" , x , y ) ; g


for ( y =5; y > =1;y =.01)

f x =1;

Page 70 of 164;
Graphics Using GNUPLOT COMPUTER PROGRAMMING-2017

fprintf ( fp , "%f n t %f n n" , x , y ) ; g


g

2. You are familiar with Lissajous gures. These are plots that one obtains when one superimposes
two perpendicular harmonic motions of di erent phases and amplitudes. Thus, for instance,

x = sin ; y = A sin(n +  )
for  in the range 0    4 and the following set of parameters

(a)  =  ; A = 1 and n = 2; 2:5; 3 (n = 1 gives an ellipse. Check.)


4

(b)  =  , n = 2 and A = 0:5; 1; 2


4

(c) n = 2; A = 1 and  =  ;  ; . 4 2

#include< stdio .h >


#include< math . h >
#define pi 3.14159

main ( )

f float x , y1 , y2 , a , n , d ;

FILE  f p=NULL ;

f p=f o p e n ( " r e s . t x t " , "w" ) ;

p r i n t f ( "GIVEN VALUES OF A , N AND DELTA" ) ;

s c a n f ( "%f %f %f " ,& a ,& n ,& d ) ;

for ( x =0; x <  =4 p i ; x+=p i / 1 0 0 . 0 )

f y1 = sin (x ); y 2=a  sin (n  x+d ) ;

f p r i n t f ( f p , "%f ,% f n n " , y1 , y 2 ) ;

g
g

Page 71 of 164;
Graphics Using GNUPLOT COMPUTER PROGRAMMING-2017

Lissajous Figures with A=1,n=2,delta=pi/4


1

0.8

0.6

0.4

0.2

-0.2

-0.4

-0.6

-0.8

-1
-1 -0.5 0 0.5 1

Figure 2.7: Problem 2

3. The periodic function y(x) with period 2 is de ned as:

y = x 0x<
= 2  x   x < 2

Plot this function from x = 6 to x = 6 .

#include< stdio .h >


#include< math . h >
#define pi 3.14159

main ( )

f
float x , y , z , x1 ; int n;

FILE  f p=NULL ;

f p=f o p e n ( " r e s . t x t " , "w" ) ;

for ( x= (6  pi ) ; x < =(6.0  p i ) ; x=x + 0 . 0 0 1  pi )

Page 72 of 164;
Graphics Using GNUPLOT COMPUTER PROGRAMMING-2017

f n = ( int )( x/(2.0  pi ) ) ;

x1 = x 2.0   pi n;

z=f a b s ( x 1 ) ;

if > (z =0 && z < pi )

f y=z ; g
if > (z = pi && z <  2 pi )

f y=2  pi z; g
f p r i n t f ( f p , "%f ,% f n n" , x , y ) ;

g
g

3.5

2.5

1.5

0.5

0
-20 -15 -10 -5 0 5 10 15 20

Figure 2.8: Problem 3

4. Plot jlm ()j , the square modulus of the orbital wave function for l = 3; m = 0; 1; 2; 3. The
2

values of jlm ()j are given by

Page 73 of 164;
Graphics Using GNUPLOT COMPUTER PROGRAMMING-2017

p  
3 14 5
 ; () = cos  cos 
2
3 0
4 3
p
42 
 ; () = sin  5 cos  1
2

p8
3 1

105
 ; () = sin  cos 
2 2

p4
3 2

70
 ; () = sin 
3
3 3
8
This is a polar plot (r = jlm ()j ; ). You should plot x against y for 0 <  < 2 where
2

x = jlm ()j cos 


2

y = jlm ()j sin 


2

/  wave function 
/

#include < stdio .h >


#include < math . h >
#define pi 3.14159

main ( )

f
float x , x1 , y 1 ; int n;

float f ( float x, int n);

FILE  f p=NULL ;

f p=f o p e n ( " r e s . t x t " , "w" ) ;

p r i n t f ( " Give value of m" ) ;

s c a n f ( "%d " ,& n ) ;

for ( x =0.0001; x < 


(2 pi ) ; x +=0.005  pi )

f
x 1= f ( x , n )  f (x , n)  cos (x ) ;

y 1= f ( x , n )  f (x , n)  sin (x );

f p r i n t f ( f p , "%f ,% f n n " , x1 , y 1 ) ;

g
g
float f ( float a , int m)

f
float v1 , v2 , v 3 ;

if (m==0)

f v1 = ( 3 . 0  sqrt (14.0))/4.0;

Page 74 of 164;
Graphics Using GNUPLOT COMPUTER PROGRAMMING-2017

v2 = ( 5 . 0 / 3 . 0 )  pow ( c o s ( a ) , 3 ) cos ( a ) ;

v 3=v 1  v2 ;

return ( v3 ) ; g
if (m==1 jj m== 1)

f v 1 =( s q r t ( 4 8 . 0 ) / 8 )  sin (a );

v2 =5. 0  cos ( a )  cos ( a) 1;

v 3=v 1  v2 ;

return ( v3 ) ; g
if (m==2 jj m== 2)

f v 1 =( s q r t ( 1 0 5 . 0 ) / 4 ) ;

v 2=s i n ( a )  sin (a)  cos ( a ) ;

v 3=v 1  v2 ;

return ( v3 ) ; g
if (m==3 jj m== 3)

f v 1 =( s q r t ( 7 0 . 0 ) / 8 ) ;

v 2=s i n ( a )  sin (a)  sin (a );

v 3=v 1  v2 ;

return ( v3 ) ; g
g

Angular Wavefunctions
0.8
m=0

0.6

0.4

0.2

-0.2

-0.4

-0.6

-0.8
-4 -3 -2 -1 0 1 2 3 4

Figure 2.9: Problem 4

5. Spherical Bessel functions jn (z )

Page 75 of 164;
Graphics Using GNUPLOT COMPUTER PROGRAMMING-2017

where

sin(z )
j (z ) =
z 0

sin(z ) cos(z )
j (z ) =
z z 1
2

and the rest can be obtained by the recurrence relation

jn (z )
jn (z ) + jn (z ) = (2n + 1)
1 +1
z
.
Using this recurrence relation, plot on the same graph, the spherical Bessel functions in the range
0  z  5 at intervals of 0:01 for n = 0; 1; 2; 3; 4; 5.

#include< stdio .h >


#include< math . h >
main ( )

f float x , Q0 , Q1 , Q2 ;

int n;

FILE  f p=NULL ;

f p=f o p e n ( " r e s . t x t " , "w" ) ;

for ( x =0.50;x < = 7 . 0 ; x +=.01)

f
Q0=s i n ( x ) / x ;

Q1=s i n ( x ) / ( x  x) cos ( x )/ x ;

f p r i n t f ( f p , "%f n t %f n t " , x , Q0 ) ;

f p r i n t f ( f p , "%f n t %f n t " , x , Q1 ) ;

for ( n =1;n < =5;n++)

f
Q2 = ( 2 . 0  n+1.0)  Q1/ x Q0 ;

f p r i n t f ( f p , "%f n t %f n n " , x , Q2 ) ;

Q0=Q1 ; Q1=Q2 ;

g
g
g

Page 76 of 164;
Graphics Using GNUPLOT COMPUTER PROGRAMMING-2017

Bessel functions
1
n=0
n=1
n=2
0.8 n=3
n=4
n=5

0.6

0.4

0.2

-0.2

-0.4
0 1 2 3 4 5 6 7

Figure 2.10: Problem 5

Page 77 of 164;
Chapter 3

Finite & In nite Series


3.1 Introduction
A commonly encountered problem in Physics is the numerical evaluation of mathematical functions like
the exponential, circular, hyperbolic or hypergeometric function for given values of their arguments and
up to some speci ed accuracy. Most of these functions can be represented by in nite series, in nite
products or continued fractions. Some examples of series representation of a function are given below:

x x 2 3

ex = 1 + x + + + ::: (3.1)
2! 3! 
k
1
 x n X x2
Jn (x) = (3.2)
4

2 k=0
k!(n + k)!
1
X xj
log(1 + x) = ( 1)j 1
(3.3)
j =1
j

We describe below some numerical methods for evaluating both nite and in nite series. [Though
representation of a function in terms of continued fractions and in nite products is also quite useful,
we shall not discuss these here.]

3.2 Finite Series


Before looking at the evaluation of in nite series, let us see how to evaluate nite series since the case
of in nite series will be an extension as we shall see. We take the example of the following series with
a total of (n + 1) terms:
x x xn
+ +  +
2 3

Sn (x) = 1 + x + (3.4)
2! 3! n!

78
Finite & In nite Series COMPUTER PROGRAMMING-2017

Here each term is of the form xi ; with i = 0; 1; 2;    ; n. As long as n is a small number, there is no
i
!

problem and we can actually evaluate each term and then sum them up. However, if we wish to nd
the sum of this series for large n, say n = 20, there is a serious problem - the computer cannot handle
\large" numbers and 20! is a \very large" number ( 2:4  10 ). So clearly we need to nd another18

way to summing of series with very large or very small terms.

We overcome this problem by not evaluating individual terms of the series. Instead we nd the ratio
of two consecutive terms, ti and ti . Suppose this ratio is R. Then ti = Rti . Since R is usually a
1 1

small number, it is possible to nd all the terms, given the rst term t , by assigning to i the values 0

1; 2; 3    . By adding these terms we get the required sum.

In the speci c example of the series Eq.(3.4) above, we can easily see that
xi
ti =
i!
xi 1

ti =
1
(i 1)!
Therefore
ti x
R= =
ti 1 i
Thus, starting with t = 1, we get
0

i = 1 t = Rt = x 1 0

x x 2

i = 2 t = Rt = x =
2
2 2 1

xx x x 2 3 3

i = 3 t = Rt = = =
3
3 2 32 6
2

and so on. We then de ne a quantity called the jth partial sum Sj as


j
X
Sj = ti
i=0
Note an interesting property of this quantity. Any partial sum is by de nition the sum of the previous
partial sum and the term itself. Thus
!
X
5
X
4

S =
5 ti = ti + t = S + t 5 4 5

i=0 i=0
This is a property we can use to sum the series iteratively. Thus, the algorithm for summing a nite
series to a given number of terms is simple.

Page 79 of 164;
Finite & In nite Series COMPUTER PROGRAMMING-2017

1. Find t or t , the rst term of the series.


0 1

2. Find R, the ratio of the i th


term.
3. Find S or S , the rst partial Sum.
0 1

4. From t or t and R, nd the next term.


0 1

5. Add the next term to the rst partial Sum to get the second partial Sum.
6. Repeat this process till we get the required partial Sum which is the Sum of the nite series.
The following program can carry out this process:

Program ser1
/  program for evaluating a finite series  /

#include < stdio .h >


#include < math . h >
main ( )

f float x, t , s ;

int n, i ;

p r i n t f ( " supply x and the number of terms n n n" ) ;

/  if n =20 , the last term is $x ^f20g /19! $  /

s c a n f ( "%f ,%d " ,& x ,& n ) ;

s =1.0; t =1.0; /  Initial values of sum s and the first term t  /

/  The following loop evaluates the terms and sums them  /

for ( i = 1; i < n; i ++) /  i starts at 1 , t 0 term is the initial value  /

f  t = x/ i ; s+ = t ; g  / x/ i is simply the ratio R  /

printf (" n n" ) ;

p r i n t f ( " x=%6.2 f , n=%d , sum= %12.5 e " , x , n , s ) ; g

In this program, the statement s+ = t generates the partial sums S (x); S (x);    while t = 2 3
x
i
generates the successive terms for i = 1; 2;    ; n.

R
Note that the order of the statements t = xi and s+ = t is important. What
happens if they are interchanged? Note also that the initialization s = 1:0 and t = 1:0
must be done outside the loop over i. What happens if these are done within the loop?

Of course, instead of taking the ratio of ti and ti , we could also take the ratio of ti 1 +1 and ti . In this
case,

Page 80 of 164;
Finite & In nite Series COMPUTER PROGRAMMING-2017

xi +1

ti =
+1
(i + 1)!
xi
ti =
i!
Thus,
ti x
R = t = +1
=
ti i+1
Note here that i will now start from 0 and the rst term is t = 1. These two methods are
0

equivalent provided we take care of the initializations of i and t.

In the above program the statement:

printf("nn");

shifts the cursor to a new line. This device is used to make the output more readable. If necessary
more than one such statements can be included. In the statement

printf("x=%6.2f,n=%d,sum= %12.5e",x,n,s);

the sum s is printed in e-format with a total eld of 12 characters with ve places after the decimal.
The following examples of numbers expressed in the e-format illustrate its use:

Number e-format
-.00234 -2.3400e-03
5643.1 5.64310e+03
1.5648 1.56480e+00
All these numbers have a total eld of 12 characters, including the signs before the number and after e.

Run the program given above for various values of n (for a xed x) and for various values of x (for a
xed n) and study the behaviour of Sn (x) as a function of x and n. Print your results in the form of a
table and also display them in the form of graphs Sn (x) vs. x for xed n, or Sn (x) vs. n for xedx.

You would have noticed by now that to obtain the results for a new set of input parameters (x and n
in this case), you have to run the program again. This is an unnecessary irritant and can be avoided by
introducing one more loop outside the loop over i. The outer loop can prompt you to feed new values
of n or x or both. Look at the following program:

Page 81 of 164;
Finite & In nite Series COMPUTER PROGRAMMING-2017

Program ser2
/  program for evaluating a finite series  /

#include < stdio .h >


#include < math . h >
main ( )

f float x, t , s ;

int n, i ;

printf (" n n supply x and the number of terms n n n" ) ;

s c a n f ( "%f ,%d " ,& x ,& n ) ;

do
f s = 0 . 0 ; t =1;

for ( i =2; i < =n ; i ++)

f s+=t ; 
t =x / ( i 1); g
printf (" nnx =%6.2 f n=%d sum= %12.5 e " , x , n , s ) ;

printf (" n n
n n" ) ;

printf (" enter x and n (n ve to break the loop ) n n" ) ;

s c a n f ( "%f ,%d " ,& x ,& n ) ;

g
while (n > 0); g

Notice that after this program has run for one set of values of x and n and printed the result, it
prompts you to input new values of x and n. It also tells you that by feeding zero or a negative value for
n you can break the loop and come out of it, since the loop will run only for positive values of n. This
is indicated by the while statement at the end of the do loop. Remember that in C or C++, a do
loop must end with a while condition. Also note that while the initialization s = 0:0; t = 1:0; is
outside the for loop, it is inside the do loop. WHY?

If you wish to plot Sn (x) against n (for a xed x) you can do so by modifying the above program. Store
variables of your program in a .txt le and then use gnuplot to plot that data. But now you will have
to change n regularly. A better way to plot would be to replace the do-while loop by a for loop in
which n changes by a xed step.

3.3 In nite Series


Whereas a nite series can always be summed in principle, the sum of an in nite series has a meaning
only if the series is convergent. So it must be ensured that the series under consideration is indeed
convergent before one embarks on its evaluation. For nite series, the number of terms to be summed

Page 82 of 164;
Finite & In nite Series COMPUTER PROGRAMMING-2017

is given in advance. This is the reason that we can use a for loop to evaluate the sum as you would
remember from Section 1.2.2.1. However, in the case of an in nite series, obviously an in nite number
of terms cannot be summed. So how do we sum an in nite series? The answer lies in the fact that if
the series is convergent, then by de nition it means that adding more and more terms to the partial
sum, changes the partial sums by smaller and smaller amounts. Thus, if we decide that we want the
sum of an in nite series to a given accuracy, then we can stop adding the sums. In e ect, what we
are doing is actually summing again a nite series though here we do not before hand how many terms
we need to some to achieve the desired accuracy.

To illustrate, consider the simple case of sin(x). We know that this function can be written as an
in nite series,
1
x x X xn
+ +    = ( 1)n
3 5 2 +1

sin(x) = x (3.5)
3! 5! n
(2n + 1)!
=0

Following the exact same method as above for a nite series, we can see that the kth term is
xk2 +1

tk = ( 1)k
(2k + 1)!
while the (k 1)th term is
xk
2 1

tk = ( 1)k 1
1
(2k 1)!
Thus the ratio
xtk 2

R= =
tk (2k + 1)(2k)
1

Clearly the rst term, t is x. What about s? The initial partial sum is obviously the initial term.
0

Thus the initial values are t = x = s; k = 1.

We can write a program to sum this series to any number of terms for a given value of x, say x =  . 4

We know that the result of sin(  ) = :7071. The program below will evaluate the series upto increasing
4

number of terms till 10. For each term, we will print the value of that term and the partial sum.

#include< stdio .h >


#include< math . h >
#define pi 3.14159

main ( )

Page 83 of 164;
Finite & In nite Series COMPUTER PROGRAMMING-2017

float x , t , sum , z , a c c = 0 . 0 0 0 0 1 ; int i ;

FILE  f p=NULL ;

f p=f o p e n ( " r e s . t x t " , "w" ) ;

x=p i / 4 . 0 ;

sum = x ; t = x ; i =1;

for ( i =1; i < =10; i ++)

f 
t = x  x /((2  i +1)   2 i );

sum+=t ;

f p r i n t f ( f p , "%d n t %f n t %f n t s i n ( x)=% f n n " , i , t , sum , s i n ( x ) ) ;

g
g

The results of this are in the Table 3.1.


n t n S n sin( 4 )
2 -0.080745 0.704652 sin(x)=0.707106
3 0.002490 0.707143 sin(x)=0.707106
4 -0.000037 0.707106 sin(x)=0.707106
5 0.000000 0.707106 sin(x)=0.707106
6 -0.000000 0.707106 sin(x)=0.707106
7 0.000000 0.707106 sin(x)=0.707106
8 -0.000000 0.707106 sin(x)=0.707106
9 0.000000 0.707106 sin(x)=0.707106
10 -0.000000 0.707106 sin(x)=0.707106

Table 3.1: Finite Series Sum for sin( 4 )

As you see, this being a very rapidly converging series, after the rst four terms, the partial sum
really does not change and so adding more and more terms will not help. So instead of adding up a
large number of terms, we can add a few terms and get the desired result. Of course, the successive
terms after the n = 5 are not really zero but very small numbers which are being evaluated to zero
because the variable de ned is a single precision oating point variable.

So the question is how does one know when to stop adding more and more terms? Or what is the
same thing, how do we check for the desired level of accuracy? Clearly, what we see from the example
above is that if the relative value of the term to be added to a partial sum is very small compared to
the partial sum itself, then it will not change the partial sum signi cantly. Thus the quantity that one
would want to evaluate and see if it is small enough is
tn
accuracy = j j
Sn 1

If this quantity is smaller than some pre-determined amount, then we can safely terminate the sum-

Page 84 of 164;
Finite & In nite Series COMPUTER PROGRAMMING-2017

mation.

One measure of accuracy can be in terms of the number of decimal places up to which the result
is required to be correct. A better method of de ning accuracy, and the one we normally use, is in
terms of the number of signi cant gures up to which the result is required to be accurate. (Why
is this method better?) In either case, the number of terms needed to obtain the desired accuracy is
determined during the process of evaluation itself and is not known in advance. We have already seen
in our discussion of Loops in C that if we don't know the number of iterations, we need to use a
do-while loop instead of a for loop.
The process of addition of terms continues as long as the magnitude of relative contribution of the
term to be added, i.e., |term/sum| remains larger than the desired accuracy. The strategy for nding
successive terms remains the same.

R Signi cant Figures: RULES


1. The leftmost NONZERO digit is ALWAYS the MOST signi cant digit.
2. When there is NO decimal point, the rightmost NONZERO digit is the least
signi cant digit.
3. In case of a decimal point, the rightmost digit is the least signi cant digit EVEN
IF IT IS A ZERO.
4. The number of digits between the most and least signi cant digits are the number
of signi cant digits.

Thus for instance, 22:00; 2234; 22340000; 2200: all have four signi cant digits. When one is
adding, subtracting, multiplying or dividing numbers, then the result should be quoted with
the least number of signi cant gures in any one of the quantities being used in the operation
of adding, multiplying etc. In your intermediate calculations, always keep ONE MORE
signi cant digit than is needed in the nal answer. Also when quoting an experimental result,
the number of signi cant gures should be one more than is suggested by the experimental precision.

Two things that need to be always avoided are


Writing more digits in an answer (intermediate or nal) than justi ed by the number
of digits in the data.
Rounding-o , say, to two digits in an intermediate answer, and then writing three
digits in the nal answer.

Page 85 of 164;
Finite & In nite Series COMPUTER PROGRAMMING-2017

While dropping o some gures from a number, the last digit that one keeps should be rounded
o for better accuracy. This is usually done by truncating the number as desired and then treating
the extra digits (which are to be dropped) as decimal fractions. Then, if the fraction is greater
than , increment the truncated least signi cant gure by one. If the fraction is smaller than ,
1
2
1
2

then do nothing. If the fraction is exactly , then increment the least signi cant digit only if it is odd.
1
2

Now we are ready to write the program to sum the in nite series for sin(x) in the range 0  x  2
upto a desired accuracy. The program can ask you what level of accuracy you would want. The program
will be like the one given below.

Program inf ser1


/  program for evaluating an infinite series for Sin ( x )  /

#i n c l u d e < stdio .h >


#include < math . h >
main ( )

f
int i ;

float t , s ,x, acc ;

float PI = 4 . 0  atan ( 1 . 0 ) ;

printf ( " Enter the value of the accuracy desired n n" ) ;

s c a n f ( "%f " ,& a c c ) ;

for ( x =0; x <  =2 PI ; x +=0.1)

f
i =1;

s=t=x ;

do
f

t = x  x /((2  i +1)  
2 i );

s+=t ;

i +=1;

g while ( fabs ( t/s ) > acc ) ;

p r i n t f ( " x=%f s i n ( x)=% f n n" , x , s ) ; g


g

This program will print a table of x and sin(x) as evaluated from the in nite series for sin(x). You
can of course print the results into a le and then plot it using gnuplot. The above program is the

Page 86 of 164;
Finite & In nite Series COMPUTER PROGRAMMING-2017

prototype of all such programs to evaluate convergent in nite series.

One can of course repeat the whole exercise with the ratio of tkt+1
k
. Then the initialisation of k will
be from 0 as should be obvious. Also the ratio R will be di erent. One can easily check that the ratio
is then
tk x 2

R= +1
=
tk (2k + 3)(2k + 2)
Of course results we will get from using either of these methods will be same.

R Some of the common errors & good practices

1. Before attempting to write the program to evaluate the sum of an in nite se-
ries, always start with calculating the k th and the (k+1) th from which you can
determine the common ratio.
2. When you have the expressions for these terms, check by putting in the values
of k to see if they indeed give the series that you want to sum.
3. Make sure that the initialisation, that is the initial values of k; s; t are correct.
4. Make sure that the order of incrementing t and s is correct.
5. Some series might involve a factorial function which needs to be evaluated in
the program. For this purpose, you can use the facotrial function that you have
written in the problems of Chapter 1.

3.4 Questions
1. Why do we evaluate ratio of consecutive terms, and not individual terms while evaluating sum of
a series?
2. What is the necessary condition to sum up an in nite series?
3. What are the possible ways of de ning accuracy while summing up an in nite series? Which one
is better and why?

Page 87 of 164;
Finite & In nite Series COMPUTER PROGRAMMING-2017

4. Which loop do you generally use for summing up a nite series? What about in nite series?
5. Compare the behaviour of some simple functions at large x (like Prob.2 and Prob.3) and explain
the discrepancy.

3.5 Problems
1. Write a program to evaluate the sum up to 20 terms of the series
1 1 1
+ + +  1+
x x x 2 3 4

for a given x(0  x  2), and compare your result with the analytic sum of the series.

#include< stdio .h >


#include< math . h >
#include< stdlib .h >
main ( )

f float x, t , s , f ; int n;

for (x =1.1;x < =5.0; x +=0.25)

f
t =1.0/( x  x); s=t ; n =1;

do
f  t =1/ x ;

s+=t ;

n+=1;

g
while < (n =18);

s=1+s ;

f =(x  x x +1)/( x  (x 1));

/  the above f is the analytical result

for the INFINITE series  /

p r i n t f ( "No . of Terms=%d x=%f sum=%f a n a l y t i c=%f n n " , n +1 , x , s , f ) ;

g
g

2. Evaluate cos(x) using the series

Page 88 of 164;
Finite & In nite Series COMPUTER PROGRAMMING-2017

x x

2 4

+ cos(x) = 1
2! 4!
accurate to four signi cant places. Plot cos(x) vs x in the range 0  x  .

/ cos ( x )  series /

/   /

#include< > stdio .h

#include< > math . h

#define pi 3.14159

main ( )

f
float x , t , sum , z , a c c = 0 . 0 0 0 0 1 ; int i ;

FILE  f p=NULL ;

f p=f o p e n ( " r e s . t x t " , "w" ) ;

for ( x =0; x < =(6  p i ) ; x=x + 0 . 0 2 )

f
sum = 1.0; t = 1 . 0 ; i =1;

do
f t = x  x/(2.0   i (2.0  i 1.0));

sum+=t ;

i ++;

g
while ( f a b s ( t /sum) > acc ) ;

f p r i n t f ( f p , "%f ,% f n n " , x , sum ) ;

g
f p r i n t f ( fp , " n n "EXACT RESULTS n n" ) ;

f o r (x =0.0;x < =(6  p i ) ; x=x + 0 . 0 2 )

f f p r i n t f ( f p , "%f ,% f n n" , x , c o s ( x ) ) ; g
g

The plot be like in Figure 3.1

Page 89 of 164;
Finite & In nite Series COMPUTER PROGRAMMING-2017

Cos(x) series
2
series
exact

1.5

0.5

-0.5

-1

-1.5
0 2 4 6 8 10 12 14 16 18 20

Figure 3.1: Cos(x) series sum & exact

3. Write a program to evaluate Jn (x) to an accuracy of four signi cant gures using the following
series expansion:
 
1 ( 2 k
 x n X 1)k x
Jn (x) =
4

2 k=0
k!(n + k)!
Plot Jn (x) against x for 0  x  10 and n = 0; 1; 2. Compare with the known behaviour of these
functions and explain the discrepancy at large x.

#include< stdio .h >


#include< math . h >
int fact ( int n)

f
int i , f a c =1;

if ( n==0) f a c =1;

else
f for ( i =1; i < =n ; i ++)

f fac 
=i ; gg
return ( fac );

Page 90 of 164;
Finite & In nite Series COMPUTER PROGRAMMING-2017

g
main ( )

f
float x , sum , t , a c c = 0 . 0 0 1 ; int k,n;

FILE  f p=NULL ;

f p=f o p e n ( " r e s . t x t " , "w" ) ;

for ( n =0;n < =2;n++)

f
for ( x =0; x < = 1 5 . 0 ; x=x + . 1 )

f k = 0 ; sum = 1 . 0 / f a c t ( n ) ; t=sum ;

do
f k++;


t = x  x/(4.0  
k ( n+k ) ) ;

sum+=t ;

g
while ( f a b s ( t /sum) > acc ) ;


sum =pow ( ( x / 2 ) , n ) ;

f p r i n t f ( f p , "%d n t %f n t %f n t %f n n " , n , f a c t ( n ) , x , sum ) ;

g
g
g

The plot be like in Figure 3.2

Page 91 of 164;
Finite & In nite Series COMPUTER PROGRAMMING-2017

Bessel functions series sum


1

0.8

0.6

0.4

0.2

-0.2

-0.4

-0.6
0 2 4 6 8 10 12 14 16

Figure 3.2: Bessel Functions series sum

4. . Evaluate F (z ) given by
  1
z 2 X ( 1)n  n z n
2 4 +1

F (z ) = cos
2 n=0
1:5:9:    :(4n + 1)
correct to four signi cant gures, for 0  z  1 , at intervals of 0:1.

/  chap 2 prob 4 /

#include< stdio .h >


#include< math . h >
#include< stdlib .h >
#define pi 3.14159

main ( )

f float z , t , s , acc =0.0001 , s1 ; int i ;

FILE  f p=NULL ;

f p=f o p e n ( " r e s . t x t " , "w" ) ;

for ( z =0.0; z < =1.0; z +=0.05)

Page 92 of 164;
Finite & In nite Series COMPUTER PROGRAMMING-2017

t=z ; s=t ; i =1;

do
f  t = pi  
pi pow ( z , 4 ) / ( 4  i +1);

s+=t ;

i +=1;

g
while ( f a b s ( t / ( s+a c c )) > acc ) ;

s 1=c o s ( p i  
z z /2)  s ;

f p r i n t f ( f p , "%f n t %f n n" , z , s 1 ) ;

g
g

The result is given in Table 3.2.


z F(z)
0.000000 0.000000
0.050000 0.049999
0.100000 0.099968
0.150000 0.149757
0.200000 0.198976
0.250000 0.246886
0.300000 0.292300
0.350000 0.333530
0.400000 0.368394
0.450000 0.394337
0.500000 0.408678
0.550000 0.409012
0.600000 0.393734
0.650000 0.362603
0.700000 0.317171
0.750000 0.260922
0.800000 0.198957
0.850000 0.137161
0.900000 0.081072
0.950000 0.034735

Table 3.2: F z( ) vs z

5. Write a program to plot the sum of the following series:


1
X zk
f (z; n) = 
k=0;2;4
2n k k ! 1
2
+n 2
k

for n = 2 and z in the range 0  z  5 . You would require the following relations:

Page 93 of 164;
Finite & In nite Series COMPUTER PROGRAMMING-2017

 
1 p
= 
2
(z + 1) = z (z )

#include< stdio .h >


#include< math . h >
#define pi 3.14159

main ( )

f float z , t , s , acc =0.0001; int n =2 , k ;

FILE  f p=NULL ;

f p=f o p e n ( " r e s . t x t " , "w" ) ;

for ( z =0; z < =5.0; z +=0.02)

f
t =1.0/(2.0  sqrt ( pi ) ) ; s=t ; k =2;

do
f  t =( z   
z 2 (n k +1.0))/( k  (k 1.0));

s+=t ;

k+=2;

g
while ( fabs ( t / s) > acc ) ;

f p r i n t f ( f p , "%f n t %f n n" , z , s ) ;

g
f c l o s e ( fp ) ;

The plot would look like Figure 3.3.

Page 94 of 164;
Finite & In nite Series COMPUTER PROGRAMMING-2017

3.5

2.5

1.5

0.5

0
0 0.5 1 1.5 2 2.5 3 3.5 4 4.5 5

Figure 3.3: Plot of f (z; n) vs z for n = 2

6. Write a program to plot the following function:


 
z 1:4z 1:4:7z
+ 
3 6 9

f (z ) = C 1 + + +
3! 6! 9!
where C = 0:35503, for z in the range 10  z  0, at intervals of 0:05.

#include< stdio .h >


#include< math . h >
#define pi 3.14159

main ( )

f float z , t , s , acc =0.01 , s1 ; int i ;

FILE  f p=NULL ;

f p=f o p e n ( " r e s . t x t " , "w" ) ;

for (z= 10.0; z < =2.0; z +=0.05)

f
t =1.0; s=t ; i =1;

do
f t =pow ( z , 3 ) / ( 3   
i (3 i 1));

Page 95 of 164;
Finite & In nite Series COMPUTER PROGRAMMING-2017

s+=t ;

i +=1;

g
while ( fabs ( t / s) > acc ) ;

s1 =0.35503  s ;

f p r i n t f ( f p , "%f n t %f n n" , z , s 1 ) ;

g
f c l o s e ( fp ) ;

The plot will look as in Figure 3.4

0.8

0.6

0.4

0.2

-0.2

-0.4
-10 -8 -6 -4 -2 0 2

Figure 3.4: Plot of f (z ) vs z

Page 96 of 164;
Chapter 4

Root Finding
4.1 Introduction
Assume that a function f (x) is continuous within the interval (x ; x ) on the real line. A point x
1 2 0

within this interval is said to be a root of the equation f (x) = 0, if f (x ) = 0 . In the Figure 4.1, we 0

see that the points x = a and x = b are the roots of the function f (x) = 6x + 45x 3. We shall 2

discuss methods of nding all the real roots of a given equation in a speci ed interval of the variable x.

100
f(x)=-6x2+45x-3

80

60

40
f(x)

20

0
a b

-20

-40

-60
-1 0 1 2 3 4 5 6 7 8
x

Figure 4.1: Root of a function

Given this de nition of the root of a function, it seems clear that the easiest way to nd the roots would
be to evaluate the function at various points and see where it is zero. However, in practice that is
not very convenient since one cannot decide beforehand how small an interval to evaluate the function.
However, we can still nd the rough location and the number of roots in a given interval. To do this,
we need to simply tabulate the function at suciently large number of points within the given interval.
Notice that if the function f (x) is zero, which it is by de nition at the location of the root, the value of

97
Root Finding COMPUTER PROGRAMMING-2017

the function will change sign at that point. That means that if the function f (x) is positive (negative)
at values of the argument x less than the root, it will be negative (positive) at values of x larger than the
root. This is clear from the Figure 4.1. So all one has to do is to nd two points, say x and x where the
1 2

function has di erent signs. Then we are assured that there exists atleast one root in the interval (x ; x ).
1 2

Once the rough location of a root has been found, our next task is to nd the root to a prescribed
accuracy by narrowing down the interval (x ; x ) within which it lies.
1 2

Most methods of root nding depend upon what is called the process of iterations. We shall describe
three such methods here. These methods are general and apply to any kind of function. There are
other methods that apply speci cally to polynomials and can nd even complex roots, but we shall not
discuss them here.

R In any program to nd the roots of a function, the rst step should ALWAYS be
tabulation of the function to determine the rough value of the roots. This tabulation
does not have to be very exact but should be coarse. The idea is to have some idea
of the rough location of the roots.

4.2 Bisection Method


Suppose the function f (x) varies as shown in the Figures(4.2 & 4.3) below. Let two points xL and xR
be on opposite sides of the root x . In the bisection method, one determines the sign of the function at
0

the mid-point, xM , of xL and xR :


(xL + xR )
xM =
2
If f (xM ) = 0, then xM is the required root. If f (xM ) is not zero and has the same sign as f (xL )
(Fig.(4.3) then the root must lie between xM and xR . In this case we replace xL by xM and repeat the
process of halving the interval and comparing the signs. In case f (xM ) has a sign opposite to
that of f (xL ) (Fig.(4.2)), then the root must lie between xL and xM . In this case we look for the root
between xL and xM by replacing xR by xM and repeating the entire process. Since the root is known
to lie between xL and xR and this interval (xR xL ) is halved in every successive approximation, the
root can be determined to any desired accuracy.

When do we stop this process? We can see that as we continue this process, the interval jxR xL j
becomes smaller and smaller. However, bear in mind that it is not the absolute value of this quantity
that is of relevance but the relative value. When this interval relative to the value of jxR + xL j becomes
smaller than a given accuracy, we can say that we have got the root to the desired accuracy. In other

Page 98 of 164;
Root Finding COMPUTER PROGRAMMING-2017

words, the process of bisecting the interval is repeated while jj xxRR xxLL jj remains greater than the desired
(

( +
)

accuracy. Since, by de nition, at a root the function must be zero, alternatively the condition for the
termination of the loop can depend on the value of the function itself, i.e., the loop is repeated while
jf (xM )j is greater than or equal to some very small number, say 10 . 6

Figure 4.2: Bisection Method

Figure 4.3: Bisection Method

The bisection method has the advantage that the procedure is guaranteed to converge. The disad-
vantage is that the method is slow. Another disadvantage is that roots lying close to each other may
be dicult to separate.

Now we can write down the algorithm for using the bisection method to determine the roots of a
given function.

1. Tabulate the function f (x) in the given interval in which the roots are to be found.
2. Determine the rough location of the root or roots. This means determining the two values xR and
xL of x between which f (x) changes sign.
3. Determine the midpoint xM of the interval xR xL .

Page 99 of 164;
Root Finding COMPUTER PROGRAMMING-2017

4. Check the sign of f (xM ). If it is the same as xR replace xR by xM or if it is the same as xL replace
xL by xM .
5. Repeat this process till the quantity jjxxRR +
xL j
xL j becomes smaller than the required accuracy.
6. Then xM is the root. As a check, evaluate f (xM ) and see that it is smaller than the required
accuracy.
As an example of the bisection method, suppose we wish to nd the roots of

f (x) = sin(x) x cos(x)


between 0 and 10. The program below will rst tabulate the function and then ask you to input
the range in which the root lies. This range is easy to see when one has tabulated the function since
the value of the function will change sign. It will also tell you the number of roots within the desired
interval that is 0 and 10 since the function will change sign at those values. However, this is just a
rough value of the root. The actual bisection routine then takes the inputs that you give from the table
(that is the number of roots, the range in which the roots lie) and gives the exact value of the roots to
the desired accuracy.

/  Bisection Method  /

#include < > stdio .h

#include < > math . h

float float f ( x)

f return  ( s i n ( x) x cos (x ) ) ;

g
main ( )

f float x , xm , x l , x r , a c c = 0 . 0 0 0 0 1 , x i n c = 0 . 5 , z , a , b , x1 , x 2 ;

int n, i ;

float f ( float x);

p r i n t f ( " Enter the minimum value of x n n" ) ;

s c a n f ( "%f " ,& a ) ;

p r i n t f ( " Enter the maximum value of x n n" ) ;

s c a n f ( "%f " ,& b ) ;

for ( x=a ; x < =b ; x=x + 0 . 1 )

f p r i n t f ( "%f n t %f n n" , x , f ( x ) ) ;

g
p r i n t f ( " input no of roots " );

s c a n f ( "%d " ,& n ) ;

for ( i =1; i < =n ; i +=1)

Page 100 of 164;


Root Finding COMPUTER PROGRAMMING-2017

f printf (" n ninput x1 , x 2 " ) ;

s c a n f ( "%f ,% f " ,& x1 ,& x 2 ) ;

for ( x=x 1 ; x < =x 2 ; x+=x i n c )

f
if ( f (x)  f ( x+x i n c ) < 0)

f x l=x ; x r=x+x i n c ;

do
f xm=( x l+x r ) / 2 . 0 ;

if ( f (xm)  f ( xl ) > 0)

f x l=xm ; g
if ( f (xm)  f ( xl ) < 0)

f x r=xm ; g
z=f a b s ( ( x l x r ) / ( x l+x r ) ) ;

p r i n t f ( "xm=%f f (xm)=% f z=%f a c c=%f n n " , xm , f (xm ) , z , a c c ) ;

g
while > (z acc ) ;

printf (" n n r o o t=%f f (xm)=% f z=%f a c c=%f n n n n " , xm , f (xm ) , z , a c c ) ;

g
g
g
g

4.3 Secant Method


The Secant method uses a secant line to approximate f (x) in the neighbourhood of a root. In this
method also we need two points to begin with. It di ers from the bisection method in that the two
points need not be on the opposite sides of the expected root as long as they are suciently close to
it. However it is always better to choose the points to lie on the opposite sides of the root. Let x 1

and x be the two points close to the root x . Consider the two points on the curve y = f (x) having
2 0

coordinates (x ; y ) and (x ; y ), where y = f (x ) and y = f (x ). The equation of the secant line


1 1 2 2 1 1 2 2

through these points is given by


y y
(x x ) y y = 2 1
(4.1)
x x 2
2 1
2

which intersects the x axis (that is at y = 0) at the point x where 3

xy xy
x = 1 2 2 1
3
y 2 y
1

Page 101 of 164;


Root Finding COMPUTER PROGRAMMING-2017

Figure 4.4: Secant Method

As can be seen from the Fig(4.4), x provides a better approximation to the actual root x . The
3 0

process of nding the secant line is repeated with the points x and x : we use a do while structure 2 3

and replace x by x and x by x within the loop. The loop is terminated when the magnitude of
1 2 2 3

the di erence between the two successive approximations to the root becomes less than the desired
accuracy. One may, as in the case of the bisection method, put the condition for the termination of the
loop on the value of the function instead of the value of the root.

The secant method usually converges much faster than the bisection method. It has the disadvantage
however that the procedure is not guaranteed to converge.
The algorithm for this method should be clear from the description above. Let us use it to nd the
roots of the function that we used in the discussion on Bisection method.

f (x) = sin(x) x cos(x)


between x = 0 and x = 10.

/  Secant Method /

#include < stdio .h >


#include < math . h >
float float f ( x)

f return ( s i n ( x) x  cos (x ) ) ;

g
main ( )

f float x , a c c = 0 . 0 0 0 0 1 , z , a , b , x1 , x2 , t , x 3 ;

int n, i ;

float f ( float x);

p r i n t f ( " Enter the minimum value of x n n" ) ;

s c a n f ( "%f " ,& a ) ;

Page 102 of 164;


Root Finding COMPUTER PROGRAMMING-2017

p r i n t f ( " Enter the maximum value of x n n" ) ;

s c a n f ( "%f " ,& b ) ;

for ( x=a ; x < =b ; x=x + 0 . 1 )

f p r i n t f ( "%f n t %f n n" , x , f ( x ) ) ;

g
p r i n t f ( " input no of roots " );

s c a n f ( "%d " ,& n ) ;

for ( i =1; i <=n ; i +=1)

f printf (" n ninput x1 , x 2 " ) ;

s c a n f ( "%f ,% f " ,& x1 ,& x 2 ) ;

do
f
f 1= f ( x 1 ) ;

f 2= f ( x 2 ) ;

x 3= ( x1  f2 x2  f 1 ) / ( f2 f1 ) ;

x 1=x 2 ;

x 2=x 3 ;

t=f a b s ( f 2 ) ;

g while > (t acc ) ;

printf (" n n r o o t=%f f ( x 2)=% f a c c=%f n n


n n " , x2 , f 2 , a c c ) ;

g
g

4.4 Newton-Raphson Method


This method is based on the Taylor expansion of a function. In geometrical terms it is equivalent to
using the tangent to a curve at a given point rather than the secant between two points to nd the root.

Let x = a be a root of the equation f (x) = 0, let a be a close approximation to it, and let h = a a.
0 0

Since a is close to a , h is expected to be small. If we can nd h, then we would know the root exactly,
0

since a = a + h. Now, using the Taylor expansion, we know that


0

h 00
f (a ) = f (a + h) = f (a) + hf 0 (a) + f (a ) +   
2

(4.2)
0
2!
If h is suciently small, then
h 00
f (a)  hf 0 (a)
2

2!

Page 103 of 164;


Root Finding COMPUTER PROGRAMMING-2017

We can therefore neglect terms of order higher than h, and since f (a ) = 0 (since a is the actual
0 0

root and therefore by de nition, f (a ) = 0), we get


0

f (a )
h
f 0 (a)
This provides an estimate of how far the guess value, a, is from the actual root, a . In the next
0

iteration a + h is taken as the new approximation to the root, a . This iterative process is continued as
0

long as j ha j remains greater than the desired accuracy.

Another way to understand the algorithm is as follows: Choose any starting point x as the initial
0

guess for the root of f (x) = 0. Draw a tangent to the curve f (x) = 0 at (x ; f (x )). Then the equation
0 0

of this tangent is simply

y = f 0 (x )(x x ) + f (x )
0 0 0

This tangent will intersect the x-axis (y = 0) at


f (x )
x =x 0
1
f 0 (x )
0
0

We check if f (x ) is smaller than the accuracy required. If yes, x is the root. Else, we repeat the
1 1

process of drawing a tangent to the curve at (x ; f (x )) and do this process iteratively till we get the
1 1

required accuracy. Figure 6.1 will give you an idea of how this works. As you can see, the guessed value
of the root, that is the point at which the tangent crosses the x-axis gets closer and closer to the actual
root.

Figure 4.5: Newton Raphson Method

It is clear that larger the numerical value of the derivative f 0 (x) in the neighbourhood of the given
root, smaller is the correction h that has to be added to obtain the next approximation to the root.
Newton-Raphson method is therefore particularly convenient when the graph of the function is steep in
the neighbourhood of the given root. On the other hand, if the derivative f 0 (x) is small near the root,
h will be large and computing the root by this method will be dicult (sometimes even impossible).

Page 104 of 164;


Root Finding COMPUTER PROGRAMMING-2017

The main advantage of this method is that only one point is required to start the procedure. Also the
method usually converges very rapidly. However, the disadvantage is that the derivative of the function
has to be calculated, and this may not be easy. It is also not guaranteed that the method will converge
to a root from any arbitrary starting point. In fact some times the method is known to fail even if one
starts reasonably close to the expected root.

We can use the Newton-Raphson method to determine the roots for the function sin(x) x cos(x)
. Note there we do not need to tabulate since we can start anywhere. However, it is always a good
practice to tabulate the function to get to know the rough value of the root. This way, when you get
the actual root, you can see if it is correct since if it is very di erent from the rough value that you
have obtained from the tabulation, then there is some error in the program.

/  Newton Raphson  /

#include< > stdio .h

#include< > math . h

float float f ( x)

f return  ( s i n ( x) x cos (x ) ) ;

g
float float g( x)

f return  (x sin (x ) ) ;

g
main ( )

f
float a , x , f , g , ai n c =0.1 , xinc =0.1 , f1 , f2 , h , acc =0.00001;

float f ( float (x );

float g( float x);

FILE  f p=NULL ;

f p=f o p e n ( " r e s . t x t " , "w" ) ;

do
f f1 = f (x );

f2 = g(x );

h = f1 / f2 ;

x = x+h ;

g
while ( f a b s ( h / x) > acc ) ;

f p r i n t f ( f p , "%f n t %f n n" , x , f 1 ) ;

R Some of the common errors & good practices

Page 105 of 164;


Root Finding COMPUTER PROGRAMMING-2017

1. Always tabulate the function to get some idea of the roots of the function before
you nd the exact roots.
2. The Bisection method will always give you a root of the function. However, if
the roots are very close to each other, it may not nd all the roots.
3. Secant method though faster than the Bisection method is not guaranteed to
discover the root of the function.
4. Newton-Raphson method is fast and convenient but again, it is not guaranteed
to converge.
5. Newton-Raphson method should be avoided if the slope of the function is steep
near the root.

4.5 Questions
1. Compare the behaviour of some simple functions at large x (like Prob.2 and Prob.3) and explain
the discrepancy.What do you understand by iterative methods? How do you nd out (roughly) if
a given equation has more than one root?
2. How many initial points are needed for the three di erent methods? How do you select them?
3. What are the advantages and disadvantages of the three methods studied for root- nding?

4.6 Problems
1. Find the roots, accurate to four signi cant gures, of the equation

eax bx = 0
2

in the range 1:0  x  1:0 for


i) a= 1.0, b = 5.0

Page 106 of 164;


Root Finding COMPUTER PROGRAMMING-2017

ii)a=-1.5, b=10.0

by three iteration methods, that is Bisection, Secant and Newton-Raphson methods. In each case,
determine the number of iterations necessary to obtain the desired accuracy.

/  roots of exp ( ax) b  


x x =0 using Newton Raphson  /

#include< stdio .h >


#include< math . h >
#include< stdlib .h >
main ( )

f
float a , b , x , f1 , f2 , h ;

float acc =0.00001; int ls ;

printf (" give values of a ,b,x n n" ) ;

s c a n f ( "%f ,% f ,% f " ,& a ,& b ,& x ) ;

l s =0;

do
f l s = l s +1;

f1 = exp ( a  x) b  
x x;

f2 = a  exp ( a  x) 2  b x;

h = f1 / f2 ;

p r i n t f ( " s t e p=%d , x=%f , f u n c t i o n=%f , h=%f n n" , l s , x , f 1 , h ) ;

x+=h ; g
while ( f a b s ( h/x ) > acc ) ;

p r i n t f ( " a=%f , b=%f , Root=%f n n" , a ,b,x);

/  roots of exp ( a  x) b  
x x = 0 using bisec  /

/  uses subroutime to calculate the function  /

#include < stdio .h >


#include < math . h >
#include< stdlib .h >
main ( )

f
float x l , xm , x r , a , b , d , a c c = 0 . 0 0 0 0 1 , z ;

float f ( float x, float a , float b);

Page 107 of 164;


Root Finding COMPUTER PROGRAMMING-2017

printf (" give values of a , b , xl , xr " ) ;

s c a n f ( "%f ,% f ,% f ,% f " ,& a ,& b ,& x l ,& x r ) ;

do
fxm = ( x l+x r ) / 2 . 0 ;

if ( f (xm) < acc )

f p r i n t f ( "%f ,% f ,% f ,% f " , xm , f ( xm , a , b ) , a c c ) g
else
f
d= f ( xm , a , b )  f ( xl , a , b ) ;

if > (d 0)

xl = xm ;

if < (d 0)

xr = xm ;

z = ( xl x r ) / ( x l+x r ) ; g
while ( f a b s ( z) > acc ) ;

p r i n t f ( "%f ,% f ,% f ,% f " , xm , f ( x l , a , b ) , f ( xm , a , b ) , z ) ;

g
g
float f ( float x, float p, float q)

f
float v;

v=e x p ( p  x) q  
x x;

return (v );

/  multiple roots of exp ( a  x) b  


x x = 0 using bisec  /

#include < stdio .h >


#include < math . h >
#include< stdlib .h >
main ( )

f
float x , xmin , xmax , x i n c , t e s t , x l , xm , x r , a , b , d , a c c = 0 . 0 0 0 0 1 , z ;

float f ( float x, float a , float b);

printf (" give values of a , b , xmin , xmax , x m i n c " ) ;

s c a n f ( "%f ,% f ,% f ,% f ,% f " ,& a ,& b ,& xmin ,&xmax,& x i n c ) ;

for ( x=xmin ; x < =xmax ; x+=x i n c )

f t e s t=f ( x , a , b )  f ( x+x i n c , a , b ) ;

if ( test < 0)

f x l=x ; x r=x+x i n c ;

Page 108 of 164;


Root Finding COMPUTER PROGRAMMING-2017

do
f
xm = ( x l+x r ) / 2 . 0 ;

d= f ( xm , a , b )  f ( xl , a , b ) ;

if > (d 0)

xl = xm ;

if < (d 0)

xr = xm ;

z = ( xl x r ) / ( x l+x r ) ;

g
while ( f a b s ( z) > acc ) ;

p r i n t f ( "%f ,% f ,% f ,% f n n " , xm , f ( x l , a , b ) , f ( xm , a , b ) , z ) ;

g
g
g
float f ( float x, float p, float q)

f
float v;

v=e x p ( p  x) q  
x x;

return (v );

/  roots of exp ( a  x) b  
x x =0 using secant method  /

#include< stdio .h >


#include< math . h >
#include< stdlib .h >
#define f (x , a , b) ( exp ( ( a )  ( x )) (b )  (x)  (x))

main ( )

f
float a , b , x1 , x2 , x3 , a c c = 0 . 0 0 1 , z ; int l s =1;

p r i n t f ( "ENTER a , b , x1 and x2 n n" ) ;

s c a n f ( "%f ,% f ,% f ,% f " ,& a ,& b ,& x1 ,& x 2 ) ;

p r i n t f ( "%f ,% f ,% f ,% f n n " , a , b , x1 , x 2 ) ;

do
f
x3 = ( x1  f ( x2 , a , b) x2  f ( x1 , a , b ) ) / ( f ( x2 , a , b) f ( x1 , a , b ) ) ;

x1 = x2 ; x2 = x3 ;

p r i n t f ( " l s=%d x 1 =%5.2 f x 2 =%5.2 f x 3 =%5.2 f f ( x 3 )=%6.3 f n n


n"

, l s , x1 , x2 , x3 , f ( x3 , a , b ) ) ;

Page 109 of 164;


Root Finding COMPUTER PROGRAMMING-2017

z = f a b s ( x1 x2 ) ;

l s ++;

g
while > (z acc ) ;

printf (" n n n n%f %f n n " , x3 , f ( x3 , a , b ) ) ;

2. Using the series expansion for J (x), nd its two lowest positive roots to an accuracy of four decimal
0

places. Note that in this problem you have been asked to nd the roots to accuracy of
4 decimal places and not 4 digits.

/  First root of Bessel ( Prob . 2, Roots )  /

#include< stdio .h >


#include< math . h >
#include< stdlib .h >
main ( )

f float x , x l , x r , xm , a c c = 0 . 0 0 0 0 1 , x i n c = 0 . 5 , z ;

float f ( float x);

for ( x =0.01;x < = 4 . 0 ; x+=x i n c )

f
if ( f (x)  f ( x+x i n c ) < 0)

f x l=x ; x r=x+x i n c ;

do
f xm=( x l+x r ) / 2 . 0 ;

/ 
i f ( f a b s ( f ( xm)) < acc )

f p r i n t f (" n n xm=%f f ( xm)=% f a c c=%f n n " , xm , f ( xm ) , a c c ) ; b r e a k ; g


 /

if ( f (xm)  f ( xl ) > 0)

f x l=xm ; g
if ( f (xm)  f ( xl ) < 0)

f x r=xm ; g
z=f a b s ( ( x l x r ) / ( x l+x r ) ) ;

p r i n t f ( "xm=%f f (xm)=% f z=%f a c c=%f n n " , xm , f (xm ) , z , a c c ) ;

g
while > (z acc ) ;

printf (" n n r o o t=%f f (xm)=% f z=%f a c c=%f n n n n " , xm , f (xm ) , z , a c c ) ;

break ;

Page 110 of 164;


Root Finding COMPUTER PROGRAMMING-2017

g
g
float float f ( x)

f float s , t , func ; int k , n =0;

s = 1 . 0 ; t=s ; n = 0 ; k = 0 ;

do
f k=k + 1 ;


t = pow ( x , 2 ) / ( 4 . 0   k ( n+k ) ) ;

s+=t ;

g
while ( fabs ( t/s ) > 0.0001);

return (s );

3. The equation

f (x; y) = 0
de nes y as an implicit function of x. . As an example, consider

f (x; y) = x + y + xy + 1 = 0
3 3

For any given x, this is a cubic equation in y; so y can be found by obtaining the roots (one or
three real roots) of this equation, say by secant method. Plot y as a function of x, for 1:5 
x  1:5. If for some value of x there are three real roots, (y ; y ; y ), plot all the three points 1 2 3

(x; y ); (x; y ); (x; y ). You may assume that 2  y  2.


1 2 3

/  plots of f (x) = x   x x + a  x + a  
a a + 1  /

#include < stdio .h >


#include < math . h >
#define pi 3.14159

main ( )

f
float x,a , f ;

FILE  f p=NULL ;

f p=f o p e n ( " r e s . t x t " , "w" ) ;

for ( a= 1.5; a < =1.5; a=a + 0 . 1 )

f
for ( x= 2.0; x < = 2 . 0 ; x=x + 0 . 0 1 )

f f = x  
x x + a  x + a  
a a + 1.0;

f p r i n t f ( f p , "%f n t %f nn" , x , f ) ;

Page 111 of 164;


Root Finding COMPUTER PROGRAMMING-2017

gg

The plot of the function will look as in Figure 4.6

Plot of the function


15
cubic function of x& y

10

-5

-10
-2 -1.5 -1 -0.5 0 0.5 1 1.5 2

Figure 4.6: Plot of the function

/  multiple roots of x  
x x + a  x + a  
a a + 1 = 0  /

#include< stdio .h >


#include< math . h >
main ( )

f
float a , x , f , g , ai n c =0.1 , xinc =0.1 , f1 , f2 , h , acc =0.00001;

FILE  f p=NULL ;

f p=f o p e n ( " r e s . t x t " , "w" ) ;

for ( a= 1.5; a < = 1 . 5 ; a+=a i n c )

f for ( x= 2.0; x < = 2 . 0 ; x=x+x i n c )

f f = x  
x x +a  x + a  a a +1.0;

Page 112 of 164;


Root Finding COMPUTER PROGRAMMING-2017

g = pow ( ( x+x i n c ) , 3 ) + a  ( x+x i n c ) + a  


a a + 1.0;

if  <
( f g 0)

fdo
f f1 = x  x x + a  x + a  
a a +1.0;

f2 = 3.0  x x + a;

h = f1 / f2 ;

x = x+h ;

g
while ( f a b s ( h / x) > acc ) ;

f p r i n t f ( f p , "%f n t %f n t %f n n" , a , x , f 1 ) ;

g
g
g g

The plot will look as in Figure 4.7

2
roots

1.5

0.5

-0.5

-1

-1.5
-1.5 -1 -0.5 0 0.5 1 1.5

Figure 4.7: Plot of the roots

4. Choosing equally spaced values of t in (0; ! ), solve the Kepler equation for 2

 sin !t = 0
Use the solution to plot the orbit whose radial coordinates are given by

Page 113 of 164;


Root Finding COMPUTER PROGRAMMING-2017

r = a(1  cos )
cos 
cos  =
1  cos
Take ! = 1:0,  = 0:8 and a = 2:0. Remember that time t, is only a parameter. The equation has
to be solved for each t in the given interval. For each t, the initial value of can be chosen to be t.

/  Kepler Orbit  /

/  orbit for omega = 1.0 , e= 0.8 , and a = 2  /

#include< stdio .h >


#include< math . h >
#define pi 3.14159

main ()

f
float f 1 , f 2 , h , x , t , x1 , y1 , r , a c c= 0.00001 , c ;

FILE  f p=NULL ;

f p=f o p e n ( " r e s . t x t " , "w" ) ;

for ( t =0.0001; t < =(2.0  p i ) ; t=t + 0 . 0 5 )

f x = t ;

do
f f1 = x 0.8  sin (x) t ;

f2 = 1.0 0.8  cos (x ) ;

h = f1 / f2 ;

x = x + h;

g
while ( f a b s ( h/x ) > acc ) ;

/  p r i n t f ("% f ,% f n
n" , t , x ) ;  /

r = 2.0  (1.0 0.8  cos (x ) ) ;

c = ( cos (x ) 0.8)/(1.0 0.8  cos (x ) ) ;

x1 = r  c ;

y1 = r  sqrt (1.0 c  c );

f p r i n t f ( f p , "%f n t %f n n " , x1 , y 1 ) ;

f p r i n t f ( f p , "%f n t %f n n " , x1 , y1 ) ;

g
g

The plot for ! = 1;  = 0:8 and a = 2 will look as in Figure 4.8

Page 114 of 164;


Root Finding COMPUTER PROGRAMMING-2017

Kepler Orbit
1.5
omega=1,e=0.8 & a=2

0.5

-0.5

-1

-1.5
-4 -3.5 -3 -2.5 -2 -1.5 -1 -0.5 0 0.5

Figure 4.8: Kepler Orbit

Page 115 of 164;


Chapter 5

Ordinary Di erential Equations


5.1 Introduction
An ordinary di erential equation (ODE) is an equation involving derivatives of an unknown function
of one independent variable. ODEs are very important tools in modeling a wide variety of physical
phenomena - oscillating systems, electrical networks, chemical reactions, satellite orbits, etc. Therefore
the solution of ODEs is of great importance in physical sciences, ecology, economics and social sciences.
We examine some of the ways of solving such equations.

Consider the general rst-order di erential equation:

dy
y0 = = f (x; y); y(x ) = y
dx 0 0

The function f (x; y) and the initial condition (x ; y ) are given. The exact solution of this equation is
0 0

a curve in the x y plane passing through the point (x ; y ) . Solving this di erential equation means
0 0

nding y(x), the equation representing this curve. In general, we are required to nd the solution, y(x),
from x = x to some nal point, x = xf . For this purpose the region from x to xf is divided into n
0 0

equal intervals, each of length h = xf n x0 . Some approximation procedure is then employed to obtain
( )

yi from (xi ; yi ) , where yi = y(xi ),and xi = x + ih. Thus, beginning with (x ; y ) one obtains (x ; y )
+1 0 0 0 1 1

. The whole process is repeated n times (using for or do while loop) to nally obtain y at x = xn = xf .

Various approximation techniques are available for the numerical solution of di erential equations; of
these we shall discuss the Euler's formula and the Runge-Kutta methods.

116
Ordinary Di erential Equations COMPUTER PROGRAMMING-2017

5.2 Euler's Formula


Consider the equation y0 = f (x; y) . If yi and yi +1 are the solutions at points xi and xi , then we may
+1

obtain yi from the approximation


+1

yi yi
xi
+1

xi
 y0  f (xi; yi)
+1

The interval between two consecutive values of x is h, the step size: (h = xi +1 xi ). Therefore

yi = yi + hf (xi ; yi ) + O(h )
+1
2

or
yi = yi +1 yi  hf (xi ; yi ) (5.1)
neglecting O(h ), the error term of order h . Beginning with (x ; y ) , this gives y = (y + y ) at
2 2
0 0 1 0 0

the point x = (x + h). Similarly y can be calculated starting with (x ; y ) , and so on. Notice that
1 0 2 1 1

this last equation is essentially a Taylor's expansion of y(x) with only the rst two terms retained.

The Euler method is not recommended for practical use because it is not very accurate when compared
to other, fancier, methods with an equivalent step size. This is because the error term is of order h . 2

Moreover, the method is not very stable. Since it is a very simple method, it is useful to obtain a rough
guess of the expected solution.

5.3 Runge-Kutta methods


A straightforward extension of this method for better accuracy would be to retain higher order terms
in Taylor's expansion. However, the calculation of higher order derivatives that this straightforward
extension requires is often cumbersome; as a result, this straightforward extension is rarely employed
in practice.

Consider however the use of a step like Equation(5.1) to take a trial step to the mid-point of the interval.
Then use the value of both x and y at that mid-point to compute the real step across the whole interval:

k = hf (xi ; yi )
1

h k
k = hf (xi + ; yi + ) 1
2
2 2
yi = yi + k + O(h )
+1 2
3

This symmetrization cancels the rst order error term, h , and makes the method second order, i.e.,
2

Page 117 of 164;


Ordinary Di erential Equations COMPUTER PROGRAMMING-2017

the error term is proportional to h . This is called the mid-point or second order Runge-Kutta
3

method.

The basic philosophy of the Runge-Kutta methods is to nd yi by evaluating the derivative of y not
+1

only at the initial point (xi ; yi ) , as is done in the Euler method, but also at the end point and some
intermediate points. The increment, y, instead of being just hf (xi ; yi ) , is some kind of an average
of all these derivatives. The intermediate points are so chosen that the terms of order h ; h ;    in the
2 3

expression for the error cancel out. So, the error is considerably reduced, being proportional to a much
higher power of h.

The most widely used method in this class of methods is the 4th-order Runge-Kutta method, RK4.
The error in this case is O(h ). For the solution of the di erential equation
5

y0 = f (x; y); y(x ) = y


0 0

the RK4 method leads to the following formula:

yi
+1  y(xi +1 ) = y(xi + h) = yi + yi
where the increment yi is given by
1
y i = ( k + 2 k + 2 k + k )
6 1 2 3 4

where
k = hf (x; y)
1

h k
k = hf (x + ; y + ) 1
2
2 2
h k
k = hf (x + ; y + ) 2
3
2 2
k = hf (x + h; y + k )
4 3

To understand this procedure better, it is instructive to look at what each of these steps is doing.

1. We start with k which is just the slope multiplied by h at the beginning of the procedure, that is
1

at the initial point. (remember that the di erential equation is y0 = f (x; y).)

2. Now we use this slope k to move halfway to the interval, then k is the estimate of the slope at
1 2

that midpoint multiplied by h. This is better than the estimate k . 1

3. Again, we use k to move halfway to the interval and get k as the estimate of the slope which is
2 3

better than k .
2

Page 118 of 164;


Ordinary Di erential Equations COMPUTER PROGRAMMING-2017

4. Finally, we use k to go all the way to the end of the interval to get k as the estimate of the slope
3 4

at the endpoint of the interval.


5. To get the value of the quantity y at the endpoint, we use a weighted sum of all these slopes to
get an accurate estimate of the slope and multiply it by the interval itself.
Just as in the Euler's method, here also beginning with (x ; y ), we obtain y = y + y, i.e., 0 0 1 0

y(x ); x = x + h; then from y we obtain y and so on. The method is very simple to implement
1 1 0 1 2

as a function which calculates yi given (xi ; yi ) and h. The accuracy of the result can be checked by
+1

repeating the calculation with a larger number of steps, say 2n, and observing the resulting convergence.

To compare the two methods, that is the Euler and Runge-Kutta (RK-4) method, let us consider a
simple rst order di erential equation. Of course, Euler's method as well as the RK-4 method can be
used for higher order equations as well. Consider the equation
dx
= xt + t sin(t ) x(0) = 1 2
(5.2) 2 3

dt
We will solve this equation exactly and compare the exact analytical solution with the numerical
solution obtained with Euler's method and RK-4 method. The exact solution is
3 1 13 t3
cos(t ) sin(t ) + e 3 x(t) = (5.3) 3 3

10 10 10
The program below will solve the di erential equation and plot the results from the analytical
calculation, Euler and RK-4 methods.

#include< stdio .h >


#include< math . h >
float float float
f ( t , x)

f return     (x t t + t t s i n ( pow ( t , 3 ) ) ) ; g
main ( )

f float f ( float t , float x);

float t =0 , x = 1 . 0 , h = 0 . 0 5 , s , t i , t f ; int i ,n; float k1 , k2 , k3 , k 4 ;

FILE  res1 ;

r e s 1=f o p e n ( " r e s 1 . d a t " , "w" ) ;

FILE  res2 ;

r e s 2=f o p e n ( " r e s 2 . d a t " , "w" ) ;

FILE  res3 ;

r e s 3=f o p e n ( " r e s 3 . d a t " , "w" ) ;

t i =0;

Page 119 of 164;


Ordinary Di erential Equations COMPUTER PROGRAMMING-2017

t f =1.0;

do
f
x = x + h   
(x t t + t  
t s i n ( pow ( t , 3 ) ) ) ;

t = t + h;

f p r i n t f ( r e s 1 , "%f %f n n" , t , x ) ;

g
while < (t =t f ) ;

for ( t=h ; t < t f ; t+=h )

f s= 0.3  c o s ( pow ( t , 3 ) ) 0.1  s i n ( pow ( t , 3 ) ) + 1.3  exp ( 0 . 3 3  pow ( t , 3 ) ) ;

f p r i n t f ( r e s 2 , "%f %f n n" , t , s ) ;

g
n=( t f t i )/h ;

t= t i ; x = 1 ;

for ( i =1; i < =n;++ i )

f k 1=h f (t ,x);

k 2=h  f ( t+h / 2 . 0 , x+k 1 / 2 . 0 ) ;

k 3=h  f ( t+h / 2 . 0 , x+k 2 / 2 . 0 ) ;

k 4=h  f ( t+h , x+k 3 ) ;

x+=(k 1 +2  k 2 +2  k 3+k 4 ) / 6 . 0 ; t+=h ;

f p r i n t f ( r e s 3 , "%f %f n n" , t , x ) ;

p r i n t f ( "%f ,% f n n" , t , x ) ;

g
g

The results when plotted are shown in Figure (5.1).

Page 120 of 164;


Ordinary Di erential Equations COMPUTER PROGRAMMING-2017

1.6
"res1.dat" u 1:2
"res2.dat" u 1:2
"res3.dat" u 1:2

1.5

1.4

1.3

1.2

1.1

1
0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1

Figure 5.1: Exact Solution, Euler's method and RK-4 method

Note that the RK-4 solution is almost identical with the exact solution while the Euler's method
gives us a solution which is a good approximation but not very exact. Explore the above program with
a smaller step size for the Euler's method and check how the accuracy improves.

5.4 Simultaneous Equations of First-Order


The Runge-Kutta method (or the Eulers method for that matter) can be extended to a system of any
number of coupled rst-order or higher order di erential equations. To solve a pair of simultaneous
di erential equations:
dy dz
y0 = = f (x; y; z ); z0 = = f (x; y; z )
dx 1
dx 2

y(x ) = y
0 0 z (x ) = z
0 0

we evaluate the quantities

Page 121 of 164;


Ordinary Di erential Equations COMPUTER PROGRAMMING-2017

k = hf (xi ; yi ; zi ) m = hf (x ; y ; zi )
   
1 1 1 2 1 1

h k m h k m
k = hf xi + ; yi + ; zi + 1 1
m = hf xi + ; yi + ; zi + 1 1
2 1
2 2 2 2
2 2
2 2
   
h k m h k m
k = hf xi + ; yi + ; zi + 2 2
m = hf xi + ; yi + ; zi + 2 2
3 1
2 2 2 3
2 2
2 2
k = hf (xi + h; yi + k ; zi + m )
4 1 3 3 m = hf (xi + h; yi + k ; zi + m )
4 2 3 3

This leads to (at xi +1 = xi + h)


1
yi = yi + (k + 2k + 2k + k )
+1
6 1 2 3 4

1
zi = zi + (m + 2m + 2m + m )
+1
6 1 2 3 4

Notice that any second-order di erential system

y00 = f (x; y; y0 ) y(x ) = ; y0 (x ) =


0 0

can be written as two coupled rst order equations by putting y0 = z

y0 = z; z 0 = f (x; y; z ); y(x ) = ; z (x ) =
0 0

This is a special case of the system considered above. In general, an nth order ODE can
be converted into a system of n rst order ODEs in a like manner.

In case of three simultaneous rst order ODE's:

y0 = f (x; y; z; u); z 0 = f (x; y; z; u); u0 = f (x; y; z; u)


1 2 3

we introduce one more set of quantities in addition to ki s and mi s, and calculate these in a similar
manner. Extension of the method to any number of coupled ODE's is obvious.

As an example, consider the simple mass m on a spring with spring constant k. The equation of
motion is given by
dy 2

m
+ ky = 0
dt 2

We impose the initial conditions of y(t = 0) = A and y0 (t = 0) = 0. The solution to this is trivial
and for the given initial conditions it is simply

Page 122 of 164;


Ordinary Di erential Equations COMPUTER PROGRAMMING-2017

r
k
y(t) = A cos(wt) w =
m
We choose k = m = A = 1 for simplicity. Then we can easily solve the second order di erential
equation by RK4 method outlined above. The program can be as follows:

/  Solving y ' '+ y ' =0

with initial condtions y ( x =0) = 1 and y ' ( x =0) =0 using RK4  /

#include< stdio .h >


#include< math . h >
#define f1 ( t , y , z ) (( z ))

#define f2 ( t , y , z ) ( y)

main ( )

f float h = 0 . 0 1 , t , y , z , k1 , k2 , k3 , k4 , m1 , m2 , m3 , m4 , r ;

FILE  f p=NULL ;

f p=f o p e n ( " r e s . t x t " , "w" ) ;

t = 0.0; y = 1.0; z = 0.0; /  Initial conditions  /

do
f k1 = h  f1 ( t , y , z ) ;

m1 = h  f2 ( t , y , z ) ;

k2 = h  f 1 ( t+h / 2 . 0 , y+k 1 / 2 . 0 , z+m1 / 2 . 0 ) ;

m2 = h  f 2 ( t+h / 2 . 0 , y+k 1 / 2 . 0 , z+m1 / 2 . 0 ) ;

k3 = h  f 1 ( t+h / 2 . 0 , y+k 2 / 2 . 0 , z+m2 / 2 . 0 ) ;

m3 = h  f 2 ( t+h / 2 . 0 , y+k 2 / 2 . 0 , z+m2 / 2 . 0 ) ;

k4 = h  f 1 ( t+h , y+k3 , z+m3 ) ;

m4 = h  f 2 ( t+h , y+k3 , z+m3 ) ;

y = y+( k 1 + 2 . 0  ( k 2+k 3 )+ k 4 ) / 6 . 0 ;

z = z +(m1+ 2 . 0  (m2+m3)+m4 ) / 6 . 0 ;

t = t+h ;

r=c o s ( t ) ;

f p r i n t f ( f p , "%f n t %f n t %f n n" , t , y , r ) ;

g
while < (t =10.0);

The graph can be plotted for the RK4 solution and the Exact solution and you can see from Figure
5.2 that the numerical solution is very good.

Page 123 of 164;


Ordinary Di erential Equations COMPUTER PROGRAMMING-2017

1.5
RK4 solution
Exact Solution

0.5

0
y

-0.5

-1

-1.5
0 1 2 3 4 5 6 7 8 9 10 11
t

Figure 5.2: Exact Solution and RK-4 method for Mass on a Spring

R Some of the common errors & good practices

1. While using the RK4 method, please make sure that the order of k ; k ; k ; k is 1 2 3 4

maintained.
2. In RK4 method, care should be taken to see that the order of incrementing the
dependent and independent variables is correct.
3. In solving simultaneous equations using the RK4 method, please ensure that the
incrementing of the ki and mi etc is alternate.
4. Always make sure that the initial values of the dependent and independent vari-
ables, that is the initial conditions are correctly implemented outside the iteration
loop.
5. Note that the division by 2 in the values of the quantities ki is written as a
division by 2:0. This is to ensure that the division is not integer division as
pointed out in Chapter 1.

Page 124 of 164;


Ordinary Di erential Equations COMPUTER PROGRAMMING-2017

5.5 Problems
1. For the di erential equation

dy
= x + y ; y(0) = 1;
dx
tabulate y(x) for 1  x  5 at intervals of 0:1 for di erent choices of the step size h (h =
0:01; 0:005; 0:002; 0:0001), along with the analytic solution. Use all the three methods for their
comparative study. Note that though the tabulation is required betweenx = 1 and x = 5
only, the process of solving the equation has to begin from x = 0, since the initial
condition is prescribed at that point. Also notice that tabulation has to be done at
intervals of 0:1 only though the step size, h, is much smaller than that.

/  solving d y / d x = x+y with

y (0)=1 using Euler ' s method  /

#include< stdio .h >


#include< math . h >
main ( )

f
float x =0 , y = 1 . 0 , h = 0 . 0 5 , s ;

FILE  res1 ;

r e s 1=f o p e n ( " r e s 1 . d a t " , "w" ) ;

FILE  res2 ;

r e s 2=f o p e n ( " r e s 2 . d a t " , "w" ) ;

do
f
y = y + h  ( x+y ) ;

x = x + h;

f p r i n t f ( r e s 1 , "%f %f n n" , x , y ) ;

g
while < (x =5.0);

for <( x=h ; x 5 . 0 ; x+=h )

f s =2.0  e x p ( x) x 1.0;

f p r i n t f ( r e s 2 , "%f %f n n" , x , s ) ;

g
g

2. The ODE describing the motion of a pendulum is

Page 125 of 164;


Ordinary Di erential Equations COMPUTER PROGRAMMING-2017

00 = sin 
The pendulum is released from rest at an angular displacement i.e. (0) = ; 0 (0) = 0. Use the
RK4 method to solve the equation for = 0:1; 0:5 and 1:0 and plot  as a function of time in the
range 0  t  8. Also plot the analytic solution valid in the small  approximation (sin    ).

/  Solving y '' = sin y with initial condtions y ( x =0) = alpha

and y ' ( x =0) =0 using RK4  /

#include< stdio .h >


#include< math . h >
#define f1 (x , u , z ) (( z ))

#define f2 (x , u , z ) (( sin (u ))) /  t=x , theta = u  /

main ( )

f
float h = 0 . 0 1 , x , u , z , k1 , k2 , k3 , k4 , m1 , m2 , m3 , m4 , a ;

FILE  f p=NULL ;

f p=f o p e n ( " r e s 1 . t x t " , "w" ) ;

for ( a =0.0; a < = 1 . 1 ; a +=0.1)

f
x = 0.0; u = a; z = 0;

do
f k1 = h  f1 (x , u , z ) ;

m1 = h  f2 (x , u , z ) ;

k2 = h  f 1 ( x+h / 2 , u+k 1 / 2 , z+m1 / 2 ) ;

m2 = h  f 2 ( x+h / 2 , u+k 1 / 2 , z+m1 / 2 ) ;

k3 = h  f 1 ( x+h / 2 , u+k 2 / 2 , z+m2 / 2 ) ;

m3 = h  f 2 ( x+h / 2 , u+k 2 / 2 , z+m2 / 2 ) ;

k4 = h  f 1 ( x+h , u+k3 , z+m3 ) ;

m4 = h  f 2 ( x+h , u+k3 , z+m3 ) ;

u = u+( k 1 + 2 . 0  ( k 2+k 3 )+ k 4 ) / 6 . 0 ;

z = z +(m1+ 2 . 0  (m2+m3)+m4 ) / 6 . 0 ;

x = x+h ;

if (( fabs (a 0.1) < 0.001) jj ( fabs (a 0.5) < 0.001) jj ( fabs (a 1.0) < 0.001))

f f p r i n t f ( f p , "%f n t %f n t %f n t %f n n" , x , u , a , a  cos (u x)); g


g
while < (x =1.0); g
g

The plot will look like as in Figure 5.3

Page 126 of 164;


Ordinary Di erential Equations COMPUTER PROGRAMMING-2017

Pendulum for different initial displacements


1
RK4
harmonic solution
0.9

0.8

0.7

0.6

0.5

0.4

0.3

0.2

0.1

0
0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1 1.1

Figure 5.3: Pendulum for di erent initial displacements & harmonic solution

3. A simple "prey-predator" system is modeled by the set of equations

x_ = x 1 2 xy; y_ = 3 y + xy 4

where x(t) and y(t) represent respectively the prey and predator populations as functions of time.
The term x tells us that the prey population grows in proportion to its own population while
1

xy says that it decreases as a result of encounters with the predators. The second equation says
2

that the predator population decreases in proportion to its own population (to model competition
for food between its members) and increases as a result of encounters with the prey (by providing
food for the predators). Solve these equations for = 0:25; = = 0:01 and = 1 with the 1 2 4 3

initial values x(0) = 100 and successively y(0) = 5; 10; 15; 20, and 25. Plot x(t) versus y(t) for
0  t  20.

/  solving dx / d t = g1  x + g2  
x y

and dy / d t = g3  y + g4  
x y RK4 method  /

#include< stdio .h >


#include< math . h >
#define f1 ( t , x , y) ( g1  (x) g2  (x)  (y))

#define f2 ( t , x , y) ( g3  (y) + g4  (x)  (y))

main ( )

Page 127 of 164;


Ordinary Di erential Equations COMPUTER PROGRAMMING-2017

f
float g1 = 0 . 2 5 , g2 = 0 . 0 1 , g3 = 1 . 0 , g4 = 0 . 0 1 , h = 0 . 0 0 1 ;

float t , x , y , k1 , k2 , k3 , k4 , m1 , m2 , m3 , m4 , y 1 ;

FILE  f p=NULL ;

f p=f o p e n ( " r e s . t x t " , "w" ) ;

for ( y 1 = 5 . 0 ; y1 < = 2 5 . 0 ; y 1 +=5.0)

f t = 0.0; x = 100.0; y = y1 ;

do
f k1 = h  f1 ( t , x , y ) ;

m1 = h  f2 ( t , x , y ) ;

k2 = h  f 1 ( t+h / 2 , x+k 1 / 2 , y+m1 / 2 ) ;

m2 = h  f 2 ( t+h / 2 , x+k 1 / 2 , y+m1 / 2 ) ;

k3 = h  f 1 ( t+h / 2 , x+k 2 / 2 , y+m2 / 2 ) ;

m3 = h  f 2 ( t+h / 2 , x+k 2 / 2 , y+m2 / 2 ) ;

k4 = h  f 1 ( t+h , x+k3 , y+m3 ) ;

m4 = h  f 2 ( t+h , x+k3 , y+m3 ) ;

x = x+( k 1 + 2 . 0  ( k 2+k 3 )+ k 4 ) / 6 . 0 ;

y = y+(m1+ 2 . 0  (m2+m3)+m4 ) / 6 . 0 ;

t = t+h ;

f p r i n t f ( f p , "%f n t %f n n" , x , y ) ;

g
while < (t =20.0); g
g

The plot will look like as in Figure 5.4

Page 128 of 164;


Ordinary Di erential Equations COMPUTER PROGRAMMING-2017

Prey-predator system for different initial conditions


80
prey-predator

70

60

50

40

30

20

10

0
40 60 80 100 120 140 160 180

Figure 5.4: Prey-predator system for di erent initial conditions

4. Solve the following di erential equation:

dy
2
dy
f (x) + f (x) + f (x)y = f (x)
1
dx 2
dx 2 3 4

with

y(0) = 0 at x = 0
dy
= 1 at x = 0
dx
where

f (x) = f (x) = 1; f (x) = 4x


1 2 3

and

X
10
( 1)i x i 2

f (x) =
4

i=0
(2i + 1)!
and plot the result from x = 0 to x = 1.

Page 129 of 164;


Ordinary Di erential Equations COMPUTER PROGRAMMING-2017

/  Solving y ' '+ y ' + 4  


x y = Sum ( i = 1 ; 1 0 ) [( 1)^ f g f g
i x^ 2i /(2 i +1)!]

with initial condtions y ( x =0) = 0 and y ' ( x =0) =1 using RK4  /

#include< stdio .h >


#include< math . h >
#define f1 (x , u , z ) (( z ))

#define f2 (x , u , z ) ( f ( ( x )) 4.0  (x)  ( u) (z )) /  y =u  /

main ( )

f float f ( float x);

float h = 0 . 0 1 , x , u , z , k1 , k2 , k3 , k4 , m1 , m2 , m3 , m4 ;

FILE  f p=NULL ;

f p=f o p e n ( " r e s . t x t " , "w" ) ;

x = 0.0; u = 0.0; z = 1.0;

do
f k1 = h  f1 (x , u , z ) ;

m1 = h  f2 (x , u , z ) ;

k2 = h  f 1 ( x+h / 2 , u+k 1 / 2 , z+m1 / 2 ) ;

m2 = h  f 2 ( x+h / 2 , u+k 1 / 2 , z+m1 / 2 ) ;

k3 = h  f 1 ( x+h / 2 , u+k 2 / 2 , z+m2 / 2 ) ;

m3 = h  f 2 ( x+h / 2 , u+k 2 / 2 , z+m2 / 2 ) ;

k4 = h  f 1 ( x+h , u+k3 , z+m3 ) ;

m4 = h  f 2 ( x+h , u+k3 , z+m3 ) ;

u = u+( k 1 + 2 . 0  ( k 2+k 3 )+ k 4 ) / 6 . 0 ;

z = z +(m1+ 2 . 0  (m2+m3)+m4 ) / 6 . 0 ;

x = x+h ;

f p r i n t f ( f p , "%f n t %f n n" , x , u ) ;

g
while < (x =1.0);

g
float f ( float x)

f
float f = 1 . 0 ,R= 1 . 0 ;

int k;

for ( k =1; k < =10; k+=1)

f R = R  x x/(2.0  
k (2.0  k+1.0));

f = f + R;

g
return ( f );

The plot will look like as in Figure 5.5

Page 130 of 164;


Ordinary Di erential Equations COMPUTER PROGRAMMING-2017

0.8
Plot of given differential equation

0.7

0.6

0.5

0.4

0.3

0.2

0.1

0
0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1 1.1

Figure 5.5: Plot of given Di erential Equation

5. Do numerical integration on the following di erential equations (Lorenz equations) with integration
step size, t = 0:01:

dx dy dz 8
= 10(x y) = x xz y = xy z
dt dt dt 3
Plot the trajectories (after removing transients)

a) in x y; x z; y z planes, and
b) in x t; y t; z t planes,

for the following values of the parameter :

i) = 5:0 ( xed point solution)


ii) = 50:0; 125:0; 200:0 (chaotic motion)
iii) = 100:0; 150:0; 250:0 (periodic motion)

Choose any reasonable initial conditions.

Page 131 of 164;


Ordinary Di erential Equations COMPUTER PROGRAMMING-2017

/  solving dx / d t = s (y z),

dy / d t = x(r z) y,

and dz / dt = xy bz using RK4 method  /

#include< stdio .h >


#include< math . h >
#define f1 ( t , x , y , z ) (s  ( ( y) (x ) ) )

#define f2 ( t , x , y , z ) ((x)  (r (z )) (y ))

#define f3 ( t , x , y , z ) ((x)  ( y) b  (z ))

main ( )

f
float s =10.0 , r =5.0 ,b =8.0/3.0 , h=0.01;

float t , x , y , z , k1 , k2 , k3 , k4 , m1 , m2 , m3 , m4 , n1 , n2 , n3 , n4 , p ;

FILE  f p=NULL ;

f p=f o p e n ( " r e s . t x t " , "w" ) ;

t = 0.0; x = 1.00; y = 2.0; z = 1.0;

do
f k1 = h  f1 ( t , x , y , z ) ;

m1 = h  f2 ( t , x , y , z ) ;

n1 = h  f3 ( t , x , y , z ) ;

k2 = h  f 1 ( t+h / 2 , x+k 1 / 2 , y+m1 / 2 , z+n1 / 2 ) ;

m2 = h  f 2 ( t+h / 2 , x+k 1 / 2 , y+m1 / 2 , z+n1 / 2 ) ;

n2 = h  f 3 ( t+h / 2 , x+k 1 / 2 , y+m1 / 2 , z+n1 / 2 ) ;

k3 = h  f 1 ( t+h / 2 , x+k 2 / 2 , y+m2 / 2 , z+n2 / 2 ) ;

m3 = h  f 2 ( t+h / 2 , x+k 2 / 2 , y+m2 / 2 , z+n2 / 2 ) ;

n3 = h  f 3 ( t+h / 2 , x+k 2 / 2 , y+m2 / 2 , z+n2 / 2 ) ;

k4 = h  f 1 ( t+h , x+k3 , y+m3 , z+n3 ) ;

m4 = h  f 2 ( t+h , x+k3 , y+m3 , z+n3 ) ;

n4 = h  f 3 ( t+h , x+k3 , y+m3 , z+n3 ) ;

x = x+( k 1 + 2 . 0  ( k 2+k 3 )+ k 4 ) / 6 . 0 ;

y = y+(m1+ 2 . 0  (m2+m3)+m4 ) / 6 . 0 ;

z = z +( n1 + 2 . 0  ( n2+n3 )+ n4 ) / 6 . 0 ;

t = t+h ;

p = ( x+y ) / 2 . 0 ;

f p r i n t f ( f p , "%f n t %f n t %f n t %f n n" , t , x , y , z ) ;

g
while < (t =20.0);

The plots of x vs t for the various values of will look like the Figures below.

Page 132 of 164;


Ordinary Di erential Equations COMPUTER PROGRAMMING-2017

Lorenz Equations: Fixed Point Solution


4.5
alpha = 5.0

3.5

2.5

1.5

1
0 2 4 6 8 10 12 14 16 18 20 22

Figure 5.6: Lorenz Equations: Fixed Point Solution

Lorenz Equations: Chaotic Motion


30
alpha = 50.0

20

10

-10

-20

-30
0 2 4 6 8 10 12 14 16 18 20 22

Figure 5.7: Lorenz Equations: Chaotic Solution

Page 133 of 164;


Ordinary Di erential Equations COMPUTER PROGRAMMING-2017

Lorenz Equations: Periodic Motion


50
alpha = 100.0

40

30

20

10

-10

-20

-30

-40
0 2 4 6 8 10 12 14 16 18 20 22

Figure 5.8: Lorenz Equations: Periodic Solution

6. To plot the bifurcation diagram for the logistic map:


A di erence equation is a particular form of recurrence relation which is derived from a di erential
equation. Consider a di erence equation

xn = xn (1 xn ) ; x
+1 0 2 [0; 1]
Here is a parameter 2 [0; 4]. Choose a single initial value x of x in the range given for x. This 0

can be any value EXCLUDING 0; 1 and 0:5. For this value of x , solve the di erence equation for 0

various values of in the range given, taking  = 0:05. Thus you will have 100 values of . For
the solution to the equation for each , remove the rst 10 iterations since these are transients.
4

Keep the next 100 iterations for each and plot a graph between x and .

/  solving x ( n+1)= a l p h a x n alpha x n ^2  /

#include< stdio .h >


#include< math . h >
main ( )

f
float a ,x; int i ;

FILE  f p=NULL ;

// FILE  f p 1=NULL ;

Page 134 of 164;


Ordinary Di erential Equations COMPUTER PROGRAMMING-2017

f p=f o p e n ( " r e s . t x t " , "w" ) ;

// f p 1=f o p e n ( " r e s 1 . t x t " , " w " ) ;

x =0.9;

for ( a =0.01; a < =4.0; a +=0.05)

f x =0.9;

i =0;

dof
x=a  x a  
x x;

// f p r i n t f ( f p 1 ,"% f n t %f n n" ,x , a ) ;

i ++;

if (i > 10000)

f
f p r i n t f ( f p , "%f n t %f n t %d n n" , x , a , i ) ;

g
g while < (i =10100);

gg

The plot will look like as in Figure 5.9

Bifurcation Diagram for Logistic Map


1

0.9

0.8

0.7

0.6

0.5

0.4

0.3

0.2

0.1

0
0 0.5 1 1.5 2 2.5 3 3.5 4

Figure 5.9: Bifurcation Diagram for the Logistic Map

Page 135 of 164;


Chapter 6

Integration
6.1 Introduction
Rb
Evaluation of the de nite integral f (x)dx is equivalent to nding the area enclosed by the curves rep-
a
resented by the integrand y(x) , the two ordinates at a and b, and the x-axis (Figure (6.1)). Numerical
integration or quadrature, as it is usually called, aims at calculating this area. To do this the required
area is divided into several strips by erecting ordinates in the interval between a and b . The area of
each strip is found by some suitable approximation and these areas are summed to get the total area.
In some procedures the width of the strips is kept equal, while in others it is unequal. It is of course
assumed that the given integral has a nite value.

6.2 Methods Based on Intervals of Equal Width


6.2.1 Trapezoidal Rule
Let the range of integration, a to b , be divided into n equal intervals, each of width h = b na . ( )

Let the ordinates at the (n + 1) points, x = a; x = a + h;    ; xn = an + h = b, be denoted by


0 1

y = y(x ); y = y(x );    ; yn = y(xn ). If we now approximate each segment of the curve between two
0 0 1 1

successive ordinates by a straight line, each strip becomes a trapezium.

136
Integration COMPUTER PROGRAMMING-2017

Figure 6.1: Trapezoidal Rule

We can nd the area of each trapezium and add. The result is

Zb
(y + y ) (y + y ) (y + yn )
f (x)dx 
= 0
h+
1
h +  + n
1 2
h 1

2 2 2
a
" #
n
h X 1

= y + yn + 2 yi
2 0

1
" #
n
h X 1

= y(a) + y(b) + 2 y(a + ih) (6.1)


2 1

This formula is called the Trapezoidal rule. It can be shown that for trapezoidal rule the leading
term in the error is
(b a)h y00 ( ) 2

Er = (6.2)
12
where  is some point in the interval (a; b) and y00 denotes the second derivative of y. Clearly, if
the integrand is a linear function of its argument, all derivatives of order two and higher
vanish, and the Trapezoidal rule produces an exact result.

As an example, consider the integral


Zb
1
I=
(1 + x) 3

a
We will evaluate it using the Trapezoidal Rule. The algorithm is straightforward. We divide the
interval into n equal segments and then evaluate the function at each segment and multiply it with the
length of the segment to get the area of the segment as explained above. Finally, we add the area of all
the segments to get the area under the curve which is the value of the de nite integral. The program

Page 137 of 164;


Integration COMPUTER PROGRAMMING-2017

could be as follows:

/  Trapezoidal Rule  /

<
#i n c l u d e stdio .h >
#include< math . h >
float f ( float x)

f
return (1/((1+ x)  (1+ x )  (1+ x ) ) ) ;

g
main ( )

f
float f ( float x);

int i ,n;

float a , b , s =0 , y =0 , h ;

p r i n t f ( " Enter the no of intervals =" ) ;

s c a n f ( "%d " ,& n ) ;

p r i n t f ( " Enter the lower l i m i t =" ) ;

s c a n f ( "%f " ,& a ) ;

p r i n t f ( " Enter the upper l i m i t =" ) ;

s c a n f ( "%f " ,& b ) ;

h=(b a )/n ;

for ( i =1; i <=n 1 ; i ++)

f
s=s+ f ( a+ i  h);

g
y=( f ( a )+ f ( b )+2  
s) h/2.0;

p r i n t f ( " the value of the integral i s=%f " , y ) ;

6.2.2 Simpson's Rule


A method that gives reasonably accurate results and is quite often used for numerical integration is
Simpson's rule. If in the previous example, we approximate the function over two adjoining segments
by a quadratic rather than a linear function, we obtain what is known as Simpson's rule:

Page 138 of 164;


Integration COMPUTER PROGRAMMING-2017

Zb  
h
f (x)dx = [y + 4(y + y +    + yn ) + 2(y + y +    + y n ) + yn ]
3 0 1 3 1 2 4 2 1

a
2 n n 3
  2 2 1
h 4y0 + yn + 4
X X
= y i +2 y i5
3 i=1
2 1

i=1
2

2 n n 3
  2 2 1
h 4y (a) + y (b) + 4
X X
= y(a + (2i 1)h) + 2 y(a + 2ih)5 (6.3)
3 i=1 i=1

It is obvious that in this case n must be even. Simpson's rule generally yields better results than
the Trapezoidal rule because we use a quadratic rather than a linear approximation to each segment of
the curve. The leading term in the error in Simpson's rule is proportional to the fourth derivative of
y ; therefore it produces exact results in the case of integrands that are general polynomial of order three.

For both methods, the rst step is to choose an appropriate interval width h . Equivalently, one can
choose the number of intervals, n . But for certain exceptions, Simpsons rule yields reasonably accurate
result for n  50 100. In the trapezoidal rule, for same kind of accuracy, a much larger number of
points may be needed.

R
Remember that for Simpson's rule n has to be even and that the various terms
have to be multiplied by proper weights.

The following example will make the implementation of Simpson's rule clear.

Consider the integral


Zb
1
(1 + x) 3

a
A program for solving this might look like this

/  this is a program to test the Simpson subroutine  /

#include < > stdio .h

#include < > math . h

float float f ( x)

f return  (1/((1+ x) (1+ x )  (1+ x ) ) ) ;

Page 139 of 164;


Integration COMPUTER PROGRAMMING-2017

g
main ( )

f float simpson ( float a , float b, int n);

float float f ( x);

int n;

float a ,b, integral ;

printf (" n n input a ,b,n " );

s c a n f ( "%f ,% f ,%d " ,& a ,& b ,& n ) ;

/  REMEMBER n should be even  /

i n t e g r a l =s i m p s o n ( a , b , n ) ;

printf (" n n n n I n t e g r a l= %f n n" , i n t e g r a l ) ;

g
float simpson ( float a , float b, int n)

f int i ;

float f ( float (x ) ) ;

float x,y;

float h=(b a )/n ;

float s= f ( a )+ f ( b ) ;

for ( i =1; i < n ; i +=2)

f x=a+ i  h;

y= f ( x ) ;

s +=4  f (x );

g
for ( i =2; i < n ; i +=2)

f x=a+ i  h;

y= f ( x ) ;

s +=2  f (x );

g

s =h / 3 . 0 ;

return s ;

6.3 Methods Based on Intervals of Unequal Width


6.3.1 Gauss Quadrature
We have noted above that the trapezoidal rule gives exact results for polynomials of order one, whereas
Simpson's rule gives exact results for polynomials of order three. We can do better than this if we
do not insist on the integrand being evaluated at equal intervals. Suppose we approximate any nite
integral by:

Page 140 of 164;


Integration COMPUTER PROGRAMMING-2017

Zb n
X
f (x)dx  wk f (xk ) (6.4)
a k=1

and choose the 2n unknowns - the points xk and the weights wk - such that we get an exact result
as long as f (x) is an arbitrary polynomial of order (2n 1), i.e.,

Z+1 n
X
   
A + A x + A x +  + A n x
0 1 2
2
2 1
2 n 1
dx = wk A + A xk + A xk +    + A n xkn
0 1 2
2
2 1
2 1

1
k=1
 
A A An
= 2 A x + + +  + 2 4 2 2

3 5 (2n 1)
0

where the last step is got by explicit integration. Since this relation must be satis ed for arbitrary
A ; A ; A ;    ; A n , we obtain the conditions
1 1 2 2 1

n
X 2
wk xki =
2 2
i = 1; 2;    ; n
k=1
2i 1
Xn
wk xki = 0
2 1
i = 1; 2;    ; n
k=1
These 2n equations can, in principle, be solved for the 2n unknowns, wk and xk . One can show
that the xk s are the zeros of the Legendre polynomial Pn (x). The weights wk are also related to the
Legendre polynomials.

As a simple illustration, for n = 2 one gets the equations

w +w = 2 1 2

2
w x +w x =
2 2
1 1
3 2 2

w x +w x = w x +w x =0
1 1 2 2 1
3
1 2
3
2

with the solution

w =w = 1 1 2

1
x = x =p
3
1 2

We see that x ; x are indeed zeroes of P (x).


1 2 2

Page 141 of 164;


Integration COMPUTER PROGRAMMING-2017

The approximation
Zb n
X
f (x)dx  wk f (xk )
1
k=1

with the wk 's and xk 's determined as above, is called the Gauss-Legendre quadrature, or sim-
ply Gauss quadrature. As the above analysis shows, this procedure should, in general, prove to
be superior to the Trapezoidal rule or Simpson's rule. The accuracy of the quadrature improves with
increasing the order of the polynomial, n . For most functions and for reasonable accuracy, n = 8 is
usually quite adequate. The weights wk and the points xk are given in standard tables for di erent
values of n . Since xk are symmetric about x = 0, and the weight factors for the two symmetric
zeroes are the same, only the positive values of xk and the corresponding wk need be read in. The
negative values of xk are generated from the positive values. Thus, all one has to do in practice is
to decide upon the value of n, read wk and xk from the tables and evaluate the series on the RHS
of Equation(6.4) which gives the value of the integral on the LHS. Actually, one should perform the
calculation for two values of n, say n = 6, and n = 8 and verify that the two results agree with each
other to the desired accuracy. If the agreement is not satisfactory, a still higher value of n should be used.

The Gauss quadrature as described above applies only when the limits of integration are ( 1; 1).
However, an integral with any nite limits (a; b) can be transformed into one with limits ( 1; 1) by a
linear transformation of the independent variable:
Zb Z+1
(b a ) (a + b) (b a)
I= f (z )dz = f( + x)dx
2 2 2
a 1

where
(a + b) (b a)
z= + x
2 2
Now applying Gauss quadrature we have the result
n
(b a) X
I= wi f (zi )
2 i =1

where
(a + b) (b a)
zi = + xi (6.5)
2 2
The xi 's and wi 's are obtained from the tables, the zi 's are then obtained from xi 's with the help
of Equation(6.5), the given function f (z ) is evaluated at these points and the series on the RHS is
evaluated. Finally the result is multiplied by the factor b a to obtain the value of the integral.
(

2
)

Page 142 of 164;


Integration COMPUTER PROGRAMMING-2017

6.3.2 Gauss-Laguerre Quadrature


Approximating integrals over the semi-in nite interval (0; 1), by a sum:
Z1 n
X
e f (x)dx 
x
wk f (xk )
0
k=1

is known as Gauss-Laguerre quadrature. [note that only f (xk ) appears on the RHS in
the sum and not the full integrand e xk f (xk ) .] The weights wk and the points xk are obtained
from considerations similar to the case of Gauss Quadrature, viz., that the series on the RHS give exact
results whenever is an arbitrary polynomial of order 2n 1 . In the present case it turns out that the
xk 's are zeros of the Laguerre polynomial Ln (x) and wK 's are also related to the Laguerre polynomials.
Again, wk and xk are available in standard tables.

6.3.3 Gauss-Hermite Quadrature


This quadrature is used to evaluate integrals over the interval ( 1; 1) using the approximation:
Z1 n
X
x2
e y(x)dx  wk y(xk )
1 k=1

where xk 's are the zeros of the Hermite polynomial Hn (x) and the weights wk 's are also related to
the Hermite polynomials. As in the case of the Legendre polynomials, zeros of the Hermite polynomials
are also placed symmetrically about the origin and therefore the number of data points to be fed to the
computer is halved. The xk s and wk s can be read from the tables.

6.3.4 General Considerations & Programming Tips


Keying in the data every time we wish to evaluate an integral is not a good programming practice. One
should key the data in a le and include this le in the program using the #INCLUDE metastate-
ment. Since Gauss-Legendre, Gauss-Laguerre and Gauss-Hermite quadratures use di erent sets of zeros
and weights, it is best to make three include les and use them according to the integral to be evaluated.

To make such a le for various values of n one uses the switch statement. This statement tests a
single expression and provides di erent actions depending on its value. The general form of switch is
as follows:

switch (n)

Page 143 of 164;


Integration COMPUTER PROGRAMMING-2017

f
case 1:

[ statements ]

break ;

case 2:

[ statements ]

break ;

. . .

g
In this example, if n has value 1, the statements following case 1 : are executed (notice the colon
after 1). If n = 2, then statements following case 2 : are executed and so on. So for di erent val-
ues of n, we can store zeros and weights in the form of arrays and can call them for the desired value of n.

The three les, GAUSS.C, LAGUERRE.C and HERMITE.C have been provided to you in the
include directory. These contain the data for the Gauss-Legendre, Gauss-Laguerre and Gauss-Hermite
quadratures respectively, for some speci c values of n: n = 4,6,8,10,12 for Gauss-Legendre and Gauss-
Hermite; n = 4,6,8,10 for Gauss-Laguerre quadrature. The required le must be included only
after n has been de ned. For example, if you wish to nd an integral using the Gauss quadrature
for n = 8 then your program may be
main ( )

f ...

n = 8;

#i n c l u d e < >
GAUSS . C

R For all three quadratures, the points xi and the weights wi are represented by
arrays x[i] and w[i] respectively. Hence, in your program also you are obliged to use
the same variable names, x[i] and w[i]. Also note that the index, i, begins with zero
and not 1. Further, due to the symmetry of the zeros and weights for the Gauss and
Gauss-Hermite quadratures, the index runs from 0 to ( n 1): only half the values are
2

supplied in the table, the other half have to be generated by symmetry. For Laguerre
quadrature the index runs from 0 to (n 1).

As an example, consider the integral


Zb
arctan x
a = 5; b = 10
x2

a
We can of course do it using the Trapezoidal method or Simpson method. However, let us see how
it can be done using the Gauss-Legendre Quadrature. Recall that the standard limits for the integral
in Gauss Quadrature is 1 to 1 while here we have 5 to 10. So we need to use Eq 6.5 to nd the
corresponding zi to the xi . The program can then be as follows:

Page 144 of 164;


Integration COMPUTER PROGRAMMING-2017

#include< stdio .h >


#include< stdlib .h >
#include< math . h >
#define f (x) ( atan ( x ) / ( ( x )  (x)))

main ( )

f float c , d , z , z1 , x [ 2 0 ] , w [ 2 0 ] , a = 5 . 0 , b = 1 0 . 0 , s ;

int i , n =6;

#i n c l u d e < GAUSS . C >


c =0.5  ( b+a ) ; d = 0 . 5  (b a );

s =0.0;

for ( i =0; i < =n / 2 1 ; i ++)

f z =( c+d  x [ i ] ) ; z 1=c d x[ i ];

s+=w [ i ]  ( f ( z )+ f ( z 1 ) ) ; g

s =d ;

p r i n t f ( " s=%f " , s ) ;

Note that the for loop runs from 0 to n 1 because remember that the array x[i] and w[i] run from
2

i = 0 to n 1 and the weights and the zeroes, that is w[i] and x[i] are symmetric. Thus for n = 6
the zeroes are x[0]; x[1]; x[2]. So the for loop reads the zeroes alternately for z and z 1 above where
 
z = b a + b a x[i] and z 1 = b a
+
2 2
b a x[i]. +
2 2

Similar programs can be written for evaluating semi-in nite integrals (with limits 0; 1 ) using La-
guerre quadrature and in nite integrals (with limits 1; 1 using Hermite quadrature.

R Some of the common errors & good practices while using gnuplot

1. While using Trapezoidal Rule, the larger the number of segments, the better is
the accuracy
2. In Simpson's Rule algorithm, make sure that the value of n is even.
3. The for loop for the odd and even terms starts at 1 and 2 and has an increment
of 2.
4. The weights with which the odd and even summations are multiplied are di er-
ent. It is 4 in the odd case where the loop starts from i = 1 and 2 in the even
case where the loop starts from 2.

Page 145 of 164;


Integration COMPUTER PROGRAMMING-2017

5. Remember to divide the result of the sum of the areas obtained in Simpson's rule
by 3.
6. While using quadratures, care should be taken to include the le GAUSS.C or
HERMITE.C or LAGUERRE.C only AFTER de ning the integer variable n and
specifying its value.
7. While using the quadratures, remember that the arrays run from 0 onwards and
NOT 1. The for loops therefore which reads the arrays should always start from
0.
8. The zeroes of the Gauss and Hermite quadratures are symmetrical and therefore
the for loops should run from 0 to n 1. For Laguerre quadrature, the for loop
2

should run from 0 to (n 1).

6.4 Problems
1. Integrate the following functions to an accuracy of 1 in 10 for given limits a and b:
5

a)
arctan x
; a = 5; b = 10 (0:142208)
x 2

Use Trapezoidal, Simpson & Gauss Quadrature.

b)
x2
e log(1 + x ); 2
a= 1; b = +1 (0:587080; 10 pt)
c)
e x log(1 + x); a = 0; b = +1 (0:596387; 8 pt)

#include< stdio .h >


#include< stdlib .h >
#include< math . h >
#define f (x) ( atan ( x ) / ( ( x )  (x)))

main ( )

Page 146 of 164;


Integration COMPUTER PROGRAMMING-2017

f float c , d , z , z1 , x [ 2 0 ] , w [ 2 0 ] , a = 5 . 0 , b = 1 0 . 0 , s ;

int i , n =6;

#i n c l u d e < GAUSS . C >


c =0.5  ( b+a ) ; d = 0 . 5  (b a );

s =0.0;

for ( i =0; i < =n / 2 1 ; i ++)

f z =( c+d  x [ i ] ) ; z 1=c d x[ i ];

s+=w [ i ]  ( f ( z )+ f ( z 1 ) ) ; g

s =d ;

p r i n t f ( " s=%f " , s ) ;

#include< stdio .h >


#include< math . h >
#define f (x) ( atan ( x ) / ( ( x )  (x)))

#define pi 3.14159

main ( )

f
float s , a , b , s1 , s2 , h , k ;

int i , N= 8 0 0 0 0 ;

a =10.0; b=200.0;

h=(b a ) /N ;

s =0.0;

for ( i =1; i < =N 1 ; i +=2)

f
s +=4  f ( a+ i  h )+2  f ( a +( i +1)  h);

g
s 2=s+ f ( a )+ f ( b ) ;


s 2 =h / 3 ;

p r i n t f ( " a=%f b=%f i n t e g 2=%f n n" , a , b , s 2 ) ;

#include< stdio .h >


#include< math . h >
#define f (x) ( l o g (1+( x )  (x)))

main ( )

f float w [ 1 2 ] , x [ 1 2 ] , s1 , s2 , s = 0 . 0 ;

int i ,n;

n =10;

#i n c l u d e < HERMITE . C >


for ( i =1; i < =n / 2 ; i ++)

Page 147 of 164;


Integration COMPUTER PROGRAMMING-2017

f s 1=x [ i 1];

s 2= x [ i 1];

s +=(( f ( s 1 )+ f ( s 2 ) )  w[ i 1]);

p r i n t f ( "%f n n" , s ) ;

g
g

#include< stdio .h >


#include< math . h >
#define f (x) ( l o g (1+( x ) ) )

main ( )

f float w [ 1 4 ] , x [ 1 4 ] , s1 , s = 0 . 0 ;

int i ,n;

n =10;

#include< LAGUERRE . C >


for < ( i =1; i =n / 2 ; i ++)

f s 1=x [ i 1];

s +=( f ( s 1 )  w[ i 1]);

p r i n t f ( "%f n n" , s ) ;

g
g

2. The time period of a pendulum is given by the integral



Z2
1
T =4  dz
1 sin 2 A
2
sin x
2

where Ais the amplitude of oscillations. For small amplitudes it is possible to approximate the
time period to
"  2 #
A
T = 2 1 +
1
4
Plot T; T and the percentage di erence between T and T as functions of A for 0 < A < .
1 1

Page 148 of 164;


Integration COMPUTER PROGRAMMING-2017

#include< stdio .h >


#include< math . h >
float floatf ( A1 , float z)

f float p;

p=1.0/(1.0 s i n ( A1 / 2 )  s i n ( A1 / 2 )  sin (z)  sin (z ) );

return (p ) ;

g
main ( )

f float A1 , a , b , z 1 , z 2 , s , s a n , p i = 3 . 1 4 1 5 9 , h , P ;

float float f ( A1 , float z );

int i , n =1000;

FILE  f p=NULL ;

f p=f o p e n ( " r e s . t x t " , "w" ) ;

for ( A1 = 0 . 1 ; A1 < p i ; A1+=0.1)

f b=p i / 2 . 0 ; a = 0 ; s = 0 ; h=(b a )/n ;

for ( i =0; i < =n 1 ; i +=2)

f s +=4  f ( A1 , a+ i  h )+2  f ( A1 , a +( i +1)  h);

g
s=s+ f ( A1 , a )+ f ( A1 , b ) ;

s  
=4 h/3.0;

san =2.0  
pi ( 1 + ( A1 / 4 . 0 )  ( A1 / 4 . 0 ) ) ;

p r i n t f ( "%f ,% f ,% f n n " , s , s a n , A1 ) ;

P=( s san )/ s ;

f p r i n t f ( f p , "%f n t%f n t %f n t %f n n " , A1 , s , s a n , P ) ;

g
g

The plot will look like as in Figure 6.2

Page 149 of 164;


Integration COMPUTER PROGRAMMING-2017

Pendulum Time period vs Amplitude


90
Integrated
Approximation
80 percentage difference

70

60

50

40

30

20

10

0
0 0.5 1 1.5 2 2.5 3

Figure 6.2: Time period of pendulum vs Amplitude

3. Let R() be the polar coordinates of a particle moving under a central force. Then  is given as a
function of R by the expression:

ZR
dr
 (R ) = h    i1
mV (r) 2
r0 r 2 mE
2
l2
2

l2
1
r2

Plot the orbit of the particle for V (r) = kr (inverse square law force). Use Gauss quadrature for
the evaluation of the integral. The upper limit,R is to be varied from r to rm , where r and rm 0 0

are the two zeroes of the factor in the square brackets. Take m = l = k = 1 and

i) E = 0:25 ( This gives r = 0:6; rm = 3:4


0 approximately)
ii)E = 0(r  0:5; rm  5)
0

4. Locate the smallest positive root of the function F (x) , given by:

Page 150 of 164;


Integration COMPUTER PROGRAMMING-2017

Z
F (x) = cos [xa cos(t)] sin n tdt 2 +1

to an accuracy of 4 signi cant gures, for n = 1 and a = 1:5.

#include < stdio .h >


#include < math . h >
#define g(x , z ) ( ( c o s ( pow ( x , 1 . 5 )  cos (( z ) ) ) )  pow ( s i n ( ( z ) ) , 3 ) )

#define pi 3.14159

main ( )

f
float x , xmin =0 ,xmax = 1 0 . 0 , x i n c = 0 . 5 , t e s t , x l , x1 , x2 , x3 , a c c = 0 . 0 0 0 0 1 , z ;

int fact ( int n); float f ( float x); int l s =0;

for ( x=xmin ; x < =xmax ; x+=x i n c )

f t e s t=f ( x )  f ( x+x i n c ) ;

if ( test < 0)

f l s = 1 ; x 1=x ; x 2=x+x i n c ;

do
f x3 = ( x1  f ( x2) x2  f ( x1 ) ) / ( f ( x2) f ( x1 ) ) ;

x1 = x2 ; x2 = x3 ; z = f a b s ( x1 x 2 ) ; l s ++;

g
while ( f a b s ( z) > acc ) ;

p r i n t f ( " r o o t=%f , f n=%f , a c c=%f n n " , x3 , f ( x 3 ) , a c c ) ;

break ;

ggg
float f ( float x)

f float a ,b, s ,h,k; int i , N= 8 0 0 ; a = 0 . 0 ; b=p i ;

h=(b a ) /N ;

s =0.0;

for ( i =1; i < =N 1 ; i +=2)

f 
s +=4 g ( x , a+ i  h )+2  g ( x , a +( i +1)  h); g
s=s+g ( x , a )+ g ( x , b ) ; s  =(h / ( 3  
2 pi ) ) ;

return ( s ); g

The lowest root obtained is at 2:723019.

5. Use the integral representation of the Bessel function:

Z2
1
Jn (z ) = cos(z cos(x))dx
2
0

to nd its zeroes in the range 0  z  12 by secant method.

Page 151 of 164;


Integration COMPUTER PROGRAMMING-2017

#include < stdio .h >


#include < math . h >
#define g(x , z ) ( cos (x  cos ( z ) ) )

#define pi 3.14159

main ( )

f
float x , xmin =0 ,xmax = 1 2 . 0 , x i n c = 0 . 5 , t e s t , x l , x1 , x2 , x3 , a c c = 0 . 0 0 0 0 1 , z ;

int fact ( int n); float f ( float x); int l s =0;

for ( x=xmin ; x < =xmax ; x+=x i n c )

f t e s t=f ( x )  f ( x+x i n c ) ;

if ( test < 0)

f l s = 1 ; x 1=x ; x 2=x+x i n c ;

do
f x3 = ( x1  f ( x2) x2  f ( x1 ) ) / ( f ( x2) f ( x1 ) ) ;

x1 = x2 ; x2 = x3 ; z = f a b s ( x1 x 2 ) ; l s ++;

g
while ( f a b s ( z) > acc ) ;

p r i n t f ( " r o o t=%f , f n=%f , a c c=%f n n " , x3 , f ( x 3 ) , a c c ) ;

ggg
float float f ( x)

f float a ,b, s ,h,k; int i , N= 8 0 0 ; a = 0 . 0 ; b=2  pi ;

h=(b a ) /N ;

for (k =1.0;k < = 1 2 . 0 ; k +=0.2)

f s =0.0;

for ( i =1; i <=N 1 ; i +=2)

f 
s +=4 g ( x , a+ i  h )+2  g ( x , a +( i +1)  h); g
s=s+g ( x , a )+ g ( x , b ) ; s  =(h / ( 3  
2 pi ) ) ;

g return ( s ); g

The zeroes of the Bessel function in this interval are found to be 2:403629; 3:518313; 8:651533
and 11:788982.

6. The spherical Bessel function of order n is given by

Z
zn
jn (z ) = cos(z cos ) sin n d
2 +1

2n n!
+1

Find all the roots of j (z ) between 0 and 10. 1

#include < stdio .h >


#include < math . h >

Page 152 of 164;


Integration COMPUTER PROGRAMMING-2017

#define g(x , z ) ( cos (( x)  cos (( z ) ) )  ( pow ( s i n ( ( z ) ) , 3 ) ) )

#define pi 3.14159

main ( )

f
float x , xmin =0 ,xmax = 1 0 . 0 , x i n c = 0 . 5 , t e s t , x l , x1 , x2 , x3 , a c c = 0 . 0 0 0 0 1 , z ;

float f ( float x); int l s =0;

for ( x=xmin ; x < =xmax ; x+=x i n c )

f p r i n t f ( "%f ,% f n n" , x , f ( x ) ) ;

t e s t=f ( x )  f ( x+x i n c ) ;

if ( test < 0)

f l s = 1 ; x 1=x ; x 2=x+x i n c ;

do
f x3 = ( x1  f ( x2) x2  f ( x1 ) ) / ( f ( x2) f ( x1 ) ) ;

x1 = x2 ; x2 = x3 ; z = f a b s ( x1 x 2 ) ; l s ++;

g
while ( f a b s ( z) > acc ) ;

p r i n t f ( " r o o t=%f , f n=%f , a c c=%f n n " , x3 , f ( x 3 ) , a c c ) ;

/ break ;  /

ggg
float f ( float x)

f float a ,b, s ,h,k; int i , N= 8 0 0 ; a = 0 . 0 ; b=p i ;

h=(b a ) /N ;

s =0.0;

for ( i =1; i < =N 1 ; i +=2)

f 
s +=4 g ( x , a+ i  h )+2  g ( x , a +( i +1)  h);

g
s=s+g ( x , a )+ g ( x , b ) ;

s  =( h / ( 3   2 pi ) ) ;

return  (x s /4.0); g

The roots are at z = 0; 4:49 and 7:73.

Page 153 of 164;


Chapter 7

Matrices
7.1 Introduction
In Physics, we are all familiar with vectors and matrices. For instance, the position vector, the electric
eld vector etc. are examples of vectors. Though in general vectors are de ned as objects in any space
which have a speci c property under rotations about an axis, we usually choose a basis and then the
vector is speci ed in terms of the projections on the basis. Thus, in 3-dimensions, we usually choose
the mutually perpendicular x; y; z basis and then any vector is simply a set of three numbers giving
us the components or projections along these three directions. For instance, we can represent a vector
X~ = 2^x + 5^y + 7^z as
2 3
2
X~ = 6
4 5 7
5
7
Similarly, there are many instances where we use matrices in Physics. The rotation matrix is one
example. In general, whenever we have tensors of rank 2, we can write them as matrices. Thus the
rotation matrix in two dimensions, R can be written as
" #
cos  sin 
R=
sin  cos 
We are already familiar with the use of numbers (both integers and oating point numbers) in C
programming. In this Chapter, we shall see how to manipulate vectors and matrices.

7.2 Arrays in C
An array is a collection of data items, all of the same type, accessed using a common name. A one-
dimensional array is like a list,a two dimensional array is like a table. C language places no limits

154
Matrices COMPUTER PROGRAMMING-2017

on the number of dimensions in an array. Some texts refer to one-dimensional arrays as vectors, two-
dimensional arrays as matrices, and use the general term arrays when the number of dimensions is
unspeci ed or unimportant. All arrays consist of contiguous memory locations. The lowest address
corresponds to the rst element and the highest address to the last element.

You already know that a simple variable like x (which may be of type oat or int), can be as-
signed only one value at a time. Once a new value is assigned to x, the earlier value is lost. While
such variables suce for most purposes, some applications, in particular those involving vectors and ma-
trices, need variables with indices, such as xi or aij . These variables constitute arrays. For example,
x ; x ; x ; x form the elements of a one-dimensional array. Similarly, a ; a ; a ; a ; a ; a ; a ; a ; a ,
0 1 2 3 00 01 02 10 11 12 20 21 22

are the elements of a two-dimensional array of 3 rows and 3 columns. A two-dimensional array of
m rows and n columns is said to be of order m  n.

7.2.1 Declaration of Arrays


Like `ordinary' variables, arrays also have to be `declared'. If the elements of an array are
numbers of type oat, the array is also of type oat, and is declared as such along with other variables
of type oat. If the elements are intended to be all integers, the array is of type int and declared
accordingly.
Array variables are declared identically to variables of their data type, except that the variable name is
followed by one pair of square [ ] brackets for each dimension of the array. That is , a variable is declared
as an array by using square brackets along with its name. Uninitialized arrays must have the dimensions
of their rows, columns, etc. listed within the square brackets. Dimensions used when declaring
arrays in C must be positive integral constants or constant expressions. For example,
int i , j , intArray [ 10 ] , number ;

float floatArray [ 1000 ];

int tableArray [ 3 ][ 5 ];

are all valid examples of declaring arrays. In the above, the array intArray is a 1-dimension has
10 elements which are integer variables while the array oatArray is a 1-dimensional array of size
1000 oating point numbers. Similarly, the array tableArray is a 2-dimensional array of 3 rows and 5
columns lled with oating point numbers.

7.2.2 Initializing & Using Arrays


Arrays may be initialized when they are declared, just as any other variables. The initialization data is
placed in curly braces following the equals sign. Each entry is separated by a comma. An array
may be partially initialized, by providing fewer data items than the size of the array. The remaining
array elements will be automatically initialized to zero.

Page 155 of 164;


Matrices COMPUTER PROGRAMMING-2017

Like simple variables, elements of arrays can also be assigned values in the declaration statement. For
example, we may have statements of the following kind in a program:

float x[3] = f 1.0 ,2.0 ,3.0 g , y,z ,h = 0.1;

int i , j =1 , a [ 5 ] = f 5 ,3 ,11 ,2 ,3 g ;

float m[ 2 ] [ 3 ] = ff 0.1 ,0.2 ,0.3 g f , 0.4 ,0.5 ,0.6 gg ;

Notice the use of curly brackets in assigning values to the elements of arrays. The
declaration and initialization of the array m[2][3] above generates the matrix
" #
0:1 0:2 0:3
m=
0:4 0:5 0:6
since in C arrays are read row by row. Once an array has been initialized in the manner explained
above, its elements can be called in the program by its indices. For example, within an expression,
a[2][3] means the element a . 23

R Thus, in the declaration statement, a[2][3] denotes a two-dimensional array of


two rows and three columns, while in an expression a[2][3] refers to a particular element
of the array, viz., the element a . So be careful! 23

Now that we have declared the arrays, how do we use them?


Elements of an array are accessed by specifying the index of the desired element within square [ ]
brackets after the array name. Array subscripts must be of integer type.

R Array indices start at zero in C, and go to one less than the size of the array.
For example, a ve element array will have indices zero through four. The elements of the array
x[3] are x[0]; x[1] and x[2]. This is because the index in C is actually an o set from the beginning
of the array. The most common mistake when working with arrays in C is forgetting that indices
start at zero and stop one less than the array size. Arrays are commonly used in conjunction with
loops, in order to perform the same calculations on all ( or some part ) of the data items in the
array. Moreover, the indices can have only non-negative integer values.

To illustrate these points, consider this simple program to generate the rst 10 Fibonacci numbers.
Recall that each Fibonacci number is the sum of two previous Fibonacci numbers.

#i n c l u d e < stdlib .h >

Page 156 of 164;


Matrices COMPUTER PROGRAMMING-2017

#i n c l u d e < stdio .h >


main ( )

f
int i ; /  declaring an integer variable i  /

int fibonacci [ 10 ]; /  declaring a 1 dimensional integer array fibonacci with 10 elements  /

fibonacci [ 0 ] = 0; /  Initialising the first element of the array fibonacci  /

fibonacci [ 1 ] = 1; /  Initialising the second element of the array fibonacci  /

for ( i = 2; i < 10; i++ )

fibonacci [ i ] = fibonacci [ i 2 ] + fibonacci [ i 1 ];

for ( i = 0; i < 10; i++ )

printf ( " Fibonacci [ %d ] = %f n n" , i , fibonacci [ i ] );

This will generate the following output:

Fibonacci[0]=0
Fibonacci[1]=1
Fibonacci[2]=1
Fibonacci[3]=2
Fibonacci[4]=3
Fibonacci[5]=5
Fibonacci[6]=8
Fibonacci[7]=13
Fibonacci[8]=21
Fibonacci[9]=34

Compare this with the program you would have written in Problem 5 in Chapter 1 to see how the use
of arrays makes things simpler.
As an example of the use of 2-dimensional arrays, consider the following sample program which adds 2
2  3 matrices and prints the result.

#i n c l u d e < stdio .h >


main ( )

f float a [2][3] = ff 0.1 ,0.2 ,0.3 g f


, 0.2 , 0.4 , 0.6 gg ;

float b [2][3] = ff 0.3 ,0.4 ,0.5 g f , 0.6 ,0.7 ,0.8 gg ;

float c [ 2 ] [ 3 ] ;

Page 157 of 164;


Matrices COMPUTER PROGRAMMING-2017

int i , j ;

for ( i =0; i < =1; i ++)

f for ( j =0; j < =2; j ++)

f c [ i ][ j ] = a[ i ][ j ] + b[ i ][ j ];

p r i n t f ( "%f n t" ,c [ i ] [ j ] ) ; g
printf (" n n" ) ; g g

Run this program and see the output. The output will be in the form of a matrix.

" #
:4 :6 :8
:4 :3 :2
This has been accomplished by using two printf statements, one in the inner loop and one in the outer
loop. If the second printf statement is omitted, the output will place all the elements in a single row.

We must be careful while declaring the order of an array. C does not check array bounds. The
statement:

float a [ 3 ] [ 3 ] ;

means that a has been declared as an array with three rows and three columns. If somewhere in the
program we use a[4][5] in some expression, no error message will be sent but the output that is produced
may be total garbage. It is safer to declare an array of order higher than we are likely to use in the
program.

7.3 The Function matalloc


The above method of declaring arrays has some drawbacks. We are most used to de ning the indices of
the rows and columns of matrices (as well as rows for vectors) starting from 1. Recall that the elements
of an m  n matrix A, are usually written as

aij i = 1; 2;    ; m j = 1; 2;    ; n
In C, as we have seen above, the arrays, whether one or two dimensional, have their indices starting
from 0. This is obviously inconvenient. However, there is a more serious matter. The way in which
we have described arrays above, allows us to de ne an array of a xed size only. Thus if we have
written a program for inverting a 5  5 matrix, it can be used to invert only a 5  5 matrix. For
inverting, say a 10  10 matrix a totally new program will have to be written. This is of course very

Page 158 of 164;


Matrices COMPUTER PROGRAMMING-2017

cumbersome. What we would like to do is to develop general programs for various matrix operations as
function programs and then use these functions for matrices of a speci c order in a particular application.

In the absence of knowledge of the order of the matrices, how do we make declarations to reserve
memory for storing them in the memory space of the computer, or call and use programs that have
been developed for matrices of any order? In C, this problem is solved by using the functions called
malloc and calloc. These functions are contained in the header le stdlib.h and this le
must, therefore, be included at the top of the program. These functions allocate contiguous
blocks of memory via pointers. The functions calloc and malloc have a similar purpose; calloc has
the additional feature that it sets initial values of all elements to zero. These functions are used for
dynamic memory allocation in C which is very useful especially in dealing with arrays.

We have written a function oat **matalloc(int m, int n) that allocates memory space to an m  n
matrix. This function will generate a column vector if we put the number of columns equal to one (i.e.
n = 1.) and a row vector if m = 1. So, no separate function is required to generate vectors. This
program has been written in such a way that the indices take values starting with 1 in accordance with
the standard notation familiar to us. It is contained in the le <MAKEMAT.C> in the include
directory, and you can access it via #include <MAKEMAT.C>.

To illustrate use of the above function, we give below a program that calls this function to allocate
memory space to two matrices, a and b, assigns elements to the matrix a, makes a copy of this matrix
(the matrix b) and then prints the matrix b. Here the elements of the matrix a are given by the formula:
i +j
i; j = 1; 2;    ; n
2 2

aij =
i + 2j + 2

#i n c l u d e < stdio .h >


#i n c l u d e < stdlib .h >
#i n c l u d e < math . h >
#i n c l u d e < MAKEMAT. C >
main ()

f int i , j ,m=3 , n =2;

float  a ,  b;

a = matalloc (m, n ) ; b = matalloc (m, n ) ;

/  now we can give elements of the matrices  /

for ( i =1; i <


=m; i ++)

f for ( j =1; j <=n ; j ++)

f a [ i ] [ j ]=( float )( i  i+j  j )/( float ) ( i +2  j +2); b [ i ] [ j ]= a [ i ] [ j ] ;

p r i n t f ( "%f n t" , b[ i ][ j ]); g printf (" n n" ) ; g g

Page 159 of 164;


Matrices COMPUTER PROGRAMMING-2017

In the above program, note the use of the pointer for the 2-dimensional arrays (matrices) a and b.
Essentially think of the 2-dimensional array as a pointer to a pointer to a oating point number (in the
case where the entries of the array are of the type oat as above. If the entries are of the type int,
then the array can be thought of as a pointer to a pointer to an integer. (For details of pointers, see
the Advanced Topic on pointers, Section 1.8 in Chapter ??.
If we have to allocate memory space for two matrices a and b of size 2  3 and 3  5 respectively, then
the rst, second and third lines after main() in the above program would be replaced by:
int m=2 , n =3 , l = 5 ;

float   a, b;

a = m a t a l l o c (m, n ) ; b = matalloc (n , l ) ;

However, note that the facility of assigning values to various elements of a matrix while
de ning it, viz.:
float a [2][3] = ff 0.1 ,0.2 ,0.3 g f
, 0.2 , 0.4 , 0.6 gg ;

float b [2][3] = ff 0.3 ,0.4 ,0.5 g f , 0.6 ,0.7 ,0.8 gg ;

is lost when a matrix is de ned via the function matalloc. So, each element may have to be assigned
its numerical value individually. Thus, for example
. . .

. . .

for ( i =1; i <


=n ; i ++)

f for ( j =1; j <


=m; j ++)

f s c a n f ( "%f " ,& x ) ; a [ i ] [ j ]= x ; gg


allows you to enter the values of the n  m elements, a[i][j ], one at a time. Also note that there is a
problem with the statement:
f
s c a n f ( "%f " ,& a [ i ] [ j ] )

g
Instead one has to use

f
s c a n f ( "%f " ,& x ) ; a [ i ] [ j ]= x ;

R Some of the common errors & good practices

1. Dimensions of arrays must always be declared a integers.


2. Arrays in C are read row by row.
3. The array indices in C start at 0 and run to one less than the size of the array.

Page 160 of 164;


Matrices COMPUTER PROGRAMMING-2017

4. Make sure the header le stdlib.h is included in your program.


5. By including the le makemat.c one can start the array indices at 1.
6. C does not check array bounds. So be careful of declaring the arrays of sucient
size.

7.4 Problems
1. Create separate functions for (a) adding, (b) subtracting, (c) multiplying, (d) printing and (e)
nding trace of matrices and (f) transferring elements of one matrix to another. For example:

void matprint ( float  int a , m, int n)

f int i , j ;

for <
( i =1; i =m; i ++)

f for <
( j =1; j =n ; j ++)

f printf ( %f n t ,a [ i ] [ j ] ) ; g printf ( n n ); g g
is the function to print an m  n matrix a. The statement (in main) to print a l  m matrix x
will simply be matprint(x,l,m);. Note that  is present along with the name of the
matrix in the function but not in the calling program. Also note that most of these
programs are of the type void. The value of the calculated matrix is not returned to
the main program in the usual way.
Test each individual function by using it in a short program to check if it is working. Once you have
checked all the individual functions, make a le called matops.c of these functions by assembling
them together. This le obviously cannot be used by itself in a standalone fashion, since it only
has functions listed in it. But now, whenever you have any program to write with matrices, you
just include this le that is write #include < matops.c> in the program and call the relevant
functions to carry out print, copy, add or multiply etc. operations on the matrices in your program.

/  this is a subroutine for transferring elements of the matrix a

into those of b  /

void mattrans ( float  float  int a , b, m, int n)

f
int i , j ;

Page 161 of 164;


Matrices COMPUTER PROGRAMMING-2017

for ( i =1; i < =m;++ i )

for ( j =1; j <=n;++ j )

b [ i ] [ j ]= a [ i ] [ j ] ;

g
/  this is a subroutine for addition of two mxn matrices  /

void matadd ( float  float  float  int


a , b, c , m, int n)

f
int i , j ;

for ( i =1; i < =m;++ i )

for ( j =1; j <=n;++ j )

c [ i ] [ j ]= a [ i ] [ j ]+ b [ i ] [ j ] ;

g
/  this is a subroutine for subtraction of mxn matrix b from matrix a  /

void matsub ( float  float  float  int


a , b, c , m, int n)

f
int i , j ;

for ( i =1; i < =m;++ i )

for ( j =1; j <=n;++ j )

c [ i ] [ j ]= a [ i ] [ j ] b[ i ][ j ];

g
/  this is a subroutine for multiplying two matrices of order lxm and mxn  /

void matmult ( float  float  float  int


a , b, c , l , int m, int n)

f int i , j ,k;

for ( i =1; i < =l ; i ++)

for ( j =1; j < =n ; j ++)

f c [ i ] [ j ]=0.0;

for ( k =1; k <=m; k++)

c [ i ] [ j ]+=a [ i ] [ k ]  b[k ][ j ];

g
g

/  this is a subroutine for printing elements of the mxn matrix a  /

void matprint ( float  int a , m, int n)

f
int i , j ;

printf (" n n" ) ;

for ( i =1; i < =m;++ i )

f for ( j =1; j < =n;++ j )

p r i n t f ( "%f " ,a [ i ] [ j ] ) ;

printf (" n n" ) ;

Page 162 of 164;


Matrices COMPUTER PROGRAMMING-2017

2. Write a program which will generate two 4  4 matrices a and b, where aij = i i j and bij = i j j , ( + ) ( + )

obtain the commutator c = [a; b] and print its elements in a matrix format. Your program should
use the program matops.c that you have written in the previous problem.

#include< stdio .h >


#include< math . h >
#include< stdlib .h >
#include< MAKEMAT. C >
#include " matops . c "

main ( )

f
float  a ,  b,  c ,  d,  e ;

int m=2 , n =2 , l =2 , i , j ;

a = m a t a l l o c (m, n ) ;

b = m a t a l l o c (m, n ) ;

c = m a t a l l o c (m, n ) ;

d = m a t a l l o c (m, n ) ;

e = m a t a l l o c (m, n ) ;

for ( i =1; i <


=m; i ++)

f
for ( j =1; j < =n ; j ++)

f
a[ i ][ j ] = ( float )( i )/( float ) ( i+j ) ;

b[ i ][ j ] = ( float )( j )/( float ) ( i+j ) ;

g
g
matmult ( a , b , c , m, n , l ) ;

p r i n t f ( "A n " ) ; n m a t p r i n t ( a , m, n ) ;

p r i n t f ( "B n n" ) ; m a t p r i n t ( b , m, n ) ;

p r i n t f ( "C = A  n
B n" ) ; m a t p r i n t ( c , m, n ) ;

for ( i =1; i < =m; i ++)

f
for ( j =1; j < =n ; j ++)

f
b[ i ][ j ] = ( float )( i )/( float ) ( i+j ) ;

a[ i ][ j ] = ( float )( j )/( float ) ( i+j ) ;

g
g
matmult ( a , b , d , m, n , l ) ;

p r i n t f ( "D = B  n
A n" ) ; m a t p r i n t ( d , m, n ) ;

matsub ( c , d , e , m, n ) ;

Page 163 of 164;


Matrices COMPUTER PROGRAMMING-2017

p r i n t f ( "E = A B   n
B A n" ) ;

m a t p r i n t ( e , m, n ) ;

Page 164 of 164;

You might also like