Unit 1.3.3 Matrix-vector multiplication via dot products
ΒΆHomework 1.3.3.1.
Compute \(\left(\begin{array}{rrrr} 2 \amp 2 \amp -1 \amp 2\\ 2 \amp 1 \amp 0 \amp -2\\ -2 \amp -2 \amp 2 \amp 2 \end{array}\right) \left(\begin{array}{r} 2\\ -1\\ 0\\ -1 \end{array}\right) =\)
(Here we really care more about exposing the dot products of rows with the vector than the final answer.)
Consider the matrix-vector multiplication
The way one is usually taught to compute this operation is that each element of \(y \text{,}\) \(\psi_i \text{,}\) is updated with the dot product of the corresponding row of \(A \text{,}\) \(\widetilde a_i^T \text{,}\) with vector \(x \text{.}\) With our notation, we can describe this as
Remark 1.3.3.
The way we remember how to do the partitioned matrix-vector multiplication
is to replace the \(m \) with a specific integer, \(3 \text{,}\) and each symbol with a number:
If you view the first as a \(3 \times 1 \) matrix and the second as a \(1 \times 1 \) matrix, the result is
You should then notice that multiplication with the partitioned matrix and vector works the same way:
with the change that in (1.3.1) the multiplication with numbers commutes while in (1.3.1) the multiplication does not (in general) commute:
but, in general,
Indeed, \(\widetilde a_i^T x \) is a dot product (inner product) while we will later be reminded that \(x \widetilde a_i^T \) is an outerproduct of vectors \(\widetilde a_i \) and \(x \text{.}\)
If we then expose the individual elements of \(A \) and \(y \) we get
This discussion explains the IJ loop for computing \(y := A x + y \text{:}\)
where we notice that again the \(i \) index ranges over the rows of the matrix and \(j \) index ranges over the columns of the matrix.
Homework 1.3.3.2.
In directory Assignments/Week1/C complete the implementation of matrix-vector multiplication in terms of dot operations
#define alpha( i,j ) A[ (j)*ldA + i ] // map alpha( i,j ) to array A #define chi( i ) x[ (i)*incx ] // map chi( i ) to array x #define psi( i ) y[ (i)*incy ] // map psi( i ) to array y void Dots( int, const double *, int, const double *, int, double * ); void MyGemv( int m, int n, double *A, int ldA, double *x, int incx, double *y, int incy ) { for ( int i=0; i<m; i++ ) Dots( , , , , , ); }in file
Assignments/Week1/C/Gemv_I_Dots.c
. You can test it by executing make I_DotsUpon completion, this should print
It appears all is wellAdmittedly, this is a very incomplete test of the routine. However, it doesn't play much of a role in the course, so we choose to be sloppy.
Remark 1.3.4.
The file name Gemv_I_Dots.c can be decoded as follows:
The Gemv stands for "GEneral Matrix-Vector multiplication."
The I indicates a loop indexed by \(i\) (a loop over rows of the matrix).
The Dots indicates that the operation performed in the body of the loop is a dot product (hence the Dot) with the result added to a scalar (hence the s).