Two-week ISTE workshop on Effective teaching/learning of computer programming Dr Deepak B Phatak Subrao Nilekani Chair Professor Department of CSE, Kanwal Rekhi Building IIT Bombay Lecture 3, Fundamental programming concepts (Iterative algorithms) Tuesday 29 June 2010 OVERVIEW Need for repetitive execution of instructions • Problem of finding maximum of given numbers Instructions for specifying iteration • with ‘for’ • With ‘While’ Problem of estimating value of log x General problem of finding roots of a polynomial Revisiting problem to find Maximum We saw that if we have to find maximum of 5 numbers we could write: int a, b, c, d, e, max; cin >>a >>b >>c >>d >e ; max = a; if (b > max) {max = b}; if (c > max) {max = c}; if (d > max) {max = d}; if (e > max) {max = e}; cout<<“Max is”<< max << "\n"; What do we do if the number of numbers is very large A possible strategy We notice a repetitive pattern in our program, which is if (number > max) { max = number} If we could execute this instruction repeatedly, every time with a different value of number, we will get the desired result. To ensure that this comparison is made with a new value every time, we consider repeating a modifying pattern cin >> number; if (number > max) { max = number} Further analysis of the repetitive strategy If we repeat this block five times, we will find the maximum of five numbers. But we need an initial value for max. If we assume all the given numbers are positive, then we could assign an arbitrary negative initial value to max Expanding our strategy in words, we wish to say something like: max = -999; // repeat the following block 5 times {cin >> number; if (number > max) { max = number} } Repetitive execution We need some kind of a ‘counting mechanism’ which will add 1 to the count every time we execute the block, and will stop repeated execution of the block once the count reaches 5 The ‘ for’ instruction provides such mechanism max = -999; for (count =1, count <=5; count ++) {cin >> number; if (number > max) { max = number} } Repetitive execution The artificial initial value for max in not a good idea (What if we are given negative numbers also). A better thing would be to read the first given number separately, assign it to max, and then repeat the block only 4 times cin >> number; max = number; for (count =1, count <=4; count ++) {cin >> number; if (number > max) { max = number} } Finding maximum of N given numbers // Program 4 (prog4.cpp) #include <iostream> using namespace std; // To find maximum of N given numbers int main() { int count, number, N, max; cin >> N; cin >> number; max = number; for (count =1, count <=N-1; count ++){ cin >> number; if (number > max) { max = number} } } General format and semantics of the ‘for’ statement for( xxx; yyy; zzz ) { www; } 0. Execute “xxx;”. Must be an assignment statement. “loop initialization” 1. Evaluate condition yyy. “loop test”. If true, continue with step 2; if false, execution of ‘for’ statement ends. 2. Execute www. “loop body” 3. Execute zzz. “loop increment” 4. Go back and repeat from 1. Sum of N natural numbers ---int main(){ int i, N, Sum = 0; cin >> N for(i=1; i < N; i=i+1){ sum = sum + i; } cout << “Sum of” << N < “numbers is”; cout << sum << “\n”; return 0; } Computing Natural Logarithm Natural Logarithm of a number a is defined as a 1/ x dx 1 A computer cannot integrate • Must use arithmetic operations. Estimate area under the curve f(x) = 1/x from 1 to a. Area approximated by small rectangles. Riemann Integral calculate Sum of areas of all rectangles between 1 and a. 1 a Riemann Integral using n rectangles Width w of i th Rectangle (same for all rectangles) w = (a-1)/n) 1 a Riemann Integral using n rectangles x coordinate of i th Rectangle x = 1 + (i-1)w 1 a Riemann Integral using n rectangles Height h of i th Rectangle h=1/x = 1/(1 + (i-1)w) 1 a How many rectangles? More the merrier! Say 1000. Total width of rectangles = a - 1. Width w of each rectangle= (a - 1)/1000 x coordinate of left side of ith rectangle x = 1 + (i-1)w. Height of ith rectangle 1/x = 1/(1+(i-1)w) Program to compute logarithm of a given value int main(){ int i; float x, area=0, w; cin >> x; w = (x-1)/1000.0; for(i=1; i <= 1000; i=i+1){ area = area + w*(1/(1+(i-1)*w)); } cout << “Log of ” << x << “is ” << area; return 0; } Factorial of a number int nfactorial, n, i; cin >> n; nfactorial = 1; for (i =1; i <= n, i++){ nfactorial = nfactorial * i; }; cout << nfactorial; Hemachandra’s Problem (12th Century AD) Suppose I have to build a wall of length 8 feet. I have bricks 2 feet long and also 1 foot long. In how many ways I can lay the bricks so that I fill the 8 feet? Possibilities: 2,2,2,2; 1,1,1,1,1,1,1,1; 2,2,2,1,1 .... Hemachandra’s Actual Problem Suppose I am designing a poetic meter with 8 beats. The meter is made of short syllables and long syllables. Short syllable (s) = 1 beat, Long syllable (l) = 2 beats. How many ways are there of filling 8 beats? Example of a poetic meter ya kun den du tu sha r ha r dha va la l l l s s l s l s s s l ya shubh r vas tra vru ta l l s l l s s Hemachandra’s Solution “By the method of Pingala, it is enough to observe that the last beat is long or short” Pingala: mathematician/poet from 500 A.D. Hemachandra is giving credit to someone who lived hundreds of years before him!! Copy if necessary and if permitted, but always give credit Hemachandra’s solution contd. S : Class of 8 beat patterns with short last beat. L : Class of 8 beat patterns with long last beat. Each 8 beat pattern is in class L or class S S = all 7 beat patterns + short beat appended. L = all 6 beat patterns + long beat appended | class S | = Number of patterns with 7 beats | class L | = Number of patterns with 6 beats |8 beat patterns| = |class S| + |class L| = |7 beat patterns| + |6 beat patterns| Algebraically.. Hn = number of patterns with n beats H8 = H7 + H6 In general Hn = Hn-1 + Hn-2 Does this help us to compute H8? We need to know H7, H6, for which we need H5, ... Algorithm Idea H1 = number of patterns with 1 beat = 1 {S} H2 = Number with 2 beats = 2 {SS, L} H3 = H2 + H1 = 2 + 1 = 3 {SSS, SL, LS} H4 = H3 + H2 = 3 + 2 = 5 H5 = H4 + H3 = 5 + 3 = 8 H6 = H5 + H4 = 8 + 5 = 13 H7 = H6 + H5 = 13 + 8 = 21 H8 = H7 + H6 = 21 + 13 = 34 ... Program to compute Hn int n; cin >> n; // which number to compute int hprev = 1, hcurrent = 2, hnext; For (int i=3; i <= n; i++){ hnext = hprev + hcurrent; // prepare for next iteration hprev = hcurrent; hcurrent = hnext; } cout << hnext; On Hemachandra Numbers Mathematics from poetry! Series is very interesting. - Number of petals in many flowers. - Ratio of consecutive terms tends to a limit. What are these numbers more commonly known as? Fibonacci numbers!! Hemachandra lived before Fibonacci. Newton Raphson method Method to find the root of f(x), i.e. x such that f(x)=0. Method works if: • f(x) and f '(x) can be easily calculated. • and a good initial guess is available. Example: To find square root of k. • use f(x) = x2 - k. f’ (x) = 2x. • f(x), f’ (x) can be calculated easily. • only 2 or 3 arithmetic operations needed • Initial guess x0 = 1 always works! can be proved. How to get better xi+1 given xi Point A =(xi,0) known. B Point B=(xi,f(xi)) is known Calculate f(xi ). Approximate f by tangent C= intercept on x axis C=(xi+1,0) f(x) C A xi+1 xi f’ (xi) = AB/AC = f(xi)/(xi - xi+1) xi+1 = (xi- f(xi)/f’ (xi)) Square root of k xi+1 = (xi- f(xi)/f’ (xi)) f(x) = x2 - k, f’ (x) = 2x xi+1 = xi - (xi2 - k)/(2xi) = (xi + k/xi)/2 Starting with x0=1, we compute x1, then x2, then... We can get as close to sqrt(k) as required. Program segment float k; cin >> k; float xi=1; // Initial guess. Known to work. for (int i=0; i < 10; i++){ // 10 iterations xi = (xi + k/xi)/2; } cout << xi; Another way float xi, k; cin >> k; for( xi = 1 ; // Initial guess. Known to work. xi*xi – k > 0.001 || k - xi*xi > 0.001 ; //until error in the square is at most 0.001 xi = (xi + k/xi)/2); cout << xi; Yet Another way float k; cin >> k; float xi=1; while(xi*xi – k > 0.001 || k - xi*xi > 0.001){ xi = (xi + k/xi)/2 ; } cout << xi; While statement while (condition) { loop body}; check condition, if true then execute loop body. Repeat. If loop body is a single statement, then need not use { }. Always putting braces is recommended; if you insert a statement, you may forget to put them, so do it at the beginning. True for other statements also: for/repeat/if. for and while If there is a “control” variable with initial value, update rule, and whose value distinctly defines each loop iteration, use for. If loop executes fixed number of times, use for. THANK YOU