#include "deparameterizer.h"
ZADE::ZADE(EvaluateFun evaluate, int D, int C, int maxNFEVALs,
           double *xmin, double *xmax, unsigned int RNi, int DEstrategy, int DEstrategyOptions)
    : jDEapin2008reduceNP(evaluate, D, 100, 4, 10, maxNFEVALs, xmin, xmax, RNi),
      C(C), DEstrategy(DEstrategy), DEstrategyOptions(DEstrategyOptions) {
    L += C;
    L += 1; //idxAge

    int idxC = idxFE + 1;
    idxAge = L-1;

    NPbest = 20;

    if (DEstrategy == PSrandBESTbin)
        NPmin = 8;

    DEparameterizer::parameterize(this);

    constraintsEpsilonTakahama2006 = new ConstraintsEpsilonTakahama2006(NP, L, C, idxFE, idxC);
}

ZADE::~ZADE() {
    delete constraintsEpsilonTakahama2006;
    delete [] bestit;
    delete [] bestBestPop;
    delete [] bestBestPopHxchg;
}

void ZADE::createRuntimeStorage() {
    bestit = new double[L];
    bestBestPop = new double[L];
    bestBestPopHxchg = new double[L];
    jDEapin2008reduceNP::createRuntimeStorage();
}

void ZADE::initPop() {
    jDEapin2008reduceNP::initPop();
    constraintsEpsilonTakahama2006->initEpsilonConstraint(pop); // square sum is my!

    //for ageing: NP_MMrandWbestAgeing
    for (int i = 0; i < NP; i++) pop[i*L + idxAge] = 0;

    if (DEstrategy == PSrandbin || DEstrategy == PSrandBESTbin) {
        // find bestBestPop & its index
        idxBestBestPop = NP - NPbest;
        if (idxBestBestPop < 0) idxBestBestPop = 0; // if NPbest > NP
        for (int i = idxBestBestPop + 1; i < NP; i++) // start i: checked if NPbest > NP
            if (isBetterFirst(pop + i*L, pop + idxBestBestPop*L))
                idxBestBestPop = i;
        replaceFirstVectorIntoSecond(pop + idxBestBestPop*L, bestBestPop);
        replaceFirstVectorIntoSecond(bestBestPop, bestBestPopHxchg);
    }
}
