Similar to vectors, composite operators can be built from primitive ones. The CompoundOperator combines two operators so that the output of the first operator is the input to the second. For example, an NMO-and-Stack operator can be constructed as a Compound Operator that combines the NMO and Stack operator. Such a Compound Operator does not require any additional programming. A programmer can concentrate on implementing the simple constituent operators and can rely on the composite operators to build up more complicated operators properly.
The CompoundOperator type is not the only composite operator: The Block Operator arranges operators into operator matrices. For example, a Block Operator organizes four operators into an operator matrix
In many cases, the programmer may be able to enhance the operator to compute additional information, such as the adjoint, the derivative, the gradient, or the Hessian. In general, such additional information allows a programmer to choose a more sophisticated solver. In Jag, every linear operator with adjoint automatically inherits its correct derivative, gradient, and Hessian method without the programmer having to add any additional code. If possible, composite operators combine their constituent's enhancements to enhancements of the composite. For example, the CompoundOperator of two linear operators with adjoint has an adjoint method as well.
In addition to the NMO operator, we wrote an entire family of convolution routines. We experimented with bilinear convolutions, recursive convolutions (for input and filters of any dimension), convolutions that are based on RsfC or RsfF, and convolutions that internally invoke native C subroutines. We also implemented a Residual, a Norm, and a composite NormResidual operator. These operators are useful for turning into a functional expression when necessary.