#include "mylib.h"
#include <cassert>       // assert()
#include <cmath>
#include <vector>

#ifdef __INTEL_CLANG_COMPILER
#pragma message(" ##########  Use of MKL  ###############")
#include <mkl.h>
#else
#pragma message(" ##########  Use of CBLAS  ###############")
//extern "C"
//{
#include <cblas.h>               // cBLAS Library
#include <lapacke.h>             // Lapack
//}
#endif

using namespace std;

double scalar(vector<double> const &x, vector<double> const &y)
{
    assert(x.size() == y.size()); // switch off via compile flag: -DNDEBUG
    size_t const N = x.size();
    double sum = 0.0;
    for (size_t i = 0; i < N; ++i)
    {
        sum += x[i] * y[i];
        //sum += exp(x[i])*log(y[i]);
    }
    return sum;
}


double scalar_cblas(vector<double> const &x, vector<double> const &y)
{
    int const asize = static_cast<int>(size(x));
    int const bsize = static_cast<int>(size(y));
    assert(asize == bsize); // switch off via compile flag: -DNDEBUG
	return cblas_ddot(asize,x.data(),1,y.data(),1);    
    //assert(x.size() == y.size()); // switch off via compile flag: -DNDEBUG
	//return cblas_ddot(x.size(),x.data(),1,y.data(),1);
}

float scalar_cblas(vector<float> const &x, vector<float> const &y)
{
    int const asize = static_cast<int>(size(x));
    int const bsize = static_cast<int>(size(y));
    assert(asize == bsize); // switch off via compile flag: -DNDEBUG
	return cblas_sdot(asize,x.data(),1,y.data(),1);    
    //assert(x.size() == y.size()); // switch off via compile flag: -DNDEBUG
	//return cblas_ddot(x.size(),x.data(),1,y.data(),1);
}


double norm(vector<double> const &x)
{
    size_t const N = x.size();
    double sum = 0.0;
    for (size_t i = 0; i < N; ++i)
    {
        sum += x[i] * x[i];
    }
    return std::sqrt(sum);
}

