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

#define NumberOfParamForPolynomial2Conv 1

AdvPolynomial2Conv::AdvPolynomial2Conv() : AdvFuncBase(std::string("Polynomial2conv"), std::string("p2c"), NumberOfParamForPolynomial2Conv)  {
}

AdvPolynomial2Conv::~AdvPolynomial2Conv() {
}

Double AdvPolynomial2Conv::Polynomial2Func(const Double x, const Double p) {
    return p*x*x;
}

Double AdvPolynomial2Conv::Polynomial2ConvFunc(const Double x,  const Double p) {

    if(ResY.size()==0) ReadResolutionFile();
    Double normFactor = 0.0;
    Double conv_result = 0.0;
    for (UInt4 i=0;i<ResX.size()-1;i++)
        {
        Double f_res = ResY.at(i);
        Double f_det = Polynomial2Func(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 AdvPolynomial2Conv::eval(const Double x, const Double *p) {
    return Polynomial2ConvFunc(x,p[0]);
}

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

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

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

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

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

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

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

