# 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

Our test using the inverter with the worked example in the Engineering Maths First Aid Kit outputted this instructive text file:
```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;
• 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.

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;

{

use this file except in compliance with the License, as described at
}

{\$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
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
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;

//validation
val(matrix.STRelements[countr1], matrix.REALelements[countr1], ValCheck);
if ValCheck <> 0 then
until valCheck = 0;
magic;
end; // end for

resetMatrix;
end; // end procedure

procedure display; //displays matrix
begin
writeln;
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;
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('  >>  ');
writeln;
textcolor(green);
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('  >>  ');
writeln;
textcolor(green);
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;

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;

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;
end;

CoFactors;
display;
// step three
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
scroll('Step four: Transposing the elements', true);
scroll('(this is flipping along the leading diagonal)', true);
transpositionalDisplay;
display;
// final step
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);

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('  >> ');

//matrix operations
'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);
textcolor(white);
SLOWinverse;
end;
'n', 'N': begin
inputMatrix;
writeln;
end;
'c', 'C': begin
cofactors;
display;
end;
'o', 'O': begin
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
error('ERROR: Command not recognised');
end;

continue
else
begin
writeln;
scroll('Would you like to do something else? (PRESS ''y'' for yes)', true);
writeln;
writeln;
if (iteration = 'y') or (iteration = 'Y') then
end; //end else

EndProgram;
end.program MatrixInverter;

{

use this file except in compliance with the License, as described at
}

{\$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
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
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;

//validation
val(matrix.STRelements[countr1], matrix.REALelements[countr1], ValCheck);
if ValCheck <> 0 then
until valCheck = 0;
magic;
end; // end for

resetMatrix;
end; // end procedure

procedure display; //displays matrix
begin
writeln;
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;
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('  >>  ');
writeln;
textcolor(green);
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('  >>  ');
writeln;
textcolor(green);
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;

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;

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;
end;

CoFactors;
display;
// step three
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
scroll('Step four: Transposing the elements', true);
scroll('(this is flipping along the leading diagonal)', true);
transpositionalDisplay;
display;
// final step
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);

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('  >> ');

//matrix operations
'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);
textcolor(white);
SLOWinverse;
end;
'n', 'N': begin
inputMatrix;
writeln;
end;
'c', 'C': begin
cofactors;
display;
end;
'o', 'O': begin
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
error('ERROR: Command not recognised');
end;

continue
else
begin
writeln;
scroll('Would you like to do something else? (PRESS ''y'' for yes)', true);
writeln;
writeln;
if (iteration = 'y') or (iteration = 'Y') then