3#include <boost/math/special_functions.hpp>
4#include <cusp/dia_matrix.h>
5#include <cusp/coo_matrix.h>
6#include <cusp/lapack/lapack.h>
31template<
class value_type>
33 cusp::host_memory>& T,
unsigned size)
35 value_type ci = T.values(0,2)/T.values(0,1), ciold = 0.;
36 value_type di = 1./T.values(0,1), diold = 0.;
37 for(
unsigned i=1; i<size; i++)
39 ciold = ci, diold = di;
40 ci = T.values(i,2)/ ( T.values(i,1)-T.values(i,0)*ciold);
41 di = -T.values( i, 0)*diold/(T.values(i,1)-T.values(i,0)*ciold);
57template<
class value_type>
59 cusp::host_memory>& T,
60 thrust::host_vector<value_type>& x,
61 const thrust::host_vector<value_type>& y, value_type a = 1.,
64 unsigned size =
y.size();
66 thrust::host_vector<value_type> ci(size), di(size);
67 ci[0] = a*T.values(0,2)/( a*T.values(0,1) + d);
68 di[0] =
y[0]/( a*T.values(0,1) + d);
69 for(
unsigned i=1; i<size; i++)
71 ci[i] = a*T.values(i,2)/ ( a*T.values(i,1) + d -a*T.values(i,0)*ci[i-1]);
72 di[i] = (
y[i]-a*T.values( i, 0)*di[i-1])/(a*T.values(i,1) + d
73 -a*T.values(i,0)*ci[i-1]);
75 x[size-1] = di[size-1];
76 for(
int i=size-2; i>=0; i--)
77 x[i] = di[i] - ci[i]*
x[i+1];
93template<
class ContainerType,
class DiaMatrix,
class CooMatrix>
107 m_size = copyable.size();
108 m_alphas.assign(m_size+1,0.);
109 m_betas.assign(m_size+1,0.);
119 m_alphas.assign(m_size+1,0.);
120 m_betas.assign(m_size+1,0.);
129 m_alphas.resize(m_size+1,0.);
130 m_betas.resize(m_size+1,0.);
169 template<
class ContainerType0,
class ContainerType1,
class ContainerType2>
170 void operator()(
const ContainerType0& a,
const ContainerType1& b,
171 const ContainerType2& c, CooMatrix& Tinv)
173 unsigned ss = m_size;
174 Tinv.resize(ss, ss, ss* ss);
177 Tinv.row_indices[0] = 0;
178 Tinv.column_indices[0] = 0;
179 Tinv.values[0] = 1./b[0];
185 for(
unsigned i = 2; i<ss+1; i++)
187 m_alphas[i] = a[i-1]*m_alphas[i-1] - c[i-1]*b[i-2]*m_alphas[i-2];
188 if (m_alphas[i] ==0 && i<ss) {
192 if (m_alphas[ss] ==0)
197 m_betas[ss-1]=a[ss-1];
198 m_betas[0] = m_alphas[ss];
199 for(
int i = ss-2; i>0; i--)
201 m_betas[i] = a[i]*m_betas[i+1] - c[i+1]*b[i]*m_betas[i+2];
208 Tinv.row_indices[0*ss+0] = 0;
209 Tinv.column_indices[0*ss+0] = 0;
210 Tinv.row_indices[(ss-1)*ss+(ss-1)] = (ss-1);
211 Tinv.column_indices[(ss-1)*ss+(ss-1)] = (ss-1);
212 Tinv.values[0*ss+0] = 1.0/(a[0]-c[1]*b[0]*m_betas[2]/m_betas[1]);
213 Tinv.values[(ss-1)*ss+(ss-1)] = 1.0/(a[ss-1] -
214 c[ss-1]*b[ss-2]*m_alphas[ss-2]/m_alphas[ss-1]);
215 for(
unsigned i=1; i<ss-1; i++)
217 Tinv.row_indices[i*ss+i] = i;
218 Tinv.column_indices[i*ss+i] = i;
219 Tinv.values[i*ss+i] =
220 1.0/(a[i]-c[i]*b[i-1]*m_alphas[i-1]/m_alphas[i]
221 -c[i+1]*b[i]*m_betas[i+2]/m_betas[i+1]);
224 for(
unsigned i=0; i<ss; i++)
226 for(
unsigned j=0; j<ss; j++)
228 Tinv.row_indices[i*ss+j] = j;
229 Tinv.column_indices[i*ss+j] = i;
231 Tinv.values[i*ss+j] =
232 sign(j-i)*std::accumulate(std::next(b.begin(),i),
233 std::next(b.begin(),j), 1.,
234 std::multiplies<value_type>())*
235 m_alphas[i]/m_alphas[j]*Tinv.values[j*ss+j];
239 Tinv.values[i*ss+j] =
240 sign(i-j)*std::accumulate(std::next(c.begin(),j+1),
241 std::next(c.begin(),i+1), 1.,
242 std::multiplies<value_type>())*
243 m_betas[i+1]/m_betas[j+1]*Tinv.values[j*ss+j];
252 if (i%2==0)
return 1;
255 ContainerType m_alphas, m_betas;
270template<
class ContainerType,
class DiaMatrix,
class CooMatrix>
284 m_size = copyable.size();
285 m_phi.assign(m_size,0.);
286 m_theta.assign(m_size,0.);
296 m_phi.assign(m_size,0.);
297 m_theta.assign(m_size,0.);
306 m_phi.resize(m_size,0.);
307 m_theta.resize(m_size,0.);
346 template<
class ContainerType0,
class ContainerType1,
class ContainerType2>
347 void operator()(
const ContainerType0& a,
const ContainerType1& b,
348 const ContainerType2& c, CooMatrix& Tinv)
350 Tinv.resize(m_size, m_size, m_size* m_size);
353 m_phi[0] = - b[0]/a[0];
354 for(
unsigned i = 1; i<m_size; i++)
356 helper = m_phi[i-1]* c[i] + a[i];
358 else m_phi[i] = -b[i]/helper;
363 if (m_size == 1) m_theta[m_size-1] = 0.0;
366 m_theta[m_size-1] = - c[m_size-1]/a[m_size-1];
367 for(
int i = m_size-2; i>=0; i--)
369 helper = m_theta[i+1]*b[i] + a[i];
371 else m_theta[i] = -c[i]/helper;
376 Tinv.row_indices[0*m_size+0] = 0;
377 Tinv.column_indices[0*m_size+0] = 0;
378 helper = a[0] + b[0]* m_theta[1];
380 else Tinv.values[0*m_size+0] = 1.0/helper;
382 Tinv.row_indices[(m_size-1)*m_size+(m_size-1)] = (m_size-1);
383 Tinv.column_indices[(m_size-1)*m_size+(m_size-1)] = (m_size-1);
384 if (m_size == 1) helper = a[m_size-1];
385 else helper = a[m_size-1] + c[m_size-1]*m_phi[m_size-2];
388 else Tinv.values[(m_size-1)*m_size+m_size-1] = 1.0/helper;
390 for(
unsigned i=1; i<m_size-1; i++)
392 Tinv.row_indices[i*m_size+i] = i;
393 Tinv.column_indices[i*m_size+i] = i;
394 helper = a[i] + c[i]*m_phi[i-1] + b[i]* m_theta[i+1];
396 else Tinv.values[i*m_size+i] = 1.0/helper;
399 for(
unsigned j=0; j<m_size-1; j++)
401 for (
unsigned i=j+1; i<m_size; i++)
403 Tinv.row_indices[i*m_size+j] = i;
404 Tinv.column_indices[i*m_size+j] = j;
405 Tinv.values[i*m_size+j] = m_theta[i]*Tinv.values[(i-1)*m_size+j];
408 for(
unsigned j=1; j<m_size; j++)
410 for (
int i=j-1; i>=0; i--)
412 Tinv.row_indices[i*m_size+j] = i;
413 Tinv.column_indices[i*m_size+j] = j;
414 Tinv.values[i*m_size+j] = m_phi[i]*Tinv.values[(i+1)*m_size+j];
419 ContainerType m_phi, m_theta;
434template<
class ContainerType,
class DiaMatrix,
class CooMatrix>
448 m_size = copyable.size();
449 m_phi.assign(m_size+1,0.);
450 m_theta.assign(m_size+1,0.);
460 m_phi.assign(m_size+1,0.);
461 m_theta.assign(m_size+1,0.);
470 m_phi.resize(m_size+1,0.);
471 m_theta.resize(m_size+1,0.);
510 template<
class ContainerType0,
class ContainerType1,
class ContainerType2>
511 void operator()(
const ContainerType0& a,
const ContainerType1& b,
512 const ContainerType2& c, CooMatrix& Tinv)
514 Tinv.resize( m_size, m_size, m_size*m_size);
516 for(
unsigned i = 0; i<m_size+1; i++)
531 m_theta[i] = a[i-1] * m_theta[i-1] - b[i-2] * c[i-1] * m_theta[i-2];
532 m_phi[is] = a[is] * m_phi[is+1] - b[is] * c[is+1] * m_phi[is+2];
537 for(
unsigned i=0; i<m_size; i++)
539 for(
unsigned j=0; j<m_size; j++)
541 Tinv.row_indices[i*m_size+j] = i;
542 Tinv.column_indices[i*m_size+j] = j;
544 Tinv.values[i*m_size+j] =
545 std::accumulate(std::next(b.begin(),i),
546 std::next(b.begin(),j), 1.,
547 std::multiplies<value_type>())*sign(i+j) *
548 m_theta[i] * m_phi[j+1]/m_theta[m_size];
552 Tinv.values[i*m_size+j] = m_theta[i] * m_phi[i+1]/m_theta[m_size];
556 Tinv.values[i*m_size+j] =
557 std::accumulate(std::next(c.begin(),j+1),
558 std::next(c.begin(),i+1), 1.,
559 std::multiplies<value_type>())*sign(i+j) *
560 m_theta[j] * m_phi[i+1]/m_theta[m_size];
569 if (i%2==0)
return 1;
572 ContainerType m_phi, m_theta;
587template<
class value_type>
588void invert(
const cusp::dia_matrix<int,value_type,cusp::host_memory>& T,
589 cusp::coo_matrix<int,value_type,cusp::host_memory>& Tinv)
591 using HCooMatrix = cusp::coo_matrix<int, value_type, cusp::host_memory>;
592 using HDiaMatrix = cusp::dia_matrix<int, value_type, cusp::host_memory>;
607template<
class value_type>
608cusp::coo_matrix<int,value_type,cusp::host_memory>
invert(
609 const cusp::dia_matrix<int,value_type,cusp::host_memory>& T)
611 using HCooMatrix = cusp::coo_matrix<int, value_type, cusp::host_memory>;
612 using HDiaMatrix = cusp::dia_matrix<int, value_type, cusp::host_memory>;
630template<
class value_type>
631std::array<value_type, 2>
compute_extreme_EV(
const cusp::dia_matrix<int,value_type, cusp::host_memory>& T)
633 unsigned size = T.num_rows;
634 cusp::array2d< value_type, cusp::host_memory> evecs;
635 cusp::array1d< value_type, cusp::host_memory> evals(size);
636 cusp::lapack::stev(T.values.column(1), T.values.column(2),
640 return std::array<value_type, 2>{EVmin, EVmax};
USE THIS ONE Compute the inverse of a general tridiagonal matrix. The algorithm does not rely on the ...
Definition: tridiaginv.h:272
void resize(unsigned new_size)
Resize inverse tridiagonal matrix and helper vectors.
Definition: tridiaginv.h:304
TridiagInvDF(unsigned size)
Construct from size of vector.
Definition: tridiaginv.h:293
void operator()(const ContainerType0 &a, const ContainerType1 &b, const ContainerType2 &c, CooMatrix &Tinv)
Compute the inverse of a tridiagonal matrix with diagonal vectors a,b,c.
Definition: tridiaginv.h:347
CooMatrix operator()(const DiaMatrix &T)
Compute the inverse of a tridiagonal matrix T.
Definition: tridiaginv.h:330
void operator()(const DiaMatrix &T, CooMatrix &Tinv)
Compute the inverse of a tridiagonal matrix T.
Definition: tridiaginv.h:316
TridiagInvDF()
Allocate nothing, Call construct method before usage.
Definition: tridiaginv.h:276
TridiagInvDF(const ContainerType ©able)
Construct from vector.
Definition: tridiaginv.h:282
dg::get_value_type< ContainerType > value_type
Definition: tridiaginv.h:274
Compute the inverse of a general tridiagonal matrix.
Definition: tridiaginv.h:436
void operator()(const DiaMatrix &T, CooMatrix &Tinv)
Compute the inverse of a tridiagonal matrix T.
Definition: tridiaginv.h:480
TridiagInvD()
Allocate nothing, Call construct method before usage.
Definition: tridiaginv.h:440
TridiagInvD(const ContainerType ©able)
Construct from vector.
Definition: tridiaginv.h:446
dg::get_value_type< ContainerType > value_type
Definition: tridiaginv.h:438
void operator()(const ContainerType0 &a, const ContainerType1 &b, const ContainerType2 &c, CooMatrix &Tinv)
Compute the inverse of a tridiagonal matrix with diagonal vectors a,b,c.
Definition: tridiaginv.h:511
CooMatrix operator()(const DiaMatrix &T)
Compute the inverse of a tridiagonal matrix T.
Definition: tridiaginv.h:494
TridiagInvD(unsigned size)
Construct from size of vector.
Definition: tridiaginv.h:457
void resize(unsigned new_size)
Resize inverse tridiagonal matrix and helper vectors.
Definition: tridiaginv.h:468
Compute the inverse of a general tridiagonal matrix.
Definition: tridiaginv.h:95
dg::get_value_type< ContainerType > value_type
Definition: tridiaginv.h:97
TridiagInvHMGTI()
Allocate nothing, Call construct method before usage.
Definition: tridiaginv.h:99
void resize(unsigned new_size)
Resize inverse tridiagonal matrix and helper vectors.
Definition: tridiaginv.h:127
CooMatrix operator()(const DiaMatrix &T)
Compute the inverse of a tridiagonal matrix T.
Definition: tridiaginv.h:153
void operator()(const ContainerType0 &a, const ContainerType1 &b, const ContainerType2 &c, CooMatrix &Tinv)
Compute the inverse of a tridiagonal matrix with diagonal vectors a,b,c.
Definition: tridiaginv.h:170
TridiagInvHMGTI(unsigned size)
Construct from size of vector.
Definition: tridiaginv.h:116
TridiagInvHMGTI(const ContainerType ©able)
Construct from vector.
Definition: tridiaginv.h:105
void operator()(const DiaMatrix &T, CooMatrix &Tinv)
Compute the inverse of a tridiagonal matrix T.
Definition: tridiaginv.h:139
OutputType reduce(const ContainerType &x, OutputType zero, BinaryOp binary_op, UnaryOp unary_op=UnaryOp())
value_type compute_Tinv_m1(const cusp::dia_matrix< int, value_type, cusp::host_memory > &T, unsigned size)
Computes the value of via a Thomas algorithm.
Definition: tridiaginv.h:32
std::array< value_type, 2 > compute_extreme_EV(const cusp::dia_matrix< int, value_type, cusp::host_memory > &T)
Compute extreme Eigenvalues of a symmetric tridiangular matrix.
Definition: tridiaginv.h:631
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 invert(const cusp::dia_matrix< int, value_type, cusp::host_memory > &T, cusp::coo_matrix< int, value_type, cusp::host_memory > &Tinv)
Invert a tridiagonal matrix.
Definition: tridiaginv.h:588
typename TensorTraits< std::decay_t< Vector > >::value_type get_value_type
thrust::host_vector< double > HVec
Classes for Krylov space approximations of a Matrix-Vector product.