3#include <boost/math/special_functions.hpp>
4#include "dg/algorithm.h"
36extern void dstev_(
char*,
int*,
double*,
double*,
double*,
int*,
double*,
int*);
37extern void sstev_(
char*,
int*,
float*,
float*,
float*,
int*,
float*,
int*);
40template<
class ContainerType0,
class ContainerType1,
class ContainerType2,
class ContainerType3>
50 static_assert( std::is_same_v<value_type, double> or std::is_same_v<value_type, float>,
51 "Value type must be either float or double");
52 static_assert( std::is_same_v<dg::get_value_type<ContainerType1>,
value_type> &&
53 std::is_same_v<dg::get_value_type<ContainerType2>,
value_type> &&
54 std::is_same_v<dg::get_value_type<ContainerType3>,
value_type>,
55 "All Vectors must have same value type");
56 static_assert( std::is_same_v<dg::get_execution_policy<ContainerType0>,
dg::SerialTag> &&
57 std::is_same_v<dg::get_execution_policy<ContainerType1>,
dg::SerialTag> &&
58 std::is_same_v<dg::get_execution_policy<ContainerType2>,
dg::SerialTag> &&
59 std::is_same_v<dg::get_execution_policy<ContainerType3>,
dg::SerialTag>,
60 "All Vectors must have serial execution policy");
65 value_type * D_ptr = thrust::raw_pointer_cast( &D[0]);
66 value_type * E_ptr = thrust::raw_pointer_cast( &E[0]);
72 Z_ptr = thrust::raw_pointer_cast( &Z[0]);
73 work_ptr = thrust::raw_pointer_cast( &work[0]);
77 if constexpr ( std::is_same_v<value_type, double>)
78 dstev_( &job, &N, D_ptr, E_ptr, Z_ptr, &ldz, work_ptr, &info);
79 else if constexpr ( std::is_same_v<value_type, float>)
80 sstev_( &job, &N, D_ptr, E_ptr, Z_ptr, ldz, work_ptr, &info);
104template<
class value_type>
113 for(
unsigned i=1; i<size; i++)
115 ciold = ci, diold = di;
116 ci = T.P[i]/ ( T.O[i]-T.M[i]*ciold);
117 di = -T.M[i]*diold/(T.O[i]-T.M[i]*ciold);
133template<
class value_type>
136 thrust::host_vector<value_type>& x,
137 const thrust::host_vector<value_type>&
y,
value_type a = 1.,
140 unsigned size =
y.size();
142 thrust::host_vector<value_type> ci(size), di(size);
143 ci[0] = a*T.P[0]/( a*T.O[0] + d);
144 di[0] =
y[0]/( a*T.O[0] + d);
145 for(
unsigned i=1; i<size; i++)
147 ci[i] = a*T.P[i]/ ( a*T.O[i] + d -a*T.M[i]*ci[i-1]);
148 di[i] = (
y[i]-a*T.M[i]*di[i-1])/(a*T.O[i] + d
151 x[size-1] = di[size-1];
152 for(
int i=size-2; i>=0; i--)
153 x[i] = di[i] - ci[i]*
x[i+1];
167template<
class real_type>
181 m_size = copyable.size();
182 m_alphas.assign(m_size+1,0.);
183 m_betas.assign(m_size+1,0.);
193 m_alphas.assign(m_size+1,0.);
194 m_betas.assign(m_size+1,0.);
203 m_alphas.resize(m_size+1,0.);
204 m_betas.resize(m_size+1,0.);
243 template<
class ContainerType0,
class ContainerType1,
class ContainerType2>
244 void operator()(
const ContainerType0& a,
const ContainerType1& b,
247 unsigned ss = m_size;
257 for(
unsigned i = 2; i<ss+1; i++)
259 m_alphas[i] = a[i-1]*m_alphas[i-1] - c[i-1]*b[i-2]*m_alphas[i-2];
260 if (m_alphas[i] ==0 && i<ss) {
264 if (m_alphas[ss] ==0)
269 m_betas[ss-1]=a[ss-1];
270 m_betas[0] = m_alphas[ss];
271 for(
int i = ss-2; i>0; i--)
273 m_betas[i] = a[i]*m_betas[i+1] - c[i+1]*b[i]*m_betas[i+2];
280 Tinv(0, 0) = 1.0/(a[0]-c[1]*b[0]*m_betas[2]/m_betas[1]);
281 Tinv(ss-1, ss-1) = 1.0/(a[ss-1] -
282 c[ss-1]*b[ss-2]*m_alphas[ss-2]/m_alphas[ss-1]);
283 for(
unsigned i=1; i<ss-1; i++)
286 1.0/(a[i]-c[i]*b[i-1]*m_alphas[i-1]/m_alphas[i]
287 -c[i+1]*b[i]*m_betas[i+2]/m_betas[i+1]);
290 for(
unsigned i=0; i<ss; i++)
292 for(
unsigned j=0; j<ss; j++)
294 Tinv.row_indices[i*ss+j] = j;
295 Tinv.column_indices[i*ss+j] = i;
298 sign(j-i)*std::accumulate(std::next(b.begin(),i),
299 std::next(b.begin(),j), 1.,
300 std::multiplies<value_type>())*
301 m_alphas[i]/m_alphas[j]*Tinv.values[j*ss+j];
306 sign(i-j)*std::accumulate(std::next(c.begin(),j+1),
307 std::next(c.begin(),i+1), 1.,
308 std::multiplies<value_type>())*
309 m_betas[i+1]/m_betas[j+1]*Tinv.values[j*ss+j];
318 if (i%2==0)
return 1;
321 thrust::host_vector<real_type> m_alphas, m_betas;
334template<
class real_type>
348 m_size = copyable.size();
349 m_phi.assign(m_size,0.);
350 m_theta.assign(m_size,0.);
360 m_phi.assign(m_size,0.);
361 m_theta.assign(m_size,0.);
370 m_phi.resize(m_size,0.);
371 m_theta.resize(m_size,0.);
410 template<
class ContainerType0,
class ContainerType1,
class ContainerType2>
411 void operator()(
const ContainerType0& a,
const ContainerType1& b,
417 m_phi[0] = - b[0]/a[0];
418 for(
unsigned i = 1; i<m_size; i++)
420 helper = m_phi[i-1]* c[i] + a[i];
422 else m_phi[i] = -b[i]/helper;
427 if (m_size == 1) m_theta[m_size-1] = 0.0;
430 m_theta[m_size-1] = - c[m_size-1]/a[m_size-1];
431 for(
int i = m_size-2; i>=0; i--)
433 helper = m_theta[i+1]*b[i] + a[i];
435 else m_theta[i] = -c[i]/helper;
440 helper = a[0] + b[0]* m_theta[1];
442 else Tinv(0,0) = 1.0/helper;
444 if (m_size == 1) helper = a[m_size-1];
445 else helper = a[m_size-1] + c[m_size-1]*m_phi[m_size-2];
448 else Tinv( m_size -1 , m_size - 1) = 1.0/helper;
450 for(
unsigned i=1; i<m_size-1; i++)
452 helper = a[i] + c[i]*m_phi[i-1] + b[i]* m_theta[i+1];
454 else Tinv(i,i) = 1.0/helper;
457 for(
unsigned j=0; j<m_size-1; j++)
459 for (
unsigned i=j+1; i<m_size; i++)
461 Tinv(i,j) = m_theta[i]*Tinv(i-1, j);
464 for(
unsigned j=1; j<m_size; j++)
466 for (
int i=j-1; i>=0; i--)
468 Tinv(i,j) = m_phi[i]*Tinv(i+1,j);
473 thrust::host_vector<real_type> m_phi, m_theta;
486template<
class real_type>
500 m_size = copyable.size();
501 m_phi.assign(m_size+1,0.);
502 m_theta.assign(m_size+1,0.);
512 m_phi.assign(m_size+1,0.);
513 m_theta.assign(m_size+1,0.);
522 m_phi.resize(m_size+1,0.);
523 m_theta.resize(m_size+1,0.);
562 template<
class ContainerType0,
class ContainerType1,
class ContainerType2>
563 void operator()(
const ContainerType0& a,
const ContainerType1& b,
568 for(
unsigned i = 0; i<m_size+1; i++)
583 m_theta[i] = a[i-1] * m_theta[i-1] - b[i-2] * c[i-1] * m_theta[i-2];
584 m_phi[is] = a[is] * m_phi[is+1] - b[is] * c[is+1] * m_phi[is+2];
589 for(
unsigned i=0; i<m_size; i++)
591 for(
unsigned j=0; j<m_size; j++)
595 std::accumulate(std::next(b.begin(),i),
596 std::next(b.begin(),j), 1.,
597 std::multiplies<value_type>())*sign(i+j) *
598 m_theta[i] * m_phi[j+1]/m_theta[m_size];
602 Tinv(i,j) = m_theta[i] * m_phi[i+1]/m_theta[m_size];
607 std::accumulate(std::next(c.begin(),j+1),
608 std::next(c.begin(),i+1), 1.,
609 std::multiplies<value_type>())*sign(i+j) *
610 m_theta[j] * m_phi[i+1]/m_theta[m_size];
619 if (i%2==0)
return 1;
622 thrust::host_vector<real_type> m_phi, m_theta;
637template<
class value_type>
654template<
class value_type>
674template<
class value_type>
679 thrust::host_vector<value_type> evals( T.O), subdiagonal( T.P), Z, work;
680 lapack::stev(
'N', evals, subdiagonal, Z, work);
683 return std::array<value_type, 2>{EVmin, EVmax};
void resize(unsigned m, T val=T())
USE THIS ONE Compute the inverse of a general tridiagonal matrix. The algorithm does not rely on the ...
Definition tridiaginv.h:336
void resize(unsigned new_size)
Resize inverse tridiagonal matrix and helper vectors.
Definition tridiaginv.h:368
TridiagInvDF(unsigned size)
Construct from size of vector.
Definition tridiaginv.h:357
void operator()(const dg::TriDiagonal< thrust::host_vector< real_type > > &T, dg::SquareMatrix< real_type > &Tinv)
Compute the inverse of a tridiagonal matrix T.
Definition tridiaginv.h:380
dg::SquareMatrix< real_type > operator()(const dg::TriDiagonal< thrust::host_vector< real_type > > &T)
Compute the inverse of a tridiagonal matrix T.
Definition tridiaginv.h:394
TridiagInvDF(const thrust::host_vector< real_type > ©able)
Construct from vector.
Definition tridiaginv.h:346
TridiagInvDF()
Allocate nothing, Call construct method before usage.
Definition tridiaginv.h:340
real_type value_type
Definition tridiaginv.h:338
void operator()(const ContainerType0 &a, const ContainerType1 &b, const ContainerType2 &c, dg::SquareMatrix< real_type > &Tinv)
Compute the inverse of a tridiagonal matrix with diagonal vectors a,b,c.
Definition tridiaginv.h:411
Compute the inverse of a general tridiagonal matrix.
Definition tridiaginv.h:488
void operator()(const dg::TriDiagonal< thrust::host_vector< real_type > > &T, dg::SquareMatrix< real_type > &Tinv)
Compute the inverse of a tridiagonal matrix T.
Definition tridiaginv.h:532
void resize(unsigned new_size)
Resize inverse tridiagonal matrix and helper vectors.
Definition tridiaginv.h:520
real_type value_type
Definition tridiaginv.h:490
TridiagInvD(unsigned size)
Construct from size of vector.
Definition tridiaginv.h:509
void operator()(const ContainerType0 &a, const ContainerType1 &b, const ContainerType2 &c, dg::SquareMatrix< real_type > &Tinv)
Compute the inverse of a tridiagonal matrix with diagonal vectors a,b,c.
Definition tridiaginv.h:563
dg::SquareMatrix< real_type > operator()(const dg::TriDiagonal< thrust::host_vector< real_type > > &T)
Compute the inverse of a tridiagonal matrix T.
Definition tridiaginv.h:546
TridiagInvD(const thrust::host_vector< real_type > ©able)
Construct from vector.
Definition tridiaginv.h:498
TridiagInvD()
Allocate nothing, Call construct method before usage.
Definition tridiaginv.h:492
Compute the inverse of a general tridiagonal matrix.
Definition tridiaginv.h:169
TridiagInvHMGTI(const thrust::host_vector< real_type > ©able)
Construct from vector.
Definition tridiaginv.h:179
TridiagInvHMGTI(unsigned size)
Construct from size of vector.
Definition tridiaginv.h:190
void operator()(const dg::TriDiagonal< thrust::host_vector< real_type > > &T, dg::SquareMatrix< real_type > &Tinv)
Compute the inverse of a tridiagonal matrix T.
Definition tridiaginv.h:213
void operator()(const ContainerType0 &a, const ContainerType1 &b, const ContainerType2 &c, dg::SquareMatrix< real_type > &Tinv)
Compute the inverse of a tridiagonal matrix with diagonal vectors a,b,c.
Definition tridiaginv.h:244
dg::SquareMatrix< real_type > operator()(const dg::TriDiagonal< thrust::host_vector< real_type > > &T)
Compute the inverse of a tridiagonal matrix T.
Definition tridiaginv.h:227
real_type value_type
Definition tridiaginv.h:171
TridiagInvHMGTI()
Allocate nothing, Call construct method before usage.
Definition tridiaginv.h:173
void resize(unsigned new_size)
Resize inverse tridiagonal matrix and helper vectors.
Definition tridiaginv.h:201
OutputType reduce(const ContainerType &x, OutputType zero, BinaryOp binary_op, UnaryOp unary_op=UnaryOp())
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:675
void compute_Tinv_y(const dg::TriDiagonal< thrust::host_vector< value_type > > &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:134
value_type compute_Tinv_m1(const dg::TriDiagonal< thrust::host_vector< value_type > > &T, unsigned size)
Computes the value of via a Thomas algorithm.
Definition tridiaginv.h:105
void invert(const dg::TriDiagonal< thrust::host_vector< value_type > > &T, dg::SquareMatrix< value_type > &Tinv)
Invert a tridiagonal matrix.
Definition tridiaginv.h:638
Classes for Krylov space approximations of a Matrix-Vector product.
double value_type
Definition tridiaginv_b.cpp:6