// This may look like C code, but it is really -*- C++ -*-
#ifndef GENERALFUNC_SEEN
#define GENERALFUNC_SEEN

namespace SOPHYA {

//================================================================
// GeneralFunction
//================================================================

//! Classe de fonctions parametrees a plusieurs variables
class GeneralFunction {
public:
  GeneralFunction(unsigned int nVar, unsigned int nPar);
  virtual ~GeneralFunction();

  //! Valeur de la fonction a definir par l'utilisateur (fct virtuelle pure)
  virtual double Value(double const xp[], double const* parm)=0;
  //! Valeur de la fonction derivee selon les parametres pouvant etre redefinie
  virtual double Val_Der(double const xp[], double const* parm
                        , double* DgDpar);

  void SetDeltaParm(int numPar, double delta=0.);
  void SetDeltaParm(double const* dparam);

  //! Retourne le nombre de variables Xi
  inline int     NVar() const {return mNVar;}
  //! Retourne le nombre de parametres Ai
  inline int     NPar() const {return mNPar;}

protected:
  const int mNVar;  //!< nombre de variables f(x,y,z,...)
  const int mNPar;  //!< nombre de parametres

  double *deltaParm;
  double *tmpParm;
};

//================================================================
// GeneralFunc
//================================================================

//! Classe de fonctions parametrees a plusieurs variables type C
class GeneralFunc : public GeneralFunction {
public:
  GeneralFunc(unsigned int nvar, unsigned int npar
        ,double (*fun)(double const*,double const*) 
        ,double (*funder)(double const*, double const*, double*)=NULL);
  virtual ~GeneralFunc();

  virtual double Value(double const xp[], double const* Par);
  virtual double Val_Der(double const xp[],double const* parm
                        , double* DgDpar);

protected:
  double (*tmpFun)   (double const*, double const*);
  double (*tmpFunDer)(double const*, double const*, double*);
};

} // Fin du namespace

#endif
