A linear operator can be defined as an extended matrix multiply. That is, it is a tensor product from one set of dimensions to another set of dimensions. It can sum along any number of dimensions, eliminating those dimensions. Also, it can expand any number of dimensions, adding new dimensions. Matrix multiplication is a particular case of a linear operator which sums along one dimension, and expands along another.

An operator only has three public functions

- The constructor
- The Forward() function that is applied to a model space and returns a data space.
- The Conjugate() function that is applied to a data space to produce a model space.

Using the summation convention, here are some familiar
geophysical operations. The order of subscripts of an operator
is defined by the axis mappings that the forward operator applies.
e.g. maps the *x* axis to a *v* axis.

Convolution along the time axis maps the time axis to a new
time axis (let us call it *t*'). The forward convolution
operator can be defined by:

The NMO modeling operator, , maps a trace from zero
offset to any given offset, *x*.

Our operators are procedural operators. That is, every operator has, at its heart, a procedure which tells it what to do with the space it is being applied to. When the operator is constructed (initialized), it is told what axes to apply itself to. At this point, it knows what axes, size, label, etc., it is expecting, and what axes it will output. Then, when the operator is applied to a space, it will automatically find the correct axes to apply itself to.

Any extra axes will merely be cycled through, applying the same operator to each index in that dimension. This ability to cycle through extra dimensions is built into the basic operator class. Any class that is derived from the base operator class inherits this ability without the author having to write any code to implement it.

In many cases the axis definitions are basic to the definition of the operator, so this strictly defined axis compatibility is necessary. e.g. a velocity analysis operator needs to know both the dimensions of the offset-time space that the forward operator should model to, and the dimensions of the velocity-time space that the conjugate operator creates.

In the current implementation you must specify all the attributes of the axes that an operator is to be applied to. This is not always necessary; a convolution operator only needs to match the axis label and sample rate. It can be applied to any length of trace stating at any initial sample. In the future we intend to implement a more liberal scheme for matching the axis definitions of operators and spaces.

Here is an example of constructing an operator. The ```floatConvolve`''
operator class performs convolution as its Forward function.

\\ Declare and initialize an instance of the floatConvolve class floatConvolve op(axis,filter);Where

floatspace result = op.Forward(x);If the x, does not have an axis that matches the axis that the operator is designed to be applied to an error will be generated at run time.

11/17/1997