/**
* InferenceGraphNode.java
* @author Fabio G. Cozman
* Copyright 1996 - 1999, Fabio G. Cozman,
* Carnergie Mellon University, Universidade de Sao Paulo
* fgcozman@usp.br, http://www.cs.cmu.edu/~fgcozman/home.html
*
* The JavaBayes distribution is free software; you can
* redistribute it and/or modify it under the terms of the GNU General
* Public License as published by the Free Software Foundation (either
* version 2 of the License or, at your option, any later version),
* provided that this notice and the name of the author appear in all
* copies. Upon request to the author, some of the packages in the
* JavaBayes distribution can be licensed under the GNU Lesser General
* Public License as published by the Free Software Foundation (either
* version 2 of the License, or (at your option) any later version).
* If you're using the software, please notify fgcozman@usp.br so
* that you can receive updates and patches. JavaBayes is distributed
* "as is", in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with the JavaBayes distribution. If not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
package InferenceGraphs;
import BayesianNetworks.*;
import QuasiBayesianNetworks.*;
import CredalSets.*;
import java.io.*;
import java.awt.*;
import java.util.*;
public class InferenceGraphNode {
InferenceGraph ig;
ProbabilityVariable pv;
ProbabilityFunction pf;
Vector parents = new Vector();
Vector children = new Vector();
Point pos;
private final String defaultInferenceGraphNodeValues[] = { "true", "false" };
private final BayesNet defaultInferenceGraphNodeBayesNet = null;
private final Vector defaultInferenceGraphNodeProperties = null;
/*
* Default constructor for an InferenceGraphNode.
*/
InferenceGraphNode(InferenceGraph i_g, String name) {
this(i_g, name, new Point(100,100));
}
/*
* Constructor for a InferenceGraphNode object. The created
* node is in an incomplete state; the constructor assumes the
* node is new and not necessarily attached to the current
* network in the InferenceGraph; no parents nor
* children are defined for such a node.
*/
InferenceGraphNode(InferenceGraph i_g, String name, Point position) {
ig = i_g;
// Initialize the variable
pv = new ProbabilityVariable(defaultInferenceGraphNodeBayesNet,
name, BayesNet.INVALID_INDEX,
defaultInferenceGraphNodeValues,
defaultInferenceGraphNodeProperties);
// Initialize the probability function
init_dists();
// Initialize the position of the node
pos = position;
}
/*
* Constructor for a InferenceGraphNode object.
* Note that parents and children are not properly set here.
*/
InferenceGraphNode(InferenceGraph i_g,
ProbabilityVariable p_v, ProbabilityFunction p_f) {
ig = i_g;
pv = p_v;
pf = p_f;
pos = parse_position(p_v);
}
/*
* Constructor for a InferenceGraphNode object.
* Note that parents and children are not properly set here.
*/
InferenceGraphNode(InferenceGraph i_g,
ProbabilityVariable p_v, ProbabilityFunction p_f,
Point position) {
ig = i_g;
pv = p_v;
pf = p_f;
pos = position;
}
/*
* Initialization for the probability function
* in the InferenceGraphNode.
*/
void init_dists() {
int i, total_values;
double new_value;
Enumeration e;
InferenceGraphNode pnode;
// Create the probability_variables
ProbabilityVariable pvs[] =
new ProbabilityVariable[parents.size() + 1];
pvs[0] = pv;
total_values = pv.number_values();
new_value = 1.0/((double)(total_values));
for (i = 1, e = parents.elements(); e.hasMoreElements(); i++) {
pnode = (InferenceGraphNode)(e.nextElement());
pvs[i] = pnode.pv;
total_values *= pnode.pv.number_values();
}
// Compute the default (uniformly distributed) values
double dists[] = new double[total_values];
for (i=0; i < dists.length; i++)
dists[i] = new_value;
// Construct the ProbabilityFunction
pf = new ProbabilityFunction(defaultInferenceGraphNodeBayesNet,
pvs, dists,
defaultInferenceGraphNodeProperties);
}
/*
* Update the position property.
*/
void update_position() {
Vector properties = pv.get_properties();
Vector properties_to_remove = new Vector();
String final_property = null;
String s, ss;
if ((properties != null) && (properties.size() > 0)) {
for (Enumeration e = properties.elements(); e.hasMoreElements(); ) {
ss = (String) e.nextElement();
s = ss.trim();
// If property is not position, skip it
if (! s.startsWith("position"))
continue;
//Schedule the current position property for removal
properties_to_remove.addElement(ss);
}
// Remove the old position properties
for (Enumeration e = properties_to_remove.elements(); e.hasMoreElements(); ) {
ss = (String)(e.nextElement());
pv.remove_property(ss);
}
}
// Build the new position property
final_property = new String("position = (" +
pos.x + ", " + pos.y + ")");
// Insert the new position
pv.add_property(final_property);
}
/*
* Get the position of a InferenceGraphNode from the
* properties in the variable.
*/
private Point parse_position(ProbabilityVariable p_v) {
Vector properties = p_v.get_properties();
Point final_position = null;
String s, ss;
// get position values from the list of properties
if (properties.size() == 0)
return(new Point(100,100));
try {
for (Enumeration e = properties.elements(); e.hasMoreElements(); ) {
ss = (String) e.nextElement();
s = ss.trim();
// If property is not position, skip it
if (! s.startsWith("position"))
continue;
// Parse the position property
StreamTokenizer st =
new StreamTokenizer(new StringBufferInputStream(s));
st.parseNumbers();
int tok;
int x = -1, y = 0;
while ((tok = st.nextToken()) != st.TT_EOF) {
if (tok != st.TT_NUMBER)
continue;
if (x == -1)
x = (int) st.nval;
else {
y = (int) st.nval;
final_position = new Point(x, y);
}
}
break;
}
} catch (IOException e) {
final_position = new Point(100,100);
}
if (final_position == null)
final_position = new Point(100,100);
return(final_position);
}
/**
* Get a single value of the probability function in the
* node given a list of pairs (Variable Value). The list
* specifies which element of the function is referred to.
*/
public double get_function_value(String variable_value_pairs[][],
int index_extreme_point) {
if (pf instanceof VertexSet)
return(((VertexSet)pf).evaluate(variable_value_pairs, index_extreme_point));
else
return(pf.evaluate(variable_value_pairs));
}
/**
* Get an array containing probability values.
*/
public double[] get_function_values() {
if (pf instanceof VertexSet) {
double[][] ep = ((VertexSet)pf).get_extreme_points();
return(ep[0]);
}
else
return(pf.get_values());
}
/**
* Get an array containing probability values; if credal
* set, return the first extreme point.
*/
public double[] get_function_values(int index) {
if (pf instanceof VertexSet) {
double[][] ep = ((VertexSet)pf).get_extreme_points();
return(ep[index]);
}
else
return(pf.get_values());
}
/**
* Set an array containing probability values; if credal
* set, insert the array in the first extreme point.
*/
public void set_function_values(double[] fv) {
if (pf instanceof VertexSet)
((VertexSet)pf).set_extreme_point(0, fv);
else
pf.set_values(fv);
}
/**
* Set an array containing an extreme point of the credal
* set.
*/
public void set_function_values(int iep, double[] fv) {
if (pf instanceof VertexSet)
((VertexSet)pf).set_extreme_point(iep, fv);
else {
if (iep == 0)
pf.set_values(fv);
}
}
/**
* Get a single value of the probability function in
* the node given the index of the value and the
* index of the extreme point.
*/
// public double get_function_value(int index, int index_extreme_point) {
// if (pf instanceof VertexQBProbabilityFunction)
// return( ((VertexQBProbabilityFunction)pf).get_value(index, index_extreme_point) );
// else
// return(pf.get_value(index));
// }
/**
* Get a single value of the probability function in
* the node given the index of the value.
*/
// public double get_function_value(int index) {
// if (pf instanceof VertexQBProbabilityFunction)
// return( ((VertexQBProbabilityFunction)pf).get_value(index, 0) );
// else
// return(pf.get_value(index));
// }
/**
* Set a single value of the probability function in the
* node given a list of pairs (Variable Value). The list
* specifies which element of the function is referred to.
*/
public void set_function_value(String variable_value_pairs[][], double val,
int index_extreme_point) {
if (pf instanceof VertexSet)
((VertexSet)pf).set_value(variable_value_pairs, val, index_extreme_point);
else
pf.set_value(variable_value_pairs, val);
}
/* ******************** Public methods ******************** */
/**
* Return the name of the variable in the node.
*/
public String get_name() {
return(pv.get_name());
}
/**
* Set the name of the variable.
*/
public void set_name(String n) {
pv.set_name(n);
}
/**
* Get the name of all variables in the probability function.
*/
public String[] get_all_names() {
String[] ns = new String[pf.number_variables()];
for (int i=0; i<ns.length; i++)
ns[i] = pf.get_variable(i).get_name();
return(ns);
}
/**
* Return the values of the variable in the node.
*/
public String[] get_values() {
return(pv.get_values());
}
/**
* Get all values for variables in the function in the node.
*/
public String[][] get_all_values() {
int i, j;
String all_values[][] = new String[pf.number_variables()][];
DiscreteVariable dv;
for (i=0; i<pf.number_variables(); i++) {
dv = pf.get_variable(i);
all_values[i] = new String[dv.number_values()];
for (j=0; j<all_values[i].length; j++) {
all_values[i][j] = dv.get_value(j);
}
}
return(all_values);
}
/**
* Return the number of values in the variable in the node.
*/
public int get_number_values() {
return(pv.number_values());
}
/**
* Indicate whether the node has parents.
*/
public boolean hasParent() {
return(pf.number_variables() > 1);
}
/**
* Return the parents of a node as an Enumeration object.
*/
public Vector get_parents() {
return(parents);
}
/**
* Return the children of a node as an Enumeration object.
*/
public Vector get_children() {
return(children);
}
/**
* Indicate whether the variable in the node is observed.
*/
public boolean is_observed() {
return(pv.is_observed());
}
/**
* Indicate whether the variable in the node is an explanatory variable.
*/
public boolean is_explanation() {
return(pv.is_explanation());
}
/**
* Return the observed value for the variable in the node.
*/
public int get_observed_value() {
return(pv.get_observed_index());
}
/**
* Return the X position of the node.
*/
public int get_pos_x() {
return(pos.x);
}
/**
* Return the Y position of the node.
*/
public int get_pos_y() {
return(pos.y);
}
/**
* Return the variable properties
*/
public Vector get_variable_properties() {
return(pv.get_properties());
}
/**
* Set the variable properties.
*/
public void set_variable_properties(Vector prop) {
pv.set_properties(prop);
}
/**
* Return the function properties.
*/
public Vector get_function_properties() {
return(pf.get_properties());
}
/**
* Set the function properties.
*/
public void set_function_properties(Vector prop) {
pf.set_properties(prop);
}
/**
* Whether or not the node represents a convex set of distributions (credal set).
*/
public boolean is_credal_set() {
if (pf instanceof QBProbabilityFunction)
return(true);
else
return(false);
}
/**
* Number of distributions that are represented by a node.
*/
public int number_extreme_distributions() {
if (pf instanceof VertexSet)
return( ((VertexSet)pf).get_extreme_points().length );
else
return(1);
}
/**
* Make sure the node represents a single distribution.
*/
public void set_no_local_credal_set() {
if (pf instanceof QBProbabilityFunction) {
if (pf instanceof VertexSet)
((VertexSet)pf).compose_values();
pf = new ProbabilityFunction(pf, pf.get_values());
}
}
/**
* Make sure the node represents a VertexSet
* a given number of extreme distributions.
*/
public void set_local_credal_set(int number_extreme_points) {
if (!(pf instanceof VertexSet)) {
pf = new VertexSet(pf);
}
((VertexSet)pf).set_local_credal_set(number_extreme_points);
}
/**
* Make sure the node represents a VertexSet.
*/
public void set_local_credal_set() {
if (!(pf instanceof VertexSet)) {
pf = new VertexSet(pf);
}
}
/**
* Set the observation for the node.
*/
public void set_observation_value(String value) {
pv.set_observed_value(value);
}
/**
* Clear the observation for the node.
*/
public void clear_observation() {
pv.set_invalid_observed_index();
}
/**
* Set the explanatory status of the node.
*/
public void set_explanation(boolean flag) {
if (flag == true)
pv.set_explanation_value(0);
else
pv.set_explanation_value(BayesNet.INVALID_INDEX);
}
/**
* Remove a property from a variable.
*/
public void remove_variable_property(int index) {
pv.remove_property(index);
}
/**
* Remove a property from a function.
*/
public void remove_function_property(int index) {
pf.remove_property(index);
}
/**
* Add a property to a variable.
*/
public void add_variable_property(String s) {
pv.add_property(s);
update_position_from_property(s);
}
/*
* Update the position of a node given a property.
*/
public void update_position_from_property(String s) {
// If property is position:
if (s.startsWith("position")) {
Point final_position = null;
// Parse the position property
try {
StreamTokenizer st =
new StreamTokenizer(new StringBufferInputStream(s));
st.parseNumbers();
int tok;
int x = -1, y = 0;
while ((tok = st.nextToken()) != st.TT_EOF) {
if (tok != st.TT_NUMBER)
continue;
if (x == -1)
x = (int) st.nval;
else {
y = (int) st.nval;
final_position = new Point(x, y);
}
}
} catch (IOException e) {
final_position = new Point(100,100);
}
if (final_position == null)
final_position = new Point(100,100);
// Update the position property.
pos = final_position;
}
}
/**
* Add a property from to function.
*/
public void add_function_property(String prop) {
pf.add_property(prop);
}
}