#include "mylib.h"
#include <cassert>                  // assert()
#include <cmath>
#include <cstdlib>                  // alignof()
//#include <iostream>
#include <numeric>
#include <vector>
using namespace std;


double scalar(unsigned int const N, double const x[], double const y[])
{
    double sum = 0.0;
    for (unsigned int i = 0; i < N; ++i)
    {
        sum += x[i] * y[i];
//     sum += exp(x[i])*log(y[i]);
    }
    return sum;
}

double scalar_unroll(unsigned int const N, double const x[], double const y[])
{
    constexpr unsigned int Stride{8};
    alignas(32) double sk[Stride] = {0.0};
    assert(alignof(sk)==32);
    assert(alignof(x)==8);
    assert(alignof(y)==8);
    for (unsigned int i = 0; i < (N/Stride)*Stride; i+=Stride)
    {
        for (unsigned int k=0; k<Stride; ++k)
        {
            sk[k] += x[i+k] * y[i+k];
        }
    }
    double sum = std::accumulate(sk, sk+Stride,0.0);
    for (unsigned int i = (N/Stride)*Stride; i < N; ++i)
    {
        sum += x[i]*y[i];
    }
    
    return sum;
}



double norm(unsigned int const N, double const x[])
{
    double sum = 0.0;
    for (unsigned int i = 0; i < N; ++i)
    {
        sum += x[i] * x[i];
    }
    return std::sqrt(sum);
}

