#include <config.h>
#include <graph/LogicalNode.h>
#include <functions/Function.h>
#include <graph/NodeError.h>
#include <graph/NodeNameTab.h>
#include <stdexcept>
#include <vector>
#include <string>
#include <math.h>
using std::vector;
using std::string;
using std::set;
using std::logic_error;
static Index mkDim(Function const *func, vector<Node*> const &parents)
{
/*
Calculates dimension of logical node as a function of its
parameters.
*/
vector<SArray const *> parameters(parents.size());
long j = 0;
for (vector<Node*>::const_iterator p = parents.begin(); p != parents.end();
++p)
{
parameters[j++] = &((*p)->data);
}
if (!func->checkParameterLength(parameters)) {
throw logic_error(string("Incorrect number of parameters for function ")
+ func->name());
}
if (!func->checkParameterDim(parameters)) {
throw logic_error(string("Non-conforming parameters for function ")
+ func->name());
}
return func->dim(parameters);
}
LogicalNode::LogicalNode(Function const *function,
vector<Node*> const ¶meters)
: DeterministicNode(mkDim(function,parameters)), _func(function)
{
for (unsigned long j = 0; j < parameters.size(); ++j) {
_parameters.push_back(¶meters[j]->data);
addParent(parameters[j]);
}
if (_func->isDiscreteValued(_parameters)) {
data.setDiscreteValued(true);
}
}
LogicalNode::~LogicalNode()
{
}
string LogicalNode::name(NodeNameTab const &name_table) const
{
string name = name_table.getName(this);
if (!name.empty())
return name;
/*
* We have to do a little work here. We can't recover the
* parameter names from the vector "_parameters", because it is
* a vector of SArrays. Conversely, the set of parents is not
* stored in the right order. By putting the two pieces of
* data together, we can reconstruct the original vector of
* parameters.
*/
vector<Node *> parameters;
vector<SArray const *>::const_iterator p;
for (p = _parameters.begin(); p != _parameters.end(); ++p) {
set<Node*>::const_iterator q;
for (q = parents().begin(); q != parents().end(); ++q) {
Node *parent = (*q);
if (*p == &parent->data) {
parameters.push_back(parent);
break;
}
}
}
string const &fname = _func->name();
if (fname == "*" || fname == "/" || fname == "+" || fname == "-")
{
name.append("(");
for (unsigned int i = 0; i < parameters.size(); ++i) {
if (i > 0) {
name.append(fname);
}
name.append(parameters[i]->name(name_table));
}
name.append(")");
}
else if (fname == "NEG")
{
name.append("(-");
name.append(parameters[0]->name(name_table));
name.append(")");
}
else
{
name.append(fname);
name.append("(");
for (unsigned int i = 0; i < parameters.size(); ++i) {
if (i > 0)
name.append(",");
name.append(parameters[i]->name(name_table));
}
name.append(")");
}
return name;
}
vector<SArray const *> const &LogicalNode::parameters() const
{
return _parameters;
}
Function const* LogicalNode::function() const
{
return _func;
}
void LogicalNode::forwardSample()
{
if (!_func->checkParameterValue(_parameters)) {
throw NodeError(this, "Invalid parameter values for LogicalNode");
}
_func->evaluate(data, _parameters);
}
LogicalNode *asLogical(Node *node)
{
return dynamic_cast<LogicalNode*>(node);
}
bool isLogical(Node const *node)
{
return dynamic_cast<LogicalNode const*>(node);
}
syntax highlighted by Code2HTML, v. 0.9.1