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.
subroutine 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 adj_mod
contains
real, 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
module matmult
use adj_mod
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.