Module `matmult` implements both the operation to multiply a vector by a matrix and the operation to multiply the
data vector by the transpose matrix . The matrix
multiplication is preceded by a call to subroutine `
adjnull`, defined in module `adj`, which optionally
erases the output according to the value of the logical parameter
`add`. When `add=.true.`, the
result of applying the operator is accumulated in the output,
e.g. `y=y+B*x`.

module adj_mod containssubroutine adjnull (adj, add, x, y)

logical, intent (in) :: adj, add real, dimension (:) :: x, y

if (.not. add) then if (adj) then x = 0. else y = 0. end if end if

end subroutine adjnull

end module adj_mod

module matmult use adj_modreal, dimension (:,:), pointer, private :: b

contains

subroutine matmult_init (matrix) real, dimension(:,:), pointer :: matrix b => matrix end subroutine matmult_init

function matmult_op (adj, add, x, y) result (stat) integer :: stat logical, intent (in) :: adj, add real, dimension (:) :: x, y

integer :: i

call adjnull (adj, add, x, y)

do i = 1, size (x) if (adj) then x (i) = x (i) + sum (b (:, i) * y (:)) else y (:) = y (:) + b (:, i) * x (i) end if end do

stat = 0 end function matmult_op

end module matmult

Subroutine `matmult_init` serves as the object
constructor, copying a pointer to the matrix in a *private*
variable `b`, local with respect to the module, but
accessible by the actual operator function `
matmult_op`. The operator function returns an integer
`stat`. In our convention, the value `stat=0`
corresponds to a normal execution of the operator routine. Otherwise,
it can return the diagnostic of an error.

Fortran 90 has intrinsic functions `matmul` and
`dot_product` for matrix-vector manipulations,
which we could have used in this simple example. We prefer more
explicit style to show how the algebraic symmetry of mathematical
constructions translate into actual code. We will see more examples of
this symmetry in the following examples.

11/11/1997