#ifndef NODE_H_ #define NODE_H_ #include #include #include class NodeNameTab; /** * Abstract base class for nodes in a directed graphical model. * * Nodes are reference managed and will delete themselves when the * reference count reaches zero. Referencing and dereferencing * takes place automatically when a node is inserted into/removed * from a graph, but can also be done by calling the ref() and * unref() member functions. * * Nodes should be dynamically allocated, and should be inserted * into a Graph as soon as they are created. * * @see Graph * @short Node in a directed graphical model */ class Node { std::set _parents; std::set _children; unsigned int _ref; /* Forbid copying of Node objects */ Node(Node const &orig); Node &operator=(Node const &rhs); public: /** * Numerical value of the node. */ SArray data; /** * Constructor. Creates a node whose data member has dimension * dim */ Node(Index const &dim); /** * Destructor. The node is unlinked before being deleted. */ virtual ~Node(); /** * Increments the reference count. */ void ref(); /** * Decrements reference count. The node deletes itself when the * reference count is zero. */ void unref(); /** * Shows the current reference count. */ unsigned int refCount(); /** * Set of parents. */ std::set const &parents() const; /** * Set of children. */ std::set const &children() const; /** * Adds parent. The parent node is modified so that this node is * added to its set of children. It is an error to attempt to add a * node as a parent of itself. * * There is no corresponding addChild member function since, in a * directed graphical model, a node is defined in terms of its parents. * * @exceptions NodeError */ void addParent(Node *node); /** * Remove parent. The parent node is modified so that this node is * remove from its set of children. If node is not a parent * of this node, then nothing happens. */ void removeParent(Node *node); /** * Removes all parent and child connections. This is a necessary * preliminary to deletion. Hence unlink is called by the destructor. */ void unlink(); /** * Sample a value for the node based only on its parent's values. */ virtual void forwardSample() = 0; /** * Initializes the node. The default behaviour is to call * forwardSample() but this can be overloaded by any subclass. It * is an error to attempt to initialize a node before its * parents. Call canInitialize() first to test this. It is also an * error to attempt to re-initialize a node. Call isInitialized() * first to test this. * @exceptions NodeError */ virtual void initialize(); /** * Shows whether a node is already initialized. */ bool isInitialized(); /** * A node can be initialized only if all of its parents are initialized. */ virtual bool canInitialize(); /** * Returns the name of the node. The default implementation looks up * the node in the supplied name table and returns an empty string if it * is not found. Subclasses can overload this function and try to calculate * the Node name based on the names of it's parents. * * @param name_table Lookup table for node names. */ virtual std::string name(NodeNameTab const &name_table) const; /** * Returns true if the node is a stochastic node. */ virtual bool isStochastic() const = 0; }; /** * Returns true if the Node's data is fixed */ bool isObserved(Node const *node); #endif /* NODE_H_ */