2015-05-13 11:25:34 +01:00
|
|
|
#ifndef GRID_ALGORITHM_LINEAR_OP_H
|
|
|
|
#define GRID_ALGORITHM_LINEAR_OP_H
|
|
|
|
|
|
|
|
namespace Grid {
|
|
|
|
|
2015-05-16 23:35:08 +01:00
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// LinearOperators Take a something and return a something.
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
//
|
2015-05-19 13:57:35 +01:00
|
|
|
// Hopefully linearity is satisfied and the AdjOp is indeed the Hermitian conjugateugate (transpose if real):
|
|
|
|
//SBase
|
2015-05-16 23:35:08 +01:00
|
|
|
// i) F(a x + b y) = aF(x) + b F(y).
|
|
|
|
// ii) <x|Op|y> = <y|AdjOp|x>^\ast
|
|
|
|
//
|
|
|
|
// Would be fun to have a test linearity & Herm Conj function!
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
template<class Field> class LinearOperatorBase {
|
2015-05-13 11:25:34 +01:00
|
|
|
public:
|
2015-05-16 23:35:08 +01:00
|
|
|
virtual void Op (const Field &in, Field &out) = 0; // Abstract base
|
|
|
|
virtual void AdjOp (const Field &in, Field &out) = 0; // Abstract base
|
2015-05-13 11:25:34 +01:00
|
|
|
};
|
|
|
|
|
2015-05-16 23:35:08 +01:00
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Hermitian operators are self adjoint and only require Op to be defined, so refine the base
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
template<class Field> class HermitianOperatorBase : public LinearOperatorBase<Field> {
|
|
|
|
public:
|
2015-05-19 13:57:35 +01:00
|
|
|
virtual void OpAndNorm(const Field &in, Field &out,double &n1,double &n2);
|
2015-05-16 23:35:08 +01:00
|
|
|
void AdjOp(const Field &in, Field &out) {
|
2015-05-17 00:19:03 +01:00
|
|
|
Op(in,out);
|
|
|
|
};
|
|
|
|
void Op(const Field &in, Field &out) {
|
2015-05-19 13:57:35 +01:00
|
|
|
double n1,n2;
|
|
|
|
OpAndNorm(in,out,n1,n2);
|
2015-05-16 23:35:08 +01:00
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// 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.
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////
|
2015-05-18 07:47:05 +01:00
|
|
|
template<class Matrix,class Field>
|
2015-05-16 23:35:08 +01:00
|
|
|
class NonHermitianOperator : public LinearOperatorBase<Field> {
|
2015-05-18 07:47:05 +01:00
|
|
|
Matrix &_Mat;
|
2015-05-16 23:35:08 +01:00
|
|
|
public:
|
2015-05-18 07:47:05 +01:00
|
|
|
NonHermitianOperator(Matrix &Mat): _Mat(Mat){};
|
2015-05-16 23:35:08 +01:00
|
|
|
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
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////
|
2015-05-18 07:47:05 +01:00
|
|
|
template<class Matrix,class Field>
|
|
|
|
class NonHermitianCheckerBoardedOperator : public LinearOperatorBase<Field> {
|
|
|
|
Matrix &_Mat;
|
2015-05-16 23:35:08 +01:00
|
|
|
public:
|
2015-05-18 07:47:05 +01:00
|
|
|
NonHermitianCheckerBoardedOperator(Matrix &Mat): _Mat(Mat){};
|
2015-05-16 23:35:08 +01:00
|
|
|
void Op (const Field &in, Field &out){
|
2015-05-17 00:19:03 +01:00
|
|
|
_Mat.Mpc(in,out);
|
2015-05-16 23:35:08 +01:00
|
|
|
}
|
|
|
|
void AdjOp (const Field &in, Field &out){ //
|
2015-05-17 00:19:03 +01:00
|
|
|
_Mat.MpcDag(in,out);
|
2015-05-16 23:35:08 +01:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Hermitian wrapper
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////
|
2015-05-18 07:47:05 +01:00
|
|
|
template<class Matrix,class Field>
|
2015-05-16 23:35:08 +01:00
|
|
|
class HermitianOperator : public HermitianOperatorBase<Field> {
|
2015-05-18 07:47:05 +01:00
|
|
|
Matrix &_Mat;
|
2015-05-16 23:35:08 +01:00
|
|
|
public:
|
2015-05-18 07:47:05 +01:00
|
|
|
HermitianOperator(Matrix &Mat): _Mat(Mat) {};
|
2015-05-19 13:57:35 +01:00
|
|
|
void OpAndNorm(const Field &in, Field &out,double &n1,double &n2){
|
|
|
|
return _Mat.MdagM(in,out,n1,n2);
|
2015-05-16 23:35:08 +01:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////
|
2015-05-18 07:47:05 +01:00
|
|
|
// Hermitian CheckerBoarded wrapper
|
2015-05-16 23:35:08 +01:00
|
|
|
////////////////////////////////////////////////////////////////////////////////////
|
2015-05-18 07:47:05 +01:00
|
|
|
template<class Matrix,class Field>
|
|
|
|
class HermitianCheckerBoardedOperator : public HermitianOperatorBase<Field> {
|
|
|
|
Matrix &_Mat;
|
2015-05-16 23:35:08 +01:00
|
|
|
public:
|
2015-05-18 07:47:05 +01:00
|
|
|
HermitianCheckerBoardedOperator(Matrix &Mat): _Mat(Mat) {};
|
|
|
|
void OpAndNorm(const Field &in, Field &out,RealD &n1,RealD &n2){
|
|
|
|
_Mat.MpcDagMpc(in,out,n1,n2);
|
2015-05-16 23:35:08 +01:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////
|
|
|
|
// Base classes for functions of operators
|
|
|
|
/////////////////////////////////////////////////////////////
|
|
|
|
template<class Field> class OperatorFunction {
|
|
|
|
public:
|
2015-05-18 07:47:05 +01:00
|
|
|
virtual void operator() (LinearOperatorBase<Field> &Linop, const Field &in, Field &out) = 0;
|
2015-05-16 23:35:08 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
// 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<T,P,Q>
|
|
|
|
const Subset& subset() const {return all;}
|
|
|
|
};
|
|
|
|
*/
|
|
|
|
|
|
|
|
// Chroma interface defining GaugeAction
|
|
|
|
/*
|
|
|
|
template<typename P, typename Q> class GaugeAction
|
|
|
|
virtual const CreateGaugeState<P,Q>& getCreateState() const = 0;
|
|
|
|
virtual GaugeState<P,Q>* createState(const Q& q) const
|
|
|
|
virtual const GaugeBC<P,Q>& getGaugeBC() const
|
|
|
|
virtual const Set& getSet(void) const = 0;
|
|
|
|
virtual void deriv(P& result, const Handle< GaugeState<P,Q> >& state) const
|
|
|
|
virtual Double S(const Handle< GaugeState<P,Q> >& state) const = 0;
|
|
|
|
|
|
|
|
class LinearGaugeAction : public GaugeAction< multi1d<LatticeColorMatrix>, multi1d<LatticeColorMatrix> >
|
|
|
|
typedef multi1d<LatticeColorMatrix> P;
|
|
|
|
typedef multi1d<LatticeColorMatrix> Q;
|
|
|
|
virtual void staple(LatticeColorMatrix& result,
|
|
|
|
const Handle< GaugeState<P,Q> >& state,
|
|
|
|
int mu, int cb) const = 0;
|
|
|
|
*/
|
|
|
|
|
|
|
|
// Chroma interface defining FermionAction
|
|
|
|
/*
|
|
|
|
template<typename T, typename P, typename Q> class FermAct4D : public FermionAction<T,P,Q>
|
|
|
|
virtual LinearOperator<T>* linOp(Handle< FermState<T,P,Q> > state) const = 0;
|
|
|
|
virtual LinearOperator<T>* lMdagM(Handle< FermState<T,P,Q> > state) const = 0;
|
|
|
|
virtual LinOpSystemSolver<T>* invLinOp(Handle< FermState<T,P,Q> > state,
|
|
|
|
virtual MdagMSystemSolver<T>* invMdagM(Handle< FermState<T,P,Q> > state,
|
|
|
|
virtual LinOpMultiSystemSolver<T>* mInvLinOp(Handle< FermState<T,P,Q> > state,
|
|
|
|
virtual MdagMMultiSystemSolver<T>* mInvMdagM(Handle< FermState<T,P,Q> > state,
|
|
|
|
virtual MdagMMultiSystemSolverAccumulate<T>* mInvMdagMAcc(Handle< FermState<T,P,Q> > state,
|
|
|
|
virtual SystemSolver<T>* qprop(Handle< FermState<T,P,Q> > state,
|
|
|
|
class DiffFermAct4D : public FermAct4D<T,P,Q>
|
|
|
|
virtual DiffLinearOperator<T,Q,P>* linOp(Handle< FermState<T,P,Q> > state) const = 0;
|
|
|
|
virtual DiffLinearOperator<T,Q,P>* lMdagM(Handle< FermState<T,P,Q> > state) const = 0;
|
|
|
|
*/
|
2015-05-13 11:25:34 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|