[ff1121]: src / lib / graph / ArrayStochasticNode.cc  Maximize  Restore  History

Download this file

163 lines (141 with data), 4.2 kB

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
#include <config.h>
#include <graph/ArrayStochasticNode.h>
#include <distribution/DistError.h>
#include <distribution/ArrayDist.h>
#include <util/nainf.h>
#include <util/dim.h>
#include <vector>
#include <string>
#include <algorithm>
using std::vector;
using std::string;
using std::copy;
using std::min;
using std::max;
namespace jags {
static vector<unsigned int> mkDim(ArrayDist const *dist,
vector<Node const *> const &parents)
{
/*
Calculates dimension of array stochastic node as a function of its
parents
*/
if (!checkNPar(dist, parents.size())) {
throw DistError(dist, "Incorrect number of parameters");
}
vector<vector<unsigned int> > parameter_dims(parents.size());
for (unsigned long j = 0; j < parents.size(); ++j) {
parameter_dims[j] = parents[j]->dim();
}
if (!dist->checkParameterDim(parameter_dims)) {
throw DistError(dist, "Non-conforming parameters");
}
return dist->dim(parameter_dims);
}
static vector<vector<unsigned int> > const &
mkParameterDims(vector<Node const *> const &parameters) {
vector<vector<unsigned int> > dims(parameters.size());
for (unsigned int j = 0; j < parameters.size(); ++j) {
dims[j] = parameters[j]->dim();
}
return getUnique(dims);
}
ArrayStochasticNode::ArrayStochasticNode(ArrayDist const *dist,
vector<Node const *> const &params,
Node const *lower, Node const *upper,
double const *data,
unsigned int length)
: StochasticNode(mkDim(dist, params), dist, params, lower, upper,
data, length),
_dist(dist), _dims(mkParameterDims(params))
{
if (!dist->checkParameterDim(_dims)) {
throw DistError(dist, "Invalid parameter dimensions");
}
}
double ArrayStochasticNode::logDensity(unsigned int chain, PDFType type) const
{
if(!_dist->checkParameterValue(_parameters[chain], _dims))
return JAGS_NEGINF;
return _dist->logDensity(_data + _length * chain, _length, type,
_parameters[chain], _dims,
lowerLimit(chain), upperLimit(chain));
}
void ArrayStochasticNode::deterministicSample(unsigned int chain)
{
_dist->typicalValue(_data + _length * chain, _length,
_parameters[chain], _dims,
lowerLimit(chain), upperLimit(chain));
}
void ArrayStochasticNode::randomSample(RNG *rng, unsigned int chain)
{
_dist->randomSample(_data + _length * chain, _length,
_parameters[chain], _dims,
lowerLimit(chain), upperLimit(chain), rng);
}
void ArrayStochasticNode::truncatedSample(RNG *rng, unsigned int chain,
double const *lower,
double const *upper)
{
/*
Some complexity required to deal with case where node is already
truncated. Note that this code is identical to that in
VectorStochasticNode
*/
double const *l = lowerLimit(chain);
double *lv = 0;
if (l || lower) {
lv = new double[_length];
if (l && lower) {
for (unsigned int i = 0; i < _length; ++i) {
lv[i] = min(l[i], lower[i]);
}
}
else if (l) {
copy(l, l + _length, lv);
}
else if (lower) {
copy(lower, lower + _length, lv);
}
}
double const *u = upperLimit(chain);
double *uv = 0;
if (u || upper) {
uv = new double[_length];
if (u && upper) {
for (unsigned int i = 0; i < _length; ++i) {
uv[i] = max(u[i], upper[i]);
}
}
else if (u) {
copy(u, u + _length, uv);
}
else if (upper) {
copy(upper, upper + _length, uv);
}
}
_dist->randomSample(_data + _length * chain, _length,
_parameters[chain], _dims, lv, uv, rng);
delete [] lv;
delete [] uv;
}
bool ArrayStochasticNode::checkParentValues(unsigned int chain) const
{
return _dist->checkParameterValue(_parameters[chain], _dims);
}
StochasticNode *
ArrayStochasticNode::clone(vector<Node const *> const &parameters,
Node const *lower, Node const *upper) const
{
return new ArrayStochasticNode(_dist, parameters, lower, upper);
}
unsigned int ArrayStochasticNode::df() const
{
return _dist->df(_dims);
}
void ArrayStochasticNode::sp(double *lower, double *upper, unsigned int length,
unsigned int chain) const
{
_dist->support(lower, upper, length, _parameters[chain], _dims);
}
} //namespace jags