35void InnerProductMatrix(Eigen::MatrixXcd &m ,
const std::vector<Field> &X,
const std::vector<Field> &Y){
36 typedef typename Field::scalar_type scomplex;
37 int Nblock = X.size();
38 for(
int b=0;b<Nblock;b++){
39 for(
int bp=0;bp<Nblock;bp++) {
44void MaddMatrix(std::vector<Field> &AP, Eigen::MatrixXcd &m ,
const std::vector<Field> &X,
const std::vector<Field> &Y,
RealD scale=1.0){
50 typedef typename Field::scalar_type scomplex;
51 int Nblock = AP.size();
52 std::vector<Field> tmp(Nblock,X[0]);
53 for(
int b=0;b<Nblock;b++){
55 for(
int bp=0;bp<Nblock;bp++) {
56 tmp[b] = tmp[b] +scomplex(scale*m(bp,b))*X[bp];
59 for(
int b=0;b<Nblock;b++){
64void MulMatrix(std::vector<Field> &AP, Eigen::MatrixXcd &m ,
const std::vector<Field> &X){
66 typedef typename Field::scalar_type scomplex;
67 int Nblock = AP.size();
68 for(
int b=0;b<Nblock;b++){
70 for(
int bp=0;bp<Nblock;bp++) {
71 AP[b] += scomplex(m(bp,b))*X[bp];
76double normv(
const std::vector<Field> &P){
77 int Nblock = P.size();
79 for(
int b=0;b<Nblock;b++) {
134 Eigen::MatrixXcd &Cinv,
149 m_rr = 0.5*(m_rr+m_rr.adjoint());
151 Eigen::MatrixXcd L = m_rr.llt().matrixL();
169 Eigen::MatrixXcd &Cinv,
170 std::vector<Field> & Q,
171 const std::vector<Field> & R)
181 m_rr = 0.5*(m_rr+m_rr.adjoint());
183 Eigen::MatrixXcd L = m_rr.llt().matrixL();
226 Nblock =
B.Grid()->_fdimensions[Orthog];
229 std::cout<<
GridLogMessage<<
" Block Conjugate Gradient : Orthog "<<Orthog<<
" Nblock "<<
Nblock<<std::endl;
231 X.Checkerboard() =
B.Checkerboard();
240 Eigen::MatrixXcd m_DZ = Eigen::MatrixXcd::Identity(
Nblock,
Nblock);
241 Eigen::MatrixXcd m_M = Eigen::MatrixXcd::Identity(
Nblock,
Nblock);
242 Eigen::MatrixXcd m_rr = Eigen::MatrixXcd::Zero(
Nblock,
Nblock);
244 Eigen::MatrixXcd m_C = Eigen::MatrixXcd::Zero(
Nblock,
Nblock);
245 Eigen::MatrixXcd m_Cinv = Eigen::MatrixXcd::Zero(
Nblock,
Nblock);
246 Eigen::MatrixXcd m_S = Eigen::MatrixXcd::Zero(
Nblock,
Nblock);
247 Eigen::MatrixXcd m_Sinv = Eigen::MatrixXcd::Zero(
Nblock,
Nblock);
249 Eigen::MatrixXcd m_tmp = Eigen::MatrixXcd::Identity(
Nblock,
Nblock);
250 Eigen::MatrixXcd m_tmp1 = Eigen::MatrixXcd::Identity(
Nblock,
Nblock);
253 std::vector<RealD> residuals(
Nblock);
254 std::vector<RealD> ssq(
Nblock);
258 for(
int b=0;b<
Nblock;b++) sssum+=ssq[b];
259 for(
int b=0;b<
Nblock;b++) std::cout <<
"src["<<b<<
"]" << ssq[b] <<std::endl;
262 for(
int b=0;b<
Nblock;b++){ assert(std::isnan(residuals[b])==0); }
265 for(
int b=0;b<
Nblock;b++){ assert(std::isnan(residuals[b])==0); }
289 std::cout <<
GridLogMessage<<
"BlockCGrQ algorithm initialisation " <<std::endl;
296 for(
int b=0;b<
Nblock;b++) std::cout <<
"res["<<b<<
"]" << residuals[b] <<std::endl;
301 std::cout <<
GridLogMessage<<
"BlockCGrQ computed initial residual and QR fact " <<std::endl;
324 sliceInnerTimer.
Start();
326 sliceInnerTimer.
Stop();
327 m_M = m_DZ.inverse();
331 sliceMaddTimer.
Start();
333 sliceMaddTimer.
Stop();
336 sliceMaddTimer.
Start();
338 sliceMaddTimer.
Stop();
344 m_tmp = m_S.adjoint();
346 sliceMaddTimer.
Start();
348 sliceMaddTimer.
Stop();
357 m_rr = m_C.adjoint() * m_C;
363 for(
int b=0;b<
Nblock;b++) {
364 rrsum+=
real(m_rr(b,b));
365 rr =
real(m_rr(b,b))/ssq[b];
366 if ( rr > max_resid ) max_resid = rr;
369 std::cout <<
GridLogIterative <<
"\titeration "<<k<<
" rr_sum "<<rrsum<<
" ssq_sum "<< sssum
370 <<
" ave "<<std::sqrt(rrsum/sssum) <<
" max "<< max_resid <<std::endl;
376 std::cout <<
GridLogMessage<<
"BlockCGrQ converged in "<<k<<
" iterations"<<std::endl;
378 for(
int b=0;b<
Nblock;b++){
380 << std::sqrt(
real(m_rr(b,b))/ssq[b])<<std::endl;
382 std::cout <<
GridLogMessage<<
"\tMax residual is "<<std::sqrt(max_resid)<<std::endl;
403 <<
" residual "<< std::sqrt(max_resid)<< std::endl;
415 Nblock = Src.Grid()->_fdimensions[Orthog];
417 std::cout<<
GridLogMessage<<
"MultiRHS Conjugate Gradient : Orthog "<<Orthog<<
" Nblock "<<
Nblock<<std::endl;
419 Psi.Checkerboard() = Src.Checkerboard();
426 std::vector<ComplexD> v_pAp(
Nblock);
427 std::vector<RealD> v_rr (
Nblock);
428 std::vector<RealD> v_rr_inv(
Nblock);
429 std::vector<RealD> v_alpha(
Nblock);
430 std::vector<RealD> v_beta(
Nblock);
433 std::vector<RealD> residuals(
Nblock);
434 std::vector<RealD> ssq(
Nblock);
438 for(
int b=0;b<
Nblock;b++) sssum+=ssq[b];
441 for(
int b=0;b<
Nblock;b++){ assert(std::isnan(residuals[b])==0); }
444 for(
int b=0;b<
Nblock;b++){ assert(std::isnan(residuals[b])==0); }
464 for(
int b=0;b<
Nblock;b++) rrsum+=
real(v_rr[b]);
466 std::cout <<
GridLogIterative <<
"\titeration "<<k<<
" rr_sum "<<rrsum<<
" ssq_sum "<< sssum
467 <<
" / "<<std::sqrt(rrsum/sssum) <<std::endl;
474 sliceInnerTimer.
Start();
476 sliceInnerTimer.
Stop();
477 for(
int b=0;b<
Nblock;b++){
478 v_alpha[b] = v_rr[b]/
real(v_pAp[b]);
482 sliceMaddTimer.
Start();
485 sliceMaddTimer.
Stop();
488 for(
int b=0;b<
Nblock;b++){
489 v_rr_inv[b] = 1.0/v_rr[b];
491 sliceNormTimer.
Start();
493 sliceNormTimer.
Stop();
494 for(
int b=0;b<
Nblock;b++){
495 v_beta[b] = v_rr_inv[b] *v_rr[b];
499 sliceMaddTimer.
Start();
501 sliceMaddTimer.
Stop();
508 for(
int b=0;b<
Nblock;b++){
509 RealD rr = v_rr[b]/ssq[b];
510 if ( rr > max_resid ) max_resid = rr;
517 std::cout <<
GridLogMessage<<
"MultiRHS solver converged in " <<k<<
" iterations"<<std::endl;
518 for(
int b=0;b<
Nblock;b++){
519 std::cout <<
GridLogMessage<<
"\t\tBlock "<<b<<
" computed resid "<< std::sqrt(v_rr[b]/ssq[b])<<std::endl;
521 std::cout <<
GridLogMessage<<
"\tMax residual is "<<std::sqrt(max_resid)<<std::endl;
541 std::cout <<
GridLogMessage <<
"MultiRHSConjugateGradient did NOT converge" << std::endl;
557 assert(
Nblock == X.size());
561 for(
int b=0;b<
Nblock;b++){
562 X[b].Checkerboard() =
B[b].Checkerboard();
569 std::vector<Field> tmp(
Nblock,Fake);
570 std::vector<Field> Q(
Nblock,Fake);
571 std::vector<Field> D(
Nblock,Fake);
572 std::vector<Field> Z(
Nblock,Fake);
573 std::vector<Field> AD(
Nblock,Fake);
575 Eigen::MatrixXcd m_DZ = Eigen::MatrixXcd::Identity(
Nblock,
Nblock);
576 Eigen::MatrixXcd m_M = Eigen::MatrixXcd::Identity(
Nblock,
Nblock);
577 Eigen::MatrixXcd m_rr = Eigen::MatrixXcd::Zero(
Nblock,
Nblock);
579 Eigen::MatrixXcd m_C = Eigen::MatrixXcd::Zero(
Nblock,
Nblock);
580 Eigen::MatrixXcd m_Cinv = Eigen::MatrixXcd::Zero(
Nblock,
Nblock);
581 Eigen::MatrixXcd m_S = Eigen::MatrixXcd::Zero(
Nblock,
Nblock);
582 Eigen::MatrixXcd m_Sinv = Eigen::MatrixXcd::Zero(
Nblock,
Nblock);
584 Eigen::MatrixXcd m_tmp = Eigen::MatrixXcd::Identity(
Nblock,
Nblock);
585 Eigen::MatrixXcd m_tmp1 = Eigen::MatrixXcd::Identity(
Nblock,
Nblock);
588 std::vector<RealD> residuals(
Nblock);
589 std::vector<RealD> ssq(
Nblock);
593 for(
int b=0;b<
Nblock;b++){ std::cout <<
"ssq["<<b<<
"] "<<ssq[b]<<std::endl;}
594 for(
int b=0;b<
Nblock;b++) sssum+=ssq[b];
597 for(
int b=0;b<
Nblock;b++){ assert(std::isnan(residuals[b])==0); }
599 for(
int b=0;b<
Nblock;b++){ residuals[b] =
norm2(X[b]);}
600 for(
int b=0;b<
Nblock;b++){ assert(std::isnan(residuals[b])==0); }
624 std::cout <<
GridLogMessage<<
"BlockCGrQvec algorithm initialisation " <<std::endl;
627 for(
int b=0;b<
Nblock;b++) {
628 Linop.
HermOp(X[b], AD[b]);
629 tmp[b] =
B[b] - AD[b];
630 std::cout <<
"r0["<<b<<
"] "<<
norm2(tmp[b])<<std::endl;
635 for(
int b=0;b<
Nblock;b++) D[b]=Q[b];
637 std::cout <<
GridLogMessage<<
"BlockCGrQ vec computed initial residual and QR fact " <<std::endl;
658 sliceInnerTimer.
Start();
660 sliceInnerTimer.
Stop();
661 m_M = m_DZ.inverse();
665 sliceMaddTimer.
Start();
667 sliceMaddTimer.
Stop();
670 sliceMaddTimer.
Start();
672 sliceMaddTimer.
Stop();
678 m_tmp = m_S.adjoint();
679 sliceMaddTimer.
Start();
681 sliceMaddTimer.
Stop();
690 m_rr = m_C.adjoint() * m_C;
696 for(
int b=0;b<
Nblock;b++) {
697 rrsum+=
real(m_rr(b,b));
698 rr =
real(m_rr(b,b))/ssq[b];
699 if ( rr > max_resid ) max_resid = rr;
702 std::cout <<
GridLogIterative <<
"\t Block Iteration "<<k<<
" ave resid "<< std::sqrt(rrsum/sssum) <<
" max "<< std::sqrt(max_resid) <<std::endl;
708 std::cout <<
GridLogMessage<<
"BlockCGrQ converged in "<<k<<
" iterations"<<std::endl;
710 for(
int b=0;b<
Nblock;b++){
711 std::cout <<
GridLogMessage<<
"\t\tblock "<<b<<
" computed resid "<< std::sqrt(
real(m_rr(b,b))/ssq[b])<<std::endl;
713 std::cout <<
GridLogMessage<<
"\tMax residual is "<<std::sqrt(max_resid)<<std::endl;
716 for(
int b=0;b<
Nblock;b++) AD[b] = AD[b]-
B[b];
732 std::cout <<
GridLogMessage <<
"BlockConjugateGradient(rQ) did NOT converge" << std::endl;
void InnerProductMatrix(Eigen::MatrixXcd &m, const std::vector< Field > &X, const std::vector< Field > &Y)
double normv(const std::vector< Field > &P)
void MaddMatrix(std::vector< Field > &AP, Eigen::MatrixXcd &m, const std::vector< Field > &X, const std::vector< Field > &Y, RealD scale=1.0)
void MulMatrix(std::vector< Field > &AP, Eigen::MatrixXcd &m, const std::vector< Field > &X)
static void sliceMulMatrix(Lattice< vobj > &R, Eigen::MatrixXcd &aa, const Lattice< vobj > &X, int Orthog, RealD scale=1.0)
static void sliceMaddMatrix(Lattice< vobj > &R, Eigen::MatrixXcd &aa, const Lattice< vobj > &X, const Lattice< vobj > &Y, int Orthog, RealD scale=1.0)
static void sliceInnerProductMatrix(Eigen::MatrixXcd &mat, const Lattice< vobj > &lhs, const Lattice< vobj > &rhs, int Orthog)
Lattice< vobj > real(const Lattice< vobj > &lhs)
ComplexD innerProduct(const Lattice< vobj > &left, const Lattice< vobj > &right)
static void sliceMaddVector(Lattice< vobj > &R, std::vector< RealD > &a, const Lattice< vobj > &X, const Lattice< vobj > &Y, int orthogdim, RealD scale=1.0)
static void sliceNorm(std::vector< RealD > &sn, const Lattice< vobj > &rhs, int Orthog)
static void sliceInnerProductVector(std::vector< ComplexD > &result, const Lattice< vobj > &lhs, const Lattice< vobj > &rhs, int orthogdim)
RealD norm2(const Lattice< vobj > &arg)
GridLogger GridLogIterative(1, "Iterative", GridLogColours, "BLUE")
GridLogger GridLogMessage(1, "Message", GridLogColours, "NORMAL")
#define NAMESPACE_BEGIN(A)
void BlockCGrQsolveVec(LinearOperatorBase< Field > &Linop, const std::vector< Field > &B, std::vector< Field > &X)
void BlockCGrQsolve(LinearOperatorBase< Field > &Linop, const Field &B, Field &X)
virtual void operator()(LinearOperatorBase< Field > &Linop, const std::vector< Field > &Src, std::vector< Field > &Psi)
void ThinQRfact(Eigen::MatrixXcd &m_rr, Eigen::MatrixXcd &C, Eigen::MatrixXcd &Cinv, Field &Q, const Field &R)
Field::scalar_type scomplex
void CGmultiRHSsolve(LinearOperatorBase< Field > &Linop, const Field &Src, Field &Psi)
Integer IterationsToComplete
void ThinQRfact(Eigen::MatrixXcd &m_rr, Eigen::MatrixXcd &C, Eigen::MatrixXcd &Cinv, std::vector< Field > &Q, const std::vector< Field > &R)
void operator()(LinearOperatorBase< Field > &Linop, const Field &Src, Field &Psi)
BlockConjugateGradient(BlockCGtype cgtype, int _Orthog, RealD tol, Integer maxit, bool err_on_no_conv=true)
GridTime Elapsed(void) const
virtual void HermOp(const Field &in, Field &out)=0