3#include "dg/algorithm.h"
152template<
class ContainerType >
167 m_v = m_vp = m_vm = copyable;
168 m_max_iter = max_iterations;
169 m_iter = max_iterations;
171 set_iter( max_iterations);
174 template<
class ...Params>
184 m_max_iter = new_max;
222 template <
class MatrixType,
class ContainerType0,
class ContainerType1,
223 class ContainerType2,
class FuncTe1>
224 unsigned solve(ContainerType0& x, FuncTe1 f,
225 MatrixType&& A,
const ContainerType1& b,
226 const ContainerType2& weights,
double eps,
227 double nrmb_correction = 1.,
228 std::string error_norm =
"universal",
232 tridiag( f, std::forward<MatrixType>(A), b, weights, eps,
233 nrmb_correction, error_norm, res_fac, q);
234 if(
"residual" == error_norm)
237 normMbVy(std::forward<MatrixType>(A), m_TH, m_yH,
x, b,
263 template<
class MatrixType,
class ContainerType0,
class ContainerType1>
265 const ContainerType1& weights,
double eps = 1e-4,
266 double nrmb_correction = 1.,
267 std::string error_norm =
"compute_extreme_EV",
272 tridiag( op, std::forward<MatrixType>(A), b, weights, eps,
273 nrmb_correction, error_norm, res_fac, q);
289 template<
class MatrixType,
class ContainerType0,
290 class ContainerType1,
class ContainerType2>
293 const ContainerType0&
y,
295 const ContainerType2& b,
double bnorm)
305 unsigned less_iter = 0;
306 for(
unsigned i=0; i<
y.size(); i++)
311 for (
unsigned i=0; i<less_iter-1; i++)
315 -T.M[i]/T.P[i], m_vm,
335 template <
class UnaryOp,
class MatrixType,
336 class ContainerType1,
class ContainerType2>
338 MatrixType&& A,
const ContainerType1& b,
339 const ContainerType2& weights,
double eps,
340 double nrmb_correction,
341 std::string error_norm =
"residual",
347 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
349 m_bnorm = nrm( weights, b);
352 DG_RANK0 std::cout <<
"# Norm of b "<<m_bnorm <<
"\n";
353 if (
"compute_extreme_EV" == error_norm ||
"compute_max_EV" == error_norm)
355 DG_RANK0 std::cout <<
"# Rel EV errors: \n";
359 DG_RANK0 std::cout <<
"# Res factor "<<res_fac <<
"\n";
360 DG_RANK0 std::cout <<
"# Residual errors: \n";
368 double residual = 1e300;
372 double lmin = -1e300, lmax = 1e300;
373 for(
unsigned i=0; i<m_max_iter; i++)
378 alphai = dot(m_vp, weights, m_v);
381 betaip = nrm( weights, m_vp);
382 if (fabs( betaip) <= 1e-12)
385 if (
"compute_extreme_EV" == error_norm ||
"compute_max_EV" == error_norm)
391 DG_RANK0 std::cout <<
"beta["<<i+1 <<
"]=0 encountered\n";
397 if(
"residual" == error_norm)
399 residual = compute_residual_error( m_TH, i)*m_bnorm;
402 else if (
"compute_extreme_EV" == error_norm ||
"compute_max_EV" == error_norm)
408 thrust::host_vector<double> evals( i+1), subdiagonal( i+1), Z, work;
409 for(
unsigned u=0; u<i+1; u++)
411 evals[u] = m_TH.
O[u];
412 subdiagonal[u] = m_TH.
P[u];
414 lapack::stev(
'N', evals, subdiagonal, Z, work);
416 DG_RANK0 std::cout <<
"# lmin = " << evals[0] <<
" lmax = "<<evals[i]<<
"\tat i = " << i <<
"\n";
418 if( fabs(lmax - evals[i]) < 10*eps*evals[i])
420 if( (
"compute_extreme_EV" == error_norm &&
422 fabs( lmin - evals[0]) < 10 * (eps*fabs(lmin) + 1e-12*lmax))
423 ||
"compute_max_EV" == error_norm)
429 lmin = evals[0], lmax = evals[i];
434 if( i>=q &&( (i<=10) || (i>10 && i%10 == 0) ))
436 residual = compute_universal_error( m_TH, i, q, f,
446 if( m_verbose &&
"compute_extreme_EV" != error_norm &&
"compute_max_EV" != error_norm)
447 DG_RANK0 std::cout <<
"# ||r||_W = " << residual <<
"\tat i = " << i <<
"\n";
448 if (res_fac*residual< eps*(xnorm + nrmb_correction) )
456 set_iter( m_max_iter);
462 template<
class ContainerType1,
class ContainerType2>
463 auto nrm(
const ContainerType1& w,
const ContainerType2& x)
467 if constexpr (is_complex)
468 return sqrt(
blas1::vdot( dg::detail::NORM(), w, x));
472 template<
class ContainerType0,
class ContainerType1,
class ContainerType2>
473 auto dot(
const ContainerType0& x0,
const ContainerType1& w,
const ContainerType2& x1)
478 if constexpr (not is_complex )
483 double compute_residual_error(
const dg::TriDiagonal<thrust::host_vector<double>>& TH,
unsigned iter)
486 return TH.P[iter]*fabs(T1);
488 template<
class UnaryOp>
489 double compute_universal_error(
const dg::TriDiagonal<thrust::host_vector<double>>& TH,
unsigned iter,
490 unsigned q, UnaryOp f,
HVec& yH)
492 unsigned new_iter = iter + 1 + q;
495 for(
unsigned u=0; u<iter+1; u++)
497 THtilde.M[u] = TH.M[u];
498 THtilde.O[u] = TH.O[u];
499 THtilde.P[u] = TH.P[u];
501 for(
unsigned u=1; u<=q; u++)
503 THtilde.M[ iter+u] = u==1 ? TH.P[iter] :
505 THtilde.O[ iter+u] = TH.O[ iter-u];
506 THtilde.P[ iter+u] = TH.M[ iter-u];
509 HVec yHtilde = f( THtilde);
510 for(
unsigned u=0; u<yH.size(); u++)
518 void set_iter(
unsigned new_iter) {
522 ContainerType m_v, m_vp, m_vm;
525 unsigned m_iter, m_max_iter;
526 bool m_verbose =
false;
Tridiagonalize and approximate via Lanczos algorithm. A is self-adjoint in the weights .
Definition lanczos.h:154
void normMbVy(MatrixType &&A, const dg::TriDiagonal< thrust::host_vector< double > > &T, const ContainerType0 &y, ContainerType1 &x, const ContainerType2 &b, double bnorm)
compute from a given tridiagonal matrix T and in-place re-computation of V
Definition lanczos.h:291
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
get_value_type< ContainerType > value_type
Definition lanczos.h:156
double get_bnorm() const
Norm of b from last call to operator()
Definition lanczos.h:198
unsigned solve(ContainerType0 &x, FuncTe1 f, MatrixType &&A, const ContainerType1 &b, const ContainerType2 &weights, double eps, double nrmb_correction=1., std::string error_norm="universal", double res_fac=1., unsigned q=1)
via Lanczos and matrix function computation. A is self-adjoint in the weights .
Definition lanczos.h:224
UniversalLanczos(const ContainerType ©able, unsigned max_iterations)
Allocate memory for the method.
Definition lanczos.h:165
void set_verbose(bool verbose)
Set or unset debugging output during iterations.
Definition lanczos.h:194
unsigned get_max() const
Get the current maximum number of iterations.
Definition lanczos.h:190
unsigned get_iter() const
Get the number of iterations in the last call to tridiag or solve (same as T.num_rows)
Definition lanczos.h:203
UniversalLanczos()
Allocate nothing, Call construct method before usage.
Definition lanczos.h:158
void set_max(unsigned new_max)
Set the maximum number of iterations.
Definition lanczos.h:183
const dg::TriDiagonal< thrust::host_vector< double > > & tridiag(UnaryOp f, MatrixType &&A, const ContainerType1 &b, const ContainerType2 &weights, double eps, double nrmb_correction, std::string error_norm="residual", double res_fac=1., unsigned q=1)
Tridiagonalization of A using Lanczos method.
Definition lanczos.h:337
void construct(Params &&...ps)
Perfect forward parameters to one of the constructors.
Definition lanczos.h:175
void copy(const ContainerTypeIn &source, ContainerTypeOut &target)
void axpbypgz(value_type alpha, const ContainerType1 &x, value_type1 beta, const ContainerType2 &y, value_type2 gamma, ContainerType &z)
void axpby(value_type alpha, const ContainerType1 &x, value_type1 beta, ContainerType &y)
auto vdot(Functor f, const ContainerType &x, const ContainerTypes &...xs) -> std::invoke_result_t< Functor, dg::get_value_type< ContainerType >, dg::get_value_type< ContainerTypes >... >
void scal(ContainerType &x, value_type alpha)
auto dot(const ContainerType1 &x, const MatrixType &m, const ContainerType2 &y)
void symv(MatrixType &&M, const ContainerType1 &x, ContainerType2 &y)
constexpr bool is_scalar_v
typename TensorTraits< std::decay_t< Vector > >::value_type get_value_type
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
auto make_Linear_Te1(int exp)
Create a functor that computes directly.
Definition matrixfunction.h:182
thrust::host_vector< double > HVec
Functions for optimizing Contours.
void resize(unsigned size)