There is a huge gap between the conception of an idea and putting it into practice. During development, things fail far more often than not. Often, when something fails, many tests are needed to track down the cause of failure. Maybe the cause cannot even be found. More insidiously, failure may be below the threshold of detection and poor performance suffered for years. The dot-product test enables us to ascertain whether the program for the adjoint of an operator is precisely consistent with the operator itself. It can be, and it should be.

Conceptually, the idea of matrix transposition is simply *a*_{ij}'=*a*_{ji}.
In practice, however, we often encounter matrices far too large
to fit in the memory of any computer.
Sometimes it is also not obvious how to formulate the process at hand
as a matrix multiplication.
(Examples are differential equations and fast Fourier transforms.)
What we find in practice is that an application and its adjoint
amounts to two routines. The first routine
amounts to the matrix multiplication .The adjoint routine computes ,where is the conjugate-transpose matrix.
In later chapters we will be solving huge sets of simultaneous equations,
in which both routines are required.
If the pair of routines are inconsistent,
we are doomed from the start.
The dot-product test is a simple test for verifying that the two
routines are adjoint to each other.

The associative property of linear algebra says that we do not need parentheses in a vector-matrix-vector product like because we get the same result no matter where we put the parentheses. They serve only to determine the sequence of computation. Thus,

(26) | ||

(27) |

(28) |

The program for applying the dot product test is `dot_test`
. The Fortran way of passing a linear operator
as an argument is to specify the function interface. Fortunately, we
have already defined the interface for a generic linear operator. To
use the `dot_test` program, you need to initialize an operator
with specific arguments (the `_init` subroutine) and then pass
the operator itself (the `_lop` function) to the test program.
You also need to specify the sizes of the model and data vectors so
that temporary arrays can be constructed. The program runs the dot
product test twice, second time with `add = .true.` to test if
the operator can be used properly for accumulating the result like
.dottestdot-product test

I tested (29) on many operators
and was surprised and delighted to find
that it is often satisfied to an accuracy near the computing precision.
I do not doubt that larger rounding errors could occur,
but so far,
every time I encountered a relative discrepancy of 10^{-5} or more,
I was later able to uncover a conceptual or programming error.
Naturally,
when I do dot-product tests, I scale the implied matrix to a
small dimension in order
to speed things along, and to be sure that
boundaries are not overwhelmed by the much larger interior.

Do not be alarmed if the operator you have defined has truncation errors. Such errors in the definition of the original operator should be identically matched by truncation errors in the adjoint operator. adjoint ! truncation errors If your code passes the dot-product test, then you really have coded the adjoint operator. In that case, to obtain inverse operators, you can take advantage of the standard methods of mathematics.

We can speak of a continuous function *f*(*t*)
or a discrete function *f*_{t}.
For continuous functions we use integration,
and for discrete ones we use summation.
In formal mathematics, the dot-product test
*defines* the adjoint operator,
except that the summation in the dot product
may need to be changed to an integral.
The input or the output or both can be given
either on a continuum or in a discrete domain.
So the dot-product test
could have an integration on one side of the equal sign
and a summation on the other.
Linear-operator theory is rich with concepts not developed here.

4/27/2004