// file: $isip_ifc/class/numeric/Histogram/hist_07.cc
// version: $Id: hist_07.cc 10427 2006-02-13 19:33:54Z srinivas $
//

// isip include files
//
#include "Histogram.h"

// method: compute
//
// arguments:
//  const Vector<TVector>& values: (input) values to histogram
//
// return: boolean value indicating status
//
// this method bins the elements of 'values' into the bins that are already
// set.
//
template <class TVector>
boolean Histogram::compute(const Vector<TVector>& values_a) {

  // see if we are already binned
  //
  if (bins_d.length() == 0) {    
    return Error::handle(name(), L"compute", ERR_BINS, __FILE__, __LINE__);
  }
  
  // update the counts
  //
  return update(values_a);
}

// explicit instantiations
//
template boolean
Histogram::compute<VectorByte>(const Vector<VectorByte>&);
template boolean
Histogram::compute<VectorDouble>(const Vector<VectorDouble>&);
template boolean
Histogram::compute<VectorFloat>(const Vector<VectorFloat>&);
template boolean
Histogram::compute<VectorLlong>(const Vector<VectorLlong>&);
template boolean
Histogram::compute<VectorLong>(const Vector<VectorLong>&);
template boolean
Histogram::compute<VectorShort>(const Vector<VectorShort>&);
template boolean
Histogram::compute<VectorUllong>(const Vector<VectorUllong>&);
template boolean
Histogram::compute<VectorUlong>(const Vector<VectorUlong>&);
template boolean
Histogram::compute<VectorUshort>(const Vector<VectorUshort>&);

// method: compute
//
// arguments:
//  const TVector& values: (input) 1D data to histogram
//
// return: boolean value indicating status
//
// 1D histogram compute
//
template <class TVector>
boolean Histogram::compute(const TVector& values_a) {

  // see if we are already binned
  //
  if (bins_d.length() == 0) {    
    return Error::handle(name(), L"compute", ERR_BINS, __FILE__, __LINE__);
  }

  // update the counts
  //
  return update(values_a);
}

// explicit instantiations
//
template boolean
Histogram::compute<VectorByte>(const VectorByte&);
template boolean
Histogram::compute<VectorDouble>(const VectorDouble&);
template boolean
Histogram::compute<VectorFloat>(const VectorFloat&);
template boolean
Histogram::compute<VectorLlong>(const VectorLlong&);
template boolean
Histogram::compute<VectorLong>(const VectorLong&);
template boolean
Histogram::compute<VectorShort>(const VectorShort&);
template boolean
Histogram::compute<VectorUllong>(const VectorUllong&);
template boolean
Histogram::compute<VectorUlong>(const VectorUlong&);
template boolean
Histogram::compute<VectorUshort>(const VectorUshort&);

// method: update
//
// arguments:
//  const Vector<TVector>& values: (input) values to histogram
//
// return: boolean value indicating status
//
// this method updates the current histogram counts with the values passed
// in as input (possibly vector) time series
//
template <class TVector>
boolean Histogram::update(const Vector<TVector>& values_a) {

  // verify that the bins are set
  //
  if ((bins_d.length() == 0) ||
      (values_a.length() != dim_d)) {
    return Error::handle(name(), L"update", ERR_BINS, __FILE__, __LINE__);
  }
  
  // define local variables
  //
  double value = 0;
  long data_length = values_a(0).length();

  for (long i = 0; i < dim_d; i++) {
    if (values_a(i).length() != data_length) {
      return Error::handle(name(), L"update", ERR_BINS, __FILE__, __LINE__);
    }
  }

  // loop over the input data and accumulate the counts
  //
  for (long k = 0; k < data_length; k++) {
    VectorLong bin_1d_index(dim_d);
    long bin_global_index = 0;
    
    for (long i = 0; i < dim_d; i++) {
      value = (double)values_a(i)(k);
      bin_1d_index(i) = findBinIndex(value, i);
      bin_global_index += bin_1d_index(i) * block_boundary_index_d(i);
    }

    counts_d(bin_global_index) += 1;
  }
  
  // exit gracefully
  //
  return true;
}

// explicit instantiations
//
template boolean
Histogram::update<VectorByte>(const Vector<VectorByte>&);
template boolean
Histogram::update<VectorDouble>(const Vector<VectorDouble>&);
template boolean
Histogram::update<VectorFloat>(const Vector<VectorFloat>&);
template boolean
Histogram::update<VectorLlong>(const Vector<VectorLlong>&);
template boolean
Histogram::update<VectorLong>(const Vector<VectorLong>&);
template boolean
Histogram::update<VectorShort>(const Vector<VectorShort>&);
template boolean
Histogram::update<VectorUllong>(const Vector<VectorUllong>&);
template boolean
Histogram::update<VectorUlong>(const Vector<VectorUlong>&);
template boolean
Histogram::update<VectorUshort>(const Vector<VectorUshort>&);

// method: update
//
// arguments:
//  const TVector& values: (input) values to histogram
//
// return: boolean value indicating status
//
// this method updates the current (1D) histogram counts with the values
// passed in as a scalar time series
//
template <class TVector>
boolean Histogram::update(const TVector& values_a) {

  Vector<VectorDouble> values(1);

  values(0).assign(values_a);

  return update(values);
}

// explicit instantiations
//
template boolean
Histogram::update<VectorByte>(const VectorByte&);
template boolean
Histogram::update<VectorDouble>(const VectorDouble&);
template boolean
Histogram::update<VectorFloat>(const VectorFloat&);
template boolean
Histogram::update<VectorLlong>(const VectorLlong&);
template boolean
Histogram::update<VectorLong>(const VectorLong&);
template boolean
Histogram::update<VectorShort>(const VectorShort&);
template boolean
Histogram::update<VectorUllong>(const VectorUllong&);
template boolean
Histogram::update<VectorUlong>(const VectorUlong&);
template boolean
Histogram::update<VectorUshort>(const VectorUshort&);
