/**
* ProbabilityFunction.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 BayesianNetworks;
import java.io.PrintStream;
import java.util.Vector;
import java.util.Enumeration;
/*******************************************************************/
public class ProbabilityFunction extends DiscreteFunction {
protected Vector properties;
protected BayesNet bn;
/**
* Default constructor for a ProbabilityFunction.
*/
public ProbabilityFunction() {
}
/**
* Constructor for ProbabilityFunction.
*/
public ProbabilityFunction(BayesNet b_n, int n_vb, int n_vl, Vector prop) {
super(n_vb, n_vl);
properties = prop;
bn = b_n;
}
/**
* Constructor for ProbabilityFunction.
*/
public ProbabilityFunction(BayesNet b_n, DiscreteVariable pvs[],
double v[], Vector prop) {
super(pvs, v);
properties = prop;
bn = b_n;
}
/**
* Constructor for ProbabilityFunction.
*/
public ProbabilityFunction(DiscreteFunction df, double[] new_values) {
super(df.variables, new_values);
if (df instanceof ProbabilityFunction) {
bn = ((ProbabilityFunction)df).bn;
properties = ((ProbabilityFunction)df).properties;
}
}
/**
* Constructor for ProbabilityFunction.
*/
public ProbabilityFunction(DiscreteFunction df, BayesNet b_n) {
super(df.variables, df.values);
bn = b_n;
if (df instanceof ProbabilityFunction)
properties = ((ProbabilityFunction)df).properties;
}
/* ************************************************************* */
/* Method that processes the properties */
/* ************************************************************* */
void process_properties() { }
/**
* Set a single value of the probability function.
*/
public void set_value(String variable_value_pairs[][], double val) {
int index;
ProbabilityVariable pv;
// Initialize with zeros an array of markers.
int value_indexes[] = new int[bn.probability_variables.length];
// Fill the array of markers.
for (int i=0; i<variable_value_pairs.length; i++) {
index = bn.index_of_variable(variable_value_pairs[i][0]);
pv = bn.probability_variables[index];
value_indexes[index] = pv.index_of_value(variable_value_pairs[i][1]);
}
// Get the position of the value in the array of values
int pos = get_position_from_indexes(bn.probability_variables,
value_indexes);
// Set the value.
values[pos] = val;
}
/**
* Evaluate a function given a list of pairs (Variable Value)
* which specifies a value of the function.
*/
public double evaluate(String variable_value_pairs[][]) {
int index;
ProbabilityVariable pv;
// Initialize with zeros an array of markers.
int value_indexes[] = new int[bn.probability_variables.length];
// Fill the array of markers.
for (int i=0; i<variable_value_pairs.length; i++) {
index = bn.index_of_variable(variable_value_pairs[i][0]);
pv = bn.probability_variables[index];
value_indexes[index] = pv.index_of_value(variable_value_pairs[i][1]);
}
// Now evaluate
return(evaluate(value_indexes));
}
/**
* Evaluate a function given a (possibly
* partial) instantiation of variables through the markers.
* The markers indicate which variables are present in the
* function to be evaluated.
*/
public double evaluate(int value_indexes[]) {
return(super.evaluate(bn.probability_variables, value_indexes));
}
/**
* Get position in a function from a (possibly
* partial) instantiation of variables through the indexes.
*/
public int get_position_from_indexes(int variable_indexes[]) {
return(super.get_position_from_indexes(bn.probability_variables,
variable_indexes));
}
/**
* Obtain expected value of a DiscreteFunction
* The current implementation is very limited; it assumes that
* both the ProbabilityFunction object and the
* DiscreteFunctions object has a single variable, and the
* variable must be the same for both functions.
*/
public double expected_value(DiscreteFunction df) {
double ev = 0.0;
for (int i=0; i<df.values.length; i++)
ev += values[i] * df.values[i];
return(ev);
}
/**
* Obtain posterior expected value of a DiscreteFunction
* This assumes that the probability values are unnormalized,
* equal to p(x, e) where e is the evidence.
* The current implementation is very limited; it assumes that
* both the ProbabilityFunction object and the
* DiscreteFunctions object has a single variable, and the
* variable must be the same for both functions.
*/
public double posterior_expected_value(DiscreteFunction df) {
double ev = 0.0;
double p = 0.0;
for (int i=0; i<df.values.length; i++) {
p += values[i];
ev += values[i] * df.values[i];
}
return(ev/p);
}
/**
* Calculate the variance of a DiscreteFunction.
* The current implementation is very limited; it assumes that
* both the ProbabilityFunction object and the
* DiscreteFunctions object has a single variable, and the
* variable must be the same for both functions.
*/
public double variance(DiscreteFunction df) {
double aux, ev=0.0, evv=0.0;
for (int i=0; i<df.values.length; i++) {
aux = values[i] * df.values[i];
ev += aux;
evv = df.values[i] * aux;
}
return(evv - ev * ev);
}
/**
* Save the contents of a ProbabilityFunction object into a PrintStream
* in the XMLBIF v0.3 format.
*/
public void save_xml_0_3(PrintStream out) {
int i, j, size_of_first = 0, size_of_others = 1;
String property;
out.println("<DEFINITION>");
if (variables != null) {
out.println("\t<FOR>" + variables[0].name + "</FOR>");
for (j=1; j<variables.length; j++) {
out.println("\t<GIVEN>" + variables[j].name + "</GIVEN>");
}
out.print("\t<TABLE>");
if (variables.length > 1) { // Necessary to invert variables.
size_of_first = variables[0].number_values();
for (j=1; j<variables.length; j++)
size_of_others *= variables[j].number_values();
for (i=0; i<size_of_others; i++)
for (j=0; j<size_of_first; j++)
out.print(values[j*size_of_others + i] + " ");
}
else { // Not necessary to invert variables.
for (j=0; j<values.length; j++)
out.print(values[j] + " ");
}
out.println("</TABLE>");
}
if ((properties != null) && (properties.size() > 0)) {
for (Enumeration e = properties.elements(); e.hasMoreElements(); ) {
property = (String)(e.nextElement());
out.println("\t<PROPERTY>" + property + "</PROPERTY>");
}
}
out.println("</DEFINITION>\n");
}
/**
* Save the contents of a ProbabilityFunction object into a PrintStream.
*/
public void save_xml(PrintStream out) {
int j;
String property;
out.println("<PROBABILITY>");
if (variables != null) {
out.println("\t<FOR>" + variables[0].name + "</FOR>");
for (j=1; j<variables.length; j++) {
out.println("\t<GIVEN>" + variables[j].name + "</GIVEN>");
}
out.print("\t<TABLE>");
for (j=0; j<values.length; j++)
out.print(values[j] + " ");
out.println("</TABLE>");
}
if ((properties != null) && (properties.size() > 0)) {
for (Enumeration e = properties.elements(); e.hasMoreElements(); ) {
property = (String)(e.nextElement());
out.println("\t<PROPERTY>" + property + "</PROPERTY>");
}
}
out.println("</PROBABILITY>\n");
}
/**
* Print method.
*/
public void print(PrintStream out) {
int j;
String property;
if (variables != null) {
out.print("probability ( ");
for (j=0; j<variables.length; j++) {
out.print( " \"" + variables[j].name + "\" ");
}
out.print(") {");
out.println(" //" + variables.length +
" variable(s) and " + values.length + " values");
out.println("\ttable ");
if (variables.length == 1) {
for (j=0; j<values.length; j++) {
out.print("\t\t" + values[j]);
if (j == (values.length-1))
out.print("; ");
out.print("\t// p(" + variables[0].values[j] + " | evidence )");
if (j != (values.length - 1))
out.println();
}
} else {
out.print("\t\t");
for (j=0; j<values.length; j++)
out.print(" " + values[j]);
}
out.print(";");
}
out.println();
if ((properties != null) && (properties.size() > 0)) {
for (Enumeration e = properties.elements(); e.hasMoreElements(); ) {
property = (String)(e.nextElement());
out.println("\tproperty \"" + property + "\" ;");
}
}
out.println("}");
}
/* *************************************************************** */
/* Methods that allow basic manipulation of non-public variables */
/* *************************************************************** */
/**
* Get the properties of the current ProbabilityFunction.
*/
public Vector get_properties() {
return(properties);
}
/**
* Set the properties.
*/
public void set_properties(Vector prop) {
properties = prop;
}
/**
* Get an Enumeration with the properties of the current ProbabilityFunction.
*/
public Enumeration get_enumerated_properties() {
return(properties.elements());
}
/**
* Add a property to the current ProbabilityFunction.
*/
public void add_property(String prop) {
if (properties == null)
properties = new Vector();
properties.addElement(prop);
}
/**
* Remove a property in the current ProbabilityFunction.
*/
public void remove_property(String prop) {
if (properties == null) return;
properties.removeElement(prop);
}
/**
* Remove a property in a given position in the current ProbabilityFunction.
* @param i Position of the property.
*/
public void remove_property(int i) {
if (properties == null) return;
properties.removeElementAt(i);
}
}