#ifndef VECTOR_HPP
#define VECTOR_HPP

#include <iostream>
#include "debug.hpp"

using namespace std;

using Real = float;

#ifdef DEBUG
struct Vector{
  size_t n;
  Real* data;
  Real& operator[](size_t i);
};

inline Real&
Vector::operator[](size_t i){
  assert(i<n);
  return data[i];
}

inline Vector
init_vector(size_t n){
  Vector v;
  v.n=n;
  v.data=new Real[n];
  return v;
}

inline void
delete_vector(Vector v){
  delete[] v.data;
}

inline bool
is_null(Vector v){
  return v.n==0;
}

static const Vector NullVector={0,nullptr};

#else
using Vector=Real*;

inline Vector
init_vector(size_t n){
  return new Real[n];
}

inline void
delete_vector(Vector v){
  delete[] v;
}
#endif

inline void
display(Vector v,size_t n){
  if(n==0){
    cout<<"[]"<<endl;
    return;
  }
  cout<<'['<<v[0];
  for(size_t i=1;i<n;++i){
    cout<<','<<v[i];
  }
  cout<<']'<<endl;
}

inline size_t
argmax(Vector v,size_t n){
  assert(n>0);
  size_t imax=0;
  Real vmax=v[0];
  for(size_t i=1;i<n;++i){
    if(v[i]>vmax){
      vmax=v[i];
      imax=i;
    }
  }
  return imax;
}

inline size_t
indice2(size_t i,size_t j,size_t nj){
  return i*nj+j;
}

inline size_t
indice3(size_t i,size_t j,size_t k,size_t nj,size_t nk){
  return (i*nj+j)*nk+k;
}

inline size_t
indice4(size_t i,size_t j,size_t k,size_t l,size_t nj,size_t nk,size_t nl){
  return ((i*nj+j)*nk+k)*nl+l;
}

#endif
