MatrixInverter
by Nathaniel Oshunniyi: Y12 Age ~17
Introduction
Nathaniel has had another great idea for an educational program and he makes it helpful to others with carefully designed output while improving his own command of advanced language features. This screenshot shows the menu and a matrix used for testing.

Program in action on a PC
We recommend Option s to see the working as in these screenshots. This screenshot shows the program running on a Raspberry Pi.

MatrixInverter running on the Pi
The final screenshot shows a later output on a PC following the same input sequence:

MatrixInverter showing calculation of a minor
Original Matrix: | 1.0000 3.0000 -1.0000 | | -2.0000 1.0000 2.0000 | | 0.0000 5.0000 3.0000 | >>>>> Step one: Calculating the determinant <<<<< >> Determinant = 21.0 >>>>> Step two: calculating the co-factor elements of the new matrix <<<<< | -7.0000 -6.0000 -10.0000 | | 14.0000 3.0000 5.0000 | | 7.0000 0.0000 7.0000 | >>>>> Step three: Multiplying by the sign matrix to create the co-factors <<<<< | -7.0000 6.0000 -10.0000 | | -14.0000 3.0000 -5.0000 | | 7.0000 -0.0000 7.0000 | >>>>> Step four: Transposing the elements <<<<< | -7.0000 6.0000 -10.0000 | | -14.0000 3.0000 -5.0000 | | 7.0000 -0.0000 7.0000 | >>>>> Final Step: Dividing by the determinant <<<<< | -0.3333 0.2857 -0.4762 | | -0.6667 0.1429 -0.2381 | | 0.3333 -0.0000 0.3333 |
The terminology can be confusing. Nathaniel refers to the cofactors before multiplication by the sign matrix as cofactor elements rather than the term minor used by Vitutor. For Option c to show the cofactors we added a line of code to call the procedure to apply the sign changes so that the program now gives the same result as WolframAlpha.
Technical Features
The program benefits from many technical features:
- own procedures and functions with parameters;
- use of inbuilt routines such as Val, Rewrite, Assign, CloseFile, Sleep and TextColor;
- appropriate comments;
- validation;
- nested loops;
- good use of case statement;
- effective animation, with scrolling text used for most but not all of the output;
- enumerated type;
- file handling;
- records;
- pointers;
- carefully formatted output.
Download
You can download the Pascal Source (instead of copying it from the page) and/or the executable MatrixInverter.exe for a PC.
Code
program MatrixInverter; { Copyright (c) 2015 Nathaniel Oshunniyi Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License, as described at http://www.apache.org/licenses/ and http://www.pp4s.co.uk/licenses/ } {$mode objfpc}{$H+} {At the end of step by step inverse say if you would like to save this worked solution to a text file} uses sysutils, strutils, crt; type TElement = (a, b, c, d, e, f, g, h, i); // enumerated type for user matrix input REALpointer = ^real; TMatrix = record REALelements: array[1..9] of real; // elements of matrix STRelements: array[1..9] of string; // string components of matrix elements (val) end; {I understand there is absolutely no need for a record here but I just want to get used to using them so I put one in.} const MAX: integer = 9; // maximum size of matrix (a little bit of future proofing) var matrix: TMatrix; fillMatrix: TElement; countr1, countr2, ValCheck: integer; // for loop integers answer, iteration : string; answerval: boolean; calcedDET: real; calc: array[1..9] of real; Pa, Pb, Pc, Pd, Pe, Pf, Pg, Ph, Pi: REALpointer; Ca, Cb, Cc, Cd, Ce, Cf, Cg, Ch, Ci: REALpointer; procedure scroll(text: string; line: boolean); // scrolling text var count: integer; begin for count := 1 to length(text) do begin write(text[count]); sleep(10); // change the speed of the scrolling text end; if line then writeln; // true = writeline, false = write end; procedure error(text: string); // user input errors begin textcolor(red); writeln(text); textcolor(white); end; procedure magic; // makes the elements simultaneously change begin clrscr; textcolor(cyan); writeln; writeln('| ', Pa^ : 12 : 4, ' ' , Pb^ : 12 : 4, ' ' , Pc^ : 12 : 4, ' |'); writeln('| ', Pd^ : 12 : 4, ' ' , Pe^ : 12 : 4, ' ' , Pf^ : 12 : 4, ' |'); writeln('| ', Pg^ : 12 : 4, ' ' , Ph^ : 12 : 4, ' ' , Pi^ : 12 : 4, ' |'); textcolor(white); end; procedure resetMatrix; // initialises the calculation variables var i : integer; begin for i := 1 to MAX do calc[i] := matrix.REALelements[i]; end; procedure inputMatrix; // user input matrix prompt begin scroll('Please enter your matrix:', true); writeln; textcolor(cyan); scroll('|a b c|', true); scroll('|d e f|', true); scroll('|g h i|', true); textcolor(white); //initialisation of variables with matrix do for countr2 := 1 to MAX do REALelements[countr2] := 0; Pa := @matrix.REALelements[1]; Pb := @matrix.REALelements[2]; Pc := @matrix.REALelements[3]; Pd := @matrix.REALelements[4]; Pe := @matrix.REALelements[5]; Pf := @matrix.REALelements[6]; Pg := @matrix.REALelements[7]; Ph := @matrix.REALelements[8]; Pi := @matrix.REALelements[9]; Ca := @calc[1]; Cb := @calc[2]; Cc := @calc[3]; Cd := @calc[4]; Ce := @calc[5]; Cf := @calc[6]; Cg := @calc[7]; Ch := @calc[8]; Ci := @calc[9]; //user input for fillMatrix := a to i do begin writeln; //user prompt repeat scroll('Element ', false); write(fillMatrix); scroll(': ', false); countr1 := ord(fillMatrix) + 1; readln(matrix.STRelements[countr1]); //validation val(matrix.STRelements[countr1], matrix.REALelements[countr1], ValCheck); if ValCheck <> 0 then error('ERROR: Please enter a number'); until valCheck = 0; magic; end; // end for resetMatrix; end; // end procedure procedure display; //displays matrix begin writeln; scroll('Your matrix is:', true); writeln; textcolor(cyan); writeln('| ', Ca^ : 12 : 4, ' ' , Cb^ : 12 : 4, ' ' , Cc^ : 12 : 4, ' |'); writeln('| ', Cd^ : 12 : 4, ' ' , Ce^ : 12 : 4, ' ' , Cf^ : 12 : 4, ' |'); writeln('| ', Cg^ : 12 : 4, ' ' , Ch^ : 12 : 4, ' ' , Ci^ : 12 : 4, ' |'); textcolor(white); end; function determinant: real; // calculates the 3 x 3 determinant var firstcomponent, secondcomponent: real; begin firstcomponent := (Pa^ * Pe^ * Pi^) + (Pb^ * Pf^ * Pg^) + (Pc^ * Pd^ * Ph^); secondcomponent := (Pg^ * Pe^ * Pc^) + (Ph^ * Pf^ * Pa^) + (Pi^ * Pd^ * Pb^); result := firstcomponent - secondcomponent; end; function smallDet(a, b, c, d : real): real; // calculates the 2 x 2 determinants needed for the cofactors begin { a b c d } result := a * d - b * c; end; procedure CoFactors; // calculates the cofactor elements (before sign matrix) begin with matrix do begin calc[1] := smallDet(Pe^, Pf^, Ph^, Pi^); calc[2] := smallDet(Pd^, Pf^, Pg^, Pi^); calc[3] := smallDet(Pd^, Pe^, Pg^, Ph^); calc[4] := smallDet(Pb^, Pc^, Ph^, Pi^); calc[5] := smallDet(Pa^, Pc^, Pg^, Pi^); calc[6] := smallDet(Pa^, Pb^, Pg^, Ph^); calc[7] := smallDet(Pb^, Pc^, Pe^, Pf^); calc[8] := smallDet(Pa^, Pc^, Pd^, Pf^); calc[9] := smallDet(Pa^, Pb^, Pd^, Pe^); end; end; procedure signMatrix; // multiplies sign matrix by cofactor elements (creating the cofactors) begin with matrix do begin calc[2] := calc[2] * -1; calc[4] := calc[4] * -1; calc[6] := calc[6] * -1; calc[8] := calc[8] * -1; end; end; procedure transpositionalDisplay; // transposes the cofactors begin Cb := @calc[4]; Cd := @calc[2]; Cc := @calc[7]; Cg := @calc[3]; Cf := @calc[8]; Ch := @calc[6]; end; procedure save; //saves the SLOWinverse procedure to a file var count: integer; det: real; savefile: text; begin assign(savefile, 'MatrixCalculation.txt'); rewrite(savefile); resetMatrix; det := determinant; writeln(savefile, 'Original Matrix:'); writeln(savefile, '| ', Ca^ : 12 : 4, ' ' , Cb^ : 12 : 4, ' ' , Cc^ : 12 : 4, ' |'); writeln(savefile, '| ', Cd^ : 12 : 4, ' ' , Ce^ : 12 : 4, ' ' , Cf^ : 12 : 4, ' |'); writeln(savefile, '| ', Cg^ : 12 : 4, ' ' , Ch^ : 12 : 4, ' ' , Ci^ : 12 : 4, ' |'); writeln(savefile); writeln(savefile); //step one (determinant) writeln(savefile, '>>>>> Step one: Calculating the determinant <<<<<'); writeln(savefile); if det = 0 then writeln(savefile, 'The determinant is 0 so there is no inverse') else begin writeln(savefile, ' >> Determinant = ', det : 0 : 1); //step two (cofactors) writeln(savefile); writeln(savefile, '>>>>> Step two: calculating the co-factor elements of the new matrix <<<<<'); CoFactors; writeln(savefile, '| ', Ca^ : 12 : 4, ' ' , Cb^ : 12 : 4, ' ' , Cc^ : 12 : 4, ' |'); writeln(savefile, '| ', Cd^ : 12 : 4, ' ' , Ce^ : 12 : 4, ' ' , Cf^ : 12 : 4, ' |'); writeln(savefile, '| ', Cg^ : 12 : 4, ' ' , Ch^ : 12 : 4, ' ' , Ci^ : 12 : 4, ' |'); // step three writeln(savefile); writeln(savefile, '>>>>> Step three: Multiplying by the sign matrix to create the co-factors <<<<<'); signMatrix; writeln(savefile, '| ', Ca^ : 12 : 4, ' ' , Cb^ : 12 : 4, ' ' , Cc^ : 12 : 4, ' |'); writeln(savefile, '| ', Cd^ : 12 : 4, ' ' , Ce^ : 12 : 4, ' ' , Cf^ : 12 : 4, ' |'); writeln(savefile, '| ', Cg^ : 12 : 4, ' ' , Ch^ : 12 : 4, ' ' , Ci^ : 12 : 4, ' |'); // step four writeln(savefile); writeln(savefile, '>>>>> Step four: Transposing the elements <<<<<'); transpositionalDisplay; writeln(savefile, '| ', Ca^ : 12 : 4, ' ' , Cb^ : 12 : 4, ' ' , Cc^ : 12 : 4, ' |'); writeln(savefile, '| ', Cd^ : 12 : 4, ' ' , Ce^ : 12 : 4, ' ' , Cf^ : 12 : 4, ' |'); writeln(savefile, '| ', Cg^ : 12 : 4, ' ' , Ch^ : 12 : 4, ' ' , Ci^ : 12 : 4, ' |'); //final step writeln(savefile); writeln(savefile, '>>>>> Final Step: Dividing by the determinant <<<<<'); for count := 1 to MAX do calc[count] := calc[count] / det; writeln(savefile, '| ', Ca^ : 12 : 4, ' ' , Cb^ : 12 : 4, ' ' , Cc^ : 12 : 4, ' |'); writeln(savefile, '| ', Cd^ : 12 : 4, ' ' , Ce^ : 12 : 4, ' ' , Cf^ : 12 : 4, ' |'); writeln(savefile, '| ', Cg^ : 12 : 4, ' ' , Ch^ : 12 : 4, ' ' , Ci^ : 12 : 4, ' |'); writeln(savefile); // end final end; textcolor(lightgreen); scroll(' Saved to file!', true); textcolor(white); closeFile(savefile); end; procedure inverse; //calculates the inverse var count: integer; det: real; begin det := determinant; if det = 0 then scroll('There is no inverse because the determinant is 0.', true) else begin CoFactors; for count := 1 to MAX do calc[count] := calc[count] / det; signMatrix; transpositionalDisplay; display; end; { The order in which you do the calculation does not matter as long as you start by calculating the new matrix elements } end; procedure SLOWinverse; //calculates the inverse var count: integer; det: real; answer: string; explanationDET: real; begin det := determinant; //step one (determinant) scroll('Step one: Calculating the determinant', true); scroll('Would you like to see how this is done? (PRESS ''y'' for yes)', true); write(' >> '); readln(answer); writeln; textcolor(green); if (answer = 'y') or (answer = 'Y') then begin scroll('Write out the matrix like this: ', true); textcolor(white); writeln('| a b c | a b '); writeln('| d e f | d e '); writeln('| g h i | g h '); textcolor(green); scroll('This makes it easier to visualise', true); writeln; scroll('The determinant is (aei + bfg + cdh) - (ceg + afh + bdi)', true); scroll('(look at the diagonals)', true); writeln; end; if det = 0 then begin textcolor(cyan); scroll('The determinant is 0 so there is no inverse', true); end else begin textcolor(cyan); writeln(' Determinant = ', det : 0 : 1); textcolor(white); //step two (cofactors) writeln; scroll('Step two: calculating the co-factors of the new matrix', true); scroll('Would you like to see how this is done? (PRESS ''y'' for yes)', true); write(' >> '); readln(answer); writeln; textcolor(green); if (answer = 'y') or (answer = 'Y') then begin scroll('Select an element, let us say a', true); writeln; textcolor(white); write('| '); textcolor(red); write('a '); textcolor(white); writeln('b c |'); writeln('| d e f |'); writeln('| g h i |'); writeln; readln; textcolor(green); scroll('Replace that element by:', true); scroll(' - Deleting the elements in its row and column', true); scroll(' - calculate the determinant of the 2x2 left', true); scroll(' - replace the element (in this case a) with the answer', true); writeln; readln; textcolor(red); writeln('| a b c |'); write('| d '); textcolor(white); writeln('e f |'); textcolor(red); write('| g '); textcolor(white); writeln('h i |'); writeln; scroll('The determinant of a 2x2 | a b |', true); writeln(' | c d | is: ad - bc'); writeln; scroll('So the determinant of | e f |', true); write(' | h i | is: '); explanationDET := smallDet(Pe^, Pf^, Ph^, Pi^); writeln(explanationDET : 0 : 1); writeln; textcolor(green); writeln; writeln('Element a is replaced with ', explanationDET : 0 : 1); textcolor(white); scroll('You do the same for each element', true); writeln; readln; end; CoFactors; display; // step three readln; scroll('Step three: Multiplying by the sign matrix to create the co-factors', true); scroll('sign matrix: | +1 -1 +1 |', true); writeln(' | -1 +1 -1 |'); writeln(' | +1 -1 +1 |'); signMatrix; display; // step four readln; scroll('Step four: Transposing the elements', true); scroll('(this is flipping along the leading diagonal)', true); transpositionalDisplay; display; // final step readln; scroll('Final Step: Dividing by the determinant', true); for count := 1 to MAX do calc[count] := calc[count] / det; display; writeln; end; scroll('Would you like to save this solution to a file? (PRESS ''y'' for yes)', true); scroll(' >> ', false); readln(answer); if (answer = 'y') or (answer = 'Y') then save; end; procedure EndProgram; begin writeln; writeln('Thanks for using the program!'); writeln(' - Nathaniel, the Don'); sleep(1222); exit; end; begin // first intro scroll('Welcome to the Matrix calculator', true); inputMatrix; //matrix calculations writeln; repeat scroll('What would you like to calculate:', true); writeln; scroll('Inverse (PRESS ''i'')', true); scroll('Inverse step-by-step (PRESS ''s'')', true); scroll('Save inverse calculation to file (PRESS ''q'')', true); writeln; scroll('Determinant (PRESS ''d'')', true); scroll('Co-factors (PRESS ''c'')', true); writeln; scroll('Show original matrix (PRESS ''o'')', true); scroll('Input new matrix (PRESS ''n'')', true); scroll('Exit (PRESS ''e'')', true); writeln; write(' >> '); readln(answer); answerval := true; //matrix operations case answer of 'i', 'I': inverse; 'd', 'D': begin textcolor(cyan); writeln; calcedDET := determinant; writeln('Determinant = ', calcedDET:0:2); textcolor(white); end; 'e', 'E': break; 's', 'S': begin textcolor(green); scroll('(Press ENTER to continue between each step)', true); readln; textcolor(white); SLOWinverse; end; 'n', 'N': begin inputMatrix; answerval := false; writeln; end; 'c', 'C': begin cofactors; signMatrix; // added by PPS display; end; 'o', 'O': begin scroll('Your matrix is:', true); writeln; textcolor(cyan); writeln('| ', Pa^:12:4, ' ' , Pb^:12:4, ' ' , Pc^:12:4, ' |'); writeln('| ', Pd^:12:4, ' ' , Pe^:12:4, ' ' , Pf^:12:4, ' |'); writeln('| ', Pg^:12:4, ' ' , Ph^:12:4, ' ' , Pi^:12:4, ' |'); textcolor(white); end; 'q', 'Q': save; else answerval := false; error('ERROR: Command not recognised'); end; if answerval = false then continue else begin writeln; scroll('Would you like to do something else? (PRESS ''y'' for yes)', true); readln(iteration); writeln; writeln; if (iteration = 'y') or (iteration = 'Y') then answerval := false; end; //end else until answerval = true; EndProgram; end.program MatrixInverter; { Copyright (c) 2015 Nathaniel Oshunniyi Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License, as described at http://www.apache.org/licenses/ and http://www.pp4s.co.uk/licenses/ } {$apptype console} {At the end of step by step inverse say if you would like to save this worked solution to a text file} uses sysutils, strutils, crt; type TElement = (a, b, c, d, e, f, g, h, i); // enumerated type for user matrix input REALpointer = ^real; TMatrix = record REALelements: array[1..9] of real; // elements of matrix STRelements: array[1..9] of string; // string components of matrix elements (val) end; {I understand there is absolutely no need for a record here but i just want to get used to using them so I put one in.} const MAX: integer = 9; // maximum size of matrix (a little bit of future proofing) var matrix: TMatrix; fillMatrix: TElement; countr1, countr2, ValCheck: integer; // for loop integers answer, iteration : string; answerval: boolean; calcedDET: real; calc: array[1..9] of real; Pa, Pb, Pc, Pd, Pe, Pf, Pg, Ph, Pi: REALpointer; Ca, Cb, Cc, Cd, Ce, Cf, Cg, Ch, Ci: REALpointer; procedure scroll(text: string; line: boolean); // scrolling text var count: integer; begin for count := 1 to length(text) do begin write(text[count]); sleep(10); // change the speed of the scrolling text end; if line then writeln; // true = writeline, false = write end; procedure error(text: string); // user input errors begin textcolor(red); writeln(text); textcolor(white); end; procedure magic; // makes the elements simultaneously change begin clrscr; textcolor(cyan); writeln; writeln('| ', Pa^ : 12 : 4, ' ' , Pb^ : 12 : 4, ' ' , Pc^ : 12 : 4, ' |'); writeln('| ', Pd^ : 12 : 4, ' ' , Pe^ : 12 : 4, ' ' , Pf^ : 12 : 4, ' |'); writeln('| ', Pg^ : 12 : 4, ' ' , Ph^ : 12 : 4, ' ' , Pi^ : 12 : 4, ' |'); textcolor(white); end; procedure resetMatrix; // initilises the calculation variables var i : integer; begin for i := 1 to MAX do calc[i] := matrix.REALelements[i]; end; procedure inputMatrix; // user input matrix prompt begin scroll('Please enter your matrix:', true); writeln; textcolor(cyan); scroll('|a b c|', true); scroll('|d e f|', true); scroll('|g h i|', true); textcolor(white); //initialisation of variables with matrix do for countr2 := 1 to MAX do REALelements[countr2] := 0; Pa := @matrix.REALelements[1]; Pb := @matrix.REALelements[2]; Pc := @matrix.REALelements[3]; Pd := @matrix.REALelements[4]; Pe := @matrix.REALelements[5]; Pf := @matrix.REALelements[6]; Pg := @matrix.REALelements[7]; Ph := @matrix.REALelements[8]; Pi := @matrix.REALelements[9]; Ca := @calc[1]; Cb := @calc[2]; Cc := @calc[3]; Cd := @calc[4]; Ce := @calc[5]; Cf := @calc[6]; Cg := @calc[7]; Ch := @calc[8]; Ci := @calc[9]; //user input for fillMatrix := a to i do begin writeln; //user prompt repeat scroll('Element ', false); write(fillMatrix); scroll(': ', false); countr1 := ord(fillMatrix) + 1; readln(matrix.STRelements[countr1]); //validation val(matrix.STRelements[countr1], matrix.REALelements[countr1], ValCheck); if ValCheck <> 0 then error('ERROR: Please enter a number'); until valCheck = 0; magic; end; // end for resetMatrix; end; // end procedure procedure display; //displays matrix begin writeln; scroll('Your matrix is:', true); writeln; textcolor(cyan); writeln('| ', Ca^ : 12 : 4, ' ' , Cb^ : 12 : 4, ' ' , Cc^ : 12 : 4, ' |'); writeln('| ', Cd^ : 12 : 4, ' ' , Ce^ : 12 : 4, ' ' , Cf^ : 12 : 4, ' |'); writeln('| ', Cg^ : 12 : 4, ' ' , Ch^ : 12 : 4, ' ' , Ci^ : 12 : 4, ' |'); textcolor(white); end; function determinant: real; // calculates the 3 x 3 determinant var firstcomponent, secondcomponent: real; begin firstcomponent := (Pa^ * Pe^ * Pi^) + (Pb^ * Pf^ * Pg^) + (Pc^ * Pd^ * Ph^); secondcomponent := (Pg^ * Pe^ * Pc^) + (Ph^ * Pf^ * Pa^) + (Pi^ * Pd^ * Pb^); result := firstcomponent - secondcomponent; end; function smallDet(a, b, c, d : real): real; // calculates the 2 x 2 determinants needed for the cofactors begin { a b c d } result := a * d - b * c; end; procedure CoFactors; // calculates the cofactor elements (before sign matrix) begin with matrix do begin calc[1] := smallDet(Pe^, Pf^, Ph^, Pi^); calc[2] := smallDet(Pd^, Pf^, Pg^, Pi^); calc[3] := smallDet(Pd^, Pe^, Pg^, Ph^); calc[4] := smallDet(Pb^, Pc^, Ph^, Pi^); calc[5] := smallDet(Pa^, Pc^, Pg^, Pi^); calc[6] := smallDet(Pa^, Pb^, Pg^, Ph^); calc[7] := smallDet(Pb^, Pc^, Pe^, Pf^); calc[8] := smallDet(Pa^, Pc^, Pd^, Pf^); calc[9] := smallDet(Pa^, Pb^, Pd^, Pe^); end; end; procedure signMatrix; // multiplies by sign matrix to the cofactor elements (creating the cofactors) begin with matrix do begin calc[2] := calc[2] * -1; calc[4] := calc[4] * -1; calc[6] := calc[6] * -1; calc[8] := calc[8] * -1; end; end; procedure transpositionalDisplay; // transposes the cofactors begin Cb := @calc[4]; Cd := @calc[2]; Cc := @calc[7]; Cg := @calc[3]; Cf := @calc[8]; Ch := @calc[6]; end; procedure save; //saves the SLOWinverse procedure to a file var count: integer; det: real; savefile: text; begin assign(savefile, 'MatrixCalculation.txt'); rewrite(savefile); resetMatrix; det := determinant; writeln(savefile, 'Original Matrix:'); writeln(savefile, '| ', Ca^ : 12 : 4, ' ' , Cb^ : 12 : 4, ' ' , Cc^ : 12 : 4, ' |'); writeln(savefile, '| ', Cd^ : 12 : 4, ' ' , Ce^ : 12 : 4, ' ' , Cf^ : 12 : 4, ' |'); writeln(savefile, '| ', Cg^ : 12 : 4, ' ' , Ch^ : 12 : 4, ' ' , Ci^ : 12 : 4, ' |'); writeln(savefile); writeln(savefile); //step one (determinant) writeln(savefile, '>>>>> Step one: Calculating the determinant <<<<<'); writeln(savefile); if det = 0 then writeln(savefile, 'The determinant is 0 so there is no inverse') else begin writeln(savefile, ' >> Determinant = ', det : 0 : 1); //step two (cofactors) writeln(savefile); writeln(savefile, '>>>>> Step two: calculating the co-factors of the new matrix <<<<<'); CoFactors; writeln(savefile, '| ', Ca^ : 12 : 4, ' ' , Cb^ : 12 : 4, ' ' , Cc^ : 12 : 4, ' |'); writeln(savefile, '| ', Cd^ : 12 : 4, ' ' , Ce^ : 12 : 4, ' ' , Cf^ : 12 : 4, ' |'); writeln(savefile, '| ', Cg^ : 12 : 4, ' ' , Ch^ : 12 : 4, ' ' , Ci^ : 12 : 4, ' |'); // step three writeln(savefile); writeln(savefile, '>>>>> Step three: Multiplying by the sign matrix to create the co-factors <<<<<'); signMatrix; writeln(savefile, '| ', Ca^ : 12 : 4, ' ' , Cb^ : 12 : 4, ' ' , Cc^ : 12 : 4, ' |'); writeln(savefile, '| ', Cd^ : 12 : 4, ' ' , Ce^ : 12 : 4, ' ' , Cf^ : 12 : 4, ' |'); writeln(savefile, '| ', Cg^ : 12 : 4, ' ' , Ch^ : 12 : 4, ' ' , Ci^ : 12 : 4, ' |'); // step four writeln(savefile); writeln(savefile, '>>>>> Step four: Transposing the elements <<<<<'); transpositionalDisplay; writeln(savefile, '| ', Ca^ : 12 : 4, ' ' , Cb^ : 12 : 4, ' ' , Cc^ : 12 : 4, ' |'); writeln(savefile, '| ', Cd^ : 12 : 4, ' ' , Ce^ : 12 : 4, ' ' , Cf^ : 12 : 4, ' |'); writeln(savefile, '| ', Cg^ : 12 : 4, ' ' , Ch^ : 12 : 4, ' ' , Ci^ : 12 : 4, ' |'); //final step writeln(savefile); writeln(savefile, '>>>>> Final Step: Dividing by the determinant <<<<<'); for count := 1 to MAX do calc[count] := calc[count] / det; writeln(savefile, '| ', Ca^ : 12 : 4, ' ' , Cb^ : 12 : 4, ' ' , Cc^ : 12 : 4, ' |'); writeln(savefile, '| ', Cd^ : 12 : 4, ' ' , Ce^ : 12 : 4, ' ' , Cf^ : 12 : 4, ' |'); writeln(savefile, '| ', Cg^ : 12 : 4, ' ' , Ch^ : 12 : 4, ' ' , Ci^ : 12 : 4, ' |'); writeln(savefile); // end final end; textcolor(lightgreen); scroll(' Saved to file!', true); textcolor(white); closeFile(savefile); end; procedure inverse; //calculates the inverse var count: integer; det: real; begin det := determinant; if det = 0 then scroll('There is no inverse', true) else begin CoFactors; for count := 1 to MAX do calc[count] := calc[count] / det; signMatrix; transpositionalDisplay; display; end; {The order in which you do the calculation does not matter as long as you start by calculating the new matrix elements} end; procedure SLOWinverse; //calculates the inverse var count: integer; det: real; answer: string; explanationDET: real; begin det := determinant; //step one (determinant) scroll('Step one: Calculating the determinant', true); scroll('Would you like to see how this is done? (PRESS ''y'' for yes)', true); write(' >> '); readln(answer); writeln; textcolor(green); if (answer = 'y') or (answer = 'Y') then begin scroll('Write out the matrix like this: ', true); textcolor(white); writeln('| a b c | a b '); writeln('| d e f | d e '); writeln('| g h i | g h '); textcolor(green); scroll('This makes it easier to visualise', true); writeln; scroll('The determinant is (aei + bfg + cdh) - (ceg + afh + bdi)', true); scroll('(look at the diagonals)', true); writeln; end; if det = 0 then begin textcolor(cyan); scroll('The determinant is 0 so there is no inverse', true); end else begin textcolor(cyan); writeln(' Determinant = ', det : 0 : 1); textcolor(white); //step two (cofactors) writeln; scroll('Step two: calculating the co-factors of the new matrix', true); scroll('Would you like to see how this is done? (PRESS ''y'' for yes)', true); write(' >> '); readln(answer); writeln; textcolor(green); if (answer = 'y') or (answer = 'Y') then begin scroll('Select an element, let us say a', true); writeln; textcolor(white); write('| '); textcolor(red); write('a '); textcolor(white); writeln('b c |'); writeln('| d e f |'); writeln('| g h i |'); writeln; readln; textcolor(green); scroll('Replace that element by:', true); scroll(' - Deleting the elements in its row and column', true); scroll(' - calculate the determinant of the 2x2 left', true); scroll(' - replace the element (in this case a) with the answer', true); writeln; readln; textcolor(red); writeln('| a b c |'); write('| d '); textcolor(white); writeln('e f |'); textcolor(red); write('| g '); textcolor(white); writeln('h i |'); writeln; scroll('The determinant of a 2x2 | a b |', true); writeln(' | c d | is: ad - bc'); writeln; scroll('So the determinant of | e f |', true); write(' | h i | is: '); explanationDET := smallDet(Pe^, Pf^, Ph^, Pi^); writeln(explanationDET : 0 : 1); writeln; textcolor(green); writeln; writeln('Element a is replaced with ', explanationDET : 0 : 1); textcolor(white); scroll('You do the same for each element', true); writeln; readln; end; CoFactors; display; // step three readln; scroll('Step three: Multiplying by the sign matrix to create the co-factors', true); scroll('sign matrix: | +1 -1 +1 |', true); writeln(' | -1 +1 -1 |'); writeln(' | +1 -1 +1 |'); signMatrix; display; // step four readln; scroll('Step four: Transposing the elements', true); scroll('(this is flipping along the leading diagonal)', true); transpositionalDisplay; display; // final step readln; scroll('Final Step: Dividing by the determinant', true); for count := 1 to MAX do calc[count] := calc[count] / det; display; writeln; end; scroll('Would you like to save this solution to a file? (PRESS ''y'' for yes)', true); scroll(' >> ', false); readln(answer); if (answer = 'y') or (answer = 'Y') then save; end; procedure EndProgram; begin writeln; writeln('Thanks for using the program!'); writeln(' - Nathaniel, the Don'); sleep(1222); exit; end; begin // first intro scroll('Welcome to the Matrix calculator', true); inputMatrix; //matrix calculations writeln; repeat scroll('What would you like to calculate:', true); writeln; scroll('Inverse (PRESS ''i'')', true); scroll('Inverse step-by-step (PRESS ''s'')', true); scroll('Save inverse calculation to file (PRESS ''q'')', true); writeln; scroll('Determinant (PRESS ''d'')', true); scroll('Co-factors (PRESS ''c'')', true); writeln; scroll('Show original matrix (PRESS ''o'')', true); scroll('Input new matrix (PRESS ''n'')', true); scroll('Exit (PRESS ''e'')', true); writeln; write(' >> '); readln(answer); answerval := true; //matrix operations case answer of 'i', 'I': inverse; 'd', 'D': begin textcolor(cyan); writeln; calcedDET := determinant; writeln('Determinant = ', calcedDET:0:2); textcolor(white); end; 'e', 'E': break; 's', 'S': begin textcolor(green); scroll('(Press ENTER to continue between each step)', true); readln; textcolor(white); SLOWinverse; end; 'n', 'N': begin inputMatrix; answerval := false; writeln; end; 'c', 'C': begin cofactors; display; end; 'o', 'O': begin scroll('Your matrix is:', true); writeln; textcolor(cyan); writeln('| ', Pa^:12:4, ' ' , Pb^:12:4, ' ' , Pc^:12:4, ' |'); writeln('| ', Pd^:12:4, ' ' , Pe^:12:4, ' ' , Pf^:12:4, ' |'); writeln('| ', Pg^:12:4, ' ' , Ph^:12:4, ' ' , Pi^:12:4, ' |'); textcolor(white); end; 'q', 'Q': save; else answerval := false; error('ERROR: Command not recognised'); end; if answerval = false then continue else begin writeln; scroll('Would you like to do something else? (PRESS ''y'' for yes)', true); readln(iteration); writeln; writeln; if (iteration = 'y') or (iteration = 'Y') then answerval := false; end; //end else until answerval = true; EndProgram; end.