Extension: Matrix functions
#include "dg/matrix/matrix.h"
Loading...
Searching...
No Matches
dg::mat::ProductMatrixFunction< ContainerType > Struct Template Reference

Computation of \( \vec x = f(A,\vec d)\vec b\) and \( \vec x = f(\vec d, A)\vec b\) where \( A \) is a positive definite matrix self-adjoint in the weights \( W\) . More...

Public Types

using container_type = ContainerType
 
using value_type = dg::get_value_type<ContainerType>
 

Public Member Functions

 ProductMatrixFunction ()=default
 Construct empty.
 
 ProductMatrixFunction (const ContainerType &copyable, unsigned max_iterations)
 Allocate memory for the method.
 
template<class ... Params>
void construct (Params &&...ps)
 Perfect forward parameters to one of the constructors.
 
void set_benchmark (bool benchmark, std::string message="ProductFunction")
 Set or unset performance timings during iterations.
 
template<class ContainerType0 , class BinaryOp , class ContainerType1 , class MatrixType , class ContainerType2 , class ContainerType3 >
unsigned apply (ContainerType0 &x, BinaryOp op, const ContainerType1 &diag, MatrixType &&A, const ContainerType2 &b, const ContainerType3 &weights, value_type eps, value_type nrmb_correction=1.)
 Compute \( \vec x = f(\vec d, A) \vec b = (E_{A} \odot F ) E^T_{A}M^T b\).
 
template<class ContainerType0 , class BinaryOp , class MatrixType , class ContainerType1 , class ContainerType2 , class ContainerType3 >
unsigned apply_adjoint (ContainerType0 &x, BinaryOp op, MatrixType &&A, const ContainerType1 &diag, const ContainerType2 &b, const ContainerType3 &weights, value_type eps, value_type nrmb_correction=1.)
 Compute \( \vec x = f(A, \vec d) \vec b = E_{A} (F^T \odot E^T_{A}M^T) b\).
 
template<class BinaryOp , class ContainerType0 , class MatrixType , class ContainerType1 , class ContainerType2 >
void compute_vlcl (BinaryOp op, const ContainerType0 &diag, MatrixType &&A, const TriDiagonal< thrust::host_vector< value_type > > &T, ContainerType1 &x, const ContainerType2 &b, value_type bnorm)
 Compute \( \vec x = f(\vec d, A) \vec b = (E_{A} \odot F ) E^T_{A}M^T b\).
 
template<class BinaryOp , class MatrixType , class ContainerType0 , class ContainerType1 , class ContainerType2 , class ContainerType3 >
void compute_vlcl_adjoint (BinaryOp op, MatrixType &&A, const ContainerType0 &diag, const TriDiagonal< thrust::host_vector< value_type > > &T, ContainerType1 &x, const ContainerType2 &b, const ContainerType3 &weights, value_type bnorm)
 Compute \( \vec x = f(A, \vec d) \vec b = E_{A} (F^T \odot E^T_{A}M^T) b\).
 
UniversalLanczos< ContainerType > & lanczos ()
 Access the Lanczos class that is constructed with the constructor parameters.
 

Detailed Description

template<class ContainerType>
struct dg::mat::ProductMatrixFunction< ContainerType >

Computation of \( \vec x = f(A,\vec d)\vec b\) and \( \vec x = f(\vec d, A)\vec b\) where \( A \) is a positive definite matrix self-adjoint in the weights \( W\) .

The first identity is computed via \( \vec x = f(\vec d, A) \vec b = (E_{A} \odot F ) E^T_{A}M^T b\) where \( E_A := V_A E_T \) and \( F_{ai} := f( d_a, \lambda_i)\) and \( T\) and \( V_A\) are the tridiagonal matrix and vectors that come out of a Lanczos iteration on \( A\), \( W\), \( \vec b\); \( \vec d\) is a vector.

The second identity is computed via \( \vec x = f(A, \vec d) \vec b = E_{A} (F^T \odot E^T_{A}M^T) b\) where \( E_A := V_A E_T \) and \( F_{ai} := f( d_a, \lambda_i)\) and \( T\) and \( V_A\) are the tridiagonal matrix and vectors that come out of a Lanczos iteration on \( A\), \( W\), \( \vec b\); \( \vec d\) is a vector

Attention
Just as in the Lanczos or PCG methods the matrix \( A\) needs to be positive-definite (i.e. it won't work for negative definite)
Note
The apply and apply_adjoint methods are just abbreviations. If one wants full control, e.g. to reuse a tridiagonalisation one has to manually code:
double max = dg::blas1::reduce( diag, -1e308, thrust::maximum<double>());
auto func = dg::mat::make_FuncEigen_Te1( [&](value_type x) {return op( max, x);});
auto T = prod.lanczos().tridiag( func, A,
b, weights, eps, nrmb_correction,
"universal", 1.0, 1);
prod.compute_vlcl( op, diag, A, T, x, b, prod.lanczos().get_bnorm());
// or
prod.compute_vlcl_adjoint( op, A, diag, T, x, b,
weights, prod.lanczos().get_bnorm());
OutputType reduce(const ContainerType &x, OutputType zero, BinaryOp binary_op, UnaryOp unary_op=UnaryOp())
auto make_FuncEigen_Te1(UnaryOp f)
Create a functor that uses Eigenvalue decomposition to compute for symmetric tridiagonal T.
Definition matrixfunction.h:29
Computation of and where is a positive definite matrix self-adjoint in the weights .
Definition matrixprod.h:48
dg::get_value_type< ContainerType > value_type
Definition matrixprod.h:50
Attention
The adjoint methods unfortunately do not converge so use cautiously!
See also
dg::mat::UniversalLanczos dg::mat::CauchyMatrixProduct

Member Typedef Documentation

◆ container_type

template<class ContainerType >
using dg::mat::ProductMatrixFunction< ContainerType >::container_type = ContainerType

◆ value_type

template<class ContainerType >
using dg::mat::ProductMatrixFunction< ContainerType >::value_type = dg::get_value_type<ContainerType>

Constructor & Destructor Documentation

◆ ProductMatrixFunction() [1/2]

template<class ContainerType >
dg::mat::ProductMatrixFunction< ContainerType >::ProductMatrixFunction ( )
default

Construct empty.

◆ ProductMatrixFunction() [2/2]

template<class ContainerType >
dg::mat::ProductMatrixFunction< ContainerType >::ProductMatrixFunction ( const ContainerType & copyable,
unsigned max_iterations )
inline

Allocate memory for the method.

Parameters
copyableA ContainerType must be copy-constructible from this
max_iterationsMaximum number of iterations in Lanczos to be used

Member Function Documentation

◆ apply()

template<class ContainerType >
template<class ContainerType0 , class BinaryOp , class ContainerType1 , class MatrixType , class ContainerType2 , class ContainerType3 >
unsigned dg::mat::ProductMatrixFunction< ContainerType >::apply ( ContainerType0 & x,
BinaryOp op,
const ContainerType1 & diag,
MatrixType && A,
const ContainerType2 & b,
const ContainerType3 & weights,
value_type eps,
value_type nrmb_correction = 1. )
inline

Compute \( \vec x = f(\vec d, A) \vec b = (E_{A} \odot F ) E^T_{A}M^T b\).

This function is equivalent to:

auto func = dg::mat::make_FuncEigen_Te1( [&](value_type x) {return op(1., x);});
auto T = m_lanczos.tridiag( func, std::forward<MatrixType>(A),
b, weights, eps, nrmb_correction,
"universal", 1.0, 2);
compute_vlcl( op, diag, std::forward<MatrixType>(A), T, x, b,
m_lanczos.get_bnorm());
return T.num_rows;
void compute_vlcl(BinaryOp op, const ContainerType0 &diag, MatrixType &&A, const TriDiagonal< thrust::host_vector< value_type > > &T, ContainerType1 &x, const ContainerType2 &b, value_type bnorm)
Compute .
Definition matrixprod.h:237
Note
The stopping criterion used on the Lanczos iteration is the universal one applied to \( f(1, x) \)
Parameters
xoutput-vector, contains result on output, ignored on input
opa binary Operator representing the product matrix function
diagthe diagonal vector
AA self-adjoint, positive definit matrix
bThe initial vector that starts orthogonalization
weightsWeights that define the scalar product in which A is self-adjoint and in which the error norm is computed.
epsrelative accuracy of residual in Lanczos iteration
nrmb_correctionthe absolute error C in units of eps to be respected
Returns
The number of Lanczos iterations used

◆ apply_adjoint()

template<class ContainerType >
template<class ContainerType0 , class BinaryOp , class MatrixType , class ContainerType1 , class ContainerType2 , class ContainerType3 >
unsigned dg::mat::ProductMatrixFunction< ContainerType >::apply_adjoint ( ContainerType0 & x,
BinaryOp op,
MatrixType && A,
const ContainerType1 & diag,
const ContainerType2 & b,
const ContainerType3 & weights,
value_type eps,
value_type nrmb_correction = 1. )
inline

Compute \( \vec x = f(A, \vec d) \vec b = E_{A} (F^T \odot E^T_{A}M^T) b\).

Attention
The adjoint methods unfortunately do not converge so use cautiously!

This function is equivalent to:

auto func = make_FuncEigen_Te1( [&](value_type x) {return op( x, 1.);});
auto T = m_lanczos.tridiag( func, std::forward<MatrixType>(A),
b, weights, eps, nrmb_correction,
"universal", 1.0, 2);
compute_vlcl_adjoint( op, std::forward<MatrixType>(A), diag, T, x, b,
weights, m_lanczos.get_bnorm());
return T.num_rows;
void compute_vlcl_adjoint(BinaryOp op, MatrixType &&A, const ContainerType0 &diag, const TriDiagonal< thrust::host_vector< value_type > > &T, ContainerType1 &x, const ContainerType2 &b, const ContainerType3 &weights, value_type bnorm)
Compute .
Definition matrixprod.h:312
Note
\( f(A, \vec d)\) is the adjoint operation to \( f( \vec d, A)\) since both \( \vec d\) and \( A\) are self-adjoint.
The stopping criterion used on the Lanczos iteration is the universal one applied to \( f(x, 1) \)
Parameters
xoutput-vector, contains result on output, ignored on input
opa binary Operator representing the product matrix function
diagthe diagonal vector
AA self-adjoint, positive definit matrix
Attention
The order of A and diag is reversed compared to the apply method
Parameters
bThe initial vector that starts orthogonalization
weightsWeights that define the scalar product in which A is self-adjoint and in which the error norm is computed.
epsrelative accuracy of residual in Lanczos iteration
nrmb_correctionthe absolute error C in units of eps to be respected
Returns
The number of Lanczos iterations used

◆ compute_vlcl()

template<class ContainerType >
template<class BinaryOp , class ContainerType0 , class MatrixType , class ContainerType1 , class ContainerType2 >
void dg::mat::ProductMatrixFunction< ContainerType >::compute_vlcl ( BinaryOp op,
const ContainerType0 & diag,
MatrixType && A,
const TriDiagonal< thrust::host_vector< value_type > > & T,
ContainerType1 & x,
const ContainerType2 & b,
value_type bnorm )
inline

Compute \( \vec x = f(\vec d, A) \vec b = (E_{A} \odot F ) E^T_{A}M^T b\).

where \( E_A := V_A E_T \) and \( F_{ai} := f( d_a, \lambda_i)\) and \( T\) and \( V_A\) are the tridiagonal matrix and vectors that come out of a Lanczos iteration on \( A\), \( W\), \( \vec b\); \( \vec d\) is a vector.

This function takes a previously computed tridiagonalisation of A, called T and computes the Eigendecomposition of T and then re-creates the Eigenvectors in V to compute the above result.

Note
the Tridiagonalisation T can thus be reused to compute various matrix functions of the same right hand side. It can be computed using
double max = dg::blas1::reduce( diag, -1e308, thrust::maximum<double>());
auto func = dg::mat::make_FuncEigen_Te1( [&](value_type x) {return op( max, x);});
auto T = prod.lanczos().tridiag( func, A,
b, weights, eps, nrmb_correction,
"universal", 1.0, 1);
prod.compute_vlcl( op, diag, A, T, x, b, prod.lanczos().get_bnorm());
// or
prod.compute_vlcl_adjoint( op, A, diag, T, x, b,
weights, prod.lanczos().get_bnorm());
Parameters
opa binary Operator representing the product matrix function
diagthe diagonal vector
AA self-adjoint, positive definit matrix
TThe tridiagonalisation of A
xoutput-vector, contains result on output, ignored on input
bThe initial vector that starts orthogonalization
bnormthe norm of b

◆ compute_vlcl_adjoint()

template<class ContainerType >
template<class BinaryOp , class MatrixType , class ContainerType0 , class ContainerType1 , class ContainerType2 , class ContainerType3 >
void dg::mat::ProductMatrixFunction< ContainerType >::compute_vlcl_adjoint ( BinaryOp op,
MatrixType && A,
const ContainerType0 & diag,
const TriDiagonal< thrust::host_vector< value_type > > & T,
ContainerType1 & x,
const ContainerType2 & b,
const ContainerType3 & weights,
value_type bnorm )
inline

Compute \( \vec x = f(A, \vec d) \vec b = E_{A} (F^T \odot E^T_{A}M^T) b\).

where \( E_A := V_A E_T \) and \( F_{ai} := f( d_a, \lambda_i)\) and \( T\) and \( V_A\) are the tridiagonal matrix and vectors that come out of a Lanczos iteration on \( A\), \( W\), \( \vec b\); \( \vec d\) is a vector

Attention
The adjoint methods unfortunately do not converge so use cautiously!

This function takes a previously computed tridiagonalisation of A, called T and computes the Eigendecomposition of T and then re-creates the Eigenvectors in V to compute the above result.

Note
\( f(A, \vec d)\) is the adjoint operation to \( f( \vec d, A)\) since both \( \vec d\) and \( A\) are self-adjoint.
Parameters
opa binary Operator representing the product matrix function
AA self-adjoint, positive definit matrix
diagthe diagonal vector
Attention
The order of A and diag is reversed compared to the apply method
Parameters
TThe tridiagonalisation of A
xoutput-vector, contains result on output, ignored on input
bThe initial vector that starts orthogonalization
weightsWeights that define the scalar product in which A is self-adjoint and in which the error norm is computed.
bnormthe norm of b

◆ construct()

template<class ContainerType >
template<class ... Params>
void dg::mat::ProductMatrixFunction< ContainerType >::construct ( Params &&... ps)
inline

Perfect forward parameters to one of the constructors.

Template Parameters
Paramsdeduced by the compiler
Parameters
psparameters forwarded to constructors

◆ lanczos()

template<class ContainerType >
UniversalLanczos< ContainerType > & dg::mat::ProductMatrixFunction< ContainerType >::lanczos ( )
inline

Access the Lanczos class that is constructed with the constructor parameters.

◆ set_benchmark()

template<class ContainerType >
void dg::mat::ProductMatrixFunction< ContainerType >::set_benchmark ( bool benchmark,
std::string message = "ProductFunction" )
inline

Set or unset performance timings during iterations.

Parameters
benchmarkIf true, additional output will be written to std::cout during solution
messageAn optional identifier that is printed together with the benchmark (intended use is to distinguish different messages in the output)

The documentation for this struct was generated from the following file: