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*);
38extern void dsygv_(
int*,
char*,
char*,
int*,
double*,
int*,
double*,
int*,
double*,
double*,
int*,
int*);
39extern void ssygv_(
int*,
char*,
char*,
int*,
float*,
int*,
float*,
int*,
float*,
float*,
int*,
int*);
42template<
class ContainerType0,
class ContainerType1,
class ContainerType2,
class ContainerType3>
52 static_assert( std::is_same_v<value_type, double> or std::is_same_v<value_type, float>,
53 "Value type must be either float or double");
54 static_assert( std::is_same_v<dg::get_value_type<ContainerType1>,
value_type> &&
55 std::is_same_v<dg::get_value_type<ContainerType2>,
value_type> &&
56 std::is_same_v<dg::get_value_type<ContainerType3>,
value_type>,
57 "All Vectors must have same value type");
58 static_assert( std::is_same_v<dg::get_execution_policy<ContainerType0>,
dg::SerialTag> &&
59 std::is_same_v<dg::get_execution_policy<ContainerType1>,
dg::SerialTag> &&
60 std::is_same_v<dg::get_execution_policy<ContainerType2>,
dg::SerialTag> &&
61 std::is_same_v<dg::get_execution_policy<ContainerType3>,
dg::SerialTag>,
62 "All Vectors must have serial execution policy");
67 value_type * D_ptr = thrust::raw_pointer_cast( &D[0]);
68 value_type * E_ptr = thrust::raw_pointer_cast( &E[0]);
74 Z_ptr = thrust::raw_pointer_cast( &Z[0]);
75 work_ptr = thrust::raw_pointer_cast( &work[0]);
79 if constexpr ( std::is_same_v<value_type, double>)
80 dstev_( &job, &N, D_ptr, E_ptr, Z_ptr, &ldz, work_ptr, &info);
81 else if constexpr ( std::is_same_v<value_type, float>)
82 sstev_( &job, &N, D_ptr, E_ptr, Z_ptr, ldz, work_ptr, &info);
92template<
class ContainerType0,
class ContainerType1,
class ContainerType2,
class ContainerType3>
107 static_assert( std::is_same_v<value_type, double> or std::is_same_v<value_type, float>,
108 "Value type must be either float or double");
109 static_assert( std::is_same_v<dg::get_value_type<ContainerType1>,
value_type> &&
110 std::is_same_v<dg::get_value_type<ContainerType2>,
value_type> &&
111 std::is_same_v<dg::get_value_type<ContainerType3>,
value_type>,
112 "All Vectors must have same value type");
113 static_assert( std::is_same_v<dg::get_execution_policy<ContainerType0>,
dg::SerialTag> &&
114 std::is_same_v<dg::get_execution_policy<ContainerType1>,
dg::SerialTag> &&
115 std::is_same_v<dg::get_execution_policy<ContainerType2>,
dg::SerialTag> &&
116 std::is_same_v<dg::get_execution_policy<ContainerType3>,
dg::SerialTag>,
117 "All Vectors must have serial execution policy");
121 value_type * A_ptr = thrust::raw_pointer_cast( &A[0]);
122 value_type * B_ptr = thrust::raw_pointer_cast( &B[0]);
123 value_type * W_ptr = thrust::raw_pointer_cast( &W[0]);
124 value_type * work_ptr = thrust::raw_pointer_cast( &work[0]);
125 int work_size = (int)work.size();
128 if constexpr ( std::is_same_v<value_type, double>)
129 dsygv_( &itype, &jobz, &uplo, &N, A_ptr, &lda, B_ptr, &ldb, W_ptr, work_ptr, &work_size, &info);
130 else if constexpr ( std::is_same_v<value_type, float>)
131 ssygv_( &itype, &jobz, &uplo, &N, A_ptr, &lda, B_ptr, &ldb, W_ptr, work_ptr, &work.size, &info);
158template<
class value_type>
167 for(
unsigned i=1; i<size; i++)
169 ciold = ci, diold = di;
170 ci = T.P[i]/ ( T.O[i]-T.M[i]*ciold);
171 di = -T.M[i]*diold/(T.O[i]-T.M[i]*ciold);
187template<
class value_type>
190 thrust::host_vector<value_type>& x,
191 const thrust::host_vector<value_type>&
y,
value_type a = 1.,
194 unsigned size =
y.size();
196 thrust::host_vector<value_type> ci(size), di(size);
197 ci[0] = a*T.P[0]/( a*T.O[0] + d);
198 di[0] =
y[0]/( a*T.O[0] + d);
199 for(
unsigned i=1; i<size; i++)
201 ci[i] = a*T.P[i]/ ( a*T.O[i] + d -a*T.M[i]*ci[i-1]);
202 di[i] = (
y[i]-a*T.M[i]*di[i-1])/(a*T.O[i] + d
205 x[size-1] = di[size-1];
206 for(
int i=size-2; i>=0; i--)
207 x[i] = di[i] - ci[i]*
x[i+1];
220template<
class real_type>
234 m_size = copyable.size();
235 m_alphas.assign(m_size+1,0.);
236 m_betas.assign(m_size+1,0.);
246 m_alphas.assign(m_size+1,0.);
247 m_betas.assign(m_size+1,0.);
256 m_alphas.resize(m_size+1,0.);
257 m_betas.resize(m_size+1,0.);
296 template<
class ContainerType0,
class ContainerType1,
class ContainerType2>
297 void operator()(
const ContainerType0& a,
const ContainerType1& b,
300 unsigned ss = m_size;
310 for(
unsigned i = 2; i<ss+1; i++)
312 m_alphas[i] = a[i-1]*m_alphas[i-1] - c[i-1]*b[i-2]*m_alphas[i-2];
313 if (m_alphas[i] ==0 && i<ss) {
317 if (m_alphas[ss] ==0)
322 m_betas[ss-1]=a[ss-1];
323 m_betas[0] = m_alphas[ss];
324 for(
int i = ss-2; i>0; i--)
326 m_betas[i] = a[i]*m_betas[i+1] - c[i+1]*b[i]*m_betas[i+2];
333 Tinv(0, 0) = 1.0/(a[0]-c[1]*b[0]*m_betas[2]/m_betas[1]);
334 Tinv(ss-1, ss-1) = 1.0/(a[ss-1] -
335 c[ss-1]*b[ss-2]*m_alphas[ss-2]/m_alphas[ss-1]);
336 for(
unsigned i=1; i<ss-1; i++)
339 1.0/(a[i]-c[i]*b[i-1]*m_alphas[i-1]/m_alphas[i]
340 -c[i+1]*b[i]*m_betas[i+2]/m_betas[i+1]);
343 for(
unsigned i=0; i<ss; i++)
345 for(
unsigned j=0; j<ss; j++)
349 sign(j-i)*std::accumulate(std::next(b.begin(),i),
350 std::next(b.begin(),j), 1.,
351 std::multiplies<value_type>())*
352 m_alphas[i]/m_alphas[j]*Tinv(j,j);
357 sign(i-j)*std::accumulate(std::next(c.begin(),j+1),
358 std::next(c.begin(),i+1), 1.,
359 std::multiplies<value_type>())*
360 m_betas[i+1]/m_betas[j+1]*Tinv(j,j);
369 if (i%2==0)
return 1;
372 thrust::host_vector<real_type> m_alphas, m_betas;
385template<
class real_type>
399 m_size = copyable.size();
400 m_phi.assign(m_size,0.);
401 m_theta.assign(m_size,0.);
411 m_phi.assign(m_size,0.);
412 m_theta.assign(m_size,0.);
421 m_phi.resize(m_size,0.);
422 m_theta.resize(m_size,0.);
461 template<
class ContainerType0,
class ContainerType1,
class ContainerType2>
462 void operator()(
const ContainerType0& a,
const ContainerType1& b,
468 m_phi[0] = - b[0]/a[0];
469 for(
unsigned i = 1; i<m_size; i++)
471 helper = m_phi[i-1]* c[i] + a[i];
473 else m_phi[i] = -b[i]/helper;
478 if (m_size == 1) m_theta[m_size-1] = 0.0;
481 m_theta[m_size-1] = - c[m_size-1]/a[m_size-1];
482 for(
int i = m_size-2; i>=0; i--)
484 helper = m_theta[i+1]*b[i] + a[i];
486 else m_theta[i] = -c[i]/helper;
491 helper = a[0] + b[0]* m_theta[1];
493 else Tinv(0,0) = 1.0/helper;
495 if (m_size == 1) helper = a[m_size-1];
496 else helper = a[m_size-1] + c[m_size-1]*m_phi[m_size-2];
499 else Tinv( m_size -1 , m_size - 1) = 1.0/helper;
501 for(
unsigned i=1; i<m_size-1; i++)
503 helper = a[i] + c[i]*m_phi[i-1] + b[i]* m_theta[i+1];
505 else Tinv(i,i) = 1.0/helper;
508 for(
unsigned j=0; j<m_size-1; j++)
510 for (
unsigned i=j+1; i<m_size; i++)
512 Tinv(i,j) = m_theta[i]*Tinv(i-1, j);
515 for(
unsigned j=1; j<m_size; j++)
517 for (
int i=j-1; i>=0; i--)
519 Tinv(i,j) = m_phi[i]*Tinv(i+1,j);
524 thrust::host_vector<real_type> m_phi, m_theta;
537template<
class real_type>
551 m_size = copyable.size();
552 m_phi.assign(m_size+1,0.);
553 m_theta.assign(m_size+1,0.);
563 m_phi.assign(m_size+1,0.);
564 m_theta.assign(m_size+1,0.);
573 m_phi.resize(m_size+1,0.);
574 m_theta.resize(m_size+1,0.);
613 template<
class ContainerType0,
class ContainerType1,
class ContainerType2>
614 void operator()(
const ContainerType0& a,
const ContainerType1& b,
619 for(
unsigned i = 0; i<m_size+1; i++)
634 m_theta[i] = a[i-1] * m_theta[i-1] - b[i-2] * c[i-1] * m_theta[i-2];
635 m_phi[is] = a[is] * m_phi[is+1] - b[is] * c[is+1] * m_phi[is+2];
640 for(
unsigned i=0; i<m_size; i++)
642 for(
unsigned j=0; j<m_size; j++)
646 std::accumulate(std::next(b.begin(),i),
647 std::next(b.begin(),j), 1.,
648 std::multiplies<value_type>())*sign(i+j) *
649 m_theta[i] * m_phi[j+1]/m_theta[m_size];
653 Tinv(i,j) = m_theta[i] * m_phi[i+1]/m_theta[m_size];
658 std::accumulate(std::next(c.begin(),j+1),
659 std::next(c.begin(),i+1), 1.,
660 std::multiplies<value_type>())*sign(i+j) *
661 m_theta[j] * m_phi[i+1]/m_theta[m_size];
670 if (i%2==0)
return 1;
673 thrust::host_vector<real_type> m_phi, m_theta;
688template<
class value_type>
705template<
class value_type>
726template<
class value_type>
730 thrust::host_vector<value_type> evals( T.O), subdiagonal( T.P), Z, work;
731 lapack::stev(
'N', evals, subdiagonal, Z, work);
732 return std::array<value_type, 2>{evals[0], evals[evals.size()-1]};
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:387
void resize(unsigned new_size)
Resize inverse tridiagonal matrix and helper vectors.
Definition tridiaginv.h:419
TridiagInvDF(unsigned size)
Construct from size of vector.
Definition tridiaginv.h:408
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:431
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:445
TridiagInvDF(const thrust::host_vector< real_type > ©able)
Construct from vector.
Definition tridiaginv.h:397
TridiagInvDF()
Allocate nothing, Call construct method before usage.
Definition tridiaginv.h:391
real_type value_type
Definition tridiaginv.h:389
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:462
Compute the inverse of a general tridiagonal matrix.
Definition tridiaginv.h:539
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:583
void resize(unsigned new_size)
Resize inverse tridiagonal matrix and helper vectors.
Definition tridiaginv.h:571
real_type value_type
Definition tridiaginv.h:541
TridiagInvD(unsigned size)
Construct from size of vector.
Definition tridiaginv.h:560
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:614
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:597
TridiagInvD(const thrust::host_vector< real_type > ©able)
Construct from vector.
Definition tridiaginv.h:549
TridiagInvD()
Allocate nothing, Call construct method before usage.
Definition tridiaginv.h:543
Compute the inverse of a general tridiagonal matrix.
Definition tridiaginv.h:222
TridiagInvHMGTI(const thrust::host_vector< real_type > ©able)
Construct from vector.
Definition tridiaginv.h:232
TridiagInvHMGTI(unsigned size)
Construct from size of vector.
Definition tridiaginv.h:243
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:266
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:297
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:280
real_type value_type
Definition tridiaginv.h:224
TridiagInvHMGTI()
Allocate nothing, Call construct method before usage.
Definition tridiaginv.h:226
void resize(unsigned new_size)
Resize inverse tridiagonal matrix and helper vectors.
Definition tridiaginv.h:254
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
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:188
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:159
void invert(const dg::TriDiagonal< thrust::host_vector< value_type > > &T, dg::SquareMatrix< value_type > &Tinv)
Invert a tridiagonal matrix.
Definition tridiaginv.h:689
Functions for optimizing Contours.
double value_type
Definition tridiaginv_b.cpp:6