#include <config.h>
#include <sampler/DiscreteSliceSampler.h>
#include <graph/StochasticNode.h>
#include <graph/NodeError.h>
#include <distributions/DistDiscrete.h>

#include <cmath>

using std::floor;
using std::vector;

DiscreteSliceSampler::DiscreteSliceSampler(StochasticNode *node, 
					   Graph const &graph,
					   double width, long ndoubles)
  : Slicer(vector<StochasticNode*>(1, node), graph, width, ndoubles), 
    _x(*node->data.value())
{
}

bool DiscreteSliceSampler::canSample(StochasticNode const *node,
				     Graph const &graph)
{
  return (node->distribution()->isDiscreteValued() &&
	  node->data.length() == 1 &&
	  node->distribution()->df(node->parameters()) == 1);
}

void DiscreteSliceSampler::setValue(double x)
{
  _x = x;
  nodes().front()->data.setValue(x, 0);
  vector<Node*> const &dc = deterministicChildren();
  for (vector<Node*>::const_iterator i(dc.begin()); i != dc.end(); ++i) {
    (*i)->forwardSample();
  }
}
  
double DiscreteSliceSampler::value()
{
  return _x;
}

double DiscreteSliceSampler::lowerLimit()
{
  StochasticNode const *snode = nodes().front();
  return snode->distribution()->lowerSupport(0, snode->parameters());
}

double DiscreteSliceSampler::upperLimit()
{
  StochasticNode const *snode = nodes().front();
  return snode->distribution()->upperSupport(0, snode->parameters());
}

void DiscreteSliceSampler::update()
{
  updateDouble();
}


syntax highlighted by Code2HTML, v. 0.9.1