Extension: Matrix functions
#include "dg/matrix/matrix.h"
Loading...
Searching...
No Matches
matrixsqrt.h
Go to the documentation of this file.
1#pragma once
2
3#include "dg/algorithm.h"
4#include "lanczos.h"
5
6namespace dg{
7namespace mat{
8
9
22template<class ContainerType>
24{
25 using container_type = ContainerType;
27
29 MatrixSqrt() = default;
30
43 template<class MatrixType>
44 MatrixSqrt( MatrixType& A, int exp,
45 const ContainerType& weights, value_type eps_rel,
46 value_type nrmb_correction = 1.,
47 unsigned max_iter = 500, unsigned cauchy_steps = 40
48 ) : m_weights(weights),
49 m_exp(exp), m_cauchy( cauchy_steps), m_eps(eps_rel),
50 m_abs(nrmb_correction)
51 {
52 m_A = [&]( const ContainerType& x, ContainerType& y){
53 return dg::apply( A, x, y);
54 };
55 m_lanczos.construct( weights, max_iter);
56
57 dg::mat::UniversalLanczos<ContainerType> eigen( weights, 2000);
58 const ContainerType rnd = weights;
60 auto T = eigen.tridiag( A, rnd, weights);
62 }
64 template<class ...Params>
65 void construct( Params&& ...ps)
66 {
67 //construct and swap
68 *this = MatrixSqrt( std::forward<Params>( ps)...);
69 }
71 unsigned get_iter() const{return m_number;}
72
80 void set_benchmark( bool benchmark, std::string message = "SQRT"){
81 m_benchmark = benchmark;
82 m_message = message;
83 }
84
91 template<class ContainerType0, class ContainerType1>
92 void operator()( const ContainerType0 b, ContainerType1& x)
93 {
94#ifdef MPI_VERSION
95 int rank;
96 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
97#endif //MPI
98 dg::Timer t;
99 t.tic();
100 auto func = make_SqrtCauchyEigen_Te1( m_exp, m_EVs, m_cauchy);
101 m_number = m_lanczos.solve( x, func, m_A, b, m_weights, m_eps, m_abs,
102 "universal", 1., 2);
103 t.toc();
104 if( m_benchmark)
105 DG_RANK0 std::cout << "# `"<<m_message<<"` solve with {"<<m_number<<","<<m_cauchy<<"} iterations took "<<t.diff()<<"s\n";
106 }
107 private:
109 ContainerType m_weights;
110 std::function< void( const ContainerType&, ContainerType&)> m_A;
111 std::array<value_type, 2> m_EVs;
112 int m_exp;
113 unsigned m_number, m_cauchy;
114 value_type m_eps, m_abs;
115 bool m_benchmark = true;
116 std::string m_message = "SQRT";
117
118};
119
120// The following is only indirectly tested in diffusion project but should appear formally in _t file here as well
139template<class ContainerType>
141{
142 using container_type = ContainerType;
144
146 MatrixFunction() = default;
147
160 template<class MatrixType>
161 MatrixFunction( MatrixType& A,
162 const ContainerType& weights, value_type eps_rel,
163 value_type nrmb_correction = 1.,
164 unsigned max_iter = 500,
165 std::function<value_type(value_type)> f_inner = [](value_type x){return x;}
166 ) : m_weights(weights),
167 m_f_inner(f_inner), m_eps(eps_rel),
168 m_abs(nrmb_correction)
169 {
170 m_A = [&]( const ContainerType& x, ContainerType& y){
171 return dg::apply( A, x, y);
172 };
173 m_lanczos.construct( weights, max_iter);
174 }
176 template<class ...Params>
177 void construct( Params&& ...ps)
178 {
179 //construct and swap
180 *this = MatrixFunction( std::forward<Params>( ps)...);
181 }
183 unsigned get_iter() const{return m_number;}
184
192 void set_benchmark( bool benchmark, std::string message = "Function"){
193 m_benchmark = benchmark;
194 m_message = message;
195 }
196
204 template<class UnaryOp, class ContainerType0, class ContainerType1>
205 void operator()( UnaryOp f_outer, const ContainerType0 b, ContainerType1& x)
206 {
207#ifdef MPI_VERSION
208 int rank;
209 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
210#endif //MPI
211 dg::Timer t;
212 t.tic();
213 auto func = make_FuncEigen_Te1( [&](value_type x) {return f_outer(m_f_inner(x));});
214 m_number = m_lanczos.solve( x, func, m_A, b, m_weights, m_eps, m_abs,
215 "universal", 1., 2);
216 t.toc();
217 if( m_benchmark)
218 DG_RANK0 std::cout << "# `"<<m_message<<"` solve with {"<<m_number<<"} iterations took "<<t.diff()<<"s\n";
219 }
220 private:
222 ContainerType m_weights;
223 std::function< void( const ContainerType&, ContainerType&)> m_A;
224 std::array<value_type, 2> m_EVs;
225 std::function<value_type(value_type)> m_f_inner;
226 unsigned m_number;
227 value_type m_eps, m_abs;
228 bool m_benchmark = true;
229 std::string m_message = "Function";
230
231};
232
233
234}//namespace mat
235}//namespace dg
Tridiagonalize and approximate via Lanczos algorithm. A is self-adjoint in the weights .
Definition lanczos.h:154
const dg::TriDiagonal< thrust::host_vector< double > > & tridiag(MatrixType &&A, const ContainerType0 &b, const ContainerType1 &weights, double eps=1e-4, double nrmb_correction=1., std::string error_norm="compute_extreme_EV", double res_fac=1., unsigned q=1)
Tridiagonalization of A using Lanczos method with .
Definition lanczos.h:264
void transform(const ContainerType1 &x, ContainerType &y, UnaryOp op)
void apply(get_value_type< ContainerType1 > alpha, MatrixType &&M, const ContainerType1 &x, get_value_type< ContainerType1 > beta, ContainerType2 &y)
typename TensorTraits< std::decay_t< Vector > >::value_type get_value_type
std::array< value_type, 2 > compute_extreme_EV(const dg::TriDiagonal< thrust::host_vector< value_type > > &T)
Compute extreme Eigenvalues of a symmetric tridiangular matrix.
Definition tridiaginv.h:727
auto make_FuncEigen_Te1(UnaryOp f)
Create a functor that uses Eigenvalue decomposition to compute for symmetric tridiagonal T.
Definition matrixfunction.h:29
auto make_SqrtCauchyEigen_Te1(int exp, std::array< value_type, 2 > EVs, unsigned stepsCauchy)
Create a functor that computes using either Eigen or SqrtCauchy solve based on whichever is fastest ...
Definition matrixfunction.h:123
Functions for optimizing Contours.
double diff() const
void toc()
void tic()
Computation of for self-adjoint positive definite .
Definition matrixsqrt.h:141
void operator()(UnaryOp f_outer, const ContainerType0 b, ContainerType1 &x)
Apply matrix function.
Definition matrixsqrt.h:205
MatrixFunction(MatrixType &A, const ContainerType &weights, value_type eps_rel, value_type nrmb_correction=1., unsigned max_iter=500, std::function< value_type(value_type)> f_inner=[](value_type x){return x;})
Construct from matrix.
Definition matrixsqrt.h:161
unsigned get_iter() const
Get the number of Lanczos iterations in latest call to operator()
Definition matrixsqrt.h:183
dg::get_value_type< ContainerType > value_type
Definition matrixsqrt.h:143
ContainerType container_type
Definition matrixsqrt.h:142
MatrixFunction()=default
Construct empty.
void set_benchmark(bool benchmark, std::string message="Function")
Set or unset performance timings during iterations.
Definition matrixsqrt.h:192
void construct(Params &&...ps)
Perfect forward parameters to one of the constructors.
Definition matrixsqrt.h:177
Fast computation of for self-adjoint positive definite .
Definition matrixsqrt.h:24
void operator()(const ContainerType0 b, ContainerType1 &x)
Apply matrix sqrt.
Definition matrixsqrt.h:92
void construct(Params &&...ps)
Perfect forward parameters to one of the constructors.
Definition matrixsqrt.h:65
dg::get_value_type< ContainerType > value_type
Definition matrixsqrt.h:26
unsigned get_iter() const
Get the number of Lanczos iterations in latest call to operator()
Definition matrixsqrt.h:71
ContainerType container_type
Definition matrixsqrt.h:25
void set_benchmark(bool benchmark, std::string message="SQRT")
Set or unset performance timings during iterations.
Definition matrixsqrt.h:80
MatrixSqrt(MatrixType &A, int exp, const ContainerType &weights, value_type eps_rel, value_type nrmb_correction=1., unsigned max_iter=500, unsigned cauchy_steps=40)
Construct from matrix.
Definition matrixsqrt.h:44
MatrixSqrt()=default
Construct empty.
double value_type
Definition tridiaginv_b.cpp:6
#define DG_RANK0