 Hello and welcome to the NPTEL course on an Introduction to Programming through C++. I am Abhiram Ranade. This is lecture sequence 3 of week 3. The reading for this is chapter 8 of the textbook. The goal of this lecture sequence is to learn methods for performing common mathematical operations. So we often need to evaluate mathematical functions such as sin x log x and we often also need to integrate functions. So these things can come up in engineering or science or even mathematics and integration can of course be performed symbolically but sometimes it is not possible to get a closed form solution. In that case we can do numerical integration. So integration is useful intrinsically but in addition we can also cast the problem of evaluating certain functions as an integration problem. So we will see that soon. Finding roots is another important mathematical operation and of course we have seen examples of such things, quadratic equations, solutions of simultaneous equations. So in general the goal here is to find an x such that f of x equal to 0 is satisfied. And of course we may have several x that we might want to find simultaneously but here let us just consider we have an equation in one variable and we want to find a solution for that single variable. So this is an intrinsically useful problem but in addition as we will see we can cast the problem of evaluating certain functions as a root finding problem. Now all these problems have methods which will give approximate answers and in fact exact answers are generally not possible for any of these problems and by that I mean exact answers which use a certain finite number of arithmetic operations. However, the methods that we describe will have the property that by doing more and more work we can reduce the error as much as we want. So we can make the error be as close to 0 as we want but for that we might have to do more arithmetic operations. So there will be some kind of a trade off. On the other hand the programs that we will write for doing these computations will be extremely simple they will just involve one loop and maybe two, three variables. So in that sense they will turn out to be good problems for developing and practicing your programming skills. So here is the outline of this lecture sequence. So first I am going to talk about methods based on Taylor series. Then I will talk about numerical integration then I will talk about a method called the bisection method and then a method called Newton-Raphson method. So let me start with an example of a Taylor series. So the question over here is how do we calculate functions such as sin x cos x ln x tan x whatever square root x. Now it turns out that these functions can be expressed as a sum of infinite terms. So let me give an example right away. So sin x can be written as x minus x cube upon 3 factorial plus x to the 5 upon 5 factorial minus x to the 7 upon 7 factorial plus as you might guess x to the 9 upon 9 factorial minus x to the 11 upon 11 factorial and so on. So as you can see the power of x increases by 2 as we go from one term to the next and the factorial also increases by 2. So you can see that there is a very clear pattern and the nice thing about this is that each term is easy to evaluate. So x to the 5 upon 5 factorial can be evaluated by doing say 5 multiplications and 5 divisions and another very important and nice thing is that even if we take the first few terms we do get a fairly good answer and if we want better accuracy we just have to take additional terms. So this is very good but in fact it has an even nicer property which is that we can get a good estimate on how bad our error is. So suppose we evaluate this sum to the first k terms then we can prove we are not going to do it in this course but it is possible to prove that the error is going to be smaller than the k plus 1th term. So if we use the k terms then the next term actually just even tells us a bound on the error. So let us try it out, let us see how we can write a program to compute the value of sin x and you may observe perhaps and it is true that the program is going to be similar to our calculation of E the base of the natural logarithm that we did earlier. So let us compute sin x using this formula this infinite sum. So our plan is going to be that in the kth iteration will add the kth term of the series to a running sum which is initialized to 0. In some sense this is very similar to the plan we made for calculating the value of E sometime ago. So let us use t sub k to denote the kth term of the series for k equal to 1, 2, 3 and so on. So looking at this sum we can say that t1 is equal to x or which we might in fact write as x to the 1 upon 1 factorial, t2 is equal to x cube upon 3 factorial but there is a minus sign over here, t3 is equal to x to the power 5 upon 5 factorial and I will just write a plus sign over here just to emphasize and so the point is that the first sign is plus then there is a minus then there is a plus and so on. So the plus and minus signs are going to alternate. So these are the terms and now I can write this tk as minus 1 to the power k plus 1, why k plus 1? So if I just wrote minus 1 to the power k then minus 1 to the power 1 would give me a negative number so I will write minus 1 to the power k plus 1 and the minus 1 to power increasing powers will make sure that the signs will alternate. Then I have x to the power 2k minus 1, let us check whether this is correct. So for k equal to 1 this gives 1 and then there is 1 factorial over here. So for k equal to 2 this 2k minus 1 will give us 4 minus 1 3 which is right upon 3 factorial and so on. So tk is indeed this. So these are the terms that we are going to calculate in subsequent consecutive iterations and we are going to add them to a running sum which we are going to initialize to 0 at the beginning. Then we know that t1 is given to us as input. So t1 is available to us at the beginning of the first iteration. So we would like t2 to be available at the beginning of the second iteration, t3 to be available at the beginning of the third iteration and so on. So our plan is something like this, at the beginning of the kth iteration we will ensure somehow that we have tk in variable capital T. We could have made a different plan. We could have said that oh we just want tk minus 1 in capital T at the beginning of the kth iteration and in the kth iteration we will somehow calculate tk. So that plan will also work, it will just give rise to a different program. So here we are just going to stick to the plan that I have written down over here which is that at the beginning of the kth iteration we will ensure we have tk in variable T. And then that means that at the end of iteration k what should we have? Well we have said at the top that s must equal the sum of the first k terms. So including tk and so tk should get added to s and for the k plus 1th iteration we would like capital T to have tk plus 1. So therefore at the end of iteration k we must make capital T equal to the k plus 1th term or tk. And what is this tk plus 1? Well I am just going to substitute k plus 1 over here. So I am going to get a k plus 2 over here and then this is going to be 2k minus 1. So if I substitute k equal to k plus 1 over here then I will get 2k plus 1 over here. And then similarly I will get 2k plus 1 factorial over here. So somehow I have to get into variable capital T this value whereas originally in capital T I had this value. How do I do that? Well if I observe these two values I can see that they are not that different. So to what extent are they different? Well here there is an extra multiplication by minus 1. So I should multiply this term by minus 1 if I want to make it look like this. But that is not enough. There is x to the power 2k minus 1 over here and I want 2k plus 1 over here. So I should also multiply it by x square. And I had 2k minus 1 factorial over here. So if I multiply it by 2k and also 2k plus 1 or rather it is in the denominator. So if I divide it by 2k and 2k plus 1 I will get this. Another way of stating the same thing is that 2k plus 1 is 2k times whatever factors I mentioned earlier. So I need a minus 1 and then I need an x square and then I need to divide by 2k and 2k plus 1. So what needs to happen is that I already have 2k and that has to be modified a little by multiplying or dividing by these terms. Once I do that I will get 2k plus 1 in capital T as I want. So in iteration T what is it that we are supposed to do? We are supposed to add the value that we have at the beginning in T into S. And then we are going to multiply T by this term over here. So T originally contained this. So when we multiply it by this term it will contain Tk plus 1 which is exactly what we wanted over here. So this allows us to write a program. So we are ready to write the program. So we will declare a variable x and read it. This is the variable whose sign we want to calculate. So let us print out a message saying what exactly we are doing. And then we wanted a variable s in which we are going to accumulate a sum and a variable T in which we are going to keep the successive terms of this series. So the first term is x so which is how we initialize T. Then we are going to do this for 10 iterations. So we could have chosen different number but 10 is as good as any. So in the first iteration we want sum to be initialized to 0 which we have done and we want T to have the value of the first term of the series. So which also we have done. Then inside the iteration we just said that we are going to add the term to the sum. So we write s equal to s plus T. And then we want to calculate the next value of the term. So the next value of the term we said can be obtained by multiplying the previous term by minus 1 and x square and then dividing by 2k and 2k plus 1. So which is what we have done over here. So at this point we have evaluated the sum to k terms. So we are going to print that just to see how the sum changes as the number of terms increases. So this is the number of terms k and we have evaluated the sum and that value is over here. That is not complete and we can also print out the error estimate. So as we said the error estimate is nothing but the new term value. That is what happens to be the case for the sine x series. So we are going to print that. So when we run this program we will see how the sum is changing or how our calculation of sine x is progressing. But we will also get an error estimate. So we will see that look the error in this current value that we have computed is at most so much. So that is the loop and then at the end what we are going to do is we are going to print out the value of sine x from the C plus plus library function. So there is a C plus plus library function called sine and we apply it to x and we are going to get that value. And this is kind of the gold standard value or the value which we can regard as the correct value and we will be able to check whether our value is the same or different from this value. So that is the end of the program. So before we go to Taylor's theorem let us execute this program and see what happens. So this is our program. This is the program that we had typed. So let us try running it. So let me first compile it and let me run it. So let me give a value of sine. So let us say I give the value 0.1. So let us see. So what does it say? So for 0.1 the value calculated is 0.1 itself and the error estimate is already not so bad. The error is at this point just about 0.0001. So already our value is pretty good. But if we go to the next step the error estimate goes down even drastically, very drastically and our value becomes something like 0.998 and then you can see from the third term after adding three terms our answer continues to remain the same basically. So very little improvement happens. So what has happened over here is that we have pretty much got the correct answer in just about three terms and you can see that this is the answer that the library function is also going to give us. So in three terms we have got the correct answer. Let us just run it one more time maybe for a different value. So let us say 0.5. So here the error is a little bit worse after the first iteration and also the second iteration. But from the third iteration onwards the error seems to be really negligible and from the fourth iteration the value is exactly the value that the library function gives and of course the error is small. So this seems pretty good. This series is giving us quite good results. So now let me talk in more general terms. So we just did something for sign turns out we can do something similar for many other functions. So Taylor's theorem is what allows us to do this and Taylor's theorem says that many interesting functions can be written in the following form. So f of x can be written as f of some x naught plus f dash of x naught. So the derivative of the function evaluated at x naught times x minus x naught plus f double dash at x naught or the derivative the second derivative of f evaluated at x naught times x minus x naught squared upon 2 factorial plus f triple dash of x naught times x minus x naught cube upon 3 factorial and so on. Now this equality holds assuming we add up infinite number of terms if x is within some particular distance of x naught and this distance is called the radius of convergence. So this is some distance that we can calculate we can estimate mathematically and so long as x is close to x naught as compared to this distance then this theorem this this expression is correct. Now why does this expression help us to evaluate f of x? I mean sin x why does it why would it help us to evaluate sin x? The point is that we can often choose x naught such that not only is it possible to evaluate f of x naught but also we can evaluate f of f dash of x naught and so on f dash f double dash and f triple dash. So we can often choose x naught such that it is possible to easily evaluate f and its derivatives of x naught. So let us take the example of sin so we will choose x naught equal to 0. So then what do we know? So we know that f of 0 or sin of 0 is 0 f dash of 0 what is the derivative of sin x it is cos x. So cos of 0 is actually 1. So again we could evaluate the derivative of f of x at x naught equal to 0. What about the third the second derivative? The second derivative of sin is minus sin and again at 0 minus sin is 0. The third derivative is minus cos but at 0 it is minus cos of 0 is minus 1. After this the pattern is actually going to repeat the fourth derivative is going to be cos and so it is going to be 0 1 0 minus 1 0 1 minus 1 and so on. So where does that leave us for sin? So sin of x if you substitute x naught in this you are going to get f of 0 so you will get a 0 over here. Then over here you are going to substitute 0 so f dash 0 is you are going to get a 1 over here and this is 0 so you are going to get an x over here so you got an x. Then for f double dash f double dash of 0 is 0 so this term will go away f triple dash is minus 1 so we are going to get a minus term over here and there is going to be an x minus x naught cube term but x naught is 0 so you are going to get x cube upon 3 factorial and as you can see the even terms are going away and the odd terms are coming out with alternating signs which is exactly what we started off with before. So what we did was exactly an application of Taylor's theorem and it turns out that this will work no matter what value you substitute. So if you go to a large enough terms this will get very very close and in the limit it will become exactly f of x. So what have we discussed? We have discussed that Taylor series are available for many functions and in fact I will ask you as an exercise to construct a series and write down the program to calculate cos of x and Taylor series is just one infinite expression which has been used for calculating math functions but people have written similar infinite expressions say infinite products or continued fractions and these can also be used to evaluate mathematical expressions. So these are discussed in the book and in the exercises in the book. So we will stop here.