gko::solver::Nullspace#
Describes the right or left nullspace of an operator and acts as the orthogonal
projector \(P = I - V V^H\) onto its complement, where \(V\) is an orthonormal basis
of the nullspace. A Nullspace is created from explicit basis vectors, from the
constant vector, or from both, and is passed as the nullspace or
left_nullspace factory parameter of Cg, Fcg, Minres, Gmres or
Bicgstab to solve singular systems.
The explicit basis is copied and orthonormalized once at creation, and
numerically dependent columns are dropped. A constant-only nullspace created with
create_from_constant is never stored and adapts to any matrix size, value type
and partition.
-
template<typename ValueType = default_precision>
class Nullspace # Inherits from
public gko::LinOp
public gko::EnableCloneable<Nullspace<default_precision>>
Nullspace represents the (right or left) nullspace of an operator and is the orthogonal projector \( P = I - V V^H \) onto its complement, where \( V \) is an orthonormal basis of the nullspace.
The constant vector is handled implicitly by subtracting the mean, so a constant-only nullspace works with any vector layout (
matrix::Denseorexperimental::distributed::Vectorwith any partition).An explicit basis is copied and orthonormalized once at creation time (twice-iterated Gram-Schmidt, also against the constant if it is part of the nullspace). Columns that are numerically linearly dependent (relative norm below \( \sqrt{\epsilon} \) after orthogonalization) are dropped; get_dimension() reports the remaining dimension.
project() removes the nullspace components of all columns of its input \( X \) at once: the coefficients \( C = V^H X \) and the column means are computed in a single pass (and, for distributed vectors, a single all-reduce), followed by \( X \leftarrow X - V C \).
The typical use is as the
nullspace/left_nullspaceparameter of an iterative solver, see enable_preconditioned_iterative_solver_factory_parameters.The object is immutable after creation apart from internal scratch buffers. Solvers and preconditioner::NullspaceProjection work on their own copy, which shares the basis, so the same object can be passed to any number of factories. Like other Ginkgo LinOps with internal caches, a single instance must not be applied concurrently from multiple threads.
- Template Parameters:
ValueType – the value type of the vectors it projects.
Public Functions
-
bool contains_constant() const noexcept#
- Returns:
whether the constant vector is part of the nullspace.
-
size_type get_dimension() const noexcept#
- Returns:
the dimension of the nullspace: the number of orthonormal explicit basis vectors, plus one if the constant is included.
-
std::shared_ptr<const LinOp> get_basis() const noexcept#
- Returns:
the orthonormalized explicit basis as a single
n x kvector of the same kind as the input basis (orthogonal to the constant if contains_constant()), or nullptr if there is none.
-
void project(ptr_param<LinOp> v) const#
Applies the projector in place: \( v \leftarrow (I - V V^H) v \), for each column of
vindependently.- Parameters:
v – a matrix::Dense or experimental::distributed::Vector with as many rows as this operator (any number of rows for a constant-only nullspace created without a size). Other precisions are converted like in apply(). If the Nullspace has an explicit basis,
vmust be of the same kind (and distribution) as that basis.
Public Static Functions
- std::shared_ptr<const Executor> exec,
- std::vector<std::shared_ptr<const LinOp>> basis,
- bool contains_constant = false,
Creates a Nullspace from an explicit basis.
- Parameters:
exec – the executor the projector (and its basis) lives on
basis – the nullspace basis vectors. Each entry is an
n x k_imatrix::Dense<ValueType> or experimental::distributed::Vector<ValueType> (all entries of the same kind and, if distributed, the same partition); their columns together span the nullspace. They do not need to be orthonormal: they are copied and orthonormalized, dropping numerically dependent columns.contains_constant – whether the constant vector is also part of the nullspace.
- std::shared_ptr<const Executor> exec,
- dim<2> size = {},
Creates a Nullspace consisting only of the constant vector (e.g. a pure-Neumann Poisson problem). The constant is never materialized, so the result can project vectors of any type and distribution.
Solvers adapt a constant-only nullspace to the size and value type of their system matrix, so the same object can be used in solver factories that are generated for matrices of different sizes (e.g. on the levels of a multigrid hierarchy) or precisions. Without a size, project() accepts vectors of any size; the size is only needed to use the Nullspace as a LinOp.
- Parameters:
exec – the executor
size – the (square, global) size
n x nof the operator.
See also
Singular systems and nullspaces: concept page.
gko::preconditioner::NullspaceProjection: the preconditioner wrapper that applies the projection.