Week 12: Transpose, Trace, and Norm
The transpose through an output array parameter, and the trace and norm as functions returning a value, reusing the week 11 readers and printers: dimensions swapped on print, squareness checked by the caller, a cast before squaring, and a revision list of the eight shapes every lab program is built from.
Functions That Produce Answers
The last lab week is matrices again, and this time the functions do the mathematics rather than the reading and printing. The transpose function fills a second matrix from the first, which is a function producing an array result through a parameter. The trace and norm functions each compute a single number from a matrix and return it, which is chapter 9's return value carrying the answer. Both programs reuse readMatrix and printMatrix from week 11 unchanged, and that reuse is the argument for having written them as functions in the first place.
Program 1: The Transpose of a Matrix
The transpose of an M by N matrix is the N by M matrix in which rows and columns change places: element [i][j] of the input becomes element [j][i] of the output.
Algorithm:
- Start.
- Read the rows and columns; if either is outside 1 to 10, print a message and stop. Read the matrix.
- For each row i and column j, set transpose[j][i] to matrix[i][j].
- Print the matrix and its transpose under headings.
- Stop.
Enter 2 3, then 1 2 3 and 4 5 6: the transpose has three rows of two, 1 4, 2 5, 3 6. The function's whole body is one assignment with the indices swapped, and the arrangement around it is what the marks are for. The transpose goes into a second array, t, passed in as a parameter, because the function cannot return an array in C and because a 2 by 3 matrix cannot be transposed in place: its transpose has a different shape, and overwriting the input while reading it would destroy elements not yet copied. The print call for t passes cols, rows in that order, since the transpose has as many rows as the input had columns; get that backwards and a 2 by 3 input prints a 2 by 3 block whose third column comes from cells of t that were never written. Those values are indeterminate, so reading them is undefined behaviour; they happen to print as zeros in this sandbox and could be anything elsewhere. It is the classic mistake in this program.
The array t reaches the function the same way m does, as a pointer to its first row, so the assignments inside transpose write into main's array directly and nothing needs to be copied back. That is chapter 11's rule that array parameters are never copies, and it is why a function can "return" a matrix through a parameter at all.
Program 2: The Trace and the Norm
The trace of a square matrix is the sum of its diagonal, the elements [i][i]. The norm used here is the square root of the sum of the squares of every element, which is defined for any shape. Trace needs a square matrix, and the program has to check.
Algorithm:
- Start.
- Read the rows and columns with the usual check, and read the matrix.
- Print the matrix.
- If the matrix is square, compute and print the trace; otherwise print that the trace is not defined for this shape.
- Compute and print the norm.
- Stop.
Enter 2 2, then 1 2 and 3 4: the trace is 1 + 4 = 5, and the norm is the square root of 1 + 4 + 9 + 16, which is 5.48. Then try 2 3 with 1 2 3 and 4 5 6: the trace line reports that it is not defined, and the norm is still printed, because it is defined for any shape and there is no reason to withhold it.
trace takes a single size, n, because a square matrix has only one, and it is main's job to establish that the matrix is square before calling it; the function is written for the case it is valid in, and the check lives with the code that has the information. It returns a long so that ten diagonal int values can be summed without overflow. norm accumulates in double and casts the element before squaring, (double) m[i][j] * m[i][j], because the product of two ints is an int and squares of values above 46340 overflow before they ever reach the double; the cast on the first operand converts the whole multiplication. That one cast is the difference between a norm that is right for every int and one that is right for small examples.
Weeks 13 to 15: Revision and the Lab Test
The syllabus gives two weeks to revise weeks 1 to 12 and then sits you at a machine with a program to write from memory. Twelve weeks of programs come down to a short list of shapes, and revising means being able to write each shape without looking:
- The guarded read:
if (scanf(...) != count)then a message andreturn 1, in front of every input. - The range guard: refuse N outside what the array holds or what the arithmetic can bear, before any loop.
- The accumulator: a total starting at 0 and a counted
foradding one term per pass. - The digit peeler:
n % 10andn / 10untilnis 0, with a copy ofnif it is needed later. - The ladder:
if,else if,elsefor exclusive cases, slabs included, with the lower slabs folded into each branch. - The
switch: constant cases,breakon every one,defaultalways present. - The array: a
#definecapacity, a checked count, a guarded fill loop, and printing with a space before every element but the first. - The function: prototype above
main, definition below, a status returned by anything that reads, and the column count in every two-dimensional parameter.
Every program in this chapter is one or two of those shapes with a formula in the middle. In the test, write the shape first and the formula second, and check the output against the sample in your record before calling it done.
Key Takeaways
- A function returns a matrix through an array parameter; transposing a non-square matrix needs a second array because the shape changes.
- Print a transpose with the dimensions swapped,
colsthenrows. - The trace is the diagonal sum of a square matrix and
mainchecks squareness before calling; the norm is the root of the sum of squares and is defined for any shape. - Cast before squaring,
(double) m[i][j] * m[i][j], so the product cannot overflow anint. - Reuse
readMatrixandprintMatrixunchanged across programs; that is what functions are for. - The lab test is a handful of shapes with a formula in the middle; revise the shapes.
How did you find this lesson?
Your rating helps us improve the content.
Create an account to track your progress and access interactive exercises. Already have one? Sign in.
Practice Exercises
The Transpose of a Matrix with a Function
Read the rows and columns of a matrix followed by its elements row by row, and print the matrix under the heading matrix A: and its transpose under the heading transpose:, one row per line with elements separated by single spaces. Compute the transpose in a user-defined function transpose(int m[MAX][MAX], int rows, int cols, int t[MAX][MAX]) that fills the second array with t[j][i] = m[i][j]; read and print with readMatrix and printMatrix from the previous week. Each dimension must be between 1 and 10 (MAX); otherwise print dimensions must be between 1 and 10 and return 1. If any number cannot be read, print invalid input and return 1.
The Trace and the Norm of a Matrix
Read the rows and columns of a matrix followed by its elements row by row. Print the matrix under the heading matrix A:, one row per line with single spaces. Then, if the matrix is square, print trace = 5 with the sum of its diagonal computed by a user-defined function long trace(int m[MAX][MAX], int n); otherwise print trace: not defined for a 2 by 3 matrix with the actual dimensions. Finally print norm = 5.48, the square root of the sum of the squares of every element to two decimal places, computed by a user-defined function double norm(int m[MAX][MAX], int rows, int cols) that accumulates in double and casts each element before squaring. Read and print with readMatrix and printMatrix. Each dimension must be between 1 and 10 (MAX); otherwise print dimensions must be between 1 and 10 and return 1. If any number cannot be read, print invalid input and return 1.
Lesson Discussion
Share your thoughts and questions
No comments yet. Be the first to share your thoughts!