4#include "dg/algorithm.h"
46template<
class ContainerType>
62 m_lanczos.construct( copyable, max_iterations);
63 m_v = m_vp = m_vm = m_f = copyable;
66 template<
class ...Params>
74 void set_benchmark(
bool benchmark, std::string message =
"ProductFunction"){
75 m_benchmark = benchmark;
106 template<
class ContainerType0,
class BinaryOp,
class ContainerType1,
107 class MatrixType,
class ContainerType2,
class ContainerType3>
111 const ContainerType1& diag,
113 const ContainerType2& b,
114 const ContainerType3& weights,
120 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
125 auto T = m_lanczos.tridiag( func, std::forward<MatrixType>(A),
126 b, weights, eps, nrmb_correction,
127 "universal", 1.0, 2);
128 compute_vlcl( op, diag, std::forward<MatrixType>(A), T,
x, b,
129 m_lanczos.get_bnorm());
132 DG_RANK0 std::cout <<
"# `"<<m_message<<
"` solve with {"<<T.num_rows<<
"} iterations took "<<t.
diff()<<
"s\n";
169 template<
class ContainerType0,
class BinaryOp,
class MatrixType,
170 class ContainerType1,
class ContainerType2,
class ContainerType3>
175 const ContainerType1& diag,
176 const ContainerType2& b,
177 const ContainerType3& weights,
185 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
190 auto T = m_lanczos.tridiag( func, std::forward<MatrixType>(A),
191 b, weights, eps, nrmb_correction,
192 "universal", 1.0, 2);
194 weights, m_lanczos.get_bnorm());
198 DG_RANK0 std::cout <<
"# `"<<m_message<<
"` solve with {"<<T.num_rows<<
"} iterations took "<<t.
diff()<<
"s\n";
235 template<
class BinaryOp,
class ContainerType0,
class MatrixType,
236 class ContainerType1,
class ContainerType2>
239 const TriDiagonal<thrust::host_vector<value_type>>& T,
241 const ContainerType2& b,
249 unsigned iter = T.O.size();
250 thrust::host_vector<value_type> evals = T.O, plus = T.P;
251 thrust::host_vector<value_type> work (2*iter-2);
254 lapack::stev(
'V', evals, plus, EHt.
data(), work);
258 for (
unsigned k=0; k<iter; k++)
264 for (
unsigned i=0; i<iter-1; i++)
268 -T.M[i]/T.P[i], m_vm,
274 for (
unsigned k=0; k<iter; k++)
310 template<
class BinaryOp,
class MatrixType,
class ContainerType0,
311 class ContainerType1,
class ContainerType2,
class ContainerType3>
314 const ContainerType0& diag,
315 const TriDiagonal<thrust::host_vector<value_type>>& T,
317 const ContainerType2& b,
318 const ContainerType3& weights,
326 unsigned iter = T.O.size();
327 thrust::host_vector<value_type> evals = T.O, plus = T.P;
328 thrust::host_vector<value_type> work (2*iter-2);
331 lapack::stev(
'V', evals, plus, EHt.
data(), work);
336 for (
unsigned k=0; k<iter; k++)
342 for (
unsigned i=0; i<iter-1; i++)
346 -T.M[i]/T.P[i], m_vm,
351 for (
unsigned k=0; k<iter; k++)
360 std::vector<double> cl( iter, 0.0);
361 for(
unsigned l=0; l<iter; l++)
362 for(
unsigned i=0; i<iter; i++)
363 for(
unsigned k=0; k<iter; k++)
364 cl[l] += EHt(k,i)*
alpha(k,i)*EHt(k,l);
369 for (
unsigned i=0; i<iter-1; i++)
373 -T.M[i]/T.P[i], m_vm,
389 bool m_benchmark =
true;
390 std::string m_message =
"ProductFunction";
391 ContainerType m_v, m_vp, m_vm, m_f;
426template<
class Geometry,
class Matrix,
class ComplexContainer>
432 m_multi( grid, stages),
433 m_previous( 2, {1, m_multi.copyable()}),
434 m_z( m_multi.copyable()),
435 m_rhs( m_multi.copyable()),
436 m_grid_points(grid.size()),
454 m_EV_up2date =
false;
463 m_cauchy_opt.set_verbose(verbose);
470 unsigned num_nodes()
const {
return m_cauchy_opt.num_nodes();}
480 if( m_adjoint != adjoint)
482 m_previous.assign( m_previous.size(), {1, m_multi.copyable()});
511 template<
class MatrixType,
class UnaryFunc,
class UnaryFuncD,
512 class ContainerType0,
class ContainerType1,
class ContainerType2>
513 void solve( ContainerType0& x, UnaryFunc func, UnaryFuncD dxfunc, std::vector<MatrixType>& ops,
514 const ContainerType1& d,
const ContainerType2& b, std::vector<double> eps)
518 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
524 update_extremeEVs( ops);
528 bool changed =
false;
531 DG_RANK0 std::cout <<
"# "<<dmin<<
" < D < "<<dmax<<
"\n";
532 DG_RANK0 std::cout <<
"# "<<m_lmin<<
" < Lambda < "<<m_lmax<<
"\n";
534 const auto& zkwk = m_cauchy_opt.update_zkwk( changed, func, dxfunc,
535 m_lmin, m_lmax, dmin, dmax, m_with_zero, m_eps);
537 m_previous.assign( m_cauchy_opt.num_nodes(), {1, m_multi.copyable()});
541 DG_RANK0 std::cout <<
"# Current number of nodes "<<m_cauchy_opt.num_nodes()<<
"\n";
544 thrust::complex<double> zk, wk;
548 ShiftedOp( MatrixType& mat,
const thrust::complex<double>& zk)
549 : m_zk(zk), m_mat(mat){}
550 void operator()(
const ComplexContainer&
x, ComplexContainer&
y)
557 auto weights()
const {
return m_mat.weights();}
558 auto precond()
const {
return m_mat.precond();}
560 const thrust::complex<double>& m_zk;
564 std::vector<ShiftedOp > shifted_ops;
565 for(
unsigned u=0; u<m_multi.stages(); u++)
566 shifted_ops.push_back( ShiftedOp{ ops[u], zk});
569 for(
unsigned k=0; k<m_cauchy_opt.num_nodes(); k++)
576 m_previous[k].extrapolate( m_z);
583 m_multi.solve( shifted_ops, m_z, m_rhs, eps);
584 m_previous[k].update( m_z);
589 m_multi.solve( shifted_ops, m_z, m_rhs, eps);
590 m_previous[k].update( m_z);
596 x += 2*
z.real();}, m_z,
x );
606 template<
class MatrixType>
607 void update_extremeEVs(std::vector<MatrixType>& ops )
611 lanczos.set_verbose(
true);
612 auto rnd = ops[0].weights();
614 auto T = lanczos.tridiag( ops[0], rnd, ops[0].weights(), 1e-4, 1.,
"compute_extreme_EV");
621 if( m_lmin < 1e-10*m_lmax)
623 if( m_verbose)
DG_RANK0 std::cout <<
"# Found zero EV!\n";
624 m_lmin = m_lmax/ m_grid_points;
632 MultigridCG2d<Geometry, Matrix, ComplexContainer, dg::complex_symmetric> m_multi;
633 std::vector<dg::Extrapolation<ComplexContainer, double>> m_previous;
634 ComplexContainer m_z, m_rhs;
635 unsigned m_grid_points;
636 CauchyOptimizer m_cauchy_opt;
637 bool m_adjoint =
true;
639 bool m_with_zero =
false;
640 double m_lmin = 0, m_lmax = 0;
641 bool m_EV_up2date =
false;
642 bool m_verbose =
false;
const std::vector< value_type > & data() const
Tridiagonalize and approximate via Lanczos algorithm. A is self-adjoint in the weights .
Definition lanczos.h:154
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)
void pointwiseDot(value_type alpha, const ContainerType1 &x1, const ContainerType2 &x2, value_type1 beta, ContainerType &y)
void transform(const ContainerType1 &x, ContainerType &y, UnaryOp op)
OutputType reduce(const ContainerType &x, OutputType zero, BinaryOp binary_op, UnaryOp unary_op=UnaryOp())
void subroutine(Subroutine f, ContainerType &&x, ContainerTypes &&... xs)
void evaluate(ContainerType &y, BinarySubroutine f, Functor g, const ContainerType0 &x0, const ContainerTypes &...xs)
auto dot(const ContainerType1 &x, const MatrixType &m, const ContainerType2 &y)
void symv(MatrixType &&M, const ContainerType1 &x, ContainerType2 &y)
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
auto make_FuncEigen_Te1(UnaryOp f)
Create a functor that uses Eigenvalue decomposition to compute for symmetric tridiagonal T.
Definition matrixfunction.h:29
dg::DMatrix Matrix
Definition lanczos_b.cpp:18
const double alpha
Definition lanczos_b.cpp:11
Functions for optimizing Contours.
Computation of or where is a positive (semi)-definite matrix self-adjoint in the weights .
Definition matrixprod.h:428
void solve(ContainerType0 &x, UnaryFunc func, UnaryFuncD dxfunc, std::vector< MatrixType > &ops, const ContainerType1 &d, const ContainerType2 &b, std::vector< double > eps)
Compute the bivariate matrix function.
Definition matrixprod.h:513
void clear_cache()
Clear the cached Eigenvalues of the matrix in the solve method.
Definition matrixprod.h:453
void set_adjoint(bool adjoint)
Determine if adjoint or direct bivariate matrix function is computed.
Definition matrixprod.h:478
unsigned num_nodes() const
Number of (complex) nodes used in the latest call to solve.
Definition matrixprod.h:470
const dg::MultigridCG2d< Geometry, Matrix, ComplexContainer, dg::complex_symmetric > & multigrid() const
Access the internal multigrid method to be able to construct matrices.
Definition matrixprod.h:444
void set_verbose(bool verbose)
Verbose output to std::cout.
Definition matrixprod.h:461
CauchyMatrixProduct()=default
CauchyMatrixProduct(double lm_eps, const Geometry &grid, unsigned stages, bool adjoint=true)
Definition matrixprod.h:430
bool get_adjoint() const
Current value of the adjoint parameter.
Definition matrixprod.h:488
Computation of and where is a positive definite matrix self-adjoint in the weights .
Definition matrixprod.h:48
void compute_vlcl_adjoint(BinaryOp op, MatrixType &&A, const ContainerType0 &diag, const TriDiagonal< thrust::host_vector< value_type > > &T, ContainerType1 &x, const ContainerType2 &b, const ContainerType3 &weights, value_type bnorm)
Compute .
Definition matrixprod.h:312
void compute_vlcl(BinaryOp op, const ContainerType0 &diag, MatrixType &&A, const TriDiagonal< thrust::host_vector< value_type > > &T, ContainerType1 &x, const ContainerType2 &b, value_type bnorm)
Compute .
Definition matrixprod.h:237
ProductMatrixFunction(const ContainerType ©able, unsigned max_iterations)
Allocate memory for the method.
Definition matrixprod.h:60
void set_benchmark(bool benchmark, std::string message="ProductFunction")
Set or unset performance timings during iterations.
Definition matrixprod.h:74
UniversalLanczos< ContainerType > & lanczos()
Access the Lanczos class that is constructed with the constructor parameters.
Definition matrixprod.h:385
ContainerType container_type
Definition matrixprod.h:49
unsigned apply(ContainerType0 &x, BinaryOp op, const ContainerType1 &diag, MatrixType &&A, const ContainerType2 &b, const ContainerType3 &weights, value_type eps, value_type nrmb_correction=1.)
Compute .
Definition matrixprod.h:108
void construct(Params &&...ps)
Perfect forward parameters to one of the constructors.
Definition matrixprod.h:67
dg::get_value_type< ContainerType > value_type
Definition matrixprod.h:50
ProductMatrixFunction()=default
Construct empty.
unsigned apply_adjoint(ContainerType0 &x, BinaryOp op, MatrixType &&A, const ContainerType1 &diag, const ContainerType2 &b, const ContainerType3 &weights, value_type eps, value_type nrmb_correction=1.)
Compute .
Definition matrixprod.h:171