|
|
|
|
Basic operators and adjoints |
With a collection of operators,
we can build more elaborate operators.
One method is chaining.
For example, the operator product
is represented in the subroutine
chain2( op1, op2, ...).
Likewise the operator product
is represented in the in the subroutine
chain3( op1, op2, op3,...).
Another way to make more elaborate operators
is to put operators in a matrix
such as subroutine array
also in module chain.
void sf_chain( sf_operator oper1 /* outer operator */,
sf_operator oper2 /* inner operator */,
bool adj /* adjoint flag */,
bool add /* addition flag */,
int nm /* model size */,
int nd /* data size */,
int nt /* intermediate size */,
/*@out@*/ float* mod /* [nm] model */,
/*@out@*/ float* dat /* [nd] data */,
float* tmp /* [nt] intermediate */)
/*< Chains two operators, computing oper1{oper2{mod}}
or its adjoint. The tmp array is used for temporary storage. >*/
{
if (adj) {
oper1 (true, false, nt, nd, tmp, dat);
oper2 (true, add, nm, nt, mod, tmp);
} else {
oper2 (false, false, nm, nt, mod, tmp);
oper1 (false, add, nt, nd, tmp, dat);
}
}
|
void sf_array( sf_operator oper1 /* top operator */,
sf_operator oper2 /* bottom operator */,
bool adj /* adjoint flag */,
bool add /* addition flag */,
int nm /* model size */,
int nd1 /* top data size */,
int nd2 /* bottom data size */,
/*@out@*/ float* mod /* [nm] model */,
/*@out@*/ float* dat1 /* [nd1] top data */,
/*@out@*/ float* dat2 /* [nd2] bottom data */)
/*< Constructs an array of two operators,
computing {oper1{mod},oper2{mod}} or its adjoint. >*/
{
if (adj) {
oper1 (true, add, nm, nd1, mod, dat1);
oper2 (true, true, nm, nd2, mod, dat2);
} else {
oper1 (false, add, nm, nd1, mod, dat1);
oper2 (false, add, nm, nd2, mod, dat2);
}
}
|
|
|
|
|
Basic operators and adjoints |