 Hi, in this lecture, we will quickly have an introduction to Python coding. We will use Python language to develop codes for some numerical methods that we will develop in our course. The first question is why Python? We have so many languages, right? One of the main reason for why we choose Python is that it is an open source programming language. Means Python is available for free. In fact, many operating systems come with Python preloaded. The second reason for why we want Python is that it is a cross platform language. You develop your code in one platform, say on Windows and then take the code and run it on another operating system, say Linux. You can do it without making any changes in syntax or any setting. That is what is meant by cross platform language. In fact, it has many inbuilt libraries that makes the programming more simple, especially when we are developing some complicated softwares or working on coding some complicated scientific problems. Python is a very popular language. It is used as a tool in many famous websites and therefore Python has a large user network. This allows us to get some supports like whenever we have problem or doubt, you can go to some discussion forum and pose your questions. It is very likely that you will get reply in that way. We can say that we can get free support when working with Python. So these are the reasons for why we preferred Python as a programming language to learn how to code certain numerical methods. Having said this, the next question is what is the editor that we want to use to write Python programs and execute them? Well, there are many editors like Visual Studio or Anaconda is there which has a collection of editors and different Python distributions. But in our course, we prefer to use Colab. Colab is a Google product and again the question is why we want to use Colab when we have many other editors? One important reason is Google Colab is integrated with Google Drive means whatever program that you write and save will be saved on your Google Drive. This is very comfortable for us. The next thing is Google Colab connects to cloud based running time. It means when you execute a Python code on Colab, it connects to a cloud based machine and executes your program on the cloud machine. This is particularly very nice because you do not need to install any software or libraries on your personal computer because your code is basically going to be run on a cloud machine. And Google Colab has almost all the commonly used libraries already installed in it. In case if you want to use a library which is not found on Colab, you can install it on your Google Drive separately. In that way, you do not need to install any extra software or libraries on your personal machine. And of course, since all your programs are saved on Google Drive, it is easy for you to share your programs with your colleagues or friends just like how you share Google documents. And these are the reasons why we want to use Python as a programming language to learn coding of some basic numerical methods and we want to use Colab as our editor. I will not be introducing Colab because it is very easy for you to understand how to start with Colab and how to use Colab as an editor. You can also find many videos on YouTube to learn Colab within 5 to 10 minutes. In fact, I have also made a short video on how to start with Colab. You can find my video on the link shown here. I will also give this link in the description box. With this, we will directly go into the Python programming. Well, Python is an easily readable programming language. It is not very complicated. Therefore, I will quickly go through certain commonly used tools from Python in our course. The first thing is how to define a variable, store a value in the variable and how to do certain arithmetic operations and print the output. A variable x is defined here and the value 10 is stored in the variable x. For that, we have to write like this. Similarly, y equal to 5 makes the Python to create a variable y and store the value 5 in that variable. Then what we are doing is we are defining another variable c and we are storing the value of the sum of x plus y in that variable c and finally we are printing the value stored in the variable c. Let us see how to run this program. To run the program, we just have to click this play button. For the first time, the Google Colab will take some time to allocate some memory in the cloud mission. The next time onwards, it will run your code more faster. Well, it has established a connection with the cloud mission and it ran your small bit of code and it has shown the output as c is equal to 15. Next let us see how to run a loop. There are two ways that you can create a loop. One is using the for loop and another one is while loop. In this program, we will see how to use for loop. The syntax for for loop is for and then running index and its range given here. You can specify the range in any way. In Python, you have a special command called range which will create a sequence of numbers ranging from 0, 1, 2 up to 1 number less than what you specify here. This is very important to remember. It will not go up to 10 just because we gave 10 here. It goes 1 number less than that. And then it takes the value i equal to 0 and then executes all the lines written below the for loop with an indent here. You can see that there is an indent given here. So whatever line you write below this with an indent will be group executed under this for loop and it will go from i equal to 0 till 9. Let us run this program and see what is the output for the first for loop. Similarly, there are also other two for loops which we will see little later. Let us now concentrate only on the first for loop. In fact, we can command all these lines by just selecting them and pressing command slash. So in Python, if you type a line which starts with a hash then Python will not execute those lines. So here, Python will not execute all these lines. Let us run this code where it will only run the first for loop. As we expected, you can see that it starts with i equal to 0 and every time we are printing the value of i. Therefore, you can see that i equal to 0 up to 9 only it went. That is very important as I shown here. It goes from 0 to 9 not up to 10 as we have written here. That is one thing that we have to remember. Next let us take another for loop where we are going from 3 to 10 range has basically three arguments. The first argument tells you where your range starts and the second argument says where it ends. Actually, it ends one number less than what you write and the third argument is about the step in which the numbers are incremented. If you do not specify anything as a third argument then by default range takes it as 1. Therefore, here writing comma 1 is equivalent to not writing it at all. So, in fact, you do not need to write it at all if it is just incremented by 1. You can see that the second for loop will print j equal to 3, 4, 5 up to 9 again because you have given 10 here therefore, it goes up to 9. What about this? This will make the print to be j equal to 3 comma and then it will not go to the next line whereas, here the outputs are printed one below the other. Now, it will be written one after the other. It is something like this up to j equal to 9 and then this print command will put a carriage written and comes to the next line to print and then this for loop will take up. Now, you can see that I am incrementing the range from 0 to 10 with an increment of 2. Therefore, it will go as 0, 2, 4, 8 and then 10 it will not print because you are allowing it to go only up to 9 therefore, it prints up to 8 only and comes out. Let us run this code. The first for loop we have already seen. In the second for loop if you recall, we asked the for loop to print one after the other that is how it went and in the third for loop we have printed k equal to 0, 2, 4, 6 and 8. In the next program, we will see how to use while loop. The format of the while loop is while and then the condition under which this loop has to run that is as long as this condition is satisfied the loop will keep on running and then this colon is just like in the for loop. It is a format of the while loop as well as for loop also it indicates that the line is ending there and then whatever is given as the indent here that will be considered as the part of the while loop. Here you can see that we have two lines which are written with indent therefore, they are considered as the part of the while loop and these two lines will be executed as long as the loop is going on and once the loop is over that is once if this condition is violated then the control comes out of the loop and prints this line that is what the program does. Let us run the program and see how the output looks like. You can see that first you have taken x is equal to 0 and then you went into the loop first you are checking what is x value x is surely less than 5 therefore, it incremented x by 1 what it means it is equivalent to saying x equal to x plus 1 and then you are printing x therefore, the first print command will print the output as x equal to 1 and then it goes back to the while loop and checks the condition as x is less than 5 because the value of x is 1 again it comes and does this and gives x equal to 2 and it goes on up to x equal to 5 when it comes for 5 it and goes prints and goes back to the while loop it checks whether 5 is less than 5 no therefore, it will come out and then since this print command is not given with an indent it will print not as the part of the while loop, but it will print once it comes out of the while loop. Now, the question is what happens if I also give an indent to this that is if I just put a tab and push it inside and align with these lines then this print will also be a part of this while loop. Now, if I run this code what happens every time it also prints that end of loop command because it is a part of the while loop now, but my aim is not to keep it as a part of the while loop. So, let me remove that let us go on with the next program the next program is an illustration of the if command that is the conditional command if else if and else this is very easy for you to understand therefore, I will leave it to you to understand this program it is not very difficult. The next program is an illustration of creating an array and extending the array length here we have a variable A in that we want to store a vector whose components are 1 2 and 3. So, this can be done by creating an array in python arrays are called lists and then what I want to do is I want to make this vector bigger every time when this for loop runs for that what you have to do is A which is the variable name dot append that will create one more memory space for the variable A and it stores the value of I in that newly created variable that is what it does and every time after extending the arrays length and storing the value of I into the new extended memory it prints the entire array A and then it does it for I is equal to 4 5 6 up to 10. Let us run this code and see how the output looks like you can see that when the control comes for the first time into the for loop the I value is equal to 4 A already had 3 components now it has appended one more component in that it has stored the variable value I into it which is 4 now that is why you see the variable output as 1 2 3 and 4 and then it goes back once again to the for loop now I is equal to 5 when it comes to this line it again extends A by one more memory and puts the value of I which is now 5 into it and then prints it that is why you can see you have 4 and then one more 5 similarly it goes on till I is equal to 10 not 11 again and again I am emphasizing because this is little confusing it goes from 4 till 10 well this is how you create a one dimensional array we will now see the danger in equating an array with another variable name let us consider this program where I am declaring a list or an array A is equal to 1 2 3 and then what I am doing is I am equating B is equal to A normally this should create a memory separately for the variable B and it should store the values of A into B and B should have the same list structure as A but it should have its own memory but in python what happens is B will not have its own memory but it will be mirrored with A and therefore any changes you make in B will also be reflected in A and vice versa let us see this by first printing the values of A and B and then go to store some value in one of the components of either A or B and that will be automatically reflected in the other variable also this is the danger of creating a variable B by equating it with a list let us run this program and see how the output comes well you can see that A is equal to 1 2 3 and then since we have written B is equal to A we also got B equal to 1 2 and 3 and finally I am changing the value of A 0 that is the first component of A is changed at this line as 100 that is correctly incorporated in A now you can see after changing that I am printing the value of A here and that is correctly taking care of the change happened in the first component of A but I never touched B you see I have only created B and stored A into 8 but I have never changed the value of B in any of the three components but since I have changed the first component of A from 1 to 100 it got reflected in the variable B also this is the danger of equating a list to a new variable on the other hand if you just put like this and see what happens now you can see that only A got changed as we wanted B is never touched upon so when you are defining a list and then you want to create another variable which initializes what is there in A then just do not put B equal to A that is very dangerous but you put B equal to A colon this is what is important when you are dealing with lists or otherwise called arrays and now we have understood the one dimensional arrays and their functionality let us go to see how to create and use two dimensional arrays a two dimensional array can be created like this now A can be viewed as a matrix whose elements are 1, 2, 3, 4, 5, 6 and 7, 8, 9, 10, 11, 8, 9 in order to emphasize that you do not need to give a space between comma and the number so I have written the last line without a space okay so that does not really matter so what I am doing here is I am basically defining two matrices A and B and then I want to multiply these two matrices you do not have a inbuilt command in python to multiply two matrices what you can do is you can create two for loops nested for loops and you can directly make the multiplication formula and get the product of two matrices or what you can do is there are some inbuilt libraries in python say for matrix multiplication you can find commands in a inbuilt library called numpy so how will you bring that numpy into your program you have to first import it this is what we are doing in the first line in fact you can do it anywhere before you use any command of that library or generally it is a good practice to define all the libraries that you are going to use in your program at the beginning of the program so I am just defining it at the beginning of the program you can also define it at this level because this is the first time you are using a numpy command right so you can also either put it here or you can put it at the beginning of the program so what it does is it imports all the commands which are written and kept in this library called numpy then whenever you call any of its commands say for instance mat mal will do the matrix multiplication of given two matrices a and b but to execute it you have to say that this command is sitting in the library called numpy so you have to type numpy dot mat mal if you do not want to type this full name then you have to import it as something so what I am choosing is I want to use instead of numpy np I want to use you can give any string here and then you can use that string to call the library I am using np therefore I have to put np dot mat mal this is matrix multiplication of a comma b and that I am storing in the variable c you can also use dot you can also use dot for multiplying a matrix with a vector which I am doing here you can see that I am multiplying the matrix a with x although this x is looking like a row vector in the dot command it will be automatically taken as a column vector and it gives you the correct result of a into x so therefore when you print this you will see the value a into x transpose here that is why I have just printed like this and in fact you can extract one particular row of the matrix a by giving this command remember in python the index always starts with 0 therefore when I give the index as 1 it is basically the second row but not the first row because first row is indexed as 0 in python it is something like c program the index starts always with 0 you have to remember that that is why I have written here print second row of a right but I have given 1 here why because 0 corresponds to the first row of a 1 corresponds to the second row of a now if I am interested in extracting a column can I put a colon 1 well that is not possible because colon 1 is not going to extract a column ok. So, column has to be done in a rather different way in order to extract a column you cannot define your matrix a in the normal list form you have to define it as np dot array of this. So, if this is a special command which is written and kept in the library numpy so you have to use that command to declare the matrix a just to have a different notation let me call this as a np you can see that the matrix a and a np are mathematically the same they are the same matrices, but a is defined using the usual list command of the python whereas, a and p is created using the command which is kept in the numpy why we are doing it with this now you can extract a column otherwise you can only extract rows you cannot extract columns let us print n a and p and now if you want to say extract the third column of the matrix a remember I am putting 2 here, but actually it extracts the third column because again I am emphasizing python will run from 0 to n minus 1 therefore, 2 will correspond to the third column and then a of colon comma 2 this will not extract the column that will not extract the column you can run this program and see what is the output of this you can see that the column extract is possible only with np you can see you get a is given like this and that we are asking it to extract the third column the third column is correctly extracted as 3 6 and 9 with a and p remember this first one is a and p and whereas, the second one is not extracting the third column, but it is still extracted the third row only. So, that is the main drawback of defining a two dimensional array directly with the inbuilt list form you have to define a matrix always with np dot array command we will learn more about handling matrices when we are doing the linear systems part let us now quickly go into the next topic of doing some programs with rounding errors. Let us see this interesting code the code says that I am I am storing the value 0.1 in x y equal to 0.2 and z equal to 0.3 then I am adding a equal to x plus y what will be the value of a mathematically a will be equal to 0.3 right then what I am doing is I am comparing z with a if z is equal to a it should give me yes it is z is equal to a that is what the print command should say otherwise it should say z is not equal to a. Obviously, we will expect that the output of this program should be z is equal to a let us see what is the output of this program the program is executed and surprisingly you can see that the code has written z is not equal to a why this is happening well this is not the problem with python you write the same code in any language that you know you can write it on matlab or any language you will see that the output is going to be z is not equal to a this is because when your processor does this computation it does not do exactly even though the numbers are very very small numbers and they are nice looking numbers also right therefore comparing such things when you are using non integer values are going to be very dangerous never do like this you should always keep a range of numbers and compare them only within that range you cannot do it with absolute comparison for instance if you take x y and z as 1 2 3 instead of 0.1, 0.2 and 0.3 then the output will be as you expect let us see what is the output of this program when I take x equal to 1 y equal to 2 and z is equal to 3 then it will print what you actually expect therefore this simple and interesting program says that computer even dealing with small numbers it has its very serious limitations on the rounding errors let us see this next interesting problem I am taking x equal to 0.8 plus 0.1 into 0.3 I am only 0.3 I am only 0.3 problem I am taking x equal to 0.8 plus 0.1 into 0.3 I am only bracketing the sum in a different way otherwise you can observe that x and y are going to be the same and then I want to find x by y right. So, I want to find x by y since x is equal to y this will be mathematically equal to 1, but since you are doing the arithmetic with real numbers they both may not have exactly equal value therefore this may not be exactly 1, but only approximately equal to 1. Now what I am doing I am subtracting 1 from x by y mathematically this should give me the value 0 and then just to have a catchy output I am multiplying it with a big number. Now whatever may be this big number it is finally a finite number therefore 0 into a finite number should be equal to 0 right. So we expect this print command to print z equal to 0 right. Let us see what is the output of this program you can see that the output is significantly large number you see we expect the output to be equal to 0, but computer made a huge error in this simple computation and this shows how dangerous it is for us to deal with computation especially when we do such computations blindly we may very likely land up with some disastrous answers. This also gives us a strong motivation to do a deeper analysis on numerical methods that we do before going into the implementation of those methods. We have to be very clear about how this methods are going to work and how we implement this methods on a computer. The next is let us take this another interesting program let us execute this program and see what is the output of this program. Well as expected you can see that a and b should be mathematically equal and that is what is also shown in this program. Now instead of 10 to the power of 15 let me make it as 10 to the power of 16 here and similarly here minus 10 to the power of 16 and run this program now you can see that a is still equal to 1, but b is not equal to 1. What happened is 10 to the power of 16 is something which has gone beyond the memory of the computer and that made this huge error between a and b. Let us try to understand this more closely let us take this program I have taken e is equal to 1 0 to 1 and we have x is equal to 2 to the power of e. Now I am going to increment my exponent e and every time I am going to save x is equal to 2 to the power of e this 2 stars means it is rise to the power it is equivalent to saying that this is nothing but 2 to the power of e mathematically. So therefore you have a loop running from 0 to 2 every time I am incrementing e by 1 and then rising 2 to the power of e and saving that value into x and then I am finding y equal to 1 by x z equal to x by x and then printing all this. Let us see what is the output of this program well the program gave a error that is because you are explicitly rising 2 to the power of e where this e is going beyond the memory capacity in the theory class we have seen that this is what we call as overflow of memory. When you are rising 2 to the power of e and the e is going beyond the maximum memory capacity of the computer then python is automatically recognizing it and giving a error command. Let us fool the python by not putting this command but define the same expression in a different way that is now what I am going to do is I am not going to increment e and then rise 2 to the power of e what I am going to do is I already have x equal to 2 to the power of e where e is 1 0 2 1. Now what I will do is every time I will multiply x by e this is nothing but x equal to x into e this one. Now, let us see what happens now python will not recognize it as an error it runs because you are not defining it in a nice way like 2 to the power of e you are not doing it with that it is able to recognize the overflow of memory but with this it is not able to recognize the overflow of memory it went on and computed it got x as infinity if you recall if the overflow of memory happens then the computer processor will treat it as infinity then y equal to 1 by infinity which it has printed as 0 and z is equal to infinity by infinity which is called as not a number n a n it has printed it as n a n from here you can see that the overflow of memory happens when the exponent is 1 0 2 4 this is 2 to the power of 1 0 2 4 is the limit of the memory of the computer in terms of 10 it is 10 to the power of 16 in terms of 2 it is 2 to the power of 1 0 2 4. So, that is what is happening here. So, there was a overflow of memory similarly you can also play around with the under flow of memory I leave it to you to play around with this code you just write this code and test it on your computer or on any programming language this will happen not only with python not only on colab it will happen with any programming language on any operating system as long as you are using a 64 bit processor this kind of overflow and under flow will always happen. Finally, we will try to understand what is machine epsilon python always deals with its variable by default in the double precision it means it gives 52 bits in the mantissa. Therefore, in one of the problems that we have seen in the last tutorial class if it is 52 bits it means 0 to 51 it goes. Therefore, from the 53rd digit onwards your processor will make a rounding approximation it takes up to 52 digits and then from the 53rd digit onwards it makes a rounding approximation in the last class we have seen that if such a thing happens then 2 to the power of minus n is the machine epsilon. So, that is what is given here I am taking x u is equal to 2 to the power of minus 53 and x o as 2 to the power of 53. Now, what I am doing is I am computing y as 100 into x o that is a big number into x u plus 1 minus 1. Now, you see this will be understood as 1 only in the computer and therefore, you will see that this is nothing but 1 minus 1 which is equal to 0. On the other hand if this is not there then this and this will get cancelled you are supposed to get the value 100 as the result, but you will get the answer as 0 for this because of this machine epsilon calculation. Let us see the output of this program you can see that y is equal to 0 whereas, it is supposed to give us y equal to 100 these are the limitations of the computer. This is not only for python or colab it is therefore, any program because this limitation is coming from the processor of your computer not from the program part ok. So, these limitations have to be carefully understood while you are working with this scientific computation otherwise you may be doing entirely wrong computation although you are method mathematically may be correct. Therefore, you have to first carefully understand all the limitations of the computer and also you should do the arithmetic error analysis of course, also you have to do the mathematical error analysis coming from the method and then arithmetic error analysis has to be done then you go for the programming of your method. This is the correct approach to numerical analysis with this let us finish this class. Thank you for your attention.