Extension: Matrix functions
#include "dg/matrix/matrix.h"
matrixfunction.h
Go to the documentation of this file.
1#pragma once
2#include <cmath>
3
4#include <boost/math/special_functions.hpp> // has to be included before lapack in certain versions
5#include <cusp/transpose.h>
6#include <cusp/array1d.h>
7#include <cusp/array2d.h>
8//#include <cusp/print.h>
9
10#include <cusp/lapack/lapack.h>
11#include "dg/algorithm.h"
12
13#include "functors.h"
14#include "sqrt_cauchy.h"
15#include "sqrt_ode.h"
16
17
18namespace dg {
19namespace mat {
22
34template<class UnaryOp>
35auto make_FuncEigen_Te1( UnaryOp f)
36{
37 return [f]( const auto& T)
38 {
39 using value_type = typename std::decay_t<decltype(T)>::value_type;
40 unsigned iter = T.num_rows;
41 cusp::array2d< value_type, cusp::host_memory> evecs(iter,iter);
42 cusp::array1d< value_type, cusp::host_memory> evals(iter);
43 dg::HVec e1H(iter,0.), yH(e1H);
44 e1H[0] = 1.;
45 yH.resize( iter);
46 //Compute Eigendecomposition
47 //MW !! the subdiagonal entries start at 0 in lapack, the n-th element
48 // is used as workspace (from lapack docu)
49 cusp::lapack::stev(T.values.column(1), T.values.column(2),
50 evals, evecs, 'V');
51 //for( unsigned u=0; u<iter; u++)
52 // std::cout << u << " "<<evals[u]<<std::endl;
53 cusp::coo_matrix<int, value_type, cusp::host_memory> EH, EHt;
54 cusp::convert(evecs, EH);
55 cusp::transpose(EH, EHt);
56 //Compute f(T) e1 = E f(Lambda) E^t e1
57 dg::blas2::symv(EHt, e1H, yH);
58 dg::blas1::transform(evals, e1H, [f] (double x){
59 try{
60 return f(x);
61 }
62 catch(boost::exception& e) //catch boost overflow error
63 {
64 return 0.;
65 }
66 });
67 dg::blas1::pointwiseDot(e1H, yH, e1H);
68 dg::blas2::symv(EH, e1H, yH);
69 return yH;
70 };
71}
72
91template< class value_type>
92auto make_SqrtCauchy_Te1( int exp, std::array<value_type,2> EVs, unsigned stepsCauchy)
93{
94 return [=]( const auto& T)
95 {
96 unsigned size = T.num_rows;
97 thrust::host_vector<value_type> e1H(size, 0.), yH(e1H);
98 e1H[0] = 1.;
99
100 dg::mat::SqrtCauchyInt<HVec> cauchysqrtH( e1H);
101 auto wTinv = [&w = cauchysqrtH.w(), &T = T]( const auto& y, auto& x)
102 {
103 // invert 1*T + w*wI
104 dg::mat::compute_Tinv_y( T, x, y, 1., w*w);
105 };
106 cauchysqrtH(T, wTinv, e1H, yH, EVs, stepsCauchy, exp);
107 return yH;
108 };
109}
110
130template< class value_type>
131auto make_SqrtCauchyEigen_Te1( int exp, std::array<value_type,2> EVs, unsigned stepsCauchy)
132{
133 std::function< value_type(value_type)> func = dg::SQRT<value_type>();
134 if( exp < 0)
135 func = [](value_type x){return 1./sqrt(x);};
136
137 auto eigen = make_FuncEigen_Te1( func);
138 auto cauchy = make_SqrtCauchy_Te1( exp, EVs, stepsCauchy);
139 return [=]( const auto& T)
140 {
141 unsigned size = T.num_rows;
142 dg::HVec yH;
143 if ( size < 40)
144 yH = eigen( T);
145 else
146 yH = cauchy(T);
147 return yH;
148 };
149}
150
151
162template< class value_type>
163auto make_SqrtODE_Te1( int exp, std::string tableau, value_type rtol,
164 value_type atol, unsigned& number)
165{
166 return [=, &num = number](const auto& T)
167 {
168 unsigned size = T.num_rows;
169 HVec e1H(size, 0), yH(e1H);
170 e1H[0] = 1.;
171 auto inv_sqrt = make_inv_sqrtodeTri( T, e1H);
172 auto sqrtHSolve = make_directODESolve( inv_sqrt,
173 tableau, rtol, atol, num);
174 dg::apply( sqrtHSolve, e1H, yH);
175 if( exp >= 0 )
176 {
177 dg::apply( T, yH, e1H);
178 return e1H;
179 }
180 return yH;
181 };
182}
183
190inline static auto make_Linear_Te1( int exp)
191{
192 return [= ](const auto& T)
193 {
194 unsigned size = T.num_rows;
195 HVec e1H(size, 0), yH(e1H);
196 e1H[0] = 1.;
197 if( exp < 0)
198 compute_Tinv_y( T, yH, e1H);
199 else
200 dg::blas2::symv( T, e1H, yH);
201 return yH;
202 };
203}
204
206} //namespace mat
207} //namespace dg
void apply(get_value_type< ContainerType1 > alpha, MatrixType &&M, const ContainerType1 &x, get_value_type< ContainerType1 > beta, ContainerType2 &y)
void transform(const ContainerType1 &x, ContainerType &y, UnaryOp op)
void pointwiseDot(get_value_type< ContainerType > alpha, const ContainerType1 &x1, const ContainerType2 &x2, get_value_type< ContainerType > beta, ContainerType &y)
void symv(MatrixType &&M, const ContainerType1 &x, ContainerType2 &y)
auto make_directODESolve(ExplicitRHS &&ode, std::string tableau, value_type epsTimerel, value_type epsTimeabs, unsigned &number, value_type t0=0., value_type t1=1.)
Operator that integrates an ODE from 0 to 1 with an adaptive ERK class as timestepper
Definition: sqrt_ode.h:38
void compute_Tinv_y(const cusp::dia_matrix< int, value_type, cusp::host_memory > &T, thrust::host_vector< value_type > &x, const thrust::host_vector< value_type > &y, value_type a=1., value_type d=0.)
Computes the value of via Thomas algorithm.
Definition: tridiaginv.h:58
void transpose(unsigned nx, unsigned ny, const ContainerType &in, ContainerType &out)
dg::MIHMatrix_t< real_type > convert(const dg::IHMatrix_t< real_type > &global, const ConversionPolicy &policy)
auto make_FuncEigen_Te1(UnaryOp f)
Create a functor that uses Eigenvalue decomposition to compute for symmetric tridiagonal T.
Definition: matrixfunction.h:35
static auto make_Linear_Te1(int exp)
Create a functor that computes directly.
Definition: matrixfunction.h:190
auto make_SqrtCauchy_Te1(int exp, std::array< value_type, 2 > EVs, unsigned stepsCauchy)
Create a functor that computes using SqrtCauchyInt.
Definition: matrixfunction.h:92
auto make_SqrtODE_Te1(int exp, std::string tableau, value_type rtol, value_type atol, unsigned &number)
Create a functor that computes using ODE solve.
Definition: matrixfunction.h:163
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:131
thrust::host_vector< double > HVec
InvSqrtODE< Container > make_inv_sqrtodeTri(const Matrix &TH, const Container &copyable)
Definition: sqrt_ode.h:167
Classes for Krylov space approximations of a Matrix-Vector product.
Cauchy integral
Definition: sqrt_cauchy.h:37
const double & w() const
The in .
Definition: sqrt_cauchy.h:60