This is a 75-point project that must be submitted to the Moodle submission page for Project P12 by 11:00 PM on Tuesday, 29 November.
Sparse matrices are frequently used in scientific and engineering applications. In the assignment you are to use a linked list to read and print a sparse matrix, which will contain only integers.
There are five types of input commands for this assignment.
The first declares the array. It is of the form:
dcl X[#rows,#cols]
This creates an array with #rows rows and
#cols columns. The array is always
“named” X. Initially all the values
of the array are zero. This command should only appear as the
first line of input.
The second command increments a value of the array. It is of
the form:
inc X[row,col]
This causes one to be added to element
X[row,col].
The third command prints a value from the array.
prt X[row,col]
Your program should print something like the following,
where val is the value of
X[row,col],
in response to this command.
X[row,col] = val
The final two commands print all the non-zero
values of a row or column.
These values should be printed in the same format used for output
of the prt command. The command for printing a row is
row X[row,*]
and for printing a column is
col X[*,col]
You will be provided with five files to get you on your way for completing this assignment. For you convenience, all five have have been packaged into a single ZIP file.
The first file,
main.c,
contains the main
routine.
This code is responsible for parsing the commands and calling
the sparse matrix routines.
You should not modify this file.
The second file, parsecommand.c, is an ugly little C program that performs the grunt work of parsing the commands used for this program. It has an associated prototype header file, parsecommand.h, which is the third file for this project.
The fourth file,
sparcematrix.h,
defines the data structures used to represent the sparse matrix along
with prototypes for the sparse matrix routines called by main
.
You must not modify this file.
The sparse matrix is implemented with linked lists for the elements
of each row and column. The “control” structure for
the sparse matrix is struct sparceMatrix
.
This structure has fields numRows
and numCols
that store the dimensions of the matrix.
The structure also has fields rows
and cols
that point to linked lists used to implement the rows and columns.
Each element of these linked lists is a struct sparceElementRect
. These structures
record the row, column, and value of each non-zero element and
contains the threads of the row and column links.
The fifth file, sparcematrix.c, is a framework for completing the five routines needed to implement the assignments.
The first routine, createSparceMatrix
, will allocate
the struct sparceMatrix
and its
associated row and column arrays for the linked lists.
Initially all the pointers of these arrays will be NULL
to indicate that all of the linked lists are “empty.”
My createSparceMatrix
routine is about 25 lines of
code.
The second routine, incrementSparceMatrix
,
adds one to an element of the matrix.
It starts by searching for the element in the appropriate
row or column list. Usually, the element hasn’t be
created, so it will be necessary to allocate and initialize
a struct sparceElementRect
.
Be sure to place the newly allocated structure in the linked lists for
both its row and column.
If the element already exists, just add one to its value
field.
My implementation of incrementSparceMatrix
is
also about 25 lines of code. Searching for the element uses only
4 lines of code, so most of the work is in allocating the new element.
The third routine printValueSparceMatrix
will search for an element that matches its row and column parameter.
If a matching element is found, its value
field is
printed.
Otherwise, 0 is printed as the value of the “element”.
This one is about 20 lines long.
The remaining two routines printRowSparceMatrix
and printColSparceMatrix
print all the non-zero
elements within a column. As you can imagine, they are very similar.
Also, since they don’t have to do any matching, they are
relatively simple. Only about a dozen lines of code are required for each.
Learning how to use the debugger would be the best skill for completing this assignment.
If that investment isn’t for you, you will probably need to
instrument your code by writing lots of debugging printf
’s
into your code. Here's an example of one you could use to look at the
row array and print which row isn’t empty.
for (i=0; i<M->numRows; ++i) { if (M->rows[i] != NULL) { printf("Row %d is not empty\n"; i) ; } }
If you are more ambitious, you could print the first element of these non-empty rows.
for (i=0; i<M->numRows; ++i) { sparceElementPtr firstOnRow = M->rows[i] ; if (firstElementPtr != NULL) { printf("Row %d starts with %d\n", i, firstElementPtr->col) ; } }
If you don’t want to enter those commands and just want a program that calls your routines, you can try using a more automated driver for your main program. This file autotest.c will replace the main.c and parsecommand.c files described above. The problem with using this driver is that you won’t have control over the commands being sent to your program.
If you want to start your programming task with training wheels, you can try use a testing routine that provides a hard-crafted sparse matrix for your main program. This file trainingwheels.c also replaces the main.c and parsecommand.c. However, it is even creates an initial matrix for you.