#include "libscl.h"
using namespace scl;
using namespace std;

int main(int argc, char** argp, char** envp)
{
  INT_32BIT seed = 12345;

  stopwatch timer;

  typedef vector<REAL>::size_type rv_int;

  const INTEGER n = 10000000;

  REAL sum;

  cout << starbox("/Memory allocation//")<<'\n';
  cout << "n = " << n << '\n';
  cout.flush();

  realmat arm(n,1);
  realmat brm(n,1);
  vector<REAL> arv(n);
  vector<REAL> brv(n);
  REAL* a;
  REAL* b;
  try {
    a = new REAL[n];
    b = new REAL[n];
  }
  catch(const bad_alloc&) {
    cerr << "Error allocation memory" << '\n';
    return 1;
  }
  catch (...) {
    cerr << "Unknown exception caught" << '\n';
    return 1;
  }

  cout<<"time = " << timer.time() << '\n';
  cout.flush();

  cout << starbox("/Initialization//")<<'\n';
  cout.flush();

  timer.reset();

  for (INTEGER i=1; i<=n; ++i) {
    arm[i] = unsk(seed);
    brm[i] = unsk(seed);
    rv_int j = i-1;
    arv[j] = arm[i];
    brv[j] = brm[i];
    int k = i-1;
    a[k] = arm[i];
    b[k] = brm[i];
  }

  cout<<"time = " << timer.time() << '\n';
  cout.flush();

  cout << starbox("/Inner products//")<<'\n';
  cout.flush();

  timer.reset();

  sum = (T(arm)*brm)[1];

  cout<<"1 of 6, sum = " << sum << ", time = " << timer.time() << '\n';
  cout.flush();

  timer.reset();

  sum = 0.0;
  for (INTEGER i=1; i<=n; ++i) {
    sum += arm[i]*brm[i];
  }

  cout<<"2 of 6, sum = " << sum << ", time = " << timer.time() << '\n';
  cout.flush();

  timer.reset();

  sum = 0.0;
  for (INTEGER i=0; i<n; ++i) {
    sum += arv[i]*brv[i];
  }

  cout<<"3 of 6, sum = " << sum << ", time = " << timer.time() << '\n';
  cout.flush();

  timer.reset();

  sum = 0.0;
  for (INTEGER i=0; i<n; ++i) {
    sum += a[i]*b[i];
  }

  cout<<"4 of 6, sum = " << sum << ", time = " << timer.time() << '\n';
  cout.flush();

  timer.reset();

  REAL* a_iter = a;
  REAL* b_iter = b;
  REAL* a_end = a + n;
  sum = 0.0;
  while(a_iter<a_end) {
   sum += (*a_iter++)*(*b_iter++);
  }

  cout<<"5 of 6, sum = " << sum << ", time = " << timer.time() << '\n';
  cout.flush();

  vector<REAL>::const_iterator arv_iter = arv.begin();
  vector<REAL>::const_iterator brv_iter = brv.begin();
  vector<REAL>::const_iterator arv_end = arv.end();  

  timer.reset();

  sum = 0.0;
  while(arv_iter<arv_end) {
   sum += (*arv_iter++)*(*brv_iter++);
  }

  cout<<"6 of 6, sum = " << sum << ", time = " << timer.time() << '\n';
  cout.flush();

  return 0;
}
