/*---------------------------------------------------------------------------*
 *                                   IT++			             *
 *---------------------------------------------------------------------------*
 * Copyright (c) 1995-2004 by Tony Ottosson, Thomas Eriksson, Pål Frenger,   *
 * Tobias Ringström, and Jonas Samuelsson.                                   *
 *                                                                           *
 * Permission to use, copy, modify, and distribute this software and its     *
 * documentation under the terms of the GNU General Public License is hereby *
 * granted. No representations are made about the suitability of this        *
 * software for any purpose. It is provided "as is" without expressed or     *
 * implied warranty. See the GNU General Public License for more details.    *
 *---------------------------------------------------------------------------*/

/*! 
  \file 
  \brief Vector quantizer class (unconstrained)
  \author Thomas Eriksson

  1.14

  2004/09/28 11:48:28
*/

#ifndef __vq_h
#define __vq_h

#include <string>
#include "itconfig.h"
#include "base/itassert.h"
#include <iostream>
#include "base/vec.h"
#include "base/mat.h"
#include "base/elmatfunc.h"
#include "base/array.h"
#include <cstring>

namespace itpp {


  /*!
    \defgroup sourcecoding Source coding routines
  */


  /*! 
    \ingroup sourcecoding
    \brief Class for vector quantization

    The following code illustrates how the VQ can be initialized from a file and
    used to quantize a random vector.
    \code
    VQ	Quantizer;
    vec	x,y;
    int	i;

    Quantizer.load("randomvq.vq");
    x=randn(Quantizer.dim());
    i=Quantizer.encode(x);
    y=Quantizer.decode(i);
    \endcode
  */
  class VQ {
  public:
    //! Default constructor
    VQ();
    //! Create a VQ from a VQ file
    VQ(const char *Name);
    //! Encode the input vector
    int encode(const vec &x);
    //! Encode the input vector, and return the num best indices
    ivec encode(const vec &x, int num);
    //! Decode the index
    vec decode(int Index) const;
    //! Decode the indices
    Array<vec> decode(const ivec &Index) const;
    //! Quantize the input vector
    vec Q(const vec &x);
    //! Quantize the input vector
    vec operator()(const vec &x);
    //! Initialize the codebook by a matrix
    void set_codebook(const mat &CB);
    //! Returns the codebook
    mat get_codebook() const;
    //! Set a codevector in the codebook
    void set_codevector(int Index, const vec &indata);
    //! Returns the codevector at the given index
    vec get_codevector(int Index) const;
    //! Rescale and translate a codevector
    void modify_codevector(int no, double mul, const vec &add);
    //! Returns the size (number of codevectors) of the VQ
    int size() const;
    //! Returns the dimension of the VQ
    int dim() const;
    //! Returns the number of bits of the VQ [log2(size)/dim]
    int nobits() const;
    /*!
      \brief Load the codebook from a file
      \param Name The name of the VQ file
      
      The file format is a textfile where each row is a vector from the codebook.
    */
    void load(const char *Name);
    /*!
      \brief Save the codebook to a file
      \param Name The name of the VQ file
      
      The file format is a textfile where each row is a vector from the codebook.
    */
    void save(const char *Name) const;
    //! Returns the distortion at the latest time a vector was encoded
    double latest_distortion();
  protected:
    //! The vector containing the code book
    vec CodeBook;
    //! The size and dimension of the code book respectively
    int Size,Dim;
    //! The distortion at the latest time a vector was encoded
    double LatestDist;
  };

  // INLINE FUNCTIONS

  inline int VQ::size() const { return Size; }

  inline int VQ::nobits() const { return needed_bits(size()); }

  inline int VQ::dim() const { return Dim; }

  inline double VQ::latest_distortion()	{ return LatestDist; }

  inline vec VQ::decode(int Index) const { return get_codevector(Index); }

  inline vec VQ::Q(const vec &x) { return decode(encode(x)); }

  inline vec VQ::operator()(const vec &x) { return Q(x); }

} //namespace itpp

#endif //__vq_h


syntax highlighted by Code2HTML, v. 0.9.1