//
// C++ Interface: %{MODULE}
//
// Description:
//
//
// Author: %{AUTHOR} <%{EMAIL}>, (C) %{YEAR}
//
// Copyright: See COPYING file that comes with this distribution
//
//
#ifndef TNet_Vector_h
#define TNet_Vector_h
#include <cstddef>
#include <cstdlib>
#include <stdexcept>
#include <iostream>
#ifdef HAVE_ATLAS
extern "C"{
#include <cblas.h>
#include <clapack.h>
}
#endif
#include "Common.h"
#include "MathAux.h"
#include "Types.h"
#include "Error.h"
namespace TNet
{
template<typename _ElemT> class Vector;
template<typename _ElemT> class SubVector;
template<typename _ElemT> class Matrix;
template<typename _ElemT> class SpMatrix;
// we need to declare the friend functions here
template<typename _ElemT>
std::ostream & operator << (std::ostream & rOut, const Vector<_ElemT> & rV);
template<typename _ElemT>
std::istream & operator >> (std::istream & rIn, Vector<_ElemT> & rV);
template<typename _ElemT>
_ElemT
BlasDot(const Vector<_ElemT>& rA, const Vector<_ElemT>& rB);
/** **************************************************************************
** **************************************************************************
* @brief Provides a matrix abstraction class
*
* This class provides a way to work with matrices in TNet.
* It encapsulates basic operations and memory optimizations.
*
*/
template<typename _ElemT>
class Vector
{
public:
/// defines a type of this
typedef Vector<_ElemT> ThisType;
Vector(): mpData(NULL)
#ifdef STK_MEMALIGN_MANUAL
,mpFreeData(NULL)
#endif
, mDim(0)
{}
/**
* @brief Copy constructor
* @param rV
*/
Vector(const Vector<_ElemT>& rV)
{ mpData=NULL; Init(rV.Dim()); Copy(rV); }
/* Type conversion constructor. */
template<typename _ElemU>
explicit Vector(const Vector<_ElemU>& rV)
{ mpData=NULL; Init(rV.Dim()); Copy(rV); }
Vector(const _ElemT* ppData, const size_t s)
{ mpData=NULL; Init(s); Copy(ppData); }
explicit Vector(const size_t s, bool clear=true)
{ mpData=NULL; Init(s,clear); }
~Vector()
{ Destroy(); }
Vector<_ElemT> &operator = (const Vector <_ElemT> &other)
{ Init(other.Dim()); Copy(other); return *this; } // Needed for inclusion in std::vector
Vector<_ElemT>&
Init(size_t length, bool clear=true);
/**
* @brief Dealocates the window from memory and resets the dimensions to (0)
*/
void
Destroy();
/**
* @brief Returns @c true if vector is initialized
*/
bool
IsInitialized() const
{ return mpData != NULL; }
/**
* @brief Sets all elements to 0
*/
void
Zero();
void
Set(_ElemT f);
inline size_t
Dim() const
{ return mDim; }
/**
* @brief Returns size of matrix in memory (in bytes)
*/
inline size_t
MSize() const
{
return (mDim + (((16 / sizeof(_ElemT)) - mDim%(16 / sizeof(_ElemT)))
% (16 / sizeof(_ElemT)))) * sizeof(_ElemT);
}
/**
* @brief Gives access to the vector memory area
* @return pointer to the first field
*/
inline _ElemT*
pData()
{ return mpData; }
/**
* @brief Gives access to the vector memory area
* @return pointer to the first field (const version)
*/
inline const _ElemT*
pData() const
{ return mpData; }
/**
* @brief Gives access to a specified vector element (const).
*/
inline _ElemT
operator [] (size_t i) const
{
#ifdef PARANOID
assert(i<mDim);
#endif
return *(mpData + i);
}
/**
* @brief Gives access to a specified vector element (non-const).
*/
inline _ElemT &
operator [] (size_t i)
{
#ifdef PARANOID
assert(i<mDim);
#endif
return *(mpData + i);
}
/**
* @brief Gives access to a specified vector element (const).
*/
inline _ElemT
operator () (size_t i) const
{
#ifdef PARANOID
assert(i<mDim);
#endif
return *(mpData + i);
}
/**
* @brief Gives access to a specified vector element (non-const).
*/
inline _ElemT &
operator () (size_t i)
{
#ifdef PARANOID
assert(i<mDim);
#endif
return *(mpData + i);
}
/**
* @brief Returns a matrix sub-range
* @param o Origin
* @param l Length
* See @c SubVector class for details
*/
SubVector<_ElemT>
Range(const size_t o, const size_t l)
{ return SubVector<_ElemT>(*this, o, l); }
/**
* @brief Returns a matrix sub-range
* @param o Origin
* @param l Length
* See @c SubVector class for details
*/
const SubVector<_ElemT>
Range(const size_t o, const size_t l) const
{ return SubVector<_ElemT>(*this, o, l); }
//########################################################################
//########################################################################
/// Copy data from another vector
Vector<_ElemT>&
Copy(const Vector<_ElemT>& rV);
/// Copy data from another vector of a different type.
template<typename _ElemU> Vector<_ElemT>&
Copy(const Vector<_ElemU>& rV);
/// Load data into the vector
Vector<_ElemT>&
Copy(const _ElemT* ppData);
Vector<_ElemT>&
CopyVectorizedMatrixRows(const Matrix<_ElemT> &rM);
Vector<_ElemT>&
RemoveElement(size_t i);
Vector<_ElemT>&
ApplyLog();
Vector<_ElemT>&
ApplyLog(const Vector<_ElemT>& rV);//ApplyLog to rV and put the result in (*this)
Vector<_ElemT>&
ApplyExp();
Vector<_ElemT>&
ApplySoftMax();
Vector<_ElemT>&
Invert();
Vector<_ElemT>&
DotMul(const Vector<_ElemT>& rV); // Multiplies each element (*this)(i) by rV(i).
Vector<_ElemT>&
BlasAxpy(const _ElemT alpha, const Vector<_ElemT>& rV);
Vector<_ElemT>&
BlasGemv(const _ElemT alpha, const Matrix<_ElemT>& rM, const MatrixTrasposeType trans, const Vector<_ElemT>& rV, const _ElemT beta = 0.0);
//########################################################################
//########################################################################
Vector<_ElemT>&
Add(const Vector<_ElemT>& rV)
{ return BlasAxpy(1.0, rV); }
Vector<_ElemT>&
Subtract(const Vector<_ElemT>& rV)
{ return BlasAxpy(-1.0, rV); }
Vector<_ElemT>&
AddScaled(_ElemT alpha, const Vector<_ElemT>& rV)
{ return BlasAxpy(alpha, rV); }
Vector<_ElemT>&
Add(_ElemT c);
Vector<_ElemT>&
MultiplyElements(const Vector<_ElemT>& rV);
// @brief elementwise : rV.*rR+beta*this --> this
Vector<_ElemT>&
MultiplyElements(_ElemT alpha, const Vector<_ElemT>& rV, const Vector<_ElemT>& rR,_ElemT beta);
Vector<_ElemT>&
DivideElements(const Vector<_ElemT>& rV);
/// @brief elementwise : rV./rR+beta*this --> this
Vector<_ElemT>&
DivideElements(_ElemT alpha, const Vector<_ElemT>& rV, const Vector<_ElemT>& rR,_ElemT beta);
Vector<_ElemT>&
Subtract(_ElemT c);
Vector<_ElemT