PROGRAMMING by malj

VIEWS: 25 PAGES: 22

									PROGRAMMING

Before we start on a course in "Numerical methods and programming"
we should look at some of the basic aspects of programming. We will
learn here, how to convert some of our ideas into a working program
and what are the parameters to keep in mind when we design an
algorithm.

There are many "languages" like, for example C, Fortran, PASCAL etc.,
that help us to convert an algorithm in to something that a computer
can understand. We will focus here only on C programming

By the end of the first part, you should have a working knowledge on
how to implement an algorithm. With this mind we will go through very
basic features of C and some of the aspects C programming that is not
immediately relevant to the implementation of the algorithms that are
taught later in this course .

So. let us start looking at how do we create a "C program".There are
basically three steps involved in converting your ideas into what is to be
done to make it a working program.

There are three steps involved in converting your idea of what is
to be done to a working program

            Creating a source code in the form of the text file
            acceptable to the compiler.

            Invoking the compiler to process the source code
            and produce an object file.

            Linking all the object files and libraries to produce
            an executable


We will look at these parts in some more detail here.

The source code is where you express the the whole computation you
want to do into a series of instructions.
The tradition is to use the C source code with an extension .c For
example myfile.c . Some compilers insist on this extension. This is an
acsii file that you can create using any one of the editors that you are
familiar with. We will look at the detailed structure of this code in a little
while .

We may have different parts of the code in different files. We then
compile them separately or together to form object files. During this
operation the compiler checks and convert your source code to a
language understandable to the particular processor that is used in the
computer. These object files that comes with an extension .o, for
example myfile.o , are in binary format.

The next step is to link these object files and other libraries and header
files etc., to produce an executable. This executable file contains a set
of instruction in a language that the processor can understand and is
the one which we run on the computer. We will see the use of header
files and system libraries in the examples given below.

Before proceed let us summarize the steps that takes us to run a
program in the form of a flow chart.
As we said earlier it is the tradition to write a C program file name
ending with the extension .C.

Example: Below we give a program that computes the square root of a
number and prints it on the scree. Since it is a C program we name it as
"myfile.c" , that is with an extension ".c".


1       #include <math.h>

2       #include <stdio.h>
3       main()
    {
4           float x,y;

5             scanf("%f\n",&x);

6               y=sqrt(x);

7             printf("%f\n",y);

        }


Before we proceed to the compilation of this program let us take a
minute to see what does each of the lines mean?.

Lines 1 and 2 are header files. These files contain the math library
functions and the input output command functions. We need the math
function library to use functions like "sqrt", "log", "power" etc. We need
the stdio library to use functions like "scanf" and "printf" which reads and
prints the data from the screen. More on this a little later.

 The program given above just has a main body. Line 3 is declares the
starting on this part. The lines inside the { } following this are the part of
the main program.

Line 4 is the declaration of the variables. Again we will see more on the
variable types later in this course. In this particular example we declare
variables "x,y" as floating points.
Line 5 reads the value of the variable from the screen.

Line 6 computes the square root of the variable "x" and put the value
into variable "y".
Line 7 prints out this value of y.
We first compile this code to produce an object code using the
command cc -c myfile.c or an equivalent command available at your
machine.

The object file produced by this, myfile.o is then linked with the system
math library using the command, cc -lm myfile.o -o myfile.exe , to
produce the executable myfile.exe.

(the second term in the command above "-lm" links the object file to the
math library. The file name that comes just after -o is the name of the
executable).

We can combine compile and link into one step as will see in later part
of the course.

Example: Let us now look at a C program that uses the library and
another function.

#include <math.h>

#include <stdio.h>

main()

{

    float x,y;
      ("%f\n",&x)

         y=sqrt(x);

         printf("%f\n",y);

         printit();
}

printf()

{

      printf("The program is Over");

}


This simple C code adds an additional component to the one we saw
earlier, it calls a function "printit".

 As before you can see the "include" files, or what are called header
files. Then we will see the main part of the program. This program is
basically computing square root of the variable x and it is printing it out
on the screen. Then it is calling some function, which prints out a
statement.

Here we see on of the main feature of a C program. The main part
does some of the calculations and it calls another function.

The function we called, named printit, which simply prints the sentence
"the program is over." can be put it a separate file. Let is call it "print.c".
We will see that how it can be compiled and how it can be executed.

There are two ways to compile this program.

To compile these programs we could type
cc -c sample.c and cc -c print.c separately.

This commands will create sample.o and print.o files. We can create the
executable by typing the command.

cc sample.o print.o -lm -o a.out

In this linking command we have put together the two files and also
included the math library file m.a

We can now execute the program by typing a.out.
You could try variations of these commands and programs to figure out
why we need the math.h file and why we need to include -lm in the
linker etc. Also try it for different math functions, for example calculating
the logarithm or trigonometric functions etc.

Another way to compile and generate an executable from this is to
simply type

cc sample.c print.c -lm -o a.out

In this the compilation and linking is put together.

Let us try another program to illustrate the use of math library and the
compilation and linking procedure.


Here is the file "sample.c",

#include<studio.h>
#include<math.h>
main( )
{
float x,y;
file *FP;
FP = fopen("sample.dat", "w");
while(x++<3.0)
  {
    y = tanh(x);
    fprintf(FP,"%f\n",y);
   }
 Printinit( );
 Fclose(FP);
}

and a file "print.c",

printinit()
      {
       printf("The program is over" "\n");

     }
As we discussed above, there are two ways for compiling.


cc    -c    sample.c creates the file called sample.o

cc    -c    print.c    creates the file called print.o

Now, we put them together and produce an executable. In the process
we will link it to the math library using -lm and use -o to direct the
executable to an output "myexe".


cc sample.o print.o -lm -o myexe

this will create a file myexe. Now, if we did not use the part of the
command after "-lm", an executable file a.out will be created by the
compilation.

We could also do it (creating the executable) in one step with the
command

cc sample.c print.c -lm -o myexe


To run the program, we use ./myexe. Then it prints on the screen that
the "program is over". This is what we have asked the function print.c.

Actually what does this program do? It is computing the tangent
hyperbolic function for a range of values of x. We achieve this using the
"while" function. The output is written in a file called "sample.dat". Note
the "fopen" and "fprintf" functions were called for this purpose. Then it
calls the function printinit(). Printinit () just prints out "the program is
over" using the function "printf". We will see more examples of the use
of these functions as we go along.


As we saw above in one command we can do two things, compile and
link. We can do compilation alone by invoking
-c along with cc. If we won't use -c, it will compile and link, that is the
default. -lm is here for linking to math library.
Let us see what happens if we do nnt use "-lm" in the command , that is
we do not
Link it to the math library and type only

cc sample.c print.c -o myexe

Does it work?
 it says that it cannot understand "tanh"

Since, tanh is built into the math library, we need that math library to
compile this program. To use mathematical functions, we need to link to
math library. For other functions, we might need other libraries. These
libraries are stored in different parts of the computer. For example in a
Linux platform, these libraries are stored in /users/lib . In general, for
different operating systems, the library functions are in different places

We were also using header files in the program. Header files are used
with   "#include"   statements.       Try   removing    header     file
#include<studio.h> and then try to compile

cc sample.c print.c -lm -o myexe

It says that it cannot understand fopen statement and and *FP
declaration etc.,

FILE, fopen and all the statements are actually put in into the header file
called <studio.h>. For simple "printf" statements, we don't need it.

So, we now have a basic idea about how to create a program, compile it
and run it. We have seen simple codes with the function and we compile
it and run it.


The anatomy of a program

Let us look at the anatomy of a program once again. It can be
summarized as below.
Compiler preprocessor commands

main function name()
{
   variable declaration
    code
}
sub-function-name (arguments)
argument declarations
{
   variable declarations
   code
}



 We have some compiler preprocessor commands. This includes
various #include files. Then comes the main function. Some name can
also be given to the main function. Then, we have the variable
declarations used in the main code. Then we have sub-functions.


In the previous example, we had the sub functions as a separate files.
But you can also include them it into the main code. In this case, in one
file, we can have main program of the main function and sub-functions
or separately. It is a good idea to have the sub-functions separately. We
also compile them n link them separately. It is always safer to do that.
For large programs, it is good to have sub functions separately. Sub
function has also the same structure like main function. It might have
some arguments which would be passed into it. Then comes argument
declaration. Then we have some variable declarations which is only
private to sub functions only. We will see the examples of these.

Before going to the example, let us look at each one these in detail.

The standard C compiler has four filters. The first one is known as the
preprocessor. This part handles the inclusion of files mentioned using
the #include command, definition of constants, macro definition etc.

The second filter checks the language statements, generates a symbol
table and reports any errors found.
The third part generates the code and a fourth filter optimizes the code
for better performance

The fourth one optimizes the function. It improves the code and modifies
the code and so that it runs faster. This is an optional part of the
compiler.

Then we look at variable declaration.

C language require that all variables are declared before they can be
used. Here we declare the variable with its class name and the data
type.

The variable declarations can have the following form,
[class] [type] [name][ = initial value].
The "initial value" is not a necessary quantity.

For example we can declare the real variable "trial" using "auto float
trial" or "auto float trail = 0.0". In the latter we also assign the variable a
value "0.0".


We will now take a closer look at the 'class' statement.

In the statement for declaring the variable "trial" we used "auto float
trial" . This means we have assigned the [class] as auto. In fact this is
the default class and not necessary to be mentioned in the declaration.

n auto variable is local to the function within which it is declared. Every
time the function is entered we need to assign a value to it before it is
used.

Auto variable is a default one. If we say float, it is taken it as auto. That
is the default variable declarations. Here are more examples.
(Sample1.c)

#include<studio.h>
#include<math.h>
main( )
{
float x,y;
while(x++<10.0)
   {
    y = cube(x);
    printf("%f %f %f \n", x,pow(x,2),y);
   }

}
Cube(x)
  float x;
{
  float y;
  y = x*x*x;
  return (y);
 }

Here, the variable is declared as "float x,y". This is nothing but "auto
float x, y".

We can add more number of variables to one declaration. When we are
using more variables, it is separated by comma. Here we are using two
variables.
In the C program, all the lines are separated by semi-colon.

The variable declared as an auto variable float x,y is only private to the
main function unless one passes it to other functions. We can have the
same variable declared in another function. For example, float y is
declared in the sub function. The y value it takes inside the sub function
is different from the other declared outside it. So for the main function
to get the result of the computation done in the sub function the value
has to be "returned".

In this program x value takes starting from 0 in steps of one in floating
point. (We will discuss more on what is a floating point and how is the
floating point and an integer actually stored in the computer etc., a little
later . Right now, the floating point is the real number.)

The sub function actually computes the cubic value of x, returns the
value to the main function and prints it. While executing the program, we
get the value of square of x (through the "pow" function) as well as cube
of x.
.
In the function call y = cube(x), we are passing the variable "x" to the
sub funtion. But we are only passing the value of the variable. In the
sub function statement the variable name need not be the same. Even if
it is the same it has to be decalred just after the function statement. and
If we don't declare the use the float x inside the sub function, we will get
the cube of x as zero. That is, auto variable float x is private to the
function.


External, is another class that is possible. An external variable is global
to the program. It should be defined outside the function boundary. A
function that uses it should declare it as extern.

The first declaration creates the storage and the subsequent
declarations does not create storage, but just tells the compiler that the
reference to this variable should be resolved by the linker. An example
program that uses the real variable as external is given below.

..
 sample3.c :

# include<math.h>
#include<studio.h>
float z; /* External variable is common to the whole program and is
decalred outside the main function */
main()
{
 float x;
 extern float z; /* The main and sub functions that uses the variable
should be declare it as extern */
 int i;
 x = 0.0;
 for(i=1;i<=3;i++)
 {
 add( x);
 printf("%f %f \n",x,z);
  }

 }

This is the main program. Here we have declared float z outside the
main function. That is z has been declared as an external floating
point. We are using extern float z in the main function also. The sub
function here that the program calls is add(x). That function is shown
below.

add(a)
  float a;
{
  extern float z;
  float y;
  y = sqrt(a);
  z = x+y;
}

This function is receiving the variable "x" passed by the main function as
variable "a". As we have discussed earlier these variables should be
declared next line to the function statement. It is also using the variable
z which is declared as extern float z. If it is not declared in the sub
function, the function will not know what z is. If the z value changes in
the main function then automatically the value changes in the sub
function and vice versa.

Now, the compilation is done by ,

cc sample3.c add.c -lm -o a.out.
we are not creating the object file. We just do everything together. Then
the program is run.

We run it and check what value "z" takes in the program of add.c if we
change it in main. We should add printf statements inside the program
add.c to do this.
add(x)
   float x;
{
  float y;
   extern float z;
   y = sqrt(x);
   z = x+y;
   printf ("%f \n",z);
}

Put similar print statements in the "main" to show that the value of "z" is
changed even though it is not "passed" through the function call.

Then ,we could have a static variables. These are special definitions.

Static variables are initialized only once by the function. The static data
is assigned the initial value only on the first time the function is entered
and is not re-initialized every time the function is entered.

We will see this here with an example

(sample2.c)

# include<math.h>
#include<studio.h>
float z;

main()

{
    float x;
    extern float z;
    int i;
    x = 0.0;
    for(i=1;i<=3;i++)
    {
    add( x);
    printf("%f %f \n",x,z);
     }

}
add(x)
 float x;
{
 static float y = 0.0;
 extern float z;
 y = y+2;
 z = x+y;
 }

We declared the static variable y = 0.0 here. It means that it will initialize
the value for y as 0 at first. Then, it won't. If we run the program, we get
the results as 2,4,6. First it takes the value 0 and then in every further
calls to add it increments by 2.

Check what happens when static statement is removed? It would
initialize this variable the first time it enters the sub function. Since "y" is
initialized every time the values of "z" will be 2 every time !

Static variables are very useful. In many cases, for example, in the case
of random number generator, we have some kind of seed. We pass this
see to a random number generator and is returns a random number and
updates the see. The next time we call the random number generator it
give a new number because the seed is new. This is a case where we
don't want the seed to me initialized in every call. We want to get a
new random number in every call. So in subsequent calls the seed
value should not be initialized, that is it should be treated as "static".

We have auto variable ,static variable and external variables. These are
the basic three classes that we have gone through. Going back to our
definitions in the variable declaration. We have [class] [type] [name
]=[initial value].
We can put any names here. We have to be careful, the variables in
the c language are case-sensitive. We mayor may not put the initial
value.
Second thing is the type. So far we have used only one or two types,
float and int..
Here is the summary or the chart of the various data types.




 We could have an integer or we could have an floating point or we
could have an character. Characters are declared as char and integers
are declared as int and floating points as float.

There are two different types of integers which we can declare, Long
integer and Short integer. In most of the present day compilers the
integers declared as int are only Long integers. It means if you have 32
bits, then 2^31 is the largest integer which we can represent. One bit is
used for sign. The third one refers the unsigned interger, here can use
the extra bit for representing integer without sign. So,it is slightly longer
than the long integers.

Then, we have floating point. Here again we could have single precision
or double precision. When we say float, it is single precision. If we say
double, then it is double precision..

Let us look at the program which uses all the data types. Here is the
program (sample4.c)
#include<studio.h>
#include<math.h>


main()

{
double x,y ;
long int i,,j,k;
char letter, chain[ ] = "a quick fox\n" ;

letter = 'B';
Y = 1.01;
  i = 9247562;
i = 2;

printf("\n")
printf(" %lf %ld %c %s\n", y, i,letter,chain);
printf("\n");
j = 0;
while(j++<31)
   {
    x = y*y ;
    k = 2*i ;
    printf("%d,%lf,%ld\n",j,x,i);
    y=x;
    i=k;

    }

}

Here the variables x and y are declared as a double. (i.e. x and y -
floating point (double) auto variables.). Then variables i.j.k are declared
as long integers. If we are using large numbers, it is advisable to use
long int. Long int can also be represented as long. We don't need to
write long int.

"letter" is a character and is declared using char. Then we have a
character array or the character string , 'a quick fox' which is called
chain[ ].
These are the examples of character declarations. You can declare a
single letter character or a group of characters as letter. We could have
an array or string of characters. Here, letter is defined as 'B'. Letter is
the character here when it is assigned to a character B. Usually, the
character is assigned within single quotes.

 Then the integer i, has been assigned a number value two. Then, it is
printed out. This program contains many printf statements. This
example also demonstrates how do we use printf statements. printf
usually prints on the screen. As shown in the previous example, you
could also open a file and use a fprinf for printing into a file.

If we are going to print out a double precision number, then we use %lf
or we could use '%e'. For long integers, we use %ld. In a C program, if
we use wrong format in the printf statements, it will print junk but will not
give compilation or run time errors The characters are printed using %c
and the strings are printed using %s.
Run the program and see what it prints.

The program has a loop in which j value increases from 0 to 31. The j
value is first assigned to zero and increased by steps of one up to 31.
The y value is assigned to 1.01 to start with. It then computes the
square of that number and it is assigned to y. Basically, it computes the
(1.01) ^2 and the square of (1.01)^2 etc. so we will see how long it will
go before goes beyond the capability of the computer.

What I want to show you is that this floating points and integers, there is
a limit to the size of the numbers which the computer can handle
because the computer has a finite precision.

When then, the program is compiled and run, it prints the number y,
integer i , the letter B and the string a quick fox.

Then it enters into the loop and prints the square of "x" every time. It
prints x=1.02.Then it squares that and keeps squaring it. Since "x" has
been declared as double precision, we can see that it goes all the way
up to j=16. Then the machine cannot handle it anymore. At j=17 th
loop, "x" is printed as infinite. As for as the computer is concerned, it is
infinite.
Similarly the integer "I" continues to double as "j" increments by one.
You can see that 2^30 is the largest integer it could print. It cannot do
beyond that. Then, it gives junk.

In the previous program, we can make a little change. Instead of double
x,y , we can change it by float x,y. Now, we see what happens. Again
we compile it and run it. Now, we see it could not go beyond j=13. But it
went up to 16 last time. So, if we want to use larger numbers and we
want more precision it is better to use double.

Let is now summarize what we have learned about the structure of a c
program.




A few word about constants. We see above an example of constant
assignment z = 2.0/3.0. Now, z is a floating point. For a mathematician
2/3 = 2.0/3.0; but for a computer 2/3 is zero and 2.0/3.0 is non zero!. In
general if we find the ratio of 2 integers, the result is the integer only. If
we declare z= 2/3 , then we get the value of zero. So, we have to be
careful while making constant assignment and remember to write it as
z=2.0/3.0 or z=2/3.0 or z=2.0/3.
                  Sample Programs -1


1.To fit a straight line through a given set of data points

data file- fit.data

2. Interpolation of evenly spaced data

3. Newton's divided difference interpolation

data file-data.dat

4.Cubic Spline interpolation

data file- data.dat

cubic.dat

5. Interpolation using the Lagrange scheme

6. A two parameter nonlinear fit using chisquare minimization

data file-non-linear.data

7.To fit a function of the form f(x)=a*g(x) + b*h(x) through the given
set of data

data file- gen-linear.data
                 Sample Programs -2
1.To find the zero of f(x) using false
position method.
2.Find the zero of the function f(x) using the secant method

3.Newton-Raphson method to find the zero of the function f(x)

4.Newton-Raphson method to find the zero of the function f(x)
when the zero is of higher order.

5.To find the zero of a function f(x) by the mid point rule.

6.Use false position method to find the zero of the function f(x)
when f(x)= 0 can be written as x=g(x)

7.Bairstows method to find the roots of a polynomial

Data file- coeff.data



                        Sample Program - 3
1. Solution of a set of linear equations by elimination
method.
2. To find the inverse of a matrix using LU decomposition.

3. Solution of a set of linear equations by pivoted elimination
method

4. Solution of a set of linear equation by LU decomposition.
                     Sample Programs - 4
1.To compute the integral of a function using Gauss
quadrature method.
2. Interpolation by Newton's divided difference formula

Datafile- data.dat

3. Find the solution of a system of non-linear equations

4. To compute the integral of a function using Simpsons rule

5. To compute the integral of a function using mid point rule

								
To top