/************************************************************************************* Grid physics library, www.github.com/paboyle/Grid Source file: ./lib/algorithms/approx/Forecast.h Copyright (C) 2015 Author: Peter Boyle Author: paboyle Author: David Murphy This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. See the full license in the file "LICENSE" in the top level distribution directory *************************************************************************************/ /* END LEGAL */ #ifndef INCLUDED_FORECAST_H #define INCLUDED_FORECAST_H namespace Grid { // Abstract base class. // Takes a matrix (Mat), a source (phi), and a vector of Fields (chi) // and returns a forecasted solution to the system D*psi = phi (psi). template class Forecast { public: virtual Field operator()(Matrix &Mat, const Field& phi, const std::vector& chi) = 0; }; // Implementation of Brower et al.'s chronological inverter (arXiv:hep-lat/9509012), // used to forecast solutions across poles of the EOFA heatbath. // // Modified from CPS (cps_pp/src/util/dirac_op/d_op_base/comsrc/minresext.C) template class ChronoForecast : public Forecast { public: Field operator()(Matrix &Mat, const Field& phi, const std::vector& prev_solns) { int degree = prev_solns.size(); Field chi(phi); // forecasted solution // Trivial cases if(degree == 0){ chi = zero; return chi; } else if(degree == 1){ return prev_solns[0]; } RealD dot; ComplexD xp; Field r(phi); // residual Field Mv(phi); std::vector v(prev_solns); // orthonormalized previous solutions std::vector MdagMv(degree,phi); // Array to hold the matrix elements std::vector> G(degree, std::vector(degree)); // Solution and source vectors std::vector a(degree); std::vector b(degree); // Orthonormalize the vector basis for(int i=0; i std::abs(G[k][k])){ k = j; } } if(k != i){ xp = b[k]; b[k] = b[i]; b[i] = xp; for(int j=0; j=0; i--){ a[i] = 0.0; for(int j=i+1; j