Computational Physics
Computational Physics
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
Page 2 of 164;
CONTENTS COMPUTER PROGRAMMING-2017
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.
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.
5
Introduction COMPUTER PROGRAMMING-2017
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.
Page 6 of 164;
Introduction COMPUTER PROGRAMMING-2017
$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.
$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.
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
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.
$emacs &
This will open a new screen. Using keyboard, type the following program:
Program 1.1
/ This program prints ` `My First C programme ' ' /
f
p r i n t f ( "My First C program n n" ) ;
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.
$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.
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
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.
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.
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.
f
float x,y;
y = sin (x );
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,
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
$ ./a.out
If every thing goes well the message in the seventh line will be printed on the screen that is
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.
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
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
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:
f
float x, x1 , x2 , y, dx , pi ;
int i , n =20;
pi = 4.0 atan ( 1 . 0 ) ;
x1 = x1 pi ;
x2 = x2 pi ;
dx = ( x2 x1 ) / ( float )(n );
f x = x1 + i dx ;
y = sin (x );
g
g
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:
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.
f
x = x1 + i dx ;
y = sin (x );
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.
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 );
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
i =0; n =20;
while < (i =n )
f x = x1 + i dx ;
y = sin (x );
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.
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.
Page 22 of 164;
Introduction COMPUTER PROGRAMMING-2017
An alternative program
f
float x , x1 , x2 , y , dx , p i ;
int i , n =20;
pi = 4.0 atan ( 1 . 0 ) ;
x1 = x1 pi ;
x2 = x2 pi ;
dx = ( x2 x1 ) / ( float )(n );
f y = sin (x );
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
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.
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.
Example 1.4
/
float f ( float x)
f
float z ;
return (z );
g
/ Main function which will call above function /
main ( )
f
float y;
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" ) ;
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
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:
main ( )
f
float y;
p r i n t f ( " Supply the value for which you want to evaluate the function n n" ) ;
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
Page 27 of 164;
Introduction COMPUTER PROGRAMMING-2017
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 ;
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:
/
f
float y , z =1.0;
int i ;
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 /
main ( )
f
float q;
int 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.
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.
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".
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 ) ;
statement ( s ) ;
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 :
break ;
case 1 :
break ;
case 2:
break ;
case 3:
break ;
case 4 :
break ;
default :
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
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.
f
float f ( float x, int n);
g
float f ( float x, int n)
f
y=x ;
return (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
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:
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
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
Operator Meaning
+ Addition
- Subtraction
* Multiplication
/ Division
% remainder after division or modulo division
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;
g
This program will give us an output of 4; 14; 2:5; 11:5.
Page 37 of 164;
Introduction COMPUTER PROGRAMMING-2017
The usage and the meaning should be clear from the table above.
Relational operators are very useful in decision making and also in loops.
Page 38 of 164;
Introduction COMPUTER PROGRAMMING-2017
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.
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 /
f
y=s i n ( x ) ;
z=c o s ( x ) ;
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.
main ( )
f
int n, rev = 0, tem ;
tem = n ;
while ( tem != 0 )
/ Use of a top checked while loop along with the logical NOT operator /
f
rev = rev 10;
tem = tem / 1 0 ;
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 /
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:
f
int year ;
if ( y e a r %400 == 0)
/ Since there is one statement after the if condition , there is no need for f g /
else if ( y e a r %100 == 0)
else if ( y e a r %4 == 0 )
else
Page 43 of 164;
Introduction COMPUTER PROGRAMMING-2017
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.
f
int n1 , n2 , i , hcf ;
f
if ( n1%i ==0 && n2%i ==0)
hcf = i ;
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.
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);
printf (" n n Enter two numbers to find H.C. F . using Euclidean algorithm : " );
if ( hcf !=0)
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
f
int n , m, i , j , k , f l a g , np ;
float x , xi ;
np = 0 ;
f
x i= i ;
m=s q r t ( x i ) ;
j =3;
f l a g =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 ) ;
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.
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:
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;
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 /
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:
f
int pi ;
int i ;
i =220;
p i=&i ;
i =1110;
p i =5;
Page 49 of 164;
Introduction COMPUTER PROGRAMMING-2017
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
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
Page 51 of 164;
Introduction COMPUTER PROGRAMMING-2017
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.
a +b =c
2 2 2
Write a program to nd all the distinct sets of Pythagorean numbers less than 100.
/ Pythogoras triplets /
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" ) ;
f d=a a+b b;
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 /
main ( )
f
int n , m, i , j , r , d ;
f j=i ;
d =0;
while > (j 9)
f r= j % 1 0 ;
j /=10;
d+=r ;
g
d+=j ;
if ( i%d==0)
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.
f int next , f i , t 1 =0 , t 2 = 1 ;
next = t1 + t2 ;
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;
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.
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 ( )
int n, i ;
Page 54 of 164;
Introduction COMPUTER PROGRAMMING-2017
if (n < 0)
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 ) (
!
)! ! (
!
)!
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 ( )
int n, r ,c ,p;
p= f a c t ( n ) / ( ( f a c t ( n r )));
c=p / ( ( f a c t ( r ) ) ) ;
Page 55 of 164;
Introduction COMPUTER PROGRAMMING-2017
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 /
f
float a , b , c , d , r1 , r 2 ;
d = b b 4
a c ;
if (d > 0)
f
// sqrt () function returns square root
r1 = ( b+s q r t ( d ) ) / ( 2 a );
r2 = ( b sqrt (d))/(2 a );
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 );
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
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.
58
Graphics Using GNUPLOT COMPUTER PROGRAMMING-2017
$gnuplot
On the gnuplot prompt type the following lines one by one (self explanatory)
Page 59 of 164;
Graphics Using GNUPLOT COMPUTER PROGRAMMING-2017
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
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
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.
Page 61 of 164;
Graphics Using GNUPLOT COMPUTER PROGRAMMING-2017
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 plot: > set label "yield point" at 0.003, 260
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
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.
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.
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:
Exit the gnuplot and then type gv plots2.eps on the terminal command prompt to see the output.
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
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:
main ( )
f
float x , y , z , x1 ; int n;
FILE f p=NULL ;
f n = ( int )( x/(2.0 pi ) ) ;
x1 = x 2.0 pi n;
z=f a b s ( x 1 ) ;
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.
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
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
f
float x , y , r , t , x0 , y 0 ;
FILE f p=NULL ;
f y =0;
f x =4;
f y =0.75 x;
/ Circle /
main ( )
f
float x , y , r , t , x0 , y 0 ;
FILE f p=NULL ;
printf ( " Supply the values of the center coordinates and radius n n" ) ;
p r i n t f ( "%f ,% f ,% f n n " , x0 , y0 , r ) ;
f y = y 0+r sin ( t ) ;
x = x 0+r cos ( t ) ;
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"
/ Box /
main ( )
f
float x , y , r , t , x0 , y 0 ;
FILE f p=NULL ;
f y =1;
f x =5;
f y =5;
f x =1;
Page 70 of 164;
Graphics Using GNUPLOT COMPUTER PROGRAMMING-2017
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
(c) n = 2; A = 1 and = ; ; . 4 2
main ( )
f float x , y1 , y2 , a , n , d ;
FILE f p=NULL ;
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
0.8
0.6
0.4
0.2
-0.2
-0.4
-0.6
-0.8
-1
-1 -0.5 0 0.5 1
y = x 0x<
= 2 x x < 2
main ( )
f
float x , y , z , x1 ; int n;
FILE f p=NULL ;
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 ) ;
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
4. Plot jlm ()j , the square modulus of the orbital wave function for l = 3; m = 0; 1; 2; 3. The
2
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
/ wave function
/
main ( )
f
float x , x1 , y 1 ; int n;
FILE f p=NULL ;
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 );
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 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 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
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
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.
f float x , Q0 , Q1 , Q2 ;
int n;
FILE f p=NULL ;
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 ) ;
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
Page 77 of 164;
Chapter 3
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.]
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
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
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
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
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 /
f float x, t , s ;
int n, i ;
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
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 /
f float x, t , s ;
int n, i ;
do
f s = 0 . 0 ; t =1;
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" ) ;
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.
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
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.
main ( )
Page 83 of 164;
Finite & In nite Series COMPUTER PROGRAMMING-2017
FILE f p=NULL ;
x=p i / 4 . 0 ;
sum = x ; t = x ; i =1;
f
t = x x /((2 i +1) 2 i );
sum+=t ;
g
g
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.
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.
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.
f
int i ;
float PI = 4 . 0 atan ( 1 . 0 ) ;
f
i =1;
s=t=x ;
do
f
t = x x /((2 i +1)
2 i );
s+=t ;
i +=1;
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
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.
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.
f float x, t , s , f ; int n;
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 ;
g
g
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 /
/ /
#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
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 ) ;
g
f p r i n t f ( fp , " n n "EXACT RESULTS n n" ) ;
f f p r i n t f ( f p , "%f ,% f n n" , x , c o s ( x ) ) ; g
g
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
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.
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
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 ) ;
g
g
g
Page 91 of 164;
Finite & In nite Series COMPUTER PROGRAMMING-2017
0.8
0.6
0.4
0.2
-0.2
-0.4
-0.6
0 2 4 6 8 10 12 14 16
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 /
main ( )
FILE f p=NULL ;
Page 92 of 164;
Finite & In nite Series COMPUTER PROGRAMMING-2017
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
Table 3.2: F z( ) vs z
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 )
main ( )
FILE f p=NULL ;
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 ) ;
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
f (z ) = C 1 + + +
3! 6! 9!
where C = 0:35503, for z in the range 10 z 0, at intervals of 0:05.
main ( )
FILE f p=NULL ;
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 ) ;
0.8
0.6
0.4
0.2
-0.2
-0.4
-10 -8 -6 -4 -2 0 2
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
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.
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
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
/ Bisection Method /
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 ;
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 " );
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 ) ) ;
g
while > (z acc ) ;
g
g
g
g
and x be the two points close to the root x . Consider the two points on the curve y = f (x) having
2 0
xy xy
x = 1 2 2 1
3
y 2 y
1
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.
/ Secant Method /
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 ;
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 " );
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
g
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
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!
We can therefore neglect terms of order higher than h, and since f (a ) = 0 (since a is the actual
0 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
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
y = f 0 (x )(x x ) + f (x )
0 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.
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).
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 /
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 );
FILE f p=NULL ;
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 ) ;
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
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.
f
float a , b , x , f1 , f2 , h ;
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 ;
x+=h ; g
while ( f a b s ( h/x ) > acc ) ;
/ roots of exp ( a x) b
x x = 0 using bisec /
f
float x l , xm , x r , a , b , d , a c c = 0 . 0 0 0 0 1 , z ;
do
fxm = ( x l+x r ) / 2 . 0 ;
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 );
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 ;
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 ;
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 /
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 ( "%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 ;
, l s , x1 , x2 , x3 , f ( x3 , a , b ) ) ;
z = f a b s ( x1 x2 ) ;
l s ++;
g
while > (z acc ) ;
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.
f float x , x l , x r , xm , a c c = 0 . 0 0 0 0 1 , x i n c = 0 . 5 , z ;
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 )
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 ) ) ;
g
while > (z acc ) ;
break ;
g
g
float float f ( x)
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
/ plots of f (x) = x x x + a x + a
a a + 1 /
main ( )
f
float x,a , f ;
FILE f p=NULL ;
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 ) ;
gg
10
-5
-10
-2 -1.5 -1 -0.5 0 0.5 1 1.5 2
/ multiple roots of x
x x + a x + a
a a + 1 = 0 /
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 f = x
x x +a x + 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
2
roots
1.5
0.5
-0.5
-1
-1.5
-1.5 -1 -0.5 0 0.5 1 1.5
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
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 /
main ()
f
float f 1 , f 2 , h , x , t , x1 , y1 , r , a c c= 0.00001 , c ;
FILE f p=NULL ;
f x = t ;
do
f f1 = x 0.8 sin (x) t ;
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 ) ; /
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
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
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
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.
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
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
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
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
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
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.
f return (x t t + t t s i n ( pow ( t , 3 ) ) ) ; g
main ( )
FILE res1 ;
FILE res2 ;
FILE res3 ;
t i =0;
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 ) ;
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 ;
f k 1=h f (t ,x);
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
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
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.
y(x ) = y
0 0 z (x ) = z
0 0
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
1
zi = zi + (m + 2m + 2m + m )
+1
6 1 2 3 4
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.
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
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:
#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 ;
do
f k1 = h f1 ( t , y , z ) ;
m1 = h f2 ( t , y , z ) ;
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.
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
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.
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.
f
float x =0 , y = 1 . 0 , h = 0 . 0 5 , s ;
FILE res1 ;
FILE res2 ;
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);
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
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 ).
main ( )
f
float h = 0 . 0 1 , x , u , z , k1 , k2 , k3 , k4 , m1 , m2 , m3 , m4 , a ;
FILE f p=NULL ;
f
x = 0.0; u = a; z = 0;
do
f k1 = h f1 (x , u , z ) ;
m1 = h f2 (x , u , z ) ;
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))
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
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 /
main ( )
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 t = 0.0; x = 100.0; y = y1 ;
do
f k1 = h f1 ( t , x , y ) ;
m1 = h f2 ( t , x , y ) ;
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
70
60
50
40
30
20
10
0
40 60 80 100 120 140 160 180
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
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.
main ( )
float h = 0 . 0 1 , x , u , z , k1 , k2 , k3 , k4 , m1 , m2 , m3 , m4 ;
FILE f p=NULL ;
do
f k1 = h f1 (x , u , z ) ;
m1 = h f2 (x , u , z ) ;
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;
f R = R x x/(2.0
k (2.0 k+1.0));
f = f + R;
g
return ( f );
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
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,
/ solving dx / d t = s (y z),
dy / d t = x(r z) y,
#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 ;
do
f k1 = h f1 ( t , x , y , z ) ;
m1 = h f2 ( t , x , y , z ) ;
n1 = h f3 ( t , x , y , z ) ;
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.
3.5
2.5
1.5
1
0 2 4 6 8 10 12 14 16 18 20 22
20
10
-10
-20
-30
0 2 4 6 8 10 12 14 16 18 20 22
40
30
20
10
-10
-20
-30
-40
0 2 4 6 8 10 12 14 16 18 20 22
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 .
f
float a ,x; int i ;
FILE f p=NULL ;
// FILE f p 1=NULL ;
x =0.9;
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
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
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.
y = y(x ); y = y(x ); ; yn = y(xn ). If we now approximate each segment of the curve between two
0 0 1 1
136
Integration COMPUTER PROGRAMMING-2017
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
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.
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
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 ;
h=(b a )/n ;
f
s=s+ f ( a+ i h);
g
y=( f ( a )+ f ( b )+2
s) h/2.0;
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.
a
A program for solving this might look like this
float float f ( x)
g
main ( )
int n;
i n t e g r a l =s i m p s o n ( a , b , n ) ;
g
float simpson ( float a , float b, int n)
f int i ;
float f ( float (x ) ) ;
float x,y;
float s= f ( a )+ f ( b ) ;
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 ;
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.
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
w =w = 1 1 2
1
x = x =p
3
1 2
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
)
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.
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.
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)
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).
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:
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;
s =0.0;
s+=w [ i ] ( f ( z )+ f ( z 1 ) ) ; g
s =d ;
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.
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
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
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)
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;
s =0.0;
s+=w [ i ] ( f ( z )+ f ( z 1 ) ) ; g
s =d ;
#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;
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 ;
main ( )
f float w [ 1 2 ] , x [ 1 2 ] , s1 , s2 , s = 0 . 0 ;
int i ,n;
n =10;
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
main ( )
f float w [ 1 4 ] , x [ 1 4 ] , s1 , s = 0 . 0 ;
int i ,n;
n =10;
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
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
f float p;
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 ;
int i , n =1000;
FILE f p=NULL ;
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 ;
g
g
70
60
50
40
30
20
10
0
0 0.5 1 1.5 2 2.5 3
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
4. Locate the smallest positive root of the function F (x) , given by:
Z
F (x) = cos [xa cos(t)] sin n tdt 2 +1
#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 ;
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 ) ;
break ;
ggg
float f ( float x)
h=(b a ) /N ;
s =0.0;
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
Z2
1
Jn (z ) = cos(z cos(x))dx
2
0
#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 ;
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 ) ;
ggg
float float f ( x)
h=(b a ) /N ;
f s =0.0;
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.
Z
zn
jn (z ) = cos(z cos ) sin n d
2 +1
2n n!
+1
#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 ;
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 ) ;
/ break ; /
ggg
float f ( float x)
h=(b a ) /N ;
s =0.0;
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
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.
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.
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:
int i , j =1 , a [ 5 ] = f 5 ,3 ,11 ,2 ,3 g ;
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 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.
f
int i ; / declaring an integer variable i /
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.
float c [ 2 ] [ 3 ] ;
int i , 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.
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
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
float a , b;
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 ;
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
. . .
. . .
g
Instead one has to use
f
s c a n f ( "%f " ,& x ) ; a [ i ] [ j ]= x ;
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:
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.
into those of b /
f
int i , j ;
b [ i ] [ j ]= a [ i ] [ j ] ;
g
/ this is a subroutine for addition of two mxn matrices /
f
int i , j ;
c [ i ] [ j ]= a [ i ] [ j ]+ b [ i ] [ j ] ;
g
/ this is a subroutine for subtraction of mxn matrix b from matrix a /
f
int i , j ;
c [ i ] [ j ]= a [ i ] [ j ] b[ i ][ j ];
g
/ this is a subroutine for multiplying two matrices of order lxm and mxn /
f int i , j ,k;
f c [ i ] [ j ]=0.0;
c [ i ] [ j ]+=a [ i ] [ k ] b[k ][ j ];
g
g
f
int i , j ;
p r i n t f ( "%f " ,a [ i ] [ j ] ) ;
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.
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 ) ;
f
for ( j =1; j < =n ; j ++)
f
a[ i ][ j ] = ( float )( i )/( 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 ) ;
f
for ( j =1; j < =n ; j ++)
f
b[ i ][ j ] = ( float )( i )/( 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 ) ;
p r i n t f ( "E = A B n
B A n" ) ;
m a t p r i n t ( e , m, n ) ;