#include "AdvVectorComplexTool.hh"

const std::string AdvVectorComplexTool::className=std::string("AdvVectorComplexTool");

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

////
Bool AdvVectorComplexTool::checkSrc(const Double* src, const UInt4 size) {
    std::string memberName = std::string("checkSrc(const Double*, UInt4)");

    if (src == NULL) {
        this->errorMessage(className, memberName, __FILE__, __LINE__, "invalid argument: the pointer to the source is NULL\n");
        return false;
    }
    if (size == 0) {
        this->errorMessage(className, memberName, __FILE__, __LINE__, "invalid argument: the size of the source is equal to 0\n");
        return false;
    }
    return true;
}

Bool AdvVectorComplexTool::checkSrc(const std::vector<Double>& src) {
    std::string memberName = std::string("checkSrc(const std::vector<Double>&)");

    if (src.empty()) {
        this->errorMessage(className, memberName, __FILE__, __LINE__, "invalid argument: the source is empty\n");
        return false;
    }
    return true;
}

Bool AdvVectorComplexTool::checkSrc(const gsl_vector* src) {
    std::string memberName = std::string("checkSrc(const gsl_vector>*)");
    if (src == NULL) {
        this->errorMessage(className, memberName, __FILE__, __LINE__, "invalid argument: the pointer to the source is NULL\n");
        return false;
    }
    if (src->size == 0) {
        this->errorMessage(className, memberName, __FILE__, __LINE__, "invalid argument: the size of the source is equal to 0\n");
        return false;
    }
    return true;
}

////

Bool AdvVectorComplexTool::checkSrc(const Double* real, const Double* imag, const UInt4 size) {
    std::string memberName = std::string("checkSrc(const Double*, const Double*)");

    if (real == NULL) {
        this->errorMessage(className, memberName, __FILE__, __LINE__, "invalid argument: the pointer to the real part is NULL.\n");
        return false;
    }
    if (imag == NULL) {
        this->errorMessage(className, memberName, __FILE__, __LINE__, "invalid argument: the pointer to the imagenary part is NULL.\n");
        return false;
    }
    if (size == 0) {
        this->errorMessage(className, memberName, __FILE__, __LINE__, "invalid argument: the size of two arrays is equal to 0.\n");
        return false;
    }
    return true;
}

Bool AdvVectorComplexTool::checkSrc(const std::vector<Double>& real, const std::vector<Double>& imag) {
    std::string memberName = std::string("checkSrc(std::vector<Double>&, std::vector<Double>&)");

    if (real.empty()) {
        this->errorMessage(className, memberName, __FILE__, __LINE__, "invalid argument: the real part is empty\n");
        return false;
    }
    if (imag.empty()) {
        this->errorMessage(className, memberName, __FILE__, __LINE__, "invalid argument: the imagenary  part is empty\n");
        return false;
    }
    return true;
}

Bool AdvVectorComplexTool::checkSrc(const gsl_vector* real, const gsl_vector* imag) {
    std::string memberName = std::string("checkSrc(const gsl_vector*, const gsl_vector*)");

    if (real == NULL) {
        this->errorMessage(className, memberName, __FILE__, __LINE__, "invalid argument: the pointer to the real part is NULL.\n");
        return false;
    }
    if (imag == NULL) {
        this->errorMessage(className, memberName, __FILE__, __LINE__, "invalid argument: the pointer to the imagenary  part is NULL.\n");
        return false;
    }
    if (real->size != imag->size) {
        this->errorMessage(className, memberName, __FILE__, __LINE__, "invalid argument: the the sies of the real part is not eqal to the size of the imagenary part.\n");
        return false;
    }
    return true;
}

///

Bool AdvVectorComplexTool::checkSrc(const gsl_vector_complex* src) {
    std::string memberName = std::string("checkSrc(const gsl_vector_complex*)");

    if (src == NULL) {
        this->errorMessage(className, memberName, __FILE__, __LINE__, "invalid gaument: the pointer to the souce is NULL.\n");
        return false;
    }
    if (src->size == 0) {
        this->errorMessage(className, memberName, __FILE__, __LINE__, "invalid gaument: the size of the souce is equal to 0\n");
        return false;
    }
    return true;
}

Bool AdvVectorComplexTool::checkSrc(const std::complex<Double>* src, const UInt4 size) {
    std::string memberName = std::string("checkSrc(const std::complex<Double>*, UInt4)");

    if (src == NULL) {
        this->errorMessage(className, memberName, __FILE__, __LINE__, "invalid gaument: the pointer to the souce is NULL.\n");
        return false;
    }
    if (size == 0) {
        this->errorMessage(className, memberName, __FILE__, __LINE__, "invalid gaument: the size of the souce is equal to 0\n");
        return false;
    }
    return true;
}

Bool AdvVectorComplexTool::checkSrc(const std::vector< std::complex<Double> >& src) {
    std::string memberName = std::string("checkSrc(const std::vector< std::complex<Double> >&)");

    if (src.empty()) {
        this->errorMessage(className, memberName, __FILE__, __LINE__, "invalid gaument: the souce is empty.\n");
        return false;
    }
    return true;
}

///

Bool AdvVectorComplexTool::checkDest(gsl_vector_complex* dest, const UInt4 srcSize) {
    std::string memberName = std::string("checkDest(gsl_vector_complex*, const UInt4)");

    if (dest == NULL) {
        this->errorMessage(className, memberName, __FILE__, __LINE__, "invalid argument: the pointer to the destination is NULL.\n");
        return false;
    }
    if (dest->size == 0) {
        this->errorMessage(className, memberName, __FILE__, __LINE__, "invalid argument: the capacity of the destination is equal to 0.\n");
        return false;
    }
    if (dest->size < srcSize) {
        this->errorMessage(className, memberName, __FILE__, __LINE__, "invalid argument: the capacity of the destination is smaller than the size of source.\n");
        return false;
    }
    return true;
}

Bool AdvVectorComplexTool::checkDest(std::vector< std::complex<Double> >& dest, const UInt4 srcSize) {
    std::string memberName = std::string("checkDest(gsl_vector_complex*, const UInt4)");

    if (dest.capacity() == 0) {
        this->errorMessage(className, memberName, __FILE__, __LINE__, "invalid argument: the capacity to the destination is equal to 0.\n");
        return false;
    }
    if (dest.capacity() < srcSize) {
        this->errorMessage(className, memberName, __FILE__, __LINE__, "invalid argument: the capacity of the destination is smaller than the size of source.\n");
        return false;
    }
    return true;
}

Bool AdvVectorComplexTool::checkDest(std::complex<Double>* dest, const UInt4 srcSize) {
    std::string memberName = std::string("checkDest(vomplex<Double>*,  UInt4)");

    if (dest == NULL) {
        this->errorMessage(className, memberName, __FILE__, __LINE__, "invalid argument: the pointer to the destination is NULL.\n");
        return false;
    }
    if (sizeof(*dest)/sizeof(dest[0]) < srcSize) {
        this->errorMessage(className, memberName, __FILE__, __LINE__, "invalid argument: the capacity of the destination is smaller than the size of source.\n");
        return false;
    }
    return true;
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void AdvVectorComplexTool::initGslVectorComplex(const AdvVectorComplexTool::Part part, const Double* src, const UInt4 size, gsl_vector_complex* dest) {
    std::string memberName = std::string("initGslVectorComplex(AdvVectorComplexTool::Part, const Double*, const UInt4, gsl_vector_complex*)");

    if (! this->checkSrc(src, size)) {
        errorMessage(className, memberName, __FILE__, __LINE__, "invalid source\n");
        return;
    }
    if (! this->checkDest(dest, size)) {
        errorMessage(className, memberName, __FILE__, __LINE__, "invalid destination\n");
        return;
    }

    gsl_vector_complex_set_zero(dest);
    gsl_vector_view view = (part==AdvVectorComplexTool::REAL) ? gsl_vector_complex_real(dest) : gsl_vector_complex_real(dest);
    for (UInt4 i=0; i<size; ++i) {
        gsl_vector_set(&view.vector, i, src[i]);
    }
}

void AdvVectorComplexTool::initGslVectorComplex(const AdvVectorComplexTool::Part part, const std::vector<Double>& src, gsl_vector_complex* dest) {
    std::string memberName = std::string("initGslVectorComplex(AdvVectorComplexTool::Part, const std::vector<Double>&, gsl_vector_complex*)");

    if (! this->checkSrc(src)) {
        errorMessage(className, memberName, __FILE__, __LINE__, "invalid source\n");
        return;
    }
    if (! this->checkDest(dest, src.size())) {
        errorMessage(className, memberName, __FILE__, __LINE__, "invalid destination\n");
        return;
    }

    gsl_vector_complex_set_zero(dest);
    gsl_vector_view view = (part==AdvVectorComplexTool::REAL) ? gsl_vector_complex_real(dest) : gsl_vector_complex_real(dest);
    for (UInt4 i=0; i<src.size(); ++i) {
        gsl_vector_set(&view.vector, i, src.at(i));
    }
}

void AdvVectorComplexTool::initGslVectorComplex(const AdvVectorComplexTool::Part part, const gsl_vector* src, gsl_vector_complex* dest) {
    std::string memberName = std::string("initGslVectorComplex(AdvVectorComplexTool::Part, const gsl_vector*, gsl_vector_complex*)");

    if (! this->checkSrc(src)) {
        errorMessage(className, memberName, __FILE__, __LINE__, "invalid source\n");
        return;
    }
    if (! this->checkDest(dest, src->size)) {
        errorMessage(className, memberName, __FILE__, __LINE__, "invalid destination\n");
        return;
    }

    gsl_vector_complex_set_zero(dest);
    gsl_vector_view view = (part==AdvVectorComplexTool::REAL) ? gsl_vector_complex_real(dest) : gsl_vector_complex_real(dest);
    gsl_vector_memcpy(&view.vector, src);
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

gsl_vector_complex* AdvVectorComplexTool::createGslVectorComplex(const AdvVectorComplexTool::Part part, const Double* src, const UInt4 size) {
    std::string memberName = std::string("createGslVectorComplex(AdvVectorComplexTool::Part, const Double*, UInt4)");

    if (! this->checkSrc(src, size)) {
        errorMessage(className, memberName, __FILE__, __LINE__, "invalid surce\n");
        return NULL;
    }
    gsl_vector_complex* retval = gsl_vector_complex_alloc(size);
    this->initGslVectorComplex(part, src, size, retval);
    return retval;
}

gsl_vector_complex* AdvVectorComplexTool::createGslVectorComplex(const AdvVectorComplexTool::Part part, const std::vector<Double>& src) {
    std::string memberName = std::string("createGslVectorComplex(AdvVectorComplexTool::Part, const std::vector<Double>&)");

    if (! this->checkSrc(src)) {
        errorMessage(className, memberName, __FILE__, __LINE__, "invalid surce\n");
        return NULL;
    }
    gsl_vector_complex* retval = gsl_vector_complex_alloc(src.size());
    this->initGslVectorComplex(part, src, retval);
    return retval;
}

gsl_vector_complex* AdvVectorComplexTool::createGslVectorComplex(const AdvVectorComplexTool::Part part, const gsl_vector* src) {
    std::string memberName = std::string("createGslVectorComplex(AdvVectorComplexTool::Part, const gsl_vector*)");

     if (! this->checkSrc(src)) {
         errorMessage(className, memberName, __FILE__, __LINE__, "invalid surce\n");
         return NULL;
     }
     gsl_vector_complex* retval = gsl_vector_complex_alloc(src->size);
     this->initGslVectorComplex(part, src, retval);
     return retval;
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void AdvVectorComplexTool::initGslVectorComplex(const Double* real, const Double* imag, const UInt4 size, gsl_vector_complex* dest) {
    std::string memberName = std::string("initGslVectorComplex(const Double*, const Double*, UInt4, gsl_vector_complex*)");

    if (! this->checkSrc(real, imag, size)) {
        errorMessage(className, memberName, __FILE__, __LINE__, "invalid source\n");
        return;
    }
    if (! this->checkDest(dest, size)) {
        errorMessage(className, memberName, __FILE__, __LINE__, "invalid destination\n");
        return;
    }

    gsl_vector_view rr = gsl_vector_complex_real(dest);
    gsl_vector_view ri = gsl_vector_complex_imag(dest);
    for (UInt4 i=0; i<size; ++i) {
        gsl_vector_set(&rr.vector, i, real[i]);
        gsl_vector_set(&ri.vector, i, imag[i]);
    }
}

void AdvVectorComplexTool::initGslVectorComplex(const std::vector<Double>& real, const std::vector<Double>& imag, gsl_vector_complex* dest) {
    std::string memberName = std::string("initGslVectorComplex(std::vector<Double>&, std::vector<Double>&, gsl_vector_complex*)");

    if (! this->checkSrc(real, imag)) {
        errorMessage(className, memberName, __FILE__, __LINE__, "invalid source\n");
        return;
    }
    if (! this->checkDest(dest, real.size())) {
        errorMessage(className, memberName, __FILE__, __LINE__, "invalid destination\n");
        return;
    }

    gsl_vector_view rr = gsl_vector_complex_real(dest);
    gsl_vector_view ri = gsl_vector_complex_real(dest);
    for (UInt4 i=0; i<real.size(); ++i) {
        gsl_vector_set(&rr.vector, i, real.at(i));
        gsl_vector_set(&ri.vector, i, imag.at(i));
    }
}

void AdvVectorComplexTool::initGslVectorComplex(const gsl_vector* real, const gsl_vector* imag, gsl_vector_complex* dest) {
    std::string memberName = std::string("initGslVectorComplex(gsl_vector*, gsl_vector*, gsl_vector_complex*)");

    if (! this->checkSrc(real, imag)) {
        errorMessage(className, memberName, __FILE__, __LINE__, "invalid source\n");
        return;
    }
    if (! this->checkDest(dest, real->size)) {
        errorMessage(className, memberName, __FILE__, __LINE__, "invalid destination\n");
        return;
    }

    gsl_vector_view rr = gsl_vector_complex_real(dest);
    gsl_vector_view ri = gsl_vector_complex_imag(dest);
    gsl_vector_memcpy(&rr.vector, real);
    gsl_vector_memcpy(&ri.vector, imag);
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

gsl_vector_complex* AdvVectorComplexTool::createGslVectorComplex(const Double* real, const Double* imag, const UInt4 size) {
    std::string memberName = std::string("createGslVectorComplex(const Double*, const Double*, UInt4)");

    if (! this->checkSrc(real, imag, size) ) {
        errorMessage(className, memberName, __FILE__, __LINE__, "invalid surce\n");
        return NULL;
    }
    gsl_vector_complex* retval = gsl_vector_complex_alloc(size);
    this->initGslVectorComplex(real, imag, size, retval);
    return retval;
}

gsl_vector_complex* AdvVectorComplexTool::createGslVectorComplex(const std::vector<Double>& real, const std::vector<Double>& imag) {
    std::string memberName = std::string("createGslVectorComplex(std::vector<Double>&, std::vector<Double>&)");

    if (! this->checkSrc(real, imag) ) {
        errorMessage(className, memberName, __FILE__, __LINE__, "invalid surce\n");
        return NULL;
    }
    gsl_vector_complex* retval = gsl_vector_complex_alloc(real.size());
    this->initGslVectorComplex(real, imag, retval);
    return retval;
}

gsl_vector_complex* AdvVectorComplexTool::createGslVectorComplex(const gsl_vector* real, const gsl_vector* imag) {
    std::string memberName = std::string("createGslVectorComplex(const gsl_vector*, const gsl_vector*)");

    if (! this->checkSrc(real, imag) ) {
        errorMessage(className, memberName, __FILE__, __LINE__, "invalid surce\n");
        return NULL;
    }
    gsl_vector_complex* retval = gsl_vector_complex_alloc(real->size);
    this->initGslVectorComplex(real, imag, retval);
    return retval;
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void AdvVectorComplexTool::initVectorComplex(const AdvVectorComplexTool::Part part, const Double* src, const UInt4 size, std::vector< std::complex<Double> >& dest) {
    std::string memberName = std::string("initVectorComplex(AdvVectorComplexTool::Part part, const Double*, UInt4, std::vector< std::complex<Double> >&)");

    if (! this->checkSrc(src, size)) {
        errorMessage(className, memberName, __FILE__, __LINE__, "invalid source\n");
        return;
    }
    if (! this->checkDest(dest, size)) {
        errorMessage(className, memberName, __FILE__, __LINE__, "invalid destination\n");
        return;
    }

    switch (part) {
    case AdvVectorComplexTool::REAL:
        for (UInt4 i=0; i<size; ++i) {
            dest.at(i) = *(new std::complex<Double>(src[i], 0.0));
        }
        break;
    case AdvVectorComplexTool::IMAG:
        for (UInt4 i=0; i<size; ++i) {
            dest.at(i) = *(new std::complex<Double>(0.0, src[i]));
        }
        break;
    }
}

void AdvVectorComplexTool::initVectorComplex(const AdvVectorComplexTool::Part part, const std::vector<Double>& src, std::vector< std::complex<Double> >& dest) {
    std::string memberName = std::string("initVectorComplex(AdvVectorComplexTool::Part, std::vector<Double>&, std::vector< std::complex<Double> >&)");

    if (! this->checkSrc(src)) {
        errorMessage(className, memberName, __FILE__, __LINE__, "invalid source\n");
        return;
    }
    if (! this->checkDest(dest, src.size())) {
        errorMessage(className, memberName, __FILE__, __LINE__, "invalid destination\n");
        return;
    }

    switch (part) {
    case AdvVectorComplexTool::REAL:
        for (UInt4 i=0; i<src.size(); ++i) {
            dest.at(i) = *(new std::complex<Double>(src.at(i), 0.0));
        }
        break;
    case AdvVectorComplexTool::IMAG:
        for (UInt4 i=0; i<src.size(); ++i) {
            dest.at(i) = *(new std::complex<Double>(0.0, src.at(i)));
        }
        break;
    }
}

void AdvVectorComplexTool::initVectorComplex(const AdvVectorComplexTool::Part part, const gsl_vector* src, std::vector< std::complex<Double> >& dest) {
    std::string memberName = std::string("initVectorComplex(AdvVectorComplexTool::Part, const gsl_vector*, std::vector< std::complex<Double> >&)");

    if (! this->checkSrc(src)) {
        errorMessage(className, memberName, __FILE__, __LINE__, "invalid source\n");
        return;
    }
    if (! this->checkDest(dest, src->size)) {
        errorMessage(className, memberName, __FILE__, __LINE__, "invalid destination\n");
        return;
    }

    switch (part) {
    case AdvVectorComplexTool::REAL:
        for (UInt4 i=0; i<src->size; ++i) {
            dest.at(i) = *(new std::complex<Double>(gsl_vector_get(src, i), 0.0));
        }
        break;
    case AdvVectorComplexTool::IMAG:
        for (UInt4 i=0; i<src->size; ++i) {
            dest.at(i) = *(new std::complex<Double>(0.0, gsl_vector_get(src, i)));
        }
        break;
    }
}


/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

std::vector< std::complex<Double> >* AdvVectorComplexTool::createVectorComplex(const AdvVectorComplexTool::Part part, const Double* src, const UInt4 size) {
    std::string memberName = std::string("createVectorComplex(AdvVectorComplexTool::Part part, const Double*, UInt4)");

    std::vector< std::complex<Double> >* retval = NULL;
    if (! this->checkSrc(src, size)) {
        errorMessage(className, memberName, __FILE__, __LINE__, "invalid surce\n");
        return NULL;
    }
    retval = new std::vector< std::complex<Double> >(size);
    this->initVectorComplex(part, src, size, *retval);
    return retval;
}

std::vector< std::complex<Double> >* AdvVectorComplexTool::createVectorComplex(const AdvVectorComplexTool::Part part, const std::vector<Double>& src) {
    std::string memberName = std::string("initVectorComplex(AdvVectorComplexTool::Part, std::vector<Double>&)");

    if (! this->checkSrc(src)) {
        errorMessage(className, memberName, __FILE__, __LINE__, "invalid surce\n");
        return NULL;
    }
    std::vector< std::complex<Double> >* retval = new std::vector< std::complex<Double> >(src.size());
    this->initVectorComplex(part, src, *retval);
    return retval;
}

std::vector< std::complex<Double> >* AdvVectorComplexTool::createVectorComplex(const AdvVectorComplexTool::Part part, const gsl_vector* src) {
    std::string memberName = std::string("initVectorComplex(AdvVectorComplexTool::Part, const gsl_vector*)");

    std::vector< std::complex<Double> >* retval = NULL;
    if (! this->checkSrc(src)) {
        errorMessage(className, memberName, __FILE__, __LINE__, "invalid surce\n");
        return NULL;
    }
    retval = new std::vector< std::complex<Double> >(src->size);
    this->initVectorComplex(part, src, *retval);
    return retval;
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void AdvVectorComplexTool::initVectorComplex(const Double* real, const Double* imag, const UInt4 size, std::vector< std::complex<Double> >& dest) {
    std::string memberName = std::string("initVectorComplex(const Double*, const Double*, UInt4, std::vector< std::complex<Double> >&)");

    if (! this->checkSrc(real, imag, size)) {
        errorMessage(className, memberName, __FILE__, __LINE__, "invalid source\n");
        return;
    }
    if (! this->checkDest(dest, size)) {
        errorMessage(className, memberName, __FILE__, __LINE__, "invalid destination\n");
        return;
    }

    for (UInt4 i=0; i<size; ++i) {
        dest.at(i) = *(new std::complex<Double>(real[i], imag[i]));
    }
}

void AdvVectorComplexTool::initVectorComplex(const std::vector<Double>& real, const std::vector<Double>& imag, std::vector< std::complex<Double> >& dest) {
    std::string memberName = std::string("initVectorComplex(std::vector<Double>&, std::vector<Double>&, std::vector< std::complex<Double> >&)");

    if (! this->checkSrc(real, imag)) {
        errorMessage(className, memberName, __FILE__, __LINE__, "invalid source\n");
        return;
    }
    if (! this->checkDest(dest, real.size())) {
        errorMessage(className, memberName, __FILE__, __LINE__, "invalid destination\n");
        return;
    }

    for (UInt4 i=0; i<real.size(); ++i) {
        dest.at(i) = *(new std::complex<Double>(real.at(i), imag.at(i)));
    }
}

void AdvVectorComplexTool::initVectorComplex(const gsl_vector* real, const gsl_vector* imag, std::vector< std::complex<Double> >& dest) {
    std::string memberName = std::string("initVectorComplex(const gsl_vector*, const gsl_vector*, std::vector< std::complex<Double> >&)");

    if (! this->checkSrc(real, imag)) {
        errorMessage(className, memberName, __FILE__, __LINE__, "invalid source\n");
        return;
    }
    if (! this->checkDest(dest, real->size)) {
        errorMessage(className, memberName, __FILE__, __LINE__, "invalid destination\n");
        return;
    }

    for (UInt4 i=0; i<real->size; ++i) {
        dest.at(i) = *(new std::complex<Double>(gsl_vector_get(real, i), gsl_vector_get(imag, i)));
    }
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

std::vector< std::complex<Double> >* AdvVectorComplexTool::createVectorComplex(const Double* real, const Double *imag, const UInt4 size) {
    std::string memberName = std::string("initVectorComplex(const Double*, const Double*, UInt4)");

    if (! this->checkSrc(real, imag, size)) {
        errorMessage(className, memberName, __FILE__, __LINE__, "invalid surce\n");
        return NULL;
    }
    std::vector< std::complex<Double> >* retval = new std::vector< std::complex<Double> >(size);
    this->initVectorComplex(real, imag, size, *retval);
    return retval;
}

std::vector< std::complex<Double> >* AdvVectorComplexTool::createVectorComplex(const std::vector<Double>& real, const std::vector<Double>& imag) {
    std::string memberName = std::string("initVectorComplex(std::vector<Double>&, std::vector<Double>&)");

    if (! this->checkSrc(real, imag)) {
        errorMessage(className, memberName, __FILE__, __LINE__, "invalid surce\n");
        return NULL;
    }
    std::vector< std::complex<Double> >* retval = new std::vector< std::complex<Double> >(real.size());
    this->initVectorComplex(real, imag, *retval);
    return retval;
}

std::vector< std::complex<Double> >* AdvVectorComplexTool::createVectorComplex(const gsl_vector* real, const gsl_vector* imag) {
    std::string memberName = std::string("initVectorComplex(const gsl_vector*, const gsl_vector*)");

    if (! this->checkSrc(real, imag )) {
        errorMessage(className, memberName, __FILE__, __LINE__, "invalid surce\n");
        return NULL;
    }
    std::vector< std::complex<Double> >* retval = new std::vector< std::complex<Double> >(real->size);
    this->initVectorComplex(real, imag, *retval);
    return retval;
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void AdvVectorComplexTool::initArrayComplex(const AdvVectorComplexTool::Part part, const Double* src, const UInt4 size, std::complex<Double>* dest) {
    std::string memberName = std::string("initArrayComplex(AdvVectorComplexTool::Part, const Double*, UINt4, std::complex<Double>*)");

    if (! this->checkSrc(src, size)) {
        errorMessage(className, memberName, __FILE__, __LINE__, "invalid source\n");
        return;
    }
    if (! this->checkDest(dest, size)) {
        errorMessage(className, memberName, __FILE__, __LINE__, "invalid destination\n");
        return;
    }

    switch (part) {
    case AdvVectorComplexTool::REAL:
        for (UInt4 i=0; i<size; ++i) {
            dest[i] = *(new std::complex<Double>(src[i], 0.0));
        }
        break;
    case AdvVectorComplexTool::IMAG:
        for (UInt4 i=0; i<size; ++i) {
            dest[i] = *(new std::complex<Double>(0.0, src[i]));
        }
        break;
    }
}

void AdvVectorComplexTool::initArrayComplex(const AdvVectorComplexTool::Part part, const std::vector<Double>& src, std::complex<Double>* dest) {
    std::string memberName = std::string("initArrayComplex(AdvVectorComplexTool::Part, std::vector<Double>&, std::complex<Double>*)");

    if (! this->checkSrc(src)) {
        errorMessage(className, memberName, __FILE__, __LINE__, "invalid source\n");
        return;
    }
    if (! this->checkDest(dest, src.size())) {
        errorMessage(className, memberName, __FILE__, __LINE__, "invalid destination\n");
        return;
    }

    switch (part) {
    case AdvVectorComplexTool::REAL:
        for (UInt4 i=0; i<src.size(); ++i) {
            dest[i] = *(new std::complex<Double>(src[i], 0.0));
        }
        break;
    case AdvVectorComplexTool::IMAG:
        for (UInt4 i=0; i<src.size(); ++i) {
            dest[i] = *(new std::complex<Double>(0.0, src[i]));
        }
        break;
    }
}

void AdvVectorComplexTool::initArrayComplex(const AdvVectorComplexTool::Part part, const gsl_vector* src, std::complex<Double>* dest) {
    std::string memberName = std::string("initArrayComplex(AdvVectorComplexTool::Part, const gsl_vector*, std::complex<Double>*)");

    if (! this->checkSrc(src)) {
        errorMessage(className, memberName, __FILE__, __LINE__, "invalid source\n");
        return;
    }
    if (! this->checkDest(dest, src->size)) {
        errorMessage(className, memberName, __FILE__, __LINE__, "invalid destination\n");
        return;
    }

    switch (part) {
    case AdvVectorComplexTool::REAL:
        for (UInt4 i=0; i<src->size; ++i) {
            dest[i] = *(new std::complex<Double>(gsl_vector_get(src, i), 0.0));
        }
        break;
    case AdvVectorComplexTool::IMAG:
        for (UInt4 i=0; i<src->size; ++i) {
            dest[i] = *(new std::complex<Double>(0.0, gsl_vector_get(src, i)));
        }
        break;
    }
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

std::complex<Double>* AdvVectorComplexTool::createArrayComplex(const AdvVectorComplexTool::Part part, const Double* src, UInt4 size) {
    std::string memberName = std::string("createArrayComplex(AdvVectorComplexTool::Part, const Double*, UINt4)");

    if ( this->checkSrc(src, size)) {
        errorMessage(className, memberName, __FILE__, __LINE__, "invalid source\n");
        return NULL;
    }
    std::complex<Double>* retval = new std::complex<Double>[size];
    this->initArrayComplex(part, src, size, retval);
    return retval;
}

std::complex<Double>* AdvVectorComplexTool::createArrayComplex(const AdvVectorComplexTool::Part part, const std::vector<Double>& src) {
    std::string memberName = std::string("createArrayComplex(AdvVectorComplexTool::Part, std::vector<Double>&*)");

    if (! this->checkSrc(src) ) {
        errorMessage(className, memberName, __FILE__, __LINE__, "invalid source\n");
        return NULL;
    }
    std::complex<Double>* retval = new std::complex<Double>[src.size()];
    this->initArrayComplex(part, src, retval);
    return retval;
}

std::complex<Double>* AdvVectorComplexTool::createArrayComplex(const AdvVectorComplexTool::Part part, const gsl_vector* src) {
    std::string memberName = std::string("createArrayComplex(AdvVectorComplexTool::Part, const gsl_vector*)");

    if (! this->checkSrc(src) ) {
        errorMessage(className, memberName, __FILE__, __LINE__, "invalid source\n");
        return NULL;
    }
    std::complex<Double>* retval = new std::complex<Double>[src->size];
    this->initArrayComplex(part, src, retval);
    return retval;
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void AdvVectorComplexTool::initArrayComplex(const Double* real, const Double* imag, const UInt4 size, std::complex<Double>* dest) {
    std::string memberName = std::string("initArrayComplex(const Double*, const Double*, UInt4, std::complex<Double>*");

    if (! this->checkSrc(real, size)) {
        errorMessage(className, memberName, __FILE__, __LINE__, "invalid source\n");
        return;
    }
    if (! this->checkDest(dest, size)) {
        errorMessage(className, memberName, __FILE__, __LINE__, "invalid destination\n");
        return;
    }

    for (UInt4 i=0; i<size; ++i) {
        dest[i] = *(new std::complex<Double>(real[i], imag[i]));
    }
}

void AdvVectorComplexTool::initArrayComplex(const std::vector<Double>& real, const std::vector<Double>& imag, std::complex<Double>* dest) {
    std::string memberName = std::string("initArrayComplex(std::vector<Double>&, std::vector<Double>&, std::complex<Double>*)");

    if (! this->checkSrc(real, imag)) {
        errorMessage(className, memberName, __FILE__, __LINE__, "invalid source\n");
        return;
    }
    if (! this->checkDest(dest, real.size())) {
        errorMessage(className, memberName, __FILE__, __LINE__, "invalid destination\n");
        return;
    }

    for (UInt4 i=0; i<real.size(); ++i) {
        dest[i] = *(new std::complex<Double>(real.at(i), imag.at(i)));
    }
}

void AdvVectorComplexTool::initArrayComplex(const gsl_vector* real, const gsl_vector* imag, std::complex<Double>* dest) {
    std::string memberName = std::string("initArrayComplex(const gsl_vector* real, const gsl_vector* imag, std::complex<Double>*)");

    if (! this->checkSrc(real, imag) ) {
        errorMessage(className, memberName, __FILE__, __LINE__, "invalid source\n");
        return;
    }
    if (! this->checkDest(dest, real->size)) {
        errorMessage(className, memberName, __FILE__, __LINE__, "invalid destination\n");
        return;
    }

    for (UInt4 i=0; i<real->size; ++i) {
        dest[i] = *(new std::complex<Double>(gsl_vector_get(real, i), gsl_vector_get(imag, i)));
    }
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

std::complex<Double>* AdvVectorComplexTool::createArrayComplex(const Double* real, const Double* imag, const UInt4 size) {
    std::string memberName = std::string("createArrayComplex(const Double* real, const Double* imag)");

    if (! this->checkSrc(real, imag, size)) {
        errorMessage(className, memberName, __FILE__, __LINE__, "invalid source\n");
        return NULL;
    }
    std::complex<Double>* retval = new std::complex<Double>[size];
    this->initArrayComplex(real, imag, size, retval);
    return retval;
}

std::complex<Double>* AdvVectorComplexTool::createArrayComplex(const std::vector<Double>& real, const std::vector<Double>& imag) {
    std::string memberName = std::string("createArrayComplex(std::vector<Double>&, std::vector<Double>&)");

    if (! this->checkSrc(real, imag)) {
        errorMessage(className, memberName, __FILE__, __LINE__, "invalid source\n");
        return NULL;
    }
    std::complex<Double>* retval = new std::complex<Double>[real.size()];
    this->initArrayComplex(real, imag, retval);
    return retval;
}

std::complex<Double>* AdvVectorComplexTool::createArrayComplex(const gsl_vector* real, const gsl_vector* imag) {
    std::string memberName = std::string("createArrayComplex(const gsl_vector*, const gsl_vector*)");

    if (! this->checkSrc(real, imag)) {
        errorMessage(className, memberName, __FILE__, __LINE__, "invalid source\n");
        return NULL;
    }
    std::complex<Double> *retval = new std::complex<Double>[real->size];
    this->initArrayComplex(real, imag, retval);
    return retval;
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

gsl_vector_complex* AdvVectorComplexTool::VectorComplexToGslVectorComplex(const std::vector< std::complex<Double> >& v) {
    std::string memberName = std::string("VectorComplexToGslVectorComplex(std::vector< std::complex<Double> >&)");

    if (! this->checkSrc(v)) {
        errorMessage(className, memberName, __FILE__, __LINE__, "invalid source\n");
        return NULL;
    }
    gsl_vector_complex *retval = gsl_vector_complex_alloc(v.size());
    gsl_vector_view rr = gsl_vector_complex_real(retval);
    gsl_vector_view ri = gsl_vector_complex_imag(retval);
    for (UInt4 i=0; i<v.size(); ++i) {
        gsl_vector_set(&rr.vector, i, v.at(i).real());
        gsl_vector_set(&ri.vector, i, v.at(i).imag());
    }
    return retval;
}

gsl_vector_complex* AdvVectorComplexTool::ArrayComplexToGslVectorComplex(const std::complex<Double>* v, UInt4 size) {
    std::string memberName = std::string("ArrayComplexToGslVectorComplex(const std::complex<Double>*, UInt4)");

    if (! this->checkSrc(v, size)) {
        errorMessage(className, memberName, __FILE__, __LINE__, "invalid source\n");
        return NULL;
    }
    gsl_vector_complex *retval = gsl_vector_complex_alloc(size);
    gsl_vector_view rr = gsl_vector_complex_real(retval);
    gsl_vector_view ri = gsl_vector_complex_imag(retval);
    for (UInt4 i=0; i<size; ++i) {
        gsl_vector_set(&rr.vector, i, v[i].real());
        gsl_vector_set(&ri.vector, i, v[i].imag());
    }
    return retval;
}

std::vector< std::complex<Double> >* AdvVectorComplexTool::GslVectorComplexToVectorComplex(const gsl_vector_complex* v) {
    std::string memberName = std::string("GslVectorComplexToVectorComplex(const gsl_vector_complex* v)");

    if (! this->checkSrc(v)) {
        errorMessage(className, memberName, __FILE__, __LINE__, "invalid source\n");
        return NULL;
    }

    std::vector< std::complex<Double> >* retval = new std::vector< std::complex<Double> >(v->size);
    for (UInt4 i=0; i<v->size; ++i) {
        const gsl_complex *zp = gsl_vector_complex_const_ptr(v, i);
        retval->at(i) = *(new std::complex<Double>(GSL_REAL(*zp), GSL_IMAG(*zp)));
    }
    return retval;
}

std::vector< std::complex<Double> >* AdvVectorComplexTool::ArrayComplexToVectorComplex(const std::complex<Double>* v, UInt4 size) {
    std::string memberName = std::string("ArrayComplexToVectorComplex(const std::complex<Double>*, UInt4)");

    if (! this->checkSrc(v, size)) {
        errorMessage(className, memberName, __FILE__, __LINE__, "invalid source\n");
        return NULL;
    }

    std::vector< std::complex<Double> >* retval = new std::vector< std::complex<Double> >(size);
    for (UInt4 i=0; i<size; ++i) {
        retval->at(i) = v[i];
    }
    return retval;
}

std::complex<Double>* AdvVectorComplexTool::VectorComplexToArrayComplex(const std::vector< std::complex<Double> >& v) {
    std::string memberName = std::string("VectorComplexToArrayComplex(std::vector< std::complex<Double> >& v)");

    if (! this->checkSrc(v)) {
        errorMessage(className, memberName, __FILE__, __LINE__, "invalid source\n");
        return NULL;
    }

    std::complex<Double>* retval = new std::complex<Double>[v.size()];
    for (UInt4 i=0; i<v.size(); ++i) {
        retval[i] = v.at(i);
    }
    return retval;
}

std::complex<Double>* AdvVectorComplexTool::GslVectorComplexToArrayComplex(const gsl_vector_complex* v) {
    std::string memberName = std::string("GslVectorComplexToArrayComplex(const gsl_vector_complex* v)");

    if (! this->checkSrc(v)) {
        errorMessage(className, memberName, __FILE__, __LINE__, "invalid source\n");
        return NULL;
    }

    std::complex<Double>* retval = new std::complex<Double>[v->size];
    for (UInt4 i=0; i < v->size; ++i) {
        const gsl_complex *zp = gsl_vector_complex_const_ptr(v, i);
        retval[i] = *(new std::complex<Double>(GSL_REAL(*zp), GSL_IMAG(*zp)));
    }
    return retval;
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

gsl_vector* AdvVectorComplexTool::getPartAsGslVector(const AdvVectorComplexTool::Part part, const gsl_vector_complex* src) {
    std::string memberName = std::string("getPartAsGslVector(AdvVectorComplexTool::Part, const gsl_vector_complex*)");

    if (! this->checkSrc(src)) {
        errorMessage(className, memberName, __FILE__, __LINE__, "invalid source\n");
        return NULL;
    }
    gsl_vector* retval = gsl_vector_alloc(src->size);
    gsl_vector_const_view view = (part == AdvVectorComplexTool::REAL ? gsl_vector_complex_const_real(src) : gsl_vector_complex_const_imag(src));
    gsl_vector_memcpy(retval, &view.vector);
    return retval;
}

gsl_vector* AdvVectorComplexTool::getPartAsGslVector(const AdvVectorComplexTool::Part part, std::complex<Double>* src, const UInt4 size) {
    std::string memberName = std::string("getPartAsGslVector(AdvVectorComplexTool::Part, std::complex<Double>*, UInt4)");

    if (! this->checkSrc(src, size)) {
        errorMessage(className, memberName, __FILE__, __LINE__, "invalid source\n");
        return NULL;
    }

    /*
    Double& (std::complex<Double>::*fp)();
    switch (part) {
    case AdvVectorComplexTool::REAL:
        fp = &std::complex<Double>::real;
        break;
    case AdvVectorComplexTool::IMAG:
        fp = &std::complex<Double>::imag;
        break;
    }

    gsl_vector* retval = gsl_vector_alloc(size);
    for (UInt4 i=0; i<size; ++i) {
        gsl_vector_set(retval, i, (src[i].*fp)());
    }
    */
    gsl_vector* retval = gsl_vector_alloc(size);
    switch (part) {
    case AdvVectorComplexTool::REAL:
        for (UInt4 i=0; i<size; ++i) gsl_vector_set(retval, i, (src[i].real()));
        break;
    case AdvVectorComplexTool::IMAG:
        for (UInt4 i=0; i<size; ++i) gsl_vector_set(retval, i, (src[i].imag()));
        break;
    }

    return retval;
}

gsl_vector* AdvVectorComplexTool::getPartAsGslVector(const AdvVectorComplexTool::Part part, std::vector< std::complex<Double> >& src) {
    std::string memberName = std::string("getPartAsGslVector(AdvVectorComplexTool::Part, std::vector< std::complex<Double> >&)");

    if (! this->checkSrc(src)) {
        errorMessage(className, memberName, __FILE__, __LINE__, "invalid source\n");
        return NULL;
    }

    /*
    Double& (std::complex<Double>::*fp)();
    switch (part) {
    case AdvVectorComplexTool::REAL:
        fp = &std::complex<Double>::real;
        break;
    case AdvVectorComplexTool::IMAG:
        fp = &std::complex<Double>::imag;
        break;
    }

    gsl_vector *retval = gsl_vector_alloc(src.size());
    for (UInt4 i=0; i<src.size(); ++i) {
        gsl_vector_set(retval, i, (src.at(i).*fp)());
    }
    */
    gsl_vector *retval = gsl_vector_alloc(src.size());
    switch (part) {
    case AdvVectorComplexTool::REAL:
        for (UInt4 i=0; i<src.size(); ++i) gsl_vector_set(retval, i, (src.at(i).real()));
        break;
    case AdvVectorComplexTool::IMAG:
        for (UInt4 i=0; i<src.size(); ++i) gsl_vector_set(retval, i, (src.at(i).imag()));
        break;
    }
    return retval;
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

Double* AdvVectorComplexTool::getPartAsArray(const AdvVectorComplexTool::Part part, const gsl_vector_complex* src) {
    std::string memberName = std::string("getPartAsArray(AdvVectorComplexTool::Part, const gsl_vector_complex*)");

    if (! this->checkSrc(src)) {
        errorMessage(className, memberName, __FILE__, __LINE__, "invalid source\n");
        return NULL;
    }

    Double *retval = new Double[src->size];
    gsl_vector_const_view view = ((part==AdvVectorComplexTool::REAL) ? gsl_vector_complex_const_real(src) : gsl_vector_complex_const_imag(src));
    for (UInt4 i=0; i<src->size; ++i) {
        retval[i] = gsl_vector_get(&view.vector, i);
    }
    return retval;
}

Double* AdvVectorComplexTool::getPartAsArray(const AdvVectorComplexTool::Part part, std::complex<Double>* src, const UInt4 size) {
    std::string memberName = std::string("getPartAsArray(AdvVectorComplexTool::Part, std::complex<Double>*src, UInt4)");

    if (! this->checkSrc(src, size)) {
        errorMessage(className, memberName, __FILE__, __LINE__, "invalid source\n");
        return NULL;
    }

    /*
    Double& (std::complex<Double>::*fp)();
    switch (part) {
    case AdvVectorComplexTool::REAL:
        fp = &std::complex<Double>::real;
        break;
    case AdvVectorComplexTool::IMAG:
        fp = &std::complex<Double>::imag;
        break;
    }

    Double *retval = new Double[size];
    for (UInt4 i=0; i<size; ++i) {
        retval[i] = (src[i].*fp)();
    }
    */
    Double *retval = new Double[size];
    switch (part) {
    case AdvVectorComplexTool::REAL:
        for (UInt4 i=0; i<size; ++i) retval[i] = (src[i].real());
        break;
    case AdvVectorComplexTool::IMAG:
        for (UInt4 i=0; i<size; ++i) retval[i] = (src[i].imag());
        break;
    }
    return retval;
}

Double* AdvVectorComplexTool::getPartAsArray(const AdvVectorComplexTool::Part part, std::vector< std::complex<Double> >& src) {
    std::string memberName = std::string("getPartAsArray(AdvVectorComplexTool::Part, std::vector< std::complex<Double> >&)");

    if (! this->checkSrc(src)) {
        errorMessage(className, memberName, __FILE__, __LINE__, "invalid source\n");
        return NULL;
    }

    /*
    Double& (std::complex<Double>::*fp)();
    switch (part) {
    case AdvVectorComplexTool::REAL:
        fp = &std::complex<Double>::real;
        break;
    case AdvVectorComplexTool::IMAG:
        fp = &std::complex<Double>::imag;
        break;
    }

    Double *retval = new Double[src.size()];
    for (UInt4 i=0; i<src.size(); ++i) {
        retval[i] = (src.at(i).*fp)();
    }
    */
    Double *retval = new Double[src.size()];
    switch (part) {
    case AdvVectorComplexTool::REAL:
        for (UInt4 i=0; i<src.size(); ++i) retval[i] = (src.at(i).real());
        break;
    case AdvVectorComplexTool::IMAG:
        for (UInt4 i=0; i<src.size(); ++i) retval[i] = (src.at(i).imag());
        break;
    }
    return retval;
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

std::vector<Double>* AdvVectorComplexTool::getPartAsVector(const AdvVectorComplexTool::Part part, const gsl_vector_complex* src) {
    std::string memberName = std::string("getPartAsVector(AdvVectorComplexTool::Part, const gsl_vector_complex*)");

    if (! this->checkSrc(src)) {
        errorMessage(className, memberName, __FILE__, __LINE__, "invalid source\n");
        return NULL;
    }

    std::vector<Double> *retval=new std::vector<Double>(src->size);
    gsl_vector_const_view view = (part==AdvVectorComplexTool::REAL ? gsl_vector_complex_const_real(src) : gsl_vector_complex_const_imag(src));
    for (UInt4 i=0; i<src->size; ++i) {
        retval->at(i)=gsl_vector_get(&view.vector, i);
    }
    return retval;
}

std::vector<Double>* AdvVectorComplexTool::getPartAsVector(const AdvVectorComplexTool::Part part, std::complex<Double>* src, const UInt4 size) {
    std::string memberName = std::string("getPartAsVector(AdvVectorComplexTool::Part, std::complex<Double>*, UInt4)");

    if (! this->checkSrc(src, size)) {
        errorMessage(className, memberName, __FILE__, __LINE__, "invalid source\n");
        return NULL;
    }

    /*
    Double& (std::complex<Double>::*fp)();
    switch (part) {
    case AdvVectorComplexTool::REAL:
        fp = &std::complex<Double>::real;
        break;
    case AdvVectorComplexTool::IMAG:
        fp = &std::complex<Double>::imag;
        break;
    }

    std::vector<Double> *retval = new std::vector<Double>(size);
    for (UInt4 i=0; i<size; ++i) {
        retval->at(i) = (src[i].*fp)();
    }
    */
    std::vector<Double> *retval = new std::vector<Double>(size);
    switch (part) {
    case AdvVectorComplexTool::REAL:
        for (UInt4 i=0; i<size; ++i) retval->at(i) = (src[i].real());
        break;
    case AdvVectorComplexTool::IMAG:
        for (UInt4 i=0; i<size; ++i) retval->at(i) = (src[i].imag());
        break;
    }
    return retval;
}

std::vector<Double>* AdvVectorComplexTool::getPartAsVector(const AdvVectorComplexTool::Part part, std::vector< std::complex<Double> >& src) {
    std::string memberName = std::string("getPartAsVector(AdvVectorComplexTool::Part, std::vector< std::complex<Double> >&)");

    if (! this->checkSrc(src)) {
        errorMessage(className, memberName, __FILE__, __LINE__, "invalid source\n");
        return NULL;
    }

    /*
    Double& (std::complex<Double>::*fp)();
    switch (part) {
    case AdvVectorComplexTool::REAL:
        fp = &std::complex<Double>::real;
        break;
    case AdvVectorComplexTool::IMAG:
        fp = &std::complex<Double>::imag;
        break;
    }

    std::vector<Double> *retval = new std::vector<Double>(src.size());
    for (UInt4 i=0; i<src.size(); ++i) {
        retval->at(i) = (src.at(i).*fp)();
    }
    */
    std::vector<Double> *retval = new std::vector<Double>(src.size());
    switch (part) {
    case AdvVectorComplexTool::REAL:
        for (UInt4 i=0; i<src.size(); ++i) retval->at(i) = (src.at(i).real());
        break;
    case AdvVectorComplexTool::IMAG:
        for (UInt4 i=0; i<src.size(); ++i) retval->at(i) = (src.at(i).imag());
        break;
    }
    return retval;
}
