#ifndef GRID_ALGORITHM_LINEAR_OP_H #define GRID_ALGORITHM_LINEAR_OP_H namespace Grid { ///////////////////////////////////////////////////////////////////////////////////////////// // LinearOperators Take a something and return a something. ///////////////////////////////////////////////////////////////////////////////////////////// // // Hopefully linearity is satisfied and the AdjOp is indeed the Hermitian conjugate (transpose if real): // // i) F(a x + b y) = aF(x) + b F(y). // ii) = ^\ast // // Would be fun to have a test linearity & Herm Conj function! ///////////////////////////////////////////////////////////////////////////////////////////// template class LinearOperatorBase { public: virtual void Op (const Field &in, Field &out) = 0; // Abstract base virtual void AdjOp (const Field &in, Field &out) = 0; // Abstract base }; ///////////////////////////////////////////////////////////////////////////////////////////// // Hermitian operators are self adjoint and only require Op to be defined, so refine the base ///////////////////////////////////////////////////////////////////////////////////////////// template class HermitianOperatorBase : public LinearOperatorBase { public: virtual RealD OpAndNorm(const Field &in, Field &out); void AdjOp(const Field &in, Field &out) { Op(in,out); }; void Op(const Field &in, Field &out) { OpAndNorm(in,out); }; }; ///////////////////////////////////////////////////////////////////////////////////////////// // Whereas non hermitian takes a generic sparse matrix (e.g. lattice action) // conforming to sparse matrix interface and builds the full checkerboard non-herm operator // Op and AdjOp distinct. // By sharing the class for Sparse Matrix across multiple operator wrappers, we can share code // between RB and non-RB variants. Sparse matrix is like the fermion action def, and then // the wrappers implement the specialisation of "Op" and "AdjOp" to the cases minimising // replication of code. ///////////////////////////////////////////////////////////////////////////////////////////// template class NonHermitianOperator : public LinearOperatorBase { Matrix &_Mat; public: NonHermitianOperator(Matrix &Mat): _Mat(Mat){}; void Op (const Field &in, Field &out){ _Mat.M(in,out); } void AdjOp (const Field &in, Field &out){ _Mat.Mdag(in,out); } }; //////////////////////////////////////////////////////////////////////////////////// // Redblack Non hermitian wrapper //////////////////////////////////////////////////////////////////////////////////// template class NonHermitianCheckerBoardedOperator : public LinearOperatorBase { Matrix &_Mat; public: NonHermitianCheckerBoardedOperator(Matrix &Mat): _Mat(Mat){}; void Op (const Field &in, Field &out){ _Mat.Mpc(in,out); } void AdjOp (const Field &in, Field &out){ // _Mat.MpcDag(in,out); } }; //////////////////////////////////////////////////////////////////////////////////// // Hermitian wrapper //////////////////////////////////////////////////////////////////////////////////// template class HermitianOperator : public HermitianOperatorBase { Matrix &_Mat; public: HermitianOperator(Matrix &Mat): _Mat(Mat) {}; RealD OpAndNorm(const Field &in, Field &out){ return _Mat.MdagM(in,out); } }; //////////////////////////////////////////////////////////////////////////////////// // Hermitian CheckerBoarded wrapper //////////////////////////////////////////////////////////////////////////////////// template class HermitianCheckerBoardedOperator : public HermitianOperatorBase { Matrix &_Mat; public: HermitianCheckerBoardedOperator(Matrix &Mat): _Mat(Mat) {}; void OpAndNorm(const Field &in, Field &out,RealD &n1,RealD &n2){ _Mat.MpcDagMpc(in,out,n1,n2); } }; ///////////////////////////////////////////////////////////// // Base classes for functions of operators ///////////////////////////////////////////////////////////// template class OperatorFunction { public: virtual void operator() (LinearOperatorBase &Linop, const Field &in, Field &out) = 0; }; // FIXME : To think about // Chroma functionality list defining LinearOperator /* virtual void operator() (T& chi, const T& psi, enum PlusMinus isign) const = 0; virtual void operator() (T& chi, const T& psi, enum PlusMinus isign, Real epsilon) const virtual const Subset& subset() const = 0; virtual unsigned long nFlops() const { return 0; } virtual void deriv(P& ds_u, const T& chi, const T& psi, enum PlusMinus isign) const class UnprecLinearOperator : public DiffLinearOperator const Subset& subset() const {return all;} }; */ // Chroma interface defining GaugeAction /* template class GaugeAction virtual const CreateGaugeState& getCreateState() const = 0; virtual GaugeState* createState(const Q& q) const virtual const GaugeBC& getGaugeBC() const virtual const Set& getSet(void) const = 0; virtual void deriv(P& result, const Handle< GaugeState >& state) const virtual Double S(const Handle< GaugeState >& state) const = 0; class LinearGaugeAction : public GaugeAction< multi1d, multi1d > typedef multi1d P; typedef multi1d Q; virtual void staple(LatticeColorMatrix& result, const Handle< GaugeState >& state, int mu, int cb) const = 0; */ // Chroma interface defining FermionAction /* template class FermAct4D : public FermionAction virtual LinearOperator* linOp(Handle< FermState > state) const = 0; virtual LinearOperator* lMdagM(Handle< FermState > state) const = 0; virtual LinOpSystemSolver* invLinOp(Handle< FermState > state, virtual MdagMSystemSolver* invMdagM(Handle< FermState > state, virtual LinOpMultiSystemSolver* mInvLinOp(Handle< FermState > state, virtual MdagMMultiSystemSolver* mInvMdagM(Handle< FermState > state, virtual MdagMMultiSystemSolverAccumulate* mInvMdagMAcc(Handle< FermState > state, virtual SystemSolver* qprop(Handle< FermState > state, class DiffFermAct4D : public FermAct4D virtual DiffLinearOperator* linOp(Handle< FermState > state) const = 0; virtual DiffLinearOperator* lMdagM(Handle< FermState > state) const = 0; */ } #endif