Presentation Slides
Presentation Slides
2 / 156
High level language
3 / 156
Low level language
4 / 156
Write a program to read a real number
1 #include <stdio.h>
2 #include <math.h>
3 int main()
4 {
5 float x;
6 printf("Enter a number ="); scanf("%f", &x);
7 printf("x= %f exp(x)=%f\n",x, exp(x));
8 return 0;
9 }
5 / 156
Operators
6 / 156
Increment-Decrement Operators
7 / 156
Aritmetic Operators
8 / 156
Logical Operators
9 / 156
Logical Operators Tableu
10 / 156
Relational Operators
11 / 156
Assigment Operators
12 / 156
Conditional Operators
13 / 156
Bitwise Operators
1 #include<stdio.h>
2 int main ( )
3 {
4 int a = 12, b = 25;
5 printf("Output = %d", a&b);
6 return 0;
7 }
14 / 156
Bitwise Operators
15 / 156
Bitwise Operators
16 / 156
Misc Operators
17 / 156
Misc Operators Example
The following program demonstrate the use of & , ∗, and sizeof() operators:
1 #include<stdio.h>
2 int main ( )
3 {
4 int x = 10;
5 int ∗ptr = &x;
6 printf ( "Value of x = %d\n ",x );
7 printf ( "Address of x = %p\n", &x );
8 printf ( "Address of x = %p\n", ptr );
9 printf ( "Value of x = %d\n", ∗ptr );
10 printf ( "Size of the x = %ld ( in Bytes )\n", sizeof( x ) );
11 return 0;
12 }
18 / 156
Control Statments
19 / 156
IF Statment
The following program tells whether an integer entered from the keyboard
is between 1 and 100 or not:
1 #include <stdio.h>
2 int main()
3 {
4 int i;
5 printf("Enter an integer = ");
6 scanf("%d",&i);
7 if (i>1 && i<100){
8 printf("The number is between 1 and 100.\n"); }
9 else{
10 printf("The number is not in that range.\n"); }
11 return 0;
12 }
20 / 156
FOR Statment Example 1
1 #include <stdio.h>
2 int main()
3 {
4 int i;
5 for (i=0; i< 10; i++) printf("i=%d\n",i);
6 return 0;
7 }
21 / 156
FOR Statment Example 2
It is known that
1 1 1 1
1− + − + − · · · = ln 2 (1)
2 3 4 5
Equation (1) can be written as:
∞ (−1)i+1
X
= ln 2
i=1
i
1 #include <stdio.h>
2 #include <math.h>
3 int main()
4 {
5 int i,n;
6 float sum=0.0;
7 printf("Enter # of iterations = ");
8 scanf("%d", &n);
9 for (i=1;i<=;i++){
10 sum = sum + pow(−1, i+1)/i; }
11 printf("Approximation of ln(2)= %f. ", sum);
12 printf("Exact value of ln(2)= %f.\n", log(2));
13 return 0;
14 }
22 / 156
FOR Statment Example 3
x3 + x − 1 = 0 (2)
We can solve ussing an iterative method, modifying Eq. (2) to be read as:
1
x= .
1 + x2
The following program uses x = 1 as initial guess:
1 #include <stdio.h>
2 int main()
3 {
4 int i,n;
5 float x=1.0;
6 printf("Enter # of iterations = ");
7 scanf("%d", &n);
8 for (i=1;i<=n;i++){
9 x = 1/(1+x∗x); }
10 printf("Iteration #=%d, x=%f.\n", i, x);
11 return 0;
12 }
23 / 156
WHILE Statment
24 / 156
DO WHILE Statment
The do while loop is similar to the while loop except that the test occurs at
the end of the loop body. This guarantees that the loop is executed at least
once before continuing.
25 / 156
SWITCH Statment
You can achieve the same result using multiple if statements but using
switch simplifies the program flow.
26 / 156
MISCELLANEOUS REMARKS exit infinite loop
From time to time, the program you wrote may be trapped in an infinite
loop and nothing can be done except for closing the window or shutting
down the machine.
27 / 156
MISCELLANEOUS REMARKS output formatting
The format, 10.6f means that 10 spaces from the beginning of the line are reserved
and the float variable is printed with 6 decimal places right justified. This formatting
option is purely cosmetic and does not change the actual value of the variable.
28 / 156
MISCELLANEOUS REMARKS return 0
However, by returning 0 to the operating system when int main() exits, the
operating system knows that the process finished normally and continues
to run accordingly.
It does the operating system a favor by telling the operating system that it
does not have to bother to do anything special.
29 / 156
HOMEWORK 01
The program must alert if there is no real root and compute the real or
complex roots in any case.
ax2 + bx + c = 0
Note: sqrt is available in <math.h>. You need to compile the program with
the −lm option, i.e.,
30 / 156
HOMEWORK 02a
To compute the complex roots, proceed as follow, first, if Q and R are both
real, define the variable:
h Æ i1/ 3
A = −sign(R) |R| + R2 − Q3
Next compute ¨
Q/ A if A ̸= 0
B=
0 if A = 0
in terms of which the three roots are:
a
x1 = (A + B) − real root
3
p
1 a 3
x2 = − (A + B) − + i (A − B) complex root
2 3 2
p
1 a 3
x3 = − (A + B) − − i (A − B) complex root
2 3 2
If the function does not need any return value, use void as the type of
return value.
1 #include <stdio.h>
2 void write()
3 {
4 printf("Hello, World!\n");
5 }
6 int main()
7 {
8 write();
9 return 0;
10 }
33 / 156
Function in C Example 2
The following program computes the function sign(x), for any real number
x.
1 #include <stdio.h>
2 int sign(float v)
3 {
4 if (v < 0) return −1;
5 if (v > 0) return 1;
6 return 0;
7 }
8 int main()
9 {
10 float x;
11 printf("\n Enter a number="); scanf("%f", &x);
12 printf("\n The sign function for number x=%f\n", x);
13 printf("\t is: \t sign(%f)=%d\n\n", x, sign(x));
14 return 0;
15 }
34 / 156
Locality of variables within a function
Variables used within a function are local , i.e., they do not retain the
values outside the function.
In the following program, the variable name, sum, is used for both f() and main() yet
sum used within f() does not propagate outside the function f() .
1 #include <stdio.h>
2 int f(int n)
3 {
4 int i,sum=0;
5 for (i=1;i<= n;i++) sum=sum+i;
6 return sum;
7 }
8 int main()
9 {
10 int i, n, sum=0;
11 printf("Enter the number of terms for the sum\n");
12 scanf("%d",&n);
13 for (i=1;i <= n;i++) sum=sum+i∗i;
14 printf("\n ================ The sums are ================\n");
15 printf("\n sum provided for main() function is:\n"); printf("\t sum = sum+i^2 = %d\n", sum);
16 printf(" sum provided for f() function is:\n"); printf("\t sum = sum + i = %d\n", f(n));
17 printf("\n ===============================================\n");
18 return 0;
19 }
The printed value of sum is the sum defined in main() even though a variable of the
same name is returned in the function, f().
35 / 156
Recursivity of functions
36 / 156
The following program, determine the Fibonacci number, ussing recursivity
functions.
1 #include <stdio.h>
2 int fibo(int n)
3 {
4 if (n==1) return 1;
5 if (n==2) return 1;
6 return fibo(n−1) + fibo(n−2);
7 }
8 int main()
9 {
10 int i;
11 printf("Enter n = "); scanf("%d", &i);
12 printf("%d\n", fibo(i));
13 return 0;
14 }
37 / 156
Example 2:PnThe summation function
Compute i=1 i = 1 + 2 + 3 + 4 + · · · + n using the recursive algorithm.
If we define
sum(n) ≡ 1 + 2 + 3 + 4 + · · · + n,
the following relation holds:
38 / 156
RANDOM NUMBERS, RAND()
39 / 156
RANDOM NUMBERS, SRAND()
However, if we use rand() the same numbers are output again and again
each time the program is run. In order to generate a different sequence of
random numbers each time the program is running, we have to invoke
srand() function available in <stdlib.h> and must be used in conjunction with
rand().
1 #include <stdio.h>
2 #include <stdlib.h>
3 int main()
4 {
5 int i;
6 printf("Enter seed integer = ");
7 scanf("%d", &i);
8 srand(i);
9 printf("%d\n", rand());
10 return 0;
11 }
40 / 156
RANDOM NUMBERS, TIME()
Using the time() function defined in <time.h>, you can generate a different
seed number every time.
The function, time() , with the argument NULL returns the elapsed time since
00 : 00 : 00 GMT, January 1, 1970, measured in seconds. (This is the
birthday of UNIX!)
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <time.h>
4 int main()
5 {
6 srand(time(NULL));
7 printf("%d\n", rand());
8 return 0;
9 }
41 / 156
Generating Random Numbers in Various Ranges
42 / 156
HOMEWORK 03: MONTE CARLO INTEGRATION
43 / 156
DEFINITION OF ARRAYS
Vectors and matrices in linear algebra can be implemented in C as arrays.
An array in C can represent many elements by a single variable name.
An array is a variable which can represent multiple elements such as numbers and
characters.
The following program defines arrays, a, b, c , which represents three elements. The
values, 1.0, 2.0, and 3.0, are assigned to the first element, the second element and
the third element of a, b, c, respectively.
1 #include <stdio.h>
2 #define N 3
3 int main()
4 {
5 float a[3];
6 float b[N]={1.0, 2.0, 3.0};
7 float c[]={1.0, 2.0, 3.0};
8 float sum_a=0.0, sum_b=0.0, sum_c=0.0;
9 int i;
10 a[0]=1.0; a[1]=2.0; a[2]=3.0;
11
12 for (i=0;i <3;i++) sum_a = sum_a + a[i];
13 for (i=0;i <3;i++) sum_b = sum_b + b[i];
14 for (i=0;i <3;i++) sum_c = sum_c + c[i];
15
16 printf("\n The sum array a[] is = %f.\n", sum_a);
17 printf("\n The sum array b[] is = %f.\n", sum_b);
18 printf("\n The sum array c[] is = %f.\n", sum_c);
19 return 0;
20 } 44 / 156
MULTI-DIMENSIONAL ARRAYS
Arrays can be nested, i.e., they can take more than 1 indices.
45 / 156
MULTI-DIMENSIONAL ARRAYS 2
46 / 156
STANDARD INPUT/OUTPUT REDIRECTION
Instead of entering data from the keyboard and displaying the output on
the computer screen, it is possible to re-direct input/output to/from other
devices such as files, printers, etc.
I/O redirections
If a.out alone is entered from the keyboard, all the output from a.out is
displayed on the screen. However, with a.out > result.dat, the output is saved
to an external file, result.dat , and nothing is shown on the screen.
$ gcc program.c -lm -o ejecutable.o
$ ./ejecutable.o > result.dat
If the program requires that the input must come from an existing external
file (data.dat) and the output must be saved to another external file
(result.dat), you can have both directions on the same line as:
$ gcc program.c -lm -o ejecutable.o
$ ./ejecutable.o < data.dat > result.dat
47 / 156
FILE HANDLING (FROM WITHIN A PROGRAM)
I/O redirection is operating system dependent (UNIX and DOS) and only
available when the C program is run from a command line.
To write/read an external file from within a C program, the file must be opened first
and must be closed after necessary operations on the file are done.
For opening/closing a file, the functions, fopen() and fclose() , with a special keyword
FILE (note the upper case) must be used.
Use the following syntax. The file variable, fp, is a pointer. This is a FILE pointer that
keeps track of the memory location of the file.
49 / 156
LINEAR INTERPOLATION
y = mx + b, (4)
where b is the intercept with the y axis and m is the slop of the line
passing through the N data points (x1 , y1 ), (x2 , y2 ), (x3 , y3 ), · · · , (xN , yN ).
The values of m and b are determined so that the stright line passes
through the data points with less error.
50 / 156
LINEAR INTERPOLATION 2
The error is defined as the difference between the measured value and
predicted value. Since this value can be either positive or negative, it is
necessary to make it positive-definite by squaring the nominal value.
Usually this precedure is named the chi-square method. Therefore, the
total error,χ2 , is the sum of the square of the difference at each point
defined as:
XN
χ2 = (mxi + b − yi )2 (5)
i=1
51 / 156
LINEAR INTERPOLATION 3
or
! ! !
N
X N
X N
X
xi2 m + xi b = xi yi
i=1 i=1 i=1
! ! !
XN XN XN
xi m + 1 b= yi
i=1 i=1 i=1
52 / 156
HOMEWORK 04a: LINEAR INTERPOLATION 3
N N N N
xi2
P P P P
xi yi xi xi yi
i=1 i=1 i=1 i=1
N
P N
P N
P
yi N xi yi
i=1 i=1 i=1
m= b= (6)
N N N N
xi2 xi2
P P P P
xi xi
i=1 i=1 i=1 i=1
N
P N
P
xi N xi N
i=1 i=1
53 / 156
LINEAR INTERPOLATION 4
There are several indicators of how well the data can be represented by a
stright line. One indicator is the correlation coefficient, wich can be
calculated from:
N
P
(xi − x̄)(yi − ȳ)
i=1
r=v v (7)
t N t N
uP uP
(xi − x̄)2 (yi − ȳ)2
i=1 i=1
with x̄ and ȳ the avarage value of xi and yi data points. The value of r
ranges from −1 to 1, but usually the value of r 2 is reported.
54 / 156
READ VALUES FROM TWO COLUMNS
The following program shows how to read and write from/to a data file with
two columns.
1 #include <stdio.h>
2 #define N 10
3 int main()
4 {
5 int i;
6 float x[N+1], y[N+1];
7 float xi, yi;
8 FILE ∗fpin,∗fpout;
9
10 fpin=fopen("data.dat","r");
11 fpout=fopen("results.dat","w");
12
13 for (i=1;i<= N; i++){
14 fscanf(fpin, "%f\t %f\n",&xi,&yi);
15 x[i]=xi;
16 y[i]=yi;
17 fprintf(fpout, "%f\t %f\n",y[i],x[i]);
18 }
19
20 printf("\n read and write ready, have a good day! \n \n");
21
22 fclose(fpin);
23 fclose(fpout);
24
25 return 0;
26 }
55 / 156
HOMEWORK 04b: LINEAR INTERPOLATION 5
56 / 156
POINTERS
57 / 156
ADDRESS OPERATOR & AND DEREFERENCING OPERATOR ∗
1 #include <stdio.h>
2 int main()
3 {
4 float a=20.0;
5 float ∗pa;
6 pa=&a;
7 printf("address pointer pa = %p\n", pa);
8 printf("address pointer &a = %p\n", &a);
9 printf("value pointer ∗pa = %f\n",∗pa);
10 printf("value variable a = %f\n", a);
11 return 0;
12 }
58 / 156
FUNCTION ARGUMENTS AND POINTERS
Note that the dummy variable, a , is declared as a pointer (∗a) and instead
of c, the address of c (&c) is passed to the function. In the function,
ten_times_point(), ∗a represents the content of the variable pointed by a.
59 / 156
FUNCTION ARGUMENTS CALLED BY REFERENCE
the following program uses a function, swap(), that takes two pointers as
arguments and exchanges the values of the two variables pointed by the
pointers:
1 #include <stdio.h>
2 void swap(float ∗pa, float ∗pb)
3 {
4 float tmp1, tmp2;
5 tmp1=∗pa;
6 tmp2=∗pb;
7 ∗pa =tmp2;
8 ∗pb =tmp1;
9 }
10 int main()
11 {
12 float a=10.0, b=50.0;
13 printf("Old a = %f and old b = %f\n",a,b);
14 swap(&a,&b);
15 printf("New a = %f and new b = %f\n", a,b);
16 return 0;
17 }
60 / 156
POINTERS AND ARRAYS
Handling matrices and vectors in linear algebra is the most relevant use of
pointers for scientific programming. When an array, a[3], the C compiler
actually interprets a as a pointer and reserves appropriate memory space.
61 / 156
PASS AN ARRAY TO A FUNCTION
The following program use a function that takes an array as an input and
doubles all the elements in that array.
1 #include <stdio.h>
2 void twice_pointer(float ∗a)
3 {
4 int i;
5 for (i=0; i<3; i++) ∗(a+i) = 2.0 ∗ ∗(a+i);
6 }
7 void twice_normal(float a[3])
8 {
9 int i;
10 for (i=0; i<3; i++) a[i] = 2.0 ∗ a[i];
11 }
12 int main()
13 {
14 float b[3]={1.0, 2.0, 3.0};
15 float c[3]={1.0, 2.0, 3.0};
16 int i;
17 twice_pointer(b);
18 twice_normal(c);
19 printf("doubles all the elements in that array ussing ponters in function\n");
20 for (i=0; i<3; i++) printf("%f\t", b[i]); printf("\n");
21 printf("doubles all the elements in that array ussing array elements in function\n");
22 for (i=0; i<3; i++) printf("%f\t", c[i]); printf("\n");
23 return 0;
24 }
62 / 156
POINTERS AND TWO DIMENSIONAL ARRAY
We will assign the address of the first element of the array num to the
pointer ptr using the address of & operator.
The two dimensional array num will be saved as a continuous block in the memory.
So, if we increment the value of ptr by 1 we will move to the next block in the
allocated memory.
1 #include <stdio.h>
2 int main(void) {
3 int num[3][4] = { {1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12} }; // 2d array
4 int ROWS = 3, COLS = 4, i, j;
5 int ∗ptr = &num[0][0]; // pointer
6 // print the element of the array via pointer ptr
7 for (i = 0; i < ROWS; i++) {
8 for (j = 0; j < COLS; j++) {
9 printf("%d ", ∗(ptr + i ∗ COLS + j));
10 }
11 printf("\n");
12 }
13 return 0;
14 }
If we want to get the value at any given row, column of the array then we can use
the value at the address of ∗ operator and the following formula.
num[i][j] = ∗(ptr + (i x no_of_cols + j))
Where, num is a two dimensional array and i and j denotes the ith row and jth
column of the array, no_of_cols denotes the total number of column in the row of the
array and ptr holds the address of the first element of the array.
63 / 156
FUNCTION POINTERS
64 / 156
FUNCTION POINTERS EXAMPLE
65 / 156
HOW TO HANDLE A STRING OF CHARACTERS
In the program above, the float variable, a, represents a single value, 2.0.
The char variable, c, represents a single character, A.
66 / 156
HOW TO HANDLE A STRING OF CHARACTERS 2
1 #include <stdio.h>
2 int main()
3 {
4 float a[]={2.0, 3.0, 4.0, 5.0}; char b[]="Hello";
5 printf("%f\n",a[0]); printf("%c\n",b[0]);
6 return 0;
7 }
67 / 156
FORMAT %s
Use the %s format to represent the entire string instead of the %c format
that represents only one character.
1 #include <stdio.h>
2 int main()
3 {
4 char ∗a;
5 a="Hello, World!";
6 printf("%s\n",a);
7 return 0;
8 }
As is seen in the examples above, a single quotation mark (’) and a double
quotation mark (") work differently. The single quotation mark must be
used for one character while the double quotation mark must be used for a
string of characters.
68 / 156
FORMAT %s 2
1 #include <stdio.h>
2 int main()
3 {
4 char str[100];
5 printf("Enter a word = ");
6 scanf("%s", str);
7 printf("%s\n",str);
8 return 0;
9 }
Note that there is no & before str in the scanf() function as str is already a
pointer. Also, only “one word” is printed even though “several words” was
entered. This is because the format, %s , in scanf(), reads input until a space
is entered (a word). If two strings (two words) are to be read, %s %s must
be used.
69 / 156
STRING COPY/COMPARE
In the program above, the strcmp() function takes two strings as the
arguments and returns 0 if the two strings match. Note that you can
output " (double quotation mark) in printf() function by using the backslash
character.
70 / 156
STRING LENGTH
71 / 156
STRUCTURES
Observe that a member in a structure can be accessed by using the dot (.).
72 / 156
ORGANIZE DATA FROM FILE IN A STRUCTURE
1 #include <stdio.h>
2 #include <string.h>
3 #define N 19
4 struct student{
5 int ID;
6 char ∗name;
7 long int code;
8 };
9 int main()
10 {
11 FILE ∗fp;
12 int x[N+1]; long int y[N+1]; char z[N+1][50];
13 int i;
14 fp=fopen("list.dat","r");
15 for (i=1;i<=N; i++){
16 fscanf(fp, "%d \t %ld \t %s \n", &x[i], &y[i], z[i]);
17 }
18 struct student listclass[N+1];
19 for (i=1;i<=N; i++){
20 listclass[i].ID = x[i];
21 listclass[i].code = y[i];
22 listclass[i].name = z[i];
23 }
24 printf("%d\n", listclass[5].ID );
25 printf("%s\n", listclass[5].name);
26 printf("%ld\n", listclass[5].code );
27 fclose(fp);
28 return 0;
29 }
73 / 156
HOMEWORK 05:
74 / 156
Note on Numerical Errors
Remember that, the data type, float, was used for all real numbers where 4
bytes are allocated for each floating number. A float variable can represent
10−38 to 1038 which covers most of the practical range. However, this
range is translated into 6 to 8 decimal digits of precision and many
problems in science and engineering require more precision that this
range.
Consider the following code:
1 #include <stdio.h>
2 int main()
3 {
4 float s=0.0;int i;
5 for (i=0;i <10000;i++) s=s+0.1;
6 printf("%f\n",s);
7 return 0;
8 }
The intention of the program is to add 0.1 for 10000 times. The result should be
1000. However, the program outputs the following result: 999.902893.
The output is not 1000 but 999.902893 which is almost 1000 but when precision is
critical, this result is not acceptable. The error in this example comes from
conversion between decimal numbers and binary numbers. The decimal numbers in
the source code are converted to the binary numbers with a possibility of
conversion error and the binary numbers are converted back to the decimal
numbers adding another conversion error.
75 / 156
Cancellation Error
Both types of errors are inevitable and there is no way to completely eliminate such
errors. However, possible harm can be minimized by using double instead of float for
floating numbers. When a number is declared as double, it is assigned 8 bytes and
effectively increases the valid range. While the range of a float variable is ±10−38 to
±1038 with seven significant digits, the range of a double variable is ±10−308 to
±10308 with 15 significant digits.
In the previous programs, change float to double and also change %f to %lf
(long float) in the printf() function.
76 / 156
Not use float but use double
77 / 156
Roots of f (x) = 0
78 / 156
BISECTION METHOD
The bisection method is based on the mean value theorem which states
that
Theorem
If f (x) is continuous over x1 ≤ x ≤ x2 and f ′ (x) exists over x1 < x < x2 and
f (x1 )f (x2 ) < 0, there is at least one point x between x1 and x2 such that
f (x) = 0.
79 / 156
NEWTON-RAPHSON METHOD
Newton-Raphson method, is the defacto standard of the algorithm to
obtain roots for f (x) = 0. Instead of specifying two points as in the
bisection method, Newton’s method requires only one point as initial
guess to start with.
From Figure, the equation of a straight line that passes (a, b) with a slope
of m is expressed as
y − b = m(x − a)
Therefore, the tangent line that passes (x1 , f (x1 )) with the slope of f ′ (x1 ) is
expressed as
y − f (x1 ) = f ′ (x1 )(x − x1 )
81 / 156
NEWTON-RAPHSON METHOD 1b
82 / 156
NEWTON-RAPHSON METHOD 1c
In general,
f (xn )
xn+1 = xn − (8)
f ′ (xn )
can be used as as an iterative formula to obtain the n + 1 approximation
from the n approximation.
Start with an initial guess of x1 which is sufficiently close to the root,
compute x2 , x3 , x4 , · · · from Eq.(8) and repeat this iteration until |xn+1 − xn |
is smaller than the set threshold.
83 / 156
NEWTON-RAPHSON METHOD 1d
Note that Newton’s method fails when f ′ (xn ) is zero which makes the
denominator in Eq.(8) zero.
84 / 156
HOMEWORK 06
Assigment:
1. Implement the Bisection and Newton Rhapson methods.
2. Plot the function:
f (x) = x sin(x) + x sin(x2 ) − ex
Find all the roots in the interval [-4,-1]
2.1 using the bisection method.
2.2 using the Newton-Raphson method.
Rta: x1 = −3.49358 x2 = −3.05902 x3 = −2.60517 x4 = −1.46616
3. Plot the function:
ex − 3x = 0
Find all the roots in the interval [0,-2].
3.1 using the bisection method.
3.2 using the Newton-Raphson method.
Rta: x1 = 0.61906 x2 = 1.51213
85 / 156
NUMERICAL DIFFERENTIATION
There are three basic schemes for numerical differentiation using three
neighboring points, Forward, Backward and Central difference.
86 / 156
FORWARD DIFFERENTIATION
When we retain only the first two terms of the right-hand side.
Then f ′ (x) can be expressed as
f (x + h) − f (x)
f ′ (x) ≈ (10)
h
This is called the forward difference scheme.
87 / 156
BACKWARD DIFFERENTIATION
∞
X (−h)n
f (x − h) = f (n) (x)
n=0
n!
h2 h3
= f (x) − f ′ (x) h + f ′′ (x) − f ′′′ (x) +··· (11)
2! 3!
≈ f (x) − f ′ (x) h
f (x) − f (x − h)
f ′ (x) ≈ (12)
h
This is called the backward difference scheme.
88 / 156
CENTRAL DIFFERENTIATION
h2 h3
f (x + h) = f (x) + f ′ (x) h + f ′′ (x) + f ′′′ (x) +···
2! 3!
h2 h3
f (x − h) = f (x) − f ′ (x) h + f ′′ (x) − f ′′′ (x) +···
2! 3!
Subtracting Eq. Eq.(11) from Eq.(9) yields
h3
f (x + h) − f (x − h) = 2 f ′ (x) h + 2f ′′′ (x) +···
3!
Dropping the second term and beyond, f ′ (x) can be expressed as
f (x + h) − f (x − h)
f ′ (x) ≈ (13)
2h
89 / 156
SECOND-ORDER DERIVATIVE
h2 h3
f (x + h) = f (x) + f ′ (x) h + f ′′ (x) + f ′′′ (x) +···
2! 3!
h2 h3
f (x − h) = f (x) − f ′ (x) h + f ′′ (x) − f ′′′ (x) +···
2! 3!
yields
f (x + h) + f (x − h) = 2 f (x) + f ′′ (x) h2 + · · ·
f (x + h) + f (x − h) − 2f (x)
f ′′ (x) ≈ (14)
h2
90 / 156
EXAMPLE
1 #include <stdio.h>
2 #define N 11
3 int main()
4 {
5 double y[N]={0, 0.0998, 0.1986, 0.2955, 0.3894, 0.4794, 0.5646, 0.6442, 0.7173, 0.7833,
0.8414};
6 double forward[N], backward[N], central[N], h=0.1;
7 int i;
8 for (i=0;i<N ;i++) forward [i] = (y[i+1]−y[i ]) /( h);
9 for (i=1;i<N+1;i++) backward[i] = (y[i ]−y[i−1]) /( h);
10 for (i=1;i<N−1;i++) central [i] = (y[i+1]−y[i−1]) /(2∗h);
11 printf ("x | forward | backward | central \n−−−−−−−−−−−−−−−−−−−−−−−−−−−\n"
);
12 for (i=1;i<N−1;i++)
13 printf ("%lf %lf %lf %lf \n", i∗h, forward[i], backward[i], central[i]);
14 return 0;
15 }
91 / 156
NOTE ON FIRST AND LAS POINT DIFFERENCE
The central difference scheme is more accurate than the forward and
backward difference schemes.
Observe that the forward difference scheme cannot compute the last point
i=N, the backward diffence scheme cannot compute de first point i=0 and
central difference connot compute the last (i=N) and first points (i=0).
92 / 156
APPROXIMATE DIFERENCE OF FIRST POINT
4h2 8h3
f (x + 2h) = f (x) + 2hf ′ (x) + f ′′ (x) + f ′′′ (x) +··· (15)
2! 3!
The h2 term in Eq.(15) can be eliminated by subtracting Eq.(15) from 4
times of Eq.(9) as
4f (x + h) − f (x + 2h) − 3f (x)
f ′ (x) ≈ (16)
2h
Equation Eq.(16) has been used to compute the diference of the first point.
93 / 156
APPROXIMATE DIFERENCE OF LAST POINT
4h2 8h3
f (x − 2h) = f (x) − 2hf ′ (x) + f ′′ (x) − f ′′′ (x) +··· (17)
2! 3!
The h2 term in Eq.(17) can be eliminated by subtracting Eq.(17) from 4
times of Eq.(11) as
3f (x) − 4f (x − h) + f (x − 2h)
f ′ (x) ≈ (18)
2h
Equation Eq.(18) has the same order of accuracy as the central difference
scheme. The price that needs to be paid is that instead of two values of
f (x), three values must be used.
94 / 156
CENTRAL DIFFERECE FIRST AND LAST POINT
The following code implement the central difference scheme, including the
calculus for first and las points.
1 #include <stdio.h>
2 #define N 11
3 int main()
4 {
5 double y[N]={0, 0.0998, 0.1986, 0.2955, 0.3894, 0.4794, 0.5646, 0.6442, 0.7173, 0.7833,
0.8414};
6 double central[N], h=0.1;
7 int i;
8 for (i=1;i<N−1;i++) central[i] = (y[i+1]−y[i−1])/(2∗h);
9 central[0 ] = (4∗y[1]−y[2]−3∗y[0])/(2∗h); /∗ first point ∗/
10 central[N−1] = (3∗y[N−1]−4∗y[N−2]+y[N−3])/(2∗h); /∗ last point ∗/
11 printf ("i | \t x | \t central | \n−−−−−−−−−−−−−−−−−−−−−−−−−−−\n");
12 for (i=0;i<N;i++)
13 printf ("%d \t %lf \t %lf \n",i, i∗h, central[i]);
14 return 0;
15 }
95 / 156
HOMEWORK 07
96 / 156
NUMERICAL INTEGRATION
97 / 156
RECTANGULAR RULE
99 / 156
TRAPEZOIDAL RULE
1 #include <stdio.h>
2 double f(double x)
3 {return 4.0/(1.0+x∗x);}
4 int main()
5 {
6 int i, n ;
7 double a=0.0, b=1.0 , h, s=0.0, x;
8 printf("Enter number of partitions = ");
9 scanf("%d", &n) ;
10 h = (b−a)/n ;
11 for (i=1;i<=n−1;i++) s = s + f(a + i∗h);
12 s=h/2∗(f(a)+f(b))+ h∗ s;
13 printf("%20.12f\n", s) ;
14 return 0;
15 }
101 / 156
SIMPSON’S RULE
102 / 156
SIMPSON’S RULE 1a
The curve that passes the three points (−h, f (−h)), (0, f (0)) and (h, f (h)) is
assumed to be
y = ax2 + bx + c
103 / 156
SIMPSON’S RULE 1b
Imposing the condition that this equation passes the three points yields
f (−h) = ah2 − bh + c
f (0) = c
f (h) = ah2 + bh + c
104 / 156
SIMPSON’S RULE 1c
Now the area between −h and h under the parabola, yet determines via
a, b and c, is given by
Zh Zh
f (h) + f (−h) − 2f (0) 2 f (h) − f (−h)
2
(ax + bx + c) dx = x + x + f (0)
−h −h 2h2 2h
h
= (f (−h) + 4f (0) + f (h)) (21)
3
By applying this for each segment in the interval [a, b], one obtains
h
I≈ ((f0 + 4f1 + f2 ) + (f2 + 4f3 + f4 ) + · · · + (f2n−2 + 4f2n−1 + f2n ))
3
h
≈ (f0 + 4f1 + 2f2 + 4f3 + 2f4 + · · · + 2f2n−2 + 4f2n−1 + f2n )
3
105 / 156
SIMPSON’S RULE 1d
Note that the number of partitioning for Simpson’s rule must be an even
number (2n), then the partition size must be declared as h = (b − a)/ (2n).
h
I≈ (f0 + f2n )
3
h
+ 4 (f1 + f3 + f5 + · · · + f2n−1 ) (22)
3
h
+ 2 (f2 + f4 + f6 + · · · + f2n−2 )
3
106 / 156
HOMEWORK 08
Assigment:
1. Deduce the Simpson’s rule for a partition shown in Eq.(21). This is, do
the intregral.
2. Implement the Simpson’s rule in a C code to solve:
Z1
4
2
dx = π
0 1+x
3. Evaluate analytically
Z1
x ln(x) dx
0
4. Write a C program to numerically integrate the above using Simpson’s
rule. Note that ln x → −∞ as x → 0. So the challenge is how to handle
this seemingly singular point at x = 0.
107 / 156
SYSTEMS OF LINEAR EQUATIONS
108 / 156
SYSTEMS OF LINEAR EQUATIONS 1a
109 / 156
SYSTEMS OF LINEAR EQUATIONS 1b
If you carry out the matrix multiplication, you will see that you arrive back
at the original system of equations.
4x + 3y − 5z = 2
−2x − 4y + 5z = 5
7x + 8y = −3
x + 2z = 1
9 + y − 6z = 6
110 / 156
SYSTEMS OF LINEAR EQUATIONS 1c
111 / 156
SYSTEMS OF LINEAR EQUATIONS 1d
112 / 156
GAUSS–JORDAN ELIMINATION METHOD
113 / 156
GAUSS–JORDAN CODE
1 #include <stdio.h>
2 #define N 3
3 int main()
4 {
5 double a[N][N+1]={{2, −1, 1, 2},{−1, 3, 3, 3},{2, 1, 4, 1}};
6 double pivot,d;
7 int i,j,k;
8 for(k=0; k<N; k++)
9 {
10 pivot=a[k][k];
11 for(j=k; j<N+1; j++) a[k][j]=a[k][j]/pivot;
12 for(i=0; i<N; i++)
13 {
14 if(i != k)
15 {
16 d=a[i][k];
17 for(j=k; j<N+1; j++) a[i][j]=a[i][j]−d∗a[k][j];
18 }
19 }
20 }
21 for(i=0; i<N; i++) printf("x[%d]=%lf\n", i+1, a[i][N]);
22 return 0;
23 }
114 / 156
HOMEWORK 09
Assigment:
1. Modify the Gauss-Jordan code in a way that the user insert the
coefficients ai,j and yi,j and the program show in the screen tha
augmented matrix [ai,j | yi ]
2. Use the last modify Gauss-Jordan code to solve the following systems
of equations:
2.1
4x1 + 3x2 − 5x3 = 2
−2x1 − 4x2 + 5x3 = 5
8x1 + 8x2 = −3
Sol: x1 = 2.208, x2 = −2.583, x3 = −0.183.
2.2
x1 + 2x2 + x3 − x4 =5
3x1 + 2x2 + 4x3 + 4x4 = 16
4x1 + 4x2 + 3x3 + 4x4 = 22
2x1 + x3 + 5x4 = 15
Sol: x1 = 16, x2 = −6, x3 = −2, x4 = −3.
115 / 156
LU DECOMPOSITION
A = LU
where L and U are lower and upper triangular matrices whose components
are expressed as
116 / 156
LU DECOMPOSITION 1a
It appears first that the two steps above to solve two equations require
more computation than solving a single equation of Ax = y. However,
finding L and U from A requires much less effort and solving for the two
equations is almost trivial.
117 / 156
LU DECOMPOSITION 1b
Here we are going to assume that the diagonal of U is 1 that is ui,i = 1 for
i = 1, 2, 3, · · · , n. This method is known as Crout’s decomposition method.
Then the first column of L and the first row of U are determined by,
The second column of L and the second row of U are determined from the
relations
119 / 156
Procedure to Compute L and U 1a
Next, third column of L and third row of U are determined in a similar way.
In general, li,j and ui,j given by
j−1
X
li,j = ai,j − li,k uk,j for i ≥ j li,j = 0 for i < j
k=1
j−1
P
ai,j − li,k uk,j
k=1
ui,j = for i < j ui,j = 0 for i > j
li,i
ui,i = 1
120 / 156
Algorithm of LU Decomposition Method
6: Print x1 , x2 , · · · , xn as solution.
121 / 156
LU DECOMPOSITION CODE 1a
1 #include<stdio.h>
2 int main()
3 {
4 int n,i,k,j,p;
5 double a[10][10],l[10][10],u[10][10],y[10],z[10],x[10],sum;
6 printf("Introduzca el orden (rango: nxn) de la matriz A:");
7 scanf("%d",&n);
8 printf("Introduzca los coeficientes de la matriz: ");
9 for(i=1;i<=n;i++) {
10 printf("\n fila −−> %d \t",i);
11 for(j=1;j<=n;j++) scanf("%lf",&a[i][j]);
12 }
13 printf("ingrese los elementos del vector y \n");
14 for(i=1;i<=n;i++) scanf("%lf",&y[i]);
15 //∗∗∗∗∗∗∗∗∗∗ Descomposicion LU ∗∗∗∗∗
16 for(k=1;k<=n;k++) {
17 u[k][k]=1;
18 for(i=k;i<=n;i++) {
19 sum=0;
20 for(p=1;p<=k−1;p++) sum+=l[i][p]∗u[p][k];
21 l[i][k]=a[i][k]−sum; }
22 for(j=k+1;j<=n;j++) {
23 sum=0;
24 for(p=1;p<=k−1;p++) sum+=l[k][p]∗u[p][j];
25 u[k][j]=(a[k][j]−sum)/l[k][k]; }
26 }
122 / 156
LU DECOMPOSITION CODE 1b
123 / 156
LU DECOMPOSITION CODE 1c
124 / 156
HOMEWORK 10
Assigment: For the circuits shown in the figures, consider:
V1 = 6 V, V2 = 3 V, R1 = 10 Ω, R2 = 10 Ω, R3 = 5 Ω, R4 = 10 Ω,
R5 = 12 Ω, R6 = 5 Ω, R7 = 50 Ω, R8 = 5 Ω, R9 = 10 Ω.
1. Use the Kirchhoff’ laws to:
1.1 Determine the matrix equation of the circuit.
1.2 Solve the above system of equations (circuit matrix) for the currents
(I1 , I2 , I3 , I4 ), using the LU decomposition code.
125 / 156
GAUSS-SEIDEL METHOD (JACOBI METHOD)
The Gauss-Seidel method and the Jacobi method are iterative methods to
solve a set of certain types of simultaneous equations. Unlike the
Gauss-Jordan elimination method, there is no guarantee that the
iterations ever converge but no thorough programming is required and
the method can be also applied to certain nonlinear simultaneous
equations.
x + 8y + 3z = 8 (24)
2x + 3y + 9z = 6
Equations Eq.(24) can be written as
10 − y − 2 z
x=
7
8 − x − 3z
y= (25)
8
6 − 2X − 3Y
z =
9
126 / 156
GAUSS-SEIDEL METHOD (JACOBI METHOD) 1a
1 #include <stdio.h>
2 int main()
3 {
4 double x, y, z;
5 int i,n;
6 x=y=z=0.0;
7 printf("Enter # of iteration = ");
8 scanf("%d", &n);
9 for (i=0;i<n;i++)
10 {
11 x = (10−y−2∗z)/7;
12 y = (8−x−3∗z)/8.0;
13 z = (6−2∗x−3∗y)/9.0;
14 }
15 printf("x = %lf, y= %lf, z=%lf\n", x,y,z);
16 return 0;
17 }
128 / 156
CONVERGENCE OF GAUSS-SEIDEL METHOD
129 / 156
CONVERGENCE OF GAUSS-SEIDEL METHOD 1a
130 / 156
HOMEWORK 11
Assigment:
1. Solve the following set of nonlinear equations by the Gauss-Seidel
method:
27 x + ex cos y − 0.12 z = 3
−0.2 x2 + 37 y + 3 x z = 6
2
x − 0.2 y sin x + 29 z = −4
Start with an initial guess of x = y = z = 1.
2. Write a computer program that applies the Gauss-Siedel method to
solve the following system of linear equations.
131 / 156
HOMEWORK 11 1b
a)
b)
132 / 156
DIFFERENTIAL EQUATIONS (IVP)
The basic form of a differential equation for initial value problems can be
expressed as
dy
= f (t, y) y(t0 ) = y0 I.C (28)
dt
where y is an unknown function, t is the independent variable, and f (t, y) is
a function of t and y. Before equation along with the initial condition (I.C)
is called the initial value problem.
There are two types of differential equations, initial value problems and
boundary value problems. We are going to restricts our study only to
the scope of initial value problems and we are going to use Euler and the
Runge-Kutta methods to solve it.
133 / 156
INITIAL VALUE PROBLEM
134 / 156
EULER’S METHOD
which can be used to predict yn+1 from yn and the slope at that point.
135 / 156
EXAMPLE 1
136 / 156
EXAMPLE 2: Lorenz Equations
Euler’s method can be used not only for a single differential equation but
for a set of simultaneous differential equations as well.
The Lorenz system is a system of ordinary differential equations first
studied by mathematician and meteorologist Edward Lorenz in 1963. It is
notable for having chaotic solutions for certain parameter values and
initial conditions.
dx
= P (y − x)
dt
dy
= −x z + R x − y (33)
dt
dz
= xy − bz
dt
The Lorenz system are nonlinear differential equations which are
deterministic yet the behavior of the solution was neither periodic,
divergent nor convergent depending on how the parameters, P, R, and b,
and the initial values are chosen.
137 / 156
EXAMPLE 2: Strange Attractor/Chaos
The following code solves Eq.(33) using Euler’s method. The three parameters are
chosen as P = 10, b = 8/ 3 and R = 28 and the initial values are chosen as
x = y = z = 5. The step size is chosen as h = 0.01 and 105 iterations are performed.
1 #include <stdio.h>
2 #define P 10.0
3 #define b 8.0/3.0
4 #define R 28.0
5 double f1(double x, double y, double z){return P∗(y−x);}
6 double f2(double x, double y, double z){return −x∗z+R∗x−y;}
7 double f3(double x, double y, double z){return x∗y−b∗z;}
8 int main()
9 {
10 FILE ∗fp;
11 double h, t, x, y, z;
12 int i;
13 fp=fopen("lorentz.dat","w");
14 t=0.0; h=0.01; x=5.0; y=5.0; z=5.0; /∗ initial values ∗/
15 for (i=0; i< 100000; i++){
16 x=x+h∗f1(x,y,z);
17 y=y+h∗f2(x,y,z);
18 z=z+h∗f3(x,y,z);
19 fprintf(fp,"%lf \t %lf \t %lf\n", x, y, z);
20 t=t+h;
21 }
22 return 0;
23 }
138 / 156
Divergence of Neighbouring Trajectories
Lorenz Attractor
139 / 156
HOMEWORK 12
1. Use the Strange Attractor code, and verify that the Lorenz’s system is
sensitive to initial condition. Prove this using five different Initial
Conditions and plotting the final results.
2. Implement Bouali attractor, defined by the following non linear
differential system.
dx
= α(1 − y) x − β z
dt
dy
= −γ (1 − x2 ) y (34)
dt
dz
= μx
dt
Restricted to Initial Conditions x = y = z = 2. Bouali attractor exhibed
chaotic solution for α = 3, β = 2.2, γ = 1 and μ = 0.001.
Bouali attractor
140 / 156
HOMEWORK 12
3. Utilize the previous code that you used to solve the Bouali attractor
and verify that these system is also sensitive to initial condition. Prove
this using three different Initial Conditions and plotting the final results.
4. Implement one of the attractors that appear in the attached link
4.1 Solve the ODE ussing the Euler method
4.2 Use 3 different Initial Conditions (I.C)
4.3 Plot the results for each I.C
Link to STRANGE ATTRACTORS DYNAMIC MATHEMATICS
141 / 156
RUNGE-KUTTA METHOD
142 / 156
RUNGE-KUTTA METHOD
143 / 156
THE METHOD
144 / 156
THE METHOD 1a
ξ 1 = yn
ξ2 = yn + h a2,1 f (tn , ξ1 )
ξ3 = yn + h a3,1 f (tn , ξ1 ) + h a3,2 f (tn + c2 h, ξ2 )
..
.
ν−1
X
ξν = yn + h aν,j f (tn + cj h, ξj ).
j=1
145 / 156
THE METHOD 1b
kj = f (tn + cj h, ξj )
given
ν
X
yn+1 = yn + h bj kj
j=1
where
k1 = y n
k2 = f (tn + c2 h, yn + h a2,1 k1 )
k3 = f (tn + c3 h, yn + h (a3,1 k1 + a3,2 k2 ))
..
.
kν = f (tn + cν h, yn + h(aν,1 k1 + aν,2 k2 + aν,3 k3 + · · · + aν,ν−1 kν−1 ))
146 / 156
THE METHOD 1c
cj A
bj
0
c2 a2,1
c3 a3,1 a3,2
.. ..
. ··· .
cν aν,1 aν,2 ··· aν,ν−1
b1 b2 ··· bν
147 / 156
RUNGE-KUTTA METHOD 4th ORDER
The most well-known method, due to Carl Runge, has 4th order and is
defined by the Butcher tableau and usually denoted as RK4.
0
1 1
2 2
1 1
2
0 2
1 0 0 1
1 1 1 1
6 3 3 6
Then the classical method is given by
4
X
yn+1 = yn + h bj kj
j=1
k1 k2 k3 k4
yn+1 = yn + h + + + (35)
6 3 3 6
or
k1 + 2 k2 + 2 k3 + k4
yn+1 = yn + h
6
148 / 156
RUNGE-KUTTA METHOD 4th ORDER 1a
RK4.
0
1 1
2 2
1 1
2
0 2
1 0 0 1
1 1 1 1
6 3 3 6
With
k1 = y n
h h
k2 = f (tn + , yn + k1 )
2 2
h h
k3 = f (tn + , yn + k2 )) (36)
2 2
k4 = f (tn + h, yn + h k3 ))
149 / 156
RUNGE-KUTTA METHOD 4th ORDER 1b
1 #include <stdio.h>
2 #include <math.h>
3 double f1(double t, double y1, double y2){return y2;}
4 double f2(double t, double y1, double y2){return − y1∗y2 − 3.0∗y1 + sin(t);}
5 int main()
6 {
7 double h, y1, y2, t, k1, k2, k3, k4, l1, l2, l3, l4;
8 int i;
9 FILE ∗fp1, ∗fp2;
10 h=0.01; t=0.0; y1=1.0; y2=1.0; /∗ Initial Conditions ∗/
11 fp1=fopen("variable_y1.dat","w"); fp2=fopen("variable_y2.dat","w");
12 for (i=0; i<=10000; i++)
13 {
14 k1=f1(t,y1,y2);
15 l1 =f2(t,y1,y2);
16 k2=f1(t+0.5∗h, y1+0.5∗h∗k1, y2+0.5∗h∗l1);
17 l2 =f2(t+0.5∗h, y1+0.5∗h∗k1, y2+0.5∗h∗l1);
18 k3=f1(t+0.5∗h, y1+0.5∗h∗k2, y2+0.5∗h∗l2);
19 l3 =f2(t+0.5∗h, y1+0.5∗h∗k2, y2+0.5∗h∗l2);
20 k4=f1(t+h , y1+h∗k3 , y2+h∗l3);
21 l4 =f2(t+h , y1+h∗k3 , y2+h∗l3);
22 y1= y1+h∗(k1+2.0∗k2+2.0∗k3+k4)/6.0;
23 y2= y2+h∗(l1+2.0∗l2+2.0∗l3+l4)/6.0;
24 t=t+h;
25 fprintf(fp1,"%lf \t %lf \n", t, y1);
26 fprintf(fp2,"%lf \t %lf \n", t, y2);
27 }
28 printf("\n succsesful, data writted in files \n \n");
29 return 0;
30 }
152 / 156
FORCED DAMPED OSCILLATOR
m a = −k x − λ v λ : viscosity
m a = −k x − λ v + F(t)
153 / 156
FORCED DAMPED OSCILLATOR
where the oscillation frequency of the force does not have to coincide with
the natural frequency of the harmonic oscillator
v
tk
u
ωf ̸= ω0 =
m
d2 x dx F0 k λ
+ 2γ + ω2o x = cos (ωf t) ω2o = 2γ = (40)
dt 2 dt m m m
where ωo : is the natural angular frequency, ωf : is the angular frequency
of the oscillating force, γ : is the damping constant, under the condition
γ < ωo .
154 / 156
HOMEWORK 13
Assigment: Forced damped oscillator
1. Transform the forced damped oscillations equation Eq.(40) in a system
of two diferential equation of 1st order, when presenting your work
show the calculations.
2. Implement a code that solve numerically the previos system using the
RK4 method.
3. For the following activities, graph the position (x) and velocity (v) until
time t = 10, for all items consider that the natural angular frecuency is
ω0 = 100 and mass is m = 1.
3.1 Forced damped oscillations:
x(0) v(0) F0 ωf γ type
0 0 5 60 20 Forced damped
0 0 5 100 20 Resonant
3.2 Forced oscillations:
x(0) v(0) F0 ωf γ type
0 0 5 60 0 Forced
0 0 5 100 0 Resonant
3.3 Damped oscillations:
x(0) v(0) F0 ωf γ type
1 0 0 0 60 Damped
3.4 Armonic oscillations:
x(0) v(0) F0 ωf γ type
1 0 0 0 0 Armonic
155 / 156
HOMEWORK 13
4. Write the steps for this rule, that is show the equivalence of equations
Eq.(35) and (36) for RK 3/ 8 rule
5. Write a code to implement the RK 3/ 8 rule and solve the diferential
equation, until t = 10:
dy 5 t2 − y
= y(0) = 1 I.C
dt et+y
6. Show a graph of yor results for y = y(t) until time t = 10.
156 / 156