#include <Thyra_LinearOpBase_decl.hpp>
Inheritance diagram for Thyra::LinearOpBase< Scalar >:
Public interface functions | |
virtual RCP< const VectorSpaceBase< Scalar > > | range () const =0 |
Return a smart pointer for the range space for this operator. | |
virtual RCP< const VectorSpaceBase< Scalar > > | domain () const =0 |
Return a smart pointer for the domain space for this operator. | |
bool | opSupported (EOpTransp M_trans) const |
Return if the M_trans operation of apply() is supported or not. | |
void | apply (const EOpTransp M_trans, const MultiVectorBase< Scalar > &X, const Ptr< MultiVectorBase< Scalar > > &Y, const Scalar alpha, const Scalar beta) const |
Apply the linear operator to a multi-vector : Y = alpha*op(M)*X + beta*Y . | |
virtual RCP< const LinearOpBase< Scalar > > | clone () const |
Clone the linear operator object (if supported). | |
Deprecated. | |
THYRA_DEPRECATED bool | applySupports (const EConj conj) const |
Deprecated. | |
THYRA_DEPRECATED void | apply (const EConj conj, const MultiVectorBase< Scalar > &X, MultiVectorBase< Scalar > *Y, const Scalar alpha=static_cast< Scalar >(1.0), const Scalar beta=static_cast< Scalar >(0.0)) const |
Deprecated. | |
THYRA_DEPRECATED bool | applyTransposeSupports (const EConj conj) const |
Deprecated. | |
THYRA_DEPRECATED void | applyTranspose (const EConj conj, const MultiVectorBase< Scalar > &X, MultiVectorBase< Scalar > *Y, const Scalar alpha=static_cast< Scalar >(1.0), const Scalar beta=static_cast< Scalar >(0.0)) const |
Deprecated. | |
Protected virtual functions to be overridden by subclasses. | |
virtual bool | opSupportedImpl (EOpTransp M_trans) const =0 |
Override in subclass. | |
virtual void | applyImpl (const EOpTransp M_trans, const MultiVectorBase< Scalar > &X, const Ptr< MultiVectorBase< Scalar > > &Y, const Scalar alpha, const Scalar beta) const =0 |
Override in subclass. | |
Related Functions | |
(Note that these are not member functions.) | |
bool | isFullyUninitialized (const LinearOpBase< Scalar > &M) |
Determines if a linear operator is in the "Fully Uninitialized" state or not. | |
bool | isPartiallyInitialized (const LinearOpBase< Scalar > &M) |
Determines if a linear operator is in the "Partially Initialized" state or not. | |
bool | isFullyInitialized (const LinearOpBase< Scalar > &M) |
Determines if a linear operator is in the "Fully Initialized" state or not. | |
bool | opSupported (const LinearOpBase< Scalar > &M, EOpTransp M_trans) |
Determines if an operation is supported for a single scalar type. | |
void | apply (const LinearOpBase< Scalar > &M, const EOpTransp M_trans, const MultiVectorBase< Scalar > &X, const Ptr< MultiVectorBase< Scalar > > &Y, const Scalar alpha=static_cast< Scalar >(1.0), const Scalar beta=static_cast< Scalar >(0.0)) |
Non-member function call for M.apply(...) . | |
void | apply (const LinearOpBase< double > &M, const EOpTransp M_trans, const MultiVectorBase< double > &X, const Ptr< MultiVectorBase< double > > &Y, const double alpha=1.0, const double beta=0.0) |
Calls apply<double>(...) . |
Y = alpha*M*X + beta*Y
Y = alpha*conjugate(M)*X + beta*Y
through the apply()
function and the operations
Y = alpha*transpose(M)*X + beta*Y
Y = alpha*adjoint(M)*X + beta*Y
through the applyTranspose()
function where Y
and X
are MultiVectorBase
objects. The reason for the exact form of the above operations is that there are direct BLAS and equivalent versions of these operations and performing a sum-into multiplication is more efficient in general.
x
and y
that lie in the domain and the range spaces of the non-transposed linear operator y = M*x
. These spaces are returned by domain()
and range()
.First, note that there is a forward declaration for this class of the form
template<class Scalar> class LinearOpBase;
that allows the class to be refereed to using just one Scalar type as LinearOpBase<Scalar>
. This is useful for both clients and subclass implementations.
When a client ANA can only support a single-scalar type of linear operator, it may be more convenient to use some of the wrapper functions such as Thyra::apply()
and Thyra::opSupported()
that are described here.
domain()
and range()
may have specialized implementations of the scalar product (i.e. in general). As a result, the operator and adjoint operator must obey the defined scalar products. Specifically, for any two vectors (in the domain space of A
) and (in the range space of A
), the adjoint operation must obey the adjoint property
where is the scalar product defined by this->range()->scalarProd()
and is the scalar product defined by this->domain()->scalarProd()
. This property of the adjoint can be checked numerically, if adjoints are supported, using the testing utility class LinearOpTester
.
Y
with the input object X
in apply()
or applyTranspose()
. Allowing aliasing would greatly complicate the development of concrete subclasses.LinearOpBase
object can not support a particular type of operator application, then this is determined by the functions applySupports()
and applyTransposeSupports()
.LinearOpTester
provides a full featured set of tests for any LinearOpBase
object. This testing class can check if the operator is truly "linear", and/or if the adjoint relationship holds, and/or if an operator is symmetric. All of the tests are controlled by the client, can be turned on and off, and pass/failure is determined by tolerances that the client can specify. In addition, this testing class can also check if two linear operators are approximately equal.LinearOpBase
object has three different states of initialization. These three initailziation states, a description of their definition, and non-member helper functions that return these states are given below:
(is_null(this->range()) && is_null(this->domain()))
, Nonmember function: isFullyUninitialized()
(!is_null(this->range()) && !is_null(this->domain())) && (!this->applySupports(conj) && !this->applyTransposeSupports(conj))
for all values of conj
, Nonmember function: isPartiallyInitialized()
(!is_null(this->range()) && !is_null(this->domain())) && (this->applySupports(conj) || this->applyTransposeSupports(conj))
for at least one valid value for conj
, Nonmember function: isFullyInitialized()
These three different states of initialization allow for the simplification of the implementation of many different types of use cases.
domain()
, range()
and apply()
. Note that the functions domain()
and range()
should simply return VectorSpaceBase
objects for subclasses that are already defined for the vectors that the linear operator interacts with through the function apply()
. Therefore, given that appropriate VectorSpaceBase
and MultiVectorBase
(and/or VectorBase
) subclasses exist, the only real work involved in implementing a LinearOpBase
subclass is in defining a single function apply()
.
This interface provides default implementations for the functions applyTranspose()
and applyTransposeSupports()
where it is assumed that the operator does not support transpose (or adjoint) operator applications. If transpose (and/or adjoint) operator applications can be supported, then the functions applyTranspose()
and applyTransposeSupports()
should be overridden as well.
If possible, the subclass should also override the clone()
function which allows clients to create copies of a LinearOpBase
object. This functionality is useful in some circumstances. However, this functionality is not required and the default clone()
implementation returns a null smart pointer object.
Definition at line 205 of file Thyra_LinearOpBase_decl.hpp.
virtual RCP< const VectorSpaceBase<Scalar> > Thyra::LinearOpBase< Scalar >::range | ( | ) | const [pure virtual] |
Return a smart pointer for the range space for this
operator.
Note that a return value of return.get()==NULL
is a flag that *this
is not fully initialized.
If return.get()!=NULL
, it is required that the object referenced by *return.get()
must have lifetime that extends past the lifetime of the returned smart pointer object. However, the object referenced by *return.get()
may change if *this
modified so this reference should not be maintained for too long.
New Behavior! It is required that the VectorSpaceBase
object embedded in return
must be valid past the lifetime of *this
linear operator object.
virtual RCP< const VectorSpaceBase<Scalar> > Thyra::LinearOpBase< Scalar >::domain | ( | ) | const [pure virtual] |
Return a smart pointer for the domain space for this
operator.
Note that a return value of return.get()==NULL
is a flag that *this
is not fully initialized.
If return.get()!=NULL
, it is required that the object referenced by *return.get()
must have lifetime that extends past the lifetime of the returned smart pointer object. However, the object referenced by *return.get()
may change if *this
modified so this reference should not be maintained for too long.
New Behavior! It is required that the VectorSpaceBase
object embedded in return
must be valid past the lifetime of *this
linear operator object.
bool Thyra::LinearOpBase< Scalar >::opSupported | ( | EOpTransp | M_trans | ) | const [inline] |
Return if the M_trans
operation of apply()
is supported or not.
Preconditions:
isPartiallyInitialized(*this)
Note that an operator must support at least one of the values of ETrans
(i.e. the transposed or the non-transposed operations must be supported, both can not be unsupported)
Definition at line 258 of file Thyra_LinearOpBase_decl.hpp.
void Thyra::LinearOpBase< Scalar >::apply | ( | const EOpTransp | M_trans, | |
const MultiVectorBase< Scalar > & | X, | |||
const Ptr< MultiVectorBase< Scalar > > & | Y, | |||
const Scalar | alpha, | |||
const Scalar | beta | |||
) | const [inline] |
Apply the linear operator to a multi-vector : Y = alpha*op(M)*X + beta*Y
.
M_trans | [in] Determines whether the operator is applied or the adjoint for op(M) . | |
X | [in] The right hand side multi-vector. | |
Y | [in/out] The target multi-vector being transformed. When beta==0.0 , this multi-vector can have uninitialized elements. | |
alpha | [in] Scalar multiplying M , where M==*this . The default value of alpha is 1.0 | |
beta | [in] The multiplier for the target multi-vector Y . The default value of beta is 0.0 . |
nonnull(this->domain()) && nonnull(this->range())
this->opSupported(M_trans)==true
(throw Exceptions::OpNotSupported
)
X.range()->isCompatible(*op(this)->domain()) == true
(throw Exceptions::IncompatibleVectorSpaces
)
Y->range()->isCompatible(*op(this)->range()) == true
(throw Exceptions::IncompatibleVectorSpaces
)
Y->domain()->isCompatible(*X.domain()) == true
(throw Exceptions::IncompatibleVectorSpaces
)
Y
can not alias X
. It is up to the client to ensure that Y
and X
are distinct since in general this can not be verified by the implementation until, perhaps, it is too late. If possible, an exception will be thrown if aliasing is detected.
Postconditions:
Y
is transformed as indicated above. Definition at line 308 of file Thyra_LinearOpBase_decl.hpp.
RCP< const LinearOpBase< Scalar > > Thyra::LinearOpBase< Scalar >::clone | ( | ) | const [virtual] |
Clone the linear operator object (if supported).
The primary purpose for this function is to allow a client to capture the current state of a linear operator object and be guaranteed that some other client will not alter its behavior. A smart implementation will use reference counting and lazy evaluation internally and will not actually copy any large amount of data unless it has to.
The default implementation returns return.get()==NULL
which is allowable. A linear operator object is not required to return a non-NULL value but many good matrix-based linear operator implementations will.
Reimplemented in Thyra::MultiVectorBase< Scalar >.
Definition at line 45 of file Thyra_LinearOpBase_def.hpp.
bool Thyra::LinearOpBase< Scalar >::applySupports | ( | const EConj | conj | ) | const |
void Thyra::LinearOpBase< Scalar >::apply | ( | const EConj | conj, | |
const MultiVectorBase< Scalar > & | X, | |||
MultiVectorBase< Scalar > * | Y, | |||
const Scalar | alpha = static_cast< Scalar >(1.0) , |
|||
const Scalar | beta = static_cast< Scalar >(0.0) | |||
) | const |
bool Thyra::LinearOpBase< Scalar >::applyTransposeSupports | ( | const EConj | conj | ) | const |
void Thyra::LinearOpBase< Scalar >::applyTranspose | ( | const EConj | conj, | |
const MultiVectorBase< Scalar > & | X, | |||
MultiVectorBase< Scalar > * | Y, | |||
const Scalar | alpha = static_cast< Scalar >(1.0) , |
|||
const Scalar | beta = static_cast< Scalar >(0.0) | |||
) | const |
virtual bool Thyra::LinearOpBase< Scalar >::opSupportedImpl | ( | EOpTransp | M_trans | ) | const [protected, pure virtual] |
Override in subclass.
virtual void Thyra::LinearOpBase< Scalar >::applyImpl | ( | const EOpTransp | M_trans, | |
const MultiVectorBase< Scalar > & | X, | |||
const Ptr< MultiVectorBase< Scalar > > & | Y, | |||
const Scalar | alpha, | |||
const Scalar | beta | |||
) | const [protected, pure virtual] |
Override in subclass.
bool isFullyUninitialized | ( | const LinearOpBase< Scalar > & | M | ) | [related] |
Determines if a linear operator is in the "Fully Uninitialized" state or not.
Definition at line 505 of file Thyra_LinearOpBase_decl.hpp.
bool isPartiallyInitialized | ( | const LinearOpBase< Scalar > & | M | ) | [related] |
Determines if a linear operator is in the "Partially Initialized" state or not.
Definition at line 512 of file Thyra_LinearOpBase_decl.hpp.
bool isFullyInitialized | ( | const LinearOpBase< Scalar > & | M | ) | [related] |
Determines if a linear operator is in the "Fully Initialized" state or not.
Definition at line 527 of file Thyra_LinearOpBase_decl.hpp.
bool opSupported | ( | const LinearOpBase< Scalar > & | M, | |
EOpTransp | M_trans | |||
) | [related] |
Determines if an operation is supported for a single scalar type.
Definition at line 543 of file Thyra_LinearOpBase_decl.hpp.
void apply | ( | const LinearOpBase< Scalar > & | M, | |
const EOpTransp | M_trans, | |||
const MultiVectorBase< Scalar > & | X, | |||
const Ptr< MultiVectorBase< Scalar > > & | Y, | |||
const Scalar | alpha = static_cast< Scalar >(1.0) , |
|||
const Scalar | beta = static_cast< Scalar >(0.0) | |||
) | [related] |
Non-member function call for M.apply(...)
.
Definition at line 106 of file Thyra_LinearOpBase_def.hpp.
void apply | ( | const LinearOpBase< double > & | M, | |
const EOpTransp | M_trans, | |||
const MultiVectorBase< double > & | X, | |||
const Ptr< MultiVectorBase< double > > & | Y, | |||
const double | alpha = 1.0 , |
|||
const double | beta = 0.0 | |||
) | [related] |
Calls apply<double>(...)
.
Non-tempalted double inlined non-member helper function.
Definition at line 550 of file Thyra_LinearOpBase_decl.hpp.