## Unit1.3.3Matrix-vector multiplication via dot products

###### Homework1.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) =$

Solution
\begin{equation*} \begin{array}{rcl} \left(\begin{array}{rrrr} 2 \amp 2 \amp -1 \amp 2\\ \hline 2 \amp 1 \amp 0 \amp -2\\ \hline -2 \amp -2 \amp 2 \amp 2 \end{array}\right) \left(\begin{array}{r} 2\\ -1\\ 0\\ -1 \end{array}\right) \amp=\amp \left( \begin{array}{r} \left(\begin{array}{rrrr} 2 \amp 2 \amp -1 \amp 2 \end{array}\right) \left(\begin{array}{r} 2\\ -1\\ 0\\ -1 \end{array}\right) \\ \hline \left(\begin{array}{rrrr} 2 \amp 1 \amp 0 \amp -2 \end{array}\right) \left(\begin{array}{c} 2\\ -1\\ 0\\ -1 \end{array}\right) \\ \hline \left(\begin{array}{rrrr} -2 \amp -2 \amp 2 \amp 2 \end{array}\right) \left(\begin{array}{c} 2\\ -1\\ 0\\ -1 \end{array}\right) \end{array} \right) \\ \amp=\amp \left( \begin{array}{r} 0 \\ 5 \\ -4 \end{array} \right) \end{array} \end{equation*}

(Here we really care more about exposing the dot products of rows with the vector than the final answer.)

Consider the matrix-vector multiplication

\begin{equation*} y := A x + y . \end{equation*}

The way one is usually taught to compute this operations 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

\begin{equation*} \begin{array}{rcl} \left( \begin{array}{c} \psi_0 \\ \hline \psi_1 \\ \hline \vdots \\ \hline \psi_{m-1} \end{array} \right) \amp:=\amp \left( \begin{array}{c} \widetilde a_0^T \\ \hline \widetilde a_1^T \\ \hline \vdots \\ \hline \widetilde a_{m-1}^T \end{array} \right) x + \left( \begin{array}{c} \psi_0 \\ \hline \psi_1 \\ \hline \vdots \\ \hline \psi_{m-1} \end{array} \right) \\ \amp = \amp \left( \begin{array}{c} \widetilde a_0^T x\\ \hline \widetilde a_1^T x\\ \hline \vdots \\ \hline \widetilde a_{m-1}^T x \end{array} \right) + \left( \begin{array}{c} \psi_0 \\ \hline \psi_1 \\ \hline \vdots \\ \hline \psi_{m-1} \end{array} \right) = \left( \begin{array}{c} \widetilde a_0^T x + \psi_0 \\ \hline \widetilde a_1^T x + \psi_1 \\ \hline \vdots \\ \hline \widetilde a_{m-1}^T x + \psi_{m-1} \end{array} \right). \end{array} \end{equation*}
###### Remark1.3.3.

The way we remember how to do the partitioned matrix-vector multiplication

\begin{equation*} \left( \begin{array}{c} \widetilde a_0^T \\ \hline \widetilde a_1^T \\ \hline \vdots \\ \hline \widetilde a_{m-1}^T \end{array} \right) x = \left( \begin{array}{c} \widetilde a_0^T x \\ \hline \widetilde a_1^T x \\ \hline \vdots \\ \hline \widetilde a_{m-1}^T x \end{array} \right) \end{equation*}

is to replace the $m$ with a specific integer, $3 \text{,}$ and each symbol with a number:

\begin{equation*} \left( \begin{array}{r} 1 \\ \hline -2 \\ \hline 3 \end{array} \right) (-1) . \end{equation*}

If you view the first as a $3 \times 1$ matrix and the second as a $1 \times 1$ matrix, the result is

$$\left( \begin{array}{r} 1 \\ \hline -2 \\ \hline 3 \end{array} \right) (-1) . = \left( \begin{array}{r} (1) \times (-1)\\ \hline (-2) \times (-1) \\ \hline (3) \times (-1) \end{array} \right) .\label{rowpartition-mv1}\tag{1.3.1}$$

You should then notice that multiplication with the partitioned matrix and vector works the same way:

$$\left( \begin{array}{c} \widetilde a_0^T \\ \hline \widetilde a_1^T \\ \hline \vdots \\ \hline \widetilde a_{m-1}^T \end{array} \right) = \left( \begin{array}{c} (\widetilde a_0^T) \times ( x )\\ \hline (\widetilde a_1^T) \times ( x ) \\ \hline \vdots \\ \hline ( \widetilde a_{m-1}^T ) \times ( x ) \end{array} \right) \label{rowpartition-mv2}\tag{1.3.2}$$

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:

\begin{equation*} (-2) \times (-1) = (-1) \times (-2) \end{equation*}

but, in general,

\begin{equation*} \widetilde a_{i}^T x \neq x \widetilde a_i^T. \end{equation*}

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

\begin{equation*} \begin{array}{l} \left( \begin{array}{c} \psi_0 \\ \psi_1 \\ \vdots \\ \psi_{m-1} \end{array}\right) \\ ~~~:= \left( \begin{array}{c @{~} c @{~} c @{~} c @{~} c @{~} c @{~} c @{~} c @{~} c @{~} c @{~} c} \alpha_{0,0} \amp \chi_0 \amp + \amp \alpha_{0,1} \amp \chi_1 \amp + \amp \cdots \amp \alpha_{0,n-1} \amp \chi_{n-1} \amp+ \amp \psi_0 \\ \alpha_{1,0} \amp \chi_0 \amp + \amp \alpha_{1,1} \amp \chi_1 \amp + \amp \cdots \amp \alpha_{1,n-1} \amp \chi_{n-1} \amp + \amp \psi_1 \\ \amp\amp\amp\amp\amp\vdots\amp\amp\amp \\ \alpha_{m-1,0} \amp \chi_0 \amp + \amp \alpha_{m-1,1} \amp \chi_1 \amp + \amp \cdots \amp \alpha_{m-1,n-1} \amp \chi_{n-1} \amp + \amp \psi_{m-1} \end{array} \right) \\ \end{array} \end{equation*}

This discussion explains the IJ loop for computing $y := A x + y \text{:}$

\begin{equation*} \begin{array}{l} {\bf for~} i := 0, \ldots , m-1 \\[0.05in] ~~~ \left. \begin{array}{l} {\bf for~} j := 0, \ldots , n-1 \\ ~~~ ~~~ \psi_i := \alpha_{i,j} \chi_{j} + \psi_i \\ {\bf end} \end{array} \right\} ~~~ \psi_i := \widetilde a_j^T x + \psi_i \\[0.1in] {\bf end} \end{array} \end{equation*}

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.

###### Homework1.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_Dots


Upon completion, this should print
It appears all is well

Admittedly, 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.