#include "AdvPolynomial1Conv.hh"
#include <numeric>
#include <cfloat>

#define NumberOfParamForPolynomial1Conv 1

AdvPolynomial1Conv::AdvPolynomial1Conv() : AdvFuncBase(string("polynomial1conv"), string("p1c"), NumberOfParamForPolynomial1Conv)  {
}

AdvPolynomial1Conv::~AdvPolynomial1Conv() {
}

Double AdvPolynomial1Conv::Polynomial1Func(const Double x, const Double p) {
    return p*x;
}

Double AdvPolynomial1Conv::Polynomial1ConvFunc(const Double x,  const Double p) {

    if(ResY.size()==0) ReadResolutionFile();
    Double normFactor = 0.0;
    Double conv_result = 0.0;
    for (int i=0;i<ResX.size()-1;i++)
        {
        Double f_res = ResY.at(i);
        Double f_det = Polynomial1Func(x-(ResX.at(i)+ResX.at(i+1))*0.5, p);
        conv_result += f_det*f_res;
        normFactor += ResY.at(i);
        }
     return conv_result/normFactor;
}

#ifdef USE_POINTER
Double AdvPolynomial1Conv::eval(const Double x, const Double *p) {
    return Polynomial1ConvFunc(x,p[0]);
}

#ifdef HAVE_DIFFERENTIAL_MEMBER
Double AdvPolynomial1Conv::der1st(const Double x, const Double *p) {
    std::cout << "Convolution::der1st is not implemented" << endl;
    return DBL_MAX;
}

Double AdvPolynomial1Conv::der2nd(const Double x, const Double *p) {
    std::cout << "Convolution::der2nd is not implemented" << endl;
    return DBL_MAX;
}

Double *AdvPolynomial1Conv::gradient(const Double x, const Double *p) {
//    std::cout << "Convolution::gradient is not implemented" << endl;
    return NULL;
}
#endif // HAVE_DIFFERENTIAL_MEMBER
#endif // USE_POINTER

#ifdef USE_VECTOR
Double AdvPolynomial1Conv::eval(const Double x, const vector<Double> &p) {
    return Polynomial1ConvFunc(x,p[0]);
}

#ifdef HAVE_DIFFERENTIAL_MEMBER
Double AdvPolynomial1Conv::der1st(const Double x, const vector<Double> &p) {
    std::cout << "Convolution::der1st is not implemented" << endl;
    return DBL_MAX;
}

Double AdvPolynomial1Conv::der2nd(const Double x, const vector<Double> &p) {
    std::cout << "Convolution::der1st is not implemented" << endl;
    return DBL_MAX;
}

vector<Double> AdvPolynomial1Conv::gradient(const Double x, const vector<Double> &p) {
//    std::cout << "Convolution::gradient is not implemented" << endl;
    vector<Double> v;
    v.clear();
    return v;
}
#endif // HAVE_DIFFERENTIAL_MEMBER
#endif // USE_VECTOR

