 Last time we discussed the array structure and saw how we could use arrays to rearrange a large number of numbers in sorted order. So, as I said last time we will be discussing matrices which are nothing but two dimensional arrays and we will see a specific problem which can be solved only using matrices very easily and that is the problem of solving a set of simultaneous algebraic equations in large number of unknown variables. Before that however I wish to point out a facility that is available in most operating systems certainly in UNIX, Linux and Ubuntu and so it is in Microsoft and all other well known operating systems and that is a easier mechanism to handle some very large values when we are to input a very large number of values not large values but very large number of values to be handled on input and output. Additionally, we will look at a new algorithm for merging two sorted arrays. I will comment on how this becomes extremely important in building efficient sorting procedures. So, first we look at handling large input and large output. Now, you have all been using keyboard to give your input, you are already used to getting your output that is produced by your c out statements in C plus plus programs on the monitor. But there are occasions when a program requires a very large number of values and it is particularly irksome if your program is still under the development stage and you are doing some debugging process. What is debugging? Anybody knows what is debugging? Long long time ago somebody who was irritated by an error in the program which he was not able to correct quickly and a friend of his asked what is bugging you and he says there is a bug in my program that is bugging you. So, bug is actually a bad bug but since then for decades bug is the name given to any error that is found in your program and removing that bug that is removing that error is called debugging. You would be familiar with compilation errors that you get usually those will be the more important errors that you feel exist in your programs. Very soon you will realize that they are absolutely nothing and that is because the compiler is there to tell you that there is some error. But when there is no syntax error and still your program does not work correctly then you realize that there is some problem with the implementation of your algorithm. You have goofed up in either some value being updated properly some index being assigned a correct value whatever whatever and longer the program becomes the harder it is to find such logical errors. So, typically what you will do you will implement your program algorithm in your program compile it run it you will give all the input that is required and then you find you do not get the correct results. You have no choice but go back to your source program make corrections or modifications recompile and rerun which is ok. But when you have to rerun giving let us say 100 values now compilation and correction and compilation may take only two minutes. But feeding those 100 values may take 10 minutes and you do not want every time you rerun the same program with some modification to keep typing 100 values every time. This is not the only case there are situations when you write a program for example for sorting a large array and someone else wants to use it tomorrow someone else wants to use it day after tomorrow everybody has to type in 1000 2000 values to be sorted every time one runs a program is not very conducive. So, clearly we need some other mechanism to handle large amount of input and output actually we believe that when we use see in and see out our input comes from the keyboard and our output goes to the monitor that is not strictly correct. What the operating system does that whenever it loads an executable program whenever you say dot slash a dot out dot slash a dot out is nothing but a command to the operating system to go to the desk find the a dot out file which contains your compiled program translated program and load it into the memory of the computer and hand over control to it. Whenever it does that it provides automatically three files to every such program which is run these three files are called the standard input file the standard output file and the standard error output file and they are abbreviated in unix as std in std out and std err. So, no matter what program you have written operating system will allocate these three files that those these are the files with which your program interacts for input whenever you execute a see in statement it does not come ordinarily from a keyboard it comes from a file called std in which the operating system has created and given similarly whenever you say see out the output does not come on your monitor it goes to a file called std out this is the file which operating system has created. Now ordinarily by default the operating system connects these to the devices namely keyboard for std in and std err to monitor. So, if this is your program let us say a dot out and somewhere you have a statement see in greater greater x when this statement is executed you expect input to come to you this input is actually coming from a file called a std in this is a file which operating system has created and as I have mentioned in the last slide this is automatically connected to your keyboard that is the reason why when see in statement is executed and when you type some numbers or input values on keyboard that stream of bytes is actually connected to std in which is connected to your inside. Similarly whenever in your program you say see out let us say why this output will actually go to std out it so happens that by default std out is connected to your monitor. Indeed unix operating system treats every device also as a file it is called a special file you will find these what they call device drivers or the programs which treat these devices as files and either collect input bytes from it or send output bytes to it these will be found in slash dev directory of any unix operating system. But that is not of our concern our concern is that if this is the standard connections that an operating system provides then how can I make my input come from a source other than the keyboard the operating system provides redirection. So if this is your a.out and as I said the input is connected to std in and the output is connected to std out instead of this connection to your keyboard it is possible to tell the operating system that look I want to run this a.out but I do not want to give input from keyboard. So please divert this std in to something else and collect input from this file what is in data.txt name of a file just like you create a c program file or whatever you can use your editor and create a text file. So suppose you have to give a value for x which is 5 you type 5 and return in that in data. In short whatever you would have typed on the keyboard you should anticipate that and prepare in advance all the input values in the form of a file like this. Since this redirection is possible and we shall see shortly how this redirection is to be commanded to the operating system operating system will severe the connection with keyboard. So no keyboard connection instead it will take input from this in exactly the same fashion it is possible to say please do not produce the output when you run this program please do not produce the output on monitor. So do not do not send it to monitor but instead send it to another file which is let us say out data.txt I am writing .txt merely to emphasize that output will be a text file just as input would be a text file. Names do not matter any name that you give it will produce an output in the text format and it will produce the output line by line row by row column by column exactly the way it would have produced it on the monitor no other. So a new line character will go to a new line etcetera to agree that such a facility will be useful. So this is what captures the essence of that facility this is called redirection. Please note that this input and output redirection are features of operating system they are nothing to do with your C plus plus program you continue to write your program with C in and C out. So for example if I give a command dot slash a dot out input data dot text this will read all input only from the named file what will happen if the file does not exist because you have forgotten to create the file the operating system will try to open that file and read from it. Since there is no file it will give an error that error is equivalent of saying file has ended there is nothing there it is just like pressing control D on the monitor when some input is expected. So you will get an error from your program which says that you are trying to execute some input statement but the data source has dried up it has disappeared. Please note the redirection symbol less than sign similarly you can redirect all output to a file which is indicated by dot slash a dot out greater than some name this will redirect all output and the redirection symbol is greater than sign. This less than and greater than symbols have no significance in relative comparison terms they are merely used because they point to the right direction. So less than symbol points leftward which means input greater than symbol points right words which means output that is the only. So do not confuse these commands or these symbols with anything that you do within your C plus plus program these are operating system commands given at the level of operating system. We said if input data file does not exist you will get an error in the input what if output data file dot txt already exists let us say you have run this program with redirection once next time you try to run it again what do you expect the operating system to do it will overwrite that file it does not care whether that file contains any useful data or not. So if you want to run the same program with different inputs then you should also create different output files if you want to retain all the output. We agree that this will be a very neat mechanism and in fact almost all of your projects that you will do and much of the program that you will write to handle very large data you will be using these most often you would be preparing the large data in the file and giving that as input. Here is an example of large data so I have roll numbers and marks for let us say my students of CS 101 I do not know exactly how many but I know they are not more than some 500 something so I will define two arrays roll and marks 600 each capital N followed by students is the number of students and K happens to be an index which I will use to iterate around the index of the arrays. I first read the number of students and then for K equal to 1 to n students in steps of 1 I will read roll number and marks this is standard absolutely no problem. Remember let us say I am writing a program which finds maximum marks and the corresponding students or I am writing a program to sort all marks in descending order and corresponding roll numbers you would agree that occasionally there would be an error that would creep in when you write your program some index value somewhere some boundary condition. Imagine every time you get the program compiled properly and try to run it and type in these 525 roll numbers and the marks and then you get an error and then again you try and so on that is where the input redirection would be most useful. So is that ok this is how I could create my file a sample so 11 is the value of N students this is followed by let us say 1001, 1002, 1004, 1005 these are different roll numbers and these may be the marks obtained. So I could create a file like this in fact for all the students and keep that file ready every time I want to run a program I can run. How will I execute this max marks dot cpp first I will compile the program and ordinarily I will execute the program like this this is where the input will come from keyboard and output will go on monitor. However I can use an input redirection I can use an input and output redirection so whatever is the output that will go into that file please note what I have written here a new file out max dot txt would be created to push the output onto that file it will be created in the current directory it is therefore useful to run your program from the directory where you want the results to be stored and if a file already exists it will be re-over it. You can specify an absolute path name to the file in which case the file will be created under whichever directory and sub directory that you want. Let me mention first why merging is important I hope you understand merging very naturally if I have two sorted arrays even containing these seven elements 15, 11, 9, 8, 6, 2, 1 and array T2 contains four elements 12, 5, 4, 3 each of these two arrays is a sorted array in descending order what I want to do is I want to merge these and create an array R can you tell me what will be the contents of R what will be the first element yes 15 this will be followed by 12 then 11, 9, 8, 6 and then suddenly this 5 will come here then 4, 3, 2, 1 agreed this should be the merged array observe that merged array is also in descending order what is the reason we are discussing this merging process so let me roll back and remind you what I had mentioned when we discussed the sorting algorithm the exchange sort or bubble sort that we discussed I said that it is a costly algorithm in that the total number of comparisons assignment shifting etcetera etcetera that the algorithm does is generally of the order of n square operations when n is the total number of elements to be sorted as an example if you have let us say 1 lakh numbers to be sorted and let us say the computer takes 10 seconds then if you have to sort 2 lakh numbers on an average it will take not 20 seconds but 40 seconds now 10 seconds to 40 seconds is a big jump I could think that instead of sorting 2 lakh numbers in one go which will take me 40 seconds let me sort 1 lakh number first which can be done in 10 seconds let me sort the remaining 1 lakh numbers next which will take me another 10 seconds I have spent only 20 seconds now if somehow I could merge these two sorted arrays in very quickly let us say in 2 seconds then the total time required will be 20 plus 22 seconds or 5 seconds it will be much less than 40 seconds and larger the numbers the greater would be the average how long will it take to merge two arrays how many operations will it involve there are totally n by 2 and n by 2 elements now so total elements are n will merging also take of the order of n square operations then there is not one but you saw that when we were mentally doing this merging process here we were looking at all the elements of one array and all the elements of second array but one element only once having decided whether that element goes into the result array or not we never looked at it again this did not happen in sorting sorting we had to keep on revisiting multiple this merge operation in fact is linear in n let us just very quickly go through this merge operation I have an array T1 I associate a index K with that array initially I start with 0 I have an array T2 I associate an index I again I start with 0 so K is married to T1 I is married to T2 the resultant array R is to be constructed by I associate an index J with R that means any time I push some element into R I will increment J by 1 initially I am starting with K equal to 0 I equal to 0 I will always compare T1 K with T2 I when K is equal to 0 what does that comparison mean is 15 greater than 12 of course 15 is greater than 12 so I will push this element 15 which is from T1 into R and the moment I do that I will increase K by 1 so the idea is I keep looking at two elements of one each from each array compare one of them will go into the resultant array whichever element goes I will increase the index of that array so that I will look at the next element and I will keep doing this till I proceed to the end now that K has become 1 T1 1 and T2 0 will be compared T1 1 is 11 T2 0 is 12 so that means now it is the turn of the element 12 to go in here which means this will now become 1 now I am comparing T1 1 and T2 1 so what will go now 11 and 5 are being compared 11 is larger so 11 will go here and this will become 2 now 9 and 5 will be compared remember now 5 remains same for some time 9 and 5 will be compared 9 is greater so 9 will come here and this will become 3 8 and 5 will be compared what will happen now 8 will go here and this will become 4 now 6 and 5 will be compared 6 will go here this will become 5 now 2 will be compared with 5 which is greater 5 so next will come 5 and this time this will become 2 now 4 will be compared with this 2 4 is greater than 2 so 4 will come out and this will become 3 third element is 3 3 is greater than 2 so 3 will come here and this will become 4 please remember the index must keep increasing as per our logic now I have a problem I have to compare T1 5 with T2 4 you agree I is 4 and K is 5 T1 5 is 2 all right but 2 is greater than what because T2 4 is undefined does not exist actually what has happened the T2 array has ended there is nothing more technically whenever such thing happens I should abandon this comparison business go to the other array and copy all the remaining elements if that array had exhausted first I would have done the same thing abandoned it come to the second array and copied all the remaining elements however I would like to keep my programming logic simple if possible and the programming logic says compare push increment compare push increment keep on doing this till you get all the elements enough I know what is my boundary condition if I am starting with j equal to 0 I have to continue pushing elements till the index becomes how much m plus n minus 1 if there are m elements here and n elements here if there are m elements in T1 and n elements in T2 total number of elements in the result array will be m plus n 0 is the first index so m plus n minus 1 is the last thing the moment index j becomes more by the way I must keep incrementing j every time I forgot to mention that every time I push a number here j must be increased so j keeps track of where the next number is going to come and whenever j exceeds this I should stop that is okay coming back to the original problem how can I simplify my programming without your polarizing my iterative algorithm where I say compare T1k and T2i and whichever element you pick up to push into R increase that R here we notice that we wish to compare with a non-existent element now suppose we put some artificial value as the last element of each of these two arrays an artificial value such that a comparison with it will always mean forget this element take other elements clearly a number that I should put here should be smaller than any number in T2 should be smaller than any number in T1 this is where we may be forced to make an assumption about the type of values that we are dealing with consider this example where we are dealing with roll numbers and marks now typically marks in any formal examination will vary between say 0 to 100 0 to 200 or something unless there is negative mark assuming that there is no negative marking any negative value could act as a guard or a sentinel or a corner stone at the end of that area so I push minus one here and minus one here these are two extra elements that I put at the end if I did that you will notice that your algorithm will continue to work correctly because now when this is four two will be compared not with a question mark but with minus one two is greater than minus one so you will get two here and this will increase to six six element is one one is compared with minus one one is still greater so one will come in here and this may become seven however by this time the overall iterative algorithm portion would have recognized that I have got m plus n elements and I can come out of the iteration this technique is often used by artificially putting a minimum possible value as the last element of course you will require one extra element in the array which is not too much of a storage problem the harder problem is to hunt out a proper sentinel if you cannot get a sentinel then there is an issue later on we shall see when we discuss the handling of files within our c plus plus program although I had digress but it is important to mention that what we saw in terms of input and output redirection is merely the tip of the ice bar because so far we have always presumed that we will give only input from one device which is keyboard and see output on one device which is monitor but with the redirection we know that input can come from a file and output can go to a file we should also know that in most applications you will have to collect input from multiple files and you may have to write output to multiple files take a banking transaction and you go to withdraw money from your ATM for you it is simple withdrawal of 200 rupees but what is happening at the back end is your account is being opened there are at least two files which are opened one is called the customer master which will validate that yes you have this account number this is your name the second will be the balance master which will say your account actually has so much value for you the output is only the money but for the back end computerized system it will have to update the account it has to subtract 200 rupees that you have withdrawn and rewrite that in a five additionally it will create a log a log record suppose something happens to this file tomorrow you should not claim your 200 rupees again so it will write some other place that means in general every program will have to do a large amount of input output with multiple files in real life so consequently this redirection which permits me to redirect only the STD in and STD out is not of much consequence in the more complex system we have facilities by which we can declare files in our programs create files open existing files read data from those files and if those files happen to be on the desk we can rewrite data and update the values inside those files we shall be studying all those things later on given that files will be handled there is a special terminator value which the operating system makes available to any program which runs on it that is called EOF end of file later on we will see how end of file can be treated as an equivalent of a sentinel where we are putting minus 1 today but that is for a later time suppose the arrays were sorted not in descending order but in ascending order will minus 1 work at the end? Suppose these two files T1 and T2 were not sorted in descending order but were sorted in ascending order and I want to create R in ascending order natural it would not work in fact the comparison will have to be different or the result of the comparison I will have to pick up the result value from the other array not the first array however at the end minus 1 is not good because I want now a value which is larger than the largest possible value so if marks are maximum out of 100 I could arbitrarily say 1000, 2000, 5000 again I will have to hunt out for an appropriate value here is the program for merging two arrays so notice a little bit of detailed commenting which is considered very vital as the programs become larger the program for merging two sorted arrays then it says input is values of m and n which is the number of elements and then values of elements of T1 and T2 arrays are assumed to be sorted output result array are containing sorted elements one vital piece of information is missing here you would like to write that assume to be sorted in descending order note carefully the declaration and comment that has been written here once the program actually starts arrays hold at most 99 sorted numbers in descending order at most 99 why the last number I want to use as minus one actually an array declared as T100 can hold 100 elements first will be T0 second will be T1 etcetera the last index may be T99 but that actually contains a valid value so there are 100 the size is actually 100 but I will put only 99 so here is the input I read m elements of the first array and n elements of the second array but I make sure that I put a sentinel value here as the mth element and another sentinel value here as the nth element is that clear I read all the input and push the next element as minus having done that so this is clear this is just the input and standard assignments to the sentinel the logic of the merge is actually extremely simple so this is the main algorithm this time I have chosen to use do why we could have used why could you have used for maybe you can try implementing in different control structures but this is probably the most straightforward iteration so I start with K equal to 0 I equal to 0 J equal to 0 and I compare T1K with T2R if T1K is greater than T2R then I take the kth element of T1 and push it to R and increase K if T1K is not greater than T2R then I take the ith element of T2 and push it to R so either I move the kth element of T1 or ith element of T2 one of the two elements will always be moved every time I look at the comparison in either case since I have pushed an element into the resultant array the resultant array index must also be increased by 1 J plus plus all that I need to do is go back and repeat this go back and repeat this because every time I do it either I will be pushing an element of T1 array or I will be pushing an element of T2 array into R and whichever element I pushed I am increasing that index and because I have put a sentinel value of minus 1 I am sure that my algorithm will work correctly till the very end and how long do I wish to continue as long as J is less than equal to M plus M is this correct the final condition I claim that the result array will have an extra value yes or no and if yes what will be that value let us take M as equal to 7 N as equal to 3 so totally how many element should be there in the result array 10 what should be the indices of those 10 elements 0 1 2 up to 9 J less than equal to M plus N M plus N is 10 not only when J is less than 10 but even when J is equal to 10 I want to continue when I continue an element will necessarily go into the index 10 which will be the 11th element in that so I will actually get that minus 1 one of the two sentinels which is not part of the original array it will be very funny if you give me two arrays and say for the please merge them and I said 16 9 4 3 minus 1 and you be happy with this suddenly this minus 1 popping up you have no clue why this minus 1 is coming you have you have data and you want it merged you are not designing this algorithm you are using my program so this is not correct what should be the correct condition then I should continue this iteration only while J is less than M you can now read a whole lot of beautiful algorithms which use sorting and merging sorting and merging sorting and merging so as I said you can you can automatically think of multiple ways I said if you had two lakh records to be sorted you could sort one lakh one lakh and merge them why stop there why not I take 50,000 50,000 50,000 50,000 and merge them why not I take 25,000 25,000 why not I take 12,000 why not I take only two elements or them next two elements or them next two elements or them and merge them these are all possible techniques and the best possible sorting algorithms come out of such thinking we shall see some of these later in the class but right now suffice it to say that we have understood the basic sorting and the basic merging later on week after when we discuss searching we will see how we utilize these facts here so this is the output statements so this is how I could execute my merge program this is kids stuff you can just read it of the model later we now come to another important use of arrays which are multi-dimensional it so happens that C++ very naturally extends the facility of array declaration and usage of single dimension to as many dimensions as you choose we shall be discussing two-dimensional arrays which are called matrices in our mathematical convention but there is no limit to the number of dimensions per se the way you declare a two-dimensional array is to say something like in a 50 40 so there are two brackets square brackets a single-dimensional array can be seen to have only one row one row n elements m elements of whatever a multi-dimensional array has one row two rows three rows fourth rows as many rows as you want so number of rows and number of columns together define a matrix and that is what is permitted to be defined in C++ so it has 50 rows and 40 columns each element is excess now by two indexes one index giving row number another index giving column so very straightforward so when I say a i j equal to 37 I will have some value j will have some value and these values will determine the row number n column the restrictions on index expressions are exactly same as they apply for one-dimensional array so if the size of the array is declared as say 50 for rows then I can vary from 0 to 49 and j can similarly vary from 0 to 39 so all rules any index i or j or both can be full-fledged numerical expressions each one will be evaluated separately converted to an integer and is your responsibility to ensure that that integer is within this range internally the storage is allocated for the entire size the moment you get that to see the declaration in a 50 comma 40 so not 50 comma 40 50 40 what it means is 2000 locations of 4 bytes each will be allocated remember in single dimensional array we said that the elements of the array occupy consecutive locations that is how C++ is able to figure out that if this is the index where should I go and look in exactly the same fashion two-dimensional arrays are also allocated consecutive locations and they are allocated in a row major order that means the 0th row all columns will be given first locations 0 1 2 3 4 5 what then the first row 0th column first column second column it is in this order that the locations will be aside although we don't have to do much with it at the moment but this is just for information so is this clear consequently whenever I say x is equal to y plus let us say bk multiplied by I can say a j star 3 i minus 7 multiplied by y if b is an array then this would be a perfectly valid expression expression evaluation as usual it will first evaluate this index this index and this index then it will pick out the appropriate element of b and pick out the appropriate element of given row number and given column number of a and use those values for doing your calculation is that ok so no confusion in this if I want to read input for a two dimensional matrix can I do that with only one iteration for i equal to 1 to n no for i equal to 0 to n minus 1 for example I will be able to vary only the row index or column index inside it I must have a nested iteration which for each value of i will change j from something to something and this complete nested iteration will take care of either reading writing or moving through all the elements of a two dimensional so these are almost logical consequences of such a declaration and usage we will now see an example of the use of matrix in our normal life and see how we could write a program everybody is familiar with a system of linear equations so you are familiar with matrices in this context I suppose you can represent the coefficients of unknown variables of a system of linear equations by a matrix as shown here so 2x plus 4y equal to 8 and 4x plus 3y equal to 1 can be represented by a matrix 2 4 4 3 and right hand side by a matrix 8 1 and we now know how to handle these matrices inside x and y are unknown variables we may declare an array of unknown variables there is nothing like an algebraic variable in programs but that is where we might put the final results once we calculate how do you calculate these results you can usually invert this matrix you are familiar with matrix inversion you know that determinant of a matrix what is a singular matrix determinant is 0 that means the matrix cannot be inverted in plain terms it means that that matrix represents such a set of simultaneous equations which are not all independent and therefore you cannot solve those equations for those unknown variables there are many techniques of solving these problems one known technique is called Gaussian elimination which is based on a simple algebraic properties of the set of such linear equations the first property is that the system remains unaffected if any equation in that system is multiplied by a constant common sense so if I have 2x plus 4y equal to 8 if I multiplied by 0.5 I will get 1x plus 2y equal to 4 please note that equation 1 dash and equation 1 are absolutely identical in terms of information that they carry there is no new information in either one one is derived from the other the whole system remains same as it was notice also that by multiplying it by an arbitrary constant 0.5 which is not as arbitrary as it appears because I have achieved the one of the unknown variables to have a coefficient 1 so you have these two equations equation 1 dash and equation 2 we can use now another property of the system the other property is that if I replace an equation by linear combination linear combination means I take one equation multiplied by some constant subtract it or add it to this equation and replace this equation by that I still do not have any change in the original system the original system remains unaffected first I represent these equations in the matrix form so I have 1 2 4 3 as the coefficient matrix and 4 1 as the right hand side please note that any transformation that I do on any equation will result in change values within the matrix and the R so this is the second property that I use that if an equation is replaced by a linear combination of itself and any other row then the system of equations remains same I now look at the equation 2 which was 4 x plus 3 y equal to 1 I want to replace this 4 x plus 3 y equal to 1 by something else I choose to replace it by first multiplying equation 1 dash by 4 this gives me 4 x plus 8 y equal to 16 and then I subtract 4 x plus 8 y equal to 16 from equation 2 I get this why am I doing this funny process I am trying to eliminate x since x had a coefficient 4 here and this equation had a coefficient 1 I multiply that by 4 and subtract that from here so I will get minus 5 y equal to minus this becomes equation 2 dash which I have written here and consequently this becomes the new equation observe the coefficient matrix let us go back a few slides we started the coefficient matrix of 2 4 4 3 then next we had it 1 2 4 3 so we got 1 here next we had it 1 2 0 minus 5 so we got 0 here we will do one more transformation we do not like this minus 5 here we like the one that you see in the upper left corner of the matrix I would like to get one there in order to get one what should I do I should multiply this equation by minus 1 by 5 minus 1 by 5 is minus 0.2 so when I multiplied by 0.2 I got this equation this is an extremely important matrix observe that this matrix has 1 on the diagonal and all 0 below what is such a matrix called upper triangular matrix and the property of an upper triangular matrix in the context of a system of simultaneous linear algebraic equations is that I can very easily find the values of all unknown variables starting with the last equation and moving backwards using back substitution so here for example the last equation 0 x plus 1 y equal to 3 directly gives me y equal to 3 I take that value of y go back to the previous equation substitute y and I can calculate x you will agree that instead of 2 by 2 equations if I had 10 by 10 equation I could have still followed exactly the same method although doing it by hand would amount to a lot of Godagini but it can be done the method is working now we will see how we can apply the matrices that we have learned the two dimensional arrays that we have learned to solve such a problem this is the essence of the problem is essence of the solution basically reduce the coefficient matrix where upper triangular form and use back substitution there are many variations of this method and these variations are required because in actual practice when you use floating point numbers which is what you have to use for computations you will face a lot of problems due to round off errors that means you are unlikely to get exact results if that alone was the problem you could live with it but depending upon the nature of the coefficient that you have in the given system of equations you may actually get very large errors in your solution and that is why there are numerical techniques very specifically evolved or research in order to provide reasonably correct solutions for very large systems which are not very stable systems as they call them the best reference on all such numerical analysis algorithms not only related to this but even other problem we are talking about linear algebraic equations you will have greater fun if instead of simple algebraic equations you have differential equations simultaneous differential equations and the fun will increase further if they are partial differential equations many of you will be actually solving large problems involving even thousand such variables ten thousand such variables and it is amazing how complex the analysis of the algorithm will become and how difficult it will become to get numerical solutions the book reference that I have given here is probably one of the most excellent books I have seen many of my colleagues in mechanical engineering aerospace engineering civil engineering routinely using this book and such papers to figure out what are the best methods I am saying all this to illustrate that while we are trying to learn programming to solve such problems there is far more to such problems in real engineering life than what it appears now here of course our main emphasis is to understand given a logical way of solving a problem how to write program to implement that so now that you know the logic are we ready to see how we could write a program for that first of all a general representation in matrix form I would generally represent a linear equation system by a matrix of this sort notice the notation that is being used a 1 1 a 1 2 a 1 3 a 1 n x 1 x 2 x 3 x n b 1 b 2 b 3 b n you agree that this is the natural way you represent however we know the peculiarity of c plus plus which is it the row index and column index do not start with 1 they start with 0 so it will be much better for us to represent such matrices in our own notation also using 0th row and 0th column as the starting point consequently in c plus plus style a general representation could be written like this so my unknown variables is now a vector which is x 0 x 1 x 2 x n if it is an n by n system similarly the right hand side vector is b 0 b 1 b 2 b n why I write like this because my subscripts denoting row number and column number can directly become my indexes in my computer program that is the only purpose and in the context of this c plus plus like representation the Gaussian elimination should result in me getting a matrix which is upper triangular matrix that means all diagonal would be 1 all elements below the diagonal will be 0 all elements above the diagonal will represent the corresponding values of the coefficients that appear after the Gaussian elimination case if I get such a matrix I hope you can easily write a program to calculate x n minus 1 then x n minus 2 etcetera x n minus 1 is simply b n minus 1 substitute that here you will get x n minus 2 and so on in a nutshell then the Gaussian elimination process is very simple so let us just consolidate what we have so far seen our ambition is to get a diagonal matrix upper triangular matrix like this initially we are starting with full matrix now we have to make suppose this is the 0 th row and this is the 0 th column the 0 th row 0 th column value should become 1 all other elements in that row should be appropriately changed and all elements below that in the 0 th column should become 0 of course they will not become 0 just like that they will become 0 if I subtract from each of the subsequent rows an appropriate multiple of the first row and that appropriate multiple will be a factor which will be based on the values of whatever you call a 0 0 and a 0 1 a 0 0 and a 0 2 etcetera etcetera so then calculate that factor once you have handled 0 th row and 0 th column you go to the sub matrix starting with row 1 column 1 then row 2 column 2 and so on so every time what you have to do a first of all get that fellow to be 1 b calculate the division of the multiplying factor by which you have to multiply this row to get a 0 here get a 0 here get a 0 here that means you have to have an iteration over all the remaining rows for this and within each iteration every element of that row will have to be appropriately multiplied by the value and subtracted from having seen this the program would be easy to understand this is the general system of equations a into x is equal to b and this is what we will have at the end when we have the upper triangular matrix I have just given this example of two variables that we saw rewritten in the form of matrix you can read through it from the Moodle it is not worthwhile going through that again here exactly the same thing that we had done this is merely for those who might get confused about what should be the index value here what should be the index value here when you actually work out the algorithm here is the program notice the declarations float mat a 100 by 100 mat b 100 x 100 notice these three things that I am using divisor factor and sum. So, divisor is what I divide every element of the row to get one there factor for any subsequent row by what factor I should multiply and subtract the corresponding row that I am concerned and sum of course is to calculate for my backtracking you know when I do reverse substitution then I will have to calculate some of those values which I have already found etcetera you will now see why input redirection could be vital suppose I say run this program and try it on a 6 by 6 matrix it would be tough to keep giving those 36 values of questions and 6 values on right hand side every time you test the program. So, internally I write it in terms of c in observe that there are two iterations one nested under the other which is required to read all elements of a matrix you agree I will vary from 0 to n minus 1 and j will vary from 0 to n minus all elements will be ready similarly I will read the matrix b now comes the elimination program for I will be equal to 0 I less than n I plus plus this is the main iteration and this carries on much beyond this page it is not ended I is equal to 0 means I am taking the 0th row and I am doing everything that is required to be done with that 0th row on to each one of the first second third fourth n n minus 1. So, I divide each row by the coefficients on the diagonal since I am talking about Ith row I is initially 0 later on I will become 1 then it will become 2. So, that is how I am proceeding below the matrix at the lower level initially. So, at any point in time I am looking at the Ith row and all the rows below that from that point on this. So, for a given Ith row the divisor is of course the I comma Ith element whatever is the element of that diagonal is the element since I want to divide each element of that row by that value the I comma Ith element will become 1 I will put an absolute 1 here I will not divide math I comma I by the divisor to get the result why because an actual floating point division may not get me 1 I want to make it 1 explicit having made that 1 I recalculate all coefficients in that row that is done. I have to calculate similarly the recalculate the corresponding element on the right hand side matrix which is what I am doing here. So, all elements in that row are over element the corresponding element of right hand side has been regret note that right now I have handled only the Ith row nothing else, but now for this value of I replace subsequent rows by subtracting the appropriate portion of the Ith equation from this. So, if I plus 1 is less than n that means I still have a row left then I will do all of that what will I do for k equal to I plus 1 to n minus 1 when I is 0 I k varies from 1 2 3 4 5 up to n minus when I is 5 k will vary from 6 7 8 up to n minus so for any row I am actually taking care of all the rows below it by this logic and what am I doing for every row I calculate the factor which is math a k k I. So, if I am looking at k Ith row then the k I element that is my factor and for math a k I I set it to 0 because I know I want to get it 0 below this point all elements have to become 0 that is how I will successfully get a upper triangular form by becoming 0. Note that if I do the actual subtraction I should actually get a 0 even in that position, but again because of the floating point arithmetic I am not sure. So, I am deliberately putting 0 because I know that it should be 0 mathematical the remaining elements I calculate every element math k j from that I subtract a factor of math a i j and get the new math a k this iteration will complete a complete row that is the kth row in a new appropriate form and the corresponding right hand side element is taken care of by this. You agree that when I finish the process I will get a upper triangular form I would strongly suggest that taken actual matrix say 3 by 3 it is not necessary that you look at the actual value, but it is necessary that you look at the indices as they vary between 0 1 and 2 and make sure that all elements are correctly being computed as desired in the Gaussian elimination process. You can confirm that this algorithm works another way of confirming it of course is to run it against the known system of equations and verify that there is a. The back substitution of course starting with the last variable say x n minus 1 is simply math b n minus 1 and for all values for i equal to n minus 2 to 0 notice that i is now being reduced by 1 i minus minus you are going backwards your first calculate x n minus 1 then for i equal to n minus 2 to this you will sum up all these elements subtracted from x i to get subtracted from math b i to get the x i this is back substitution. So you see your entire program for Gauss elimination is hardly 15 lines of code in just 15 to 20 lines of code you have now the power to make the computer solve a system of say 1000 by 1000 unknown 1000 equations and 1000 unknown I hope you appreciate the power of programming that now makes it possible for you to solve such complex problem. You will also appreciate that why I must have that input and output redirection otherwise I might write this program may be understand it in half an hour of discussion write some variation of it in other half an hour compile and run it but to feed 1000 by 1000 values while checking the program could be a mess the results are output like this. So I output the entire matrix a I output the entire matrix b please note that both the matrices are preserved they continue to contain whatever was the input and the final results is printed here this is the simple input data a file called cof slot text some arbitrary name I have given. So it has the left hand side coefficients of unknown variables and right hand side coefficients of matrix b say 4 by 4 matrix. So first the value 4 is given and next 4 rows each containing 4 values is given next there are 2 blank lines in between are they necessary no will they create a problem no because any number of return or blanks etcetera are ignored by C in as long as it is still looking for a valid value. So this will this input will be red and this is the output. So if you say dot slash a dot out less than cof slot txt greater than result dot text your input will be read from cof dot text and the output will be produced on result dot text. Please note nothing will appear on your monitor except the dollar symbol after the operating system has finished with your programming. Now the data has gone into a file there are 2 commands by which you can look at any text file on the screen one is called cat which is what is used here and the other is called less cat stands for concatenation actually the command is this command is very funny you can actually say cat file 1 file 2 file 3. So what it does is it concatenates all the 3 files and produces the output on your screen. So takes the first file put keeps putting lines on that on your screen when that file ends takes the second file takes the third file. If you give it only one parameter cat some file name it will concatenate only one file meaning it will simply throw it out on the monitor. So it is equivalent of saying print my file on the monitor the less command actually gives you control suppose there are too many lines in your file if you say cat the file will just go past your eyes very quickly and only the last few lines will be visible on the monitor. So if you say less it will show one screen full of information and wait patiently for you. So you have to press a key a space bar for example to go to the next page and so on is this clear there is only one problem the problem is that while values of x 0 x 1 x 3 x 2 x 3 are very clearly visible the input matrix has not come in a very unscramble fashion the values are not neatly written as rows and column you will see that 1.4 minus 2 lot of space minus 1.8 1 minus 1.08696 these are all fritter I would like the output to look like this. So the coefficient matrix appears in one side in a proper 4 by 4 format the right hand side appears properly. We have not seen yet how to control where our output characters appear on screen later on we shall see special functions in C plus plus called print f for example which will permit us to format the output well. In the meanwhile I would suggest try to use some tricks with C out for example introduce tab characters introduce spaces introduce appropriate strings with spaces so that you can get an output which looks decent but that is that is a matter of choice and test.