/* 
 * File:   Vector.hpp
 * Author: jens
 *
 * Created on 19. Dezember 2014, 18:24
 */

#ifndef _RADIO_VECTOR_HPP_
#define	_RADIO_VECTOR_HPP_

#define VECTOR_USE_BLAZE

#include <complex>
#include <radio/cpx.h>
#include <radio/real.h>

#ifndef radio_float_t
#define radio_float_t float
#endif

#ifdef VECTOR_USE_EIGEN
#include <Eigen/Dense>
#endif

#ifdef VECTOR_USE_BLAZE
#include <blaze/Blaze.h>
#endif

#ifdef VECTOR_USE_ARMADILLO
#include <armadillo>
#endif

namespace Radio
{
	
typedef radio_float_t RealScalar;
typedef std::complex<radio_float_t> ComplexScalar;

#ifdef VECTOR_USE_EIGEN

typedef Eigen::Matrix<RealScalar, Eigen::Dynamic, 1> RVec;
typedef Eigen::Matrix<ComplexScalar, Eigen::Dynamic, 1> CVec;

typedef Eigen::Matrix<RealScalar, Eigen::Dynamic, Eigen::Dynamic> RMat;
typedef Eigen::Matrix<ComplexScalar, Eigen::Dynamic, Eigen::Dynamic> CMat;

#endif

#ifdef VECTOR_USE_BLAZE
typedef blaze::DynamicVector<RealScalar> RVec;
typedef blaze::DynamicVector<ComplexScalar> CVec;

typedef blaze::DynamicMatrix<RealScalar> RMat;
typedef blaze::DynamicMatrix<ComplexScalar> CMat;

inline void ror(auto &vec)
{
	vec = elements(vec, [size=vec.size()](size_t i){ return (i-1) % size; }, vec.size());
}

inline void rol(auto &vec)
{
	vec = elements(vec, [size=vec.size()](size_t i){ return (i+1) % size; }, vec.size());
}

inline void insert_left(auto &vec, auto const &x)
{
	ror(vec);
	vec[0] = x;
}

inline void insert_right(auto &vec, auto const &x)
{
	rol(vec);
	vec[vec.size()-1] = x;
}

#endif

#ifdef VECTOR_USE_ARMADILLO
#error "Vector: Implement armadillo support!"
#endif

static ComplexScalar toComplexScalar(cpx_t v)
{
	return ComplexScalar(v.real, v.imag);
}

static cpx_t toCpx(ComplexScalar v)
{
	return Cpx(v.real(), v.imag());
}

static void toComplexVector(CVec &dst, cpx_t const *pSrc, uint32_t len)
{
	for (uint32_t i=0; i < len; i++)
	{
		dst[i] = ComplexScalar(pSrc[i].real, pSrc[i].imag);
	}
}

static void toCpxVector(cpx_t *pDst, CVec const &src, uint32_t len)
{
	for (uint32_t i=0; i < len; i++)
	{
		pDst[i].real = src[i].real();
		pDst[i].imag = src[i].imag();
	}
}

} // ::Radio

#endif	/* _RADIO_VECTOR_HPP_ */

