/**
* VertexSet.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 CredalSets;
import BayesianNetworks.*;
import java.io.*;
import java.util.Vector;
import java.util.Enumeration;
public class VertexSet
extends FinitelyGeneratedSet {
// Variable that indicates which extreme point is active
ProbabilityVariable auxiliary_variable;
// The set of extreme points; the first coordinate indexes
// a set of double[] arrays (each array contains the values
// for an extreme point).
double extreme_points[][];
/**
* Default constructor for a VertexQBProbabilityFunction.
*/
public VertexSet(BayesNet b_n, ProbabilityVariable pvs[],
double ep[][], Vector prop) {
// Call the super constructor with ep[0].
super(b_n, pvs, ep[0], prop);
// Now replace ep[0] with a new array to avoid wrong
// cross-references among arrays.
double[] vals = new double[ep[0].length];
values = vals;
// Update the extreme_points and the values.
extreme_points = ep;
compose_values();
}
/**
* Constructor for a VertexQBProbabilityFunction.
*/
public VertexSet(BayesNet b_n, ProbabilityVariable pvs[],
double v[], Vector prop, double ep[][]) {
super(b_n, pvs, v, (double[])null, (double[])null, prop);
extreme_points = ep;
}
/**
* Constructor for a VertexQBProbabilityFunction.
*/
public VertexSet(ProbabilityFunction pf) {
super(pf, pf.get_values());
if (pf instanceof VertexSet)
extreme_points = ((VertexSet)pf).extreme_points;
else {
extreme_points = new double[1][];
extreme_points[0] = pf.get_values();
}
}
/**
* Constructor for a VertexQBProbabilityFunction from a
* ProbabilityFunction object and new values.
*/
public VertexSet(ProbabilityFunction pf, double new_values[]) {
super(pf, new_values);
if (pf instanceof VertexSet) {
extreme_points = ((VertexSet)pf).extreme_points;
auxiliary_variable = ((VertexSet)pf).auxiliary_variable;
}
else {
extreme_points = new double[1][];
extreme_points[0] = pf.get_values();
}
}
/**
* Put together all the values for the possible vertices of
* credal set and create an auxiliary variable to indicate
* which vertex to consider
* There are three things to do:
* 1) Create an auxiliary_variable with correct values.
* 2) Combine the values into a new array.
* 3) Insert the auxiliary_variable into the variables array.
*/
public VertexSet prepare_auxiliary_variable(BayesNet transformed_bn) {
int i;
double new_values[];
// Assume that values and auxiliary_variable are correct if
// auxiliary_variable is non null (cannot happen in current version)
if (auxiliary_variable != null) return(this);
// Create the auxiliary variable for this credal set
ProbabilityVariable auxv = create_auxiliary_variable(transformed_bn);
// Create the new values for the credal set with auxiliary_variable
new_values = create_new_values(transformed_bn);
// Now insert the auxiliary_variable in the variables array
DiscreteVariable new_variables[] =
new DiscreteVariable[ variables.length + 1 ];
for (i=0; i<variables.length; i++)
new_variables[i] = variables[i];
new_variables[i] = auxv;
// Use the new_values array to create a new
// VertexQBProbabilityFunction that incorporates the auxiliary_variable
VertexSet new_qbpf = new VertexSet(this, new_values);
new_qbpf.bn = transformed_bn;
new_qbpf.auxiliary_variable = auxv;
new_qbpf.variables = new_variables;
return(new_qbpf);
}
/**
* Create a new array of values that combines extreme points.
*/
private double[] create_new_values(BayesNet transformed_bn) {
int i, j;
// Combine vertices and the auxiliary_variable and create new values
double new_values[] =
new double[ extreme_points.length * values.length ];
for (i=0; i<values.length; i++) {
for (j=0; j<extreme_points.length; j++) {
new_values[j + i*extreme_points.length] =
extreme_points[j][i];
}
}
return(new_values);
}
/**
* Create an auxiliar variable to indicate the vertices.
*/
private ProbabilityVariable
create_auxiliary_variable(BayesNet transformed_bn) {
int i,j;
// Compose the name of the auxiliary variable
StringBuffer buffer_auxiliary_variable_name =
new StringBuffer("<Transparent:");
buffer_auxiliary_variable_name.append(variables[0].get_name());
buffer_auxiliary_variable_name.append(">");
String auxiliary_variable_name =
new String(buffer_auxiliary_variable_name);
// Compose the values of the auxiliary variable
String auxiliary_variable_values[] = new String[ extreme_points.length ];
for (i=0; i<auxiliary_variable_values.length; i++)
auxiliary_variable_values[i] = String.valueOf(i);
// Create the auxiliary variable
ProbabilityVariable auxv =
new ProbabilityVariable(transformed_bn, auxiliary_variable_name,
BayesNet.INVALID_INDEX,
auxiliary_variable_values, ((Vector)null));
// Mark the auxiliary variable as auxiliary
auxv.set_type(ProbabilityVariable.TRANSPARENT);
// Return the created auxiliary variable
return(auxv);
}
/**
* Evaluate a function given a list of pairs (Variable Value)
* which specifies a value of the function, and the index
* of the extreme distribution to consider.
*/
public double evaluate(String variable_value_pairs[][],
int index_extreme_point) {
int index;
ProbabilityVariable pv;
// Initialize with zeros an array of markers.
int value_indexes[] = new int[bn.number_variables()];
// 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.get_probability_variable(index);
value_indexes[index] = pv.index_of_value(variable_value_pairs[i][1]);
}
// Now evaluate
int position = get_position_from_indexes(bn.get_probability_variables(),
value_indexes);
return(extreme_points[index_extreme_point][position]);
}
/**
* Set a single value of the probability function.
*/
public void set_value(String variable_value_pairs[][], double val,
int index_extreme_point) {
int index;
ProbabilityVariable pv;
// Initialize with zeros an array of markers.
int value_indexes[] = new int[bn.number_variables()];
// 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.get_probability_variable(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.get_probability_variables(),
value_indexes);
// Set the value.
extreme_points[index_extreme_point][pos] = val;
compose_values();
}
/**
* Print method.
*/
public void print(PrintStream out) {
int i, j;
String property;
if (variables != null) {
out.print("probability ( ");
for (j=0; j<variables.length; j++) {
out.print(" \"" + variables[j].get_name() + "\" ");
}
out.print(") {");
out.println(" //" + variables.length +
" variable(s) and " + values.length + " values");
if (extreme_points != null) {
for (i=0; i<extreme_points.length; i++) {
out.print("\ttable ");
for (j=0; j<extreme_points[i].length; j++)
out.print(extreme_points[i][j] + " ");
out.println(";");
}
out.print(" // Values: ");
}
out.print("\ttable ");
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("}");
}
/**
* Produce the centroid of all extreme distributions and
* insert it into the values of the distribution.
*/
public void compose_values() {
double aux, n;
if (extreme_points == null)
return;
n = (double)(extreme_points.length);
for (int i=0; i<values.length; i++) {
aux = 0.0;
for (int j=0; j<extreme_points.length; j++)
aux += extreme_points[j][i];
values[i] = aux/n;
}
}
/**
* Set the number of extreme distributions in the credal set.
*/
public void set_local_credal_set(int number_extreme_points) {
int i, j, k;
int number_current_extreme_points;
double new_extreme_points[][];
// Update the values in case some extreme distributions
// have changed.
compose_values();
if (extreme_points == null)
number_current_extreme_points = 0;
else {
number_current_extreme_points = extreme_points.length;
// If the new size is equal to current size, return.
if (number_extreme_points == number_current_extreme_points)
return;
}
// Allocate the new extreme distributions.
new_extreme_points = new double[number_extreme_points][values.length];
// If the new size is larger than the current size.
if (number_extreme_points > number_current_extreme_points) {
// First copy what is already there.
for (i=0; i<number_current_extreme_points; i++) {
for (j=0; j<extreme_points[i].length; j++) {
new_extreme_points[i][j] = extreme_points[i][j];
}
}
// Then fill with copies of values.
for (k=i; k<new_extreme_points.length; k++) {
for (j=0; j<values.length; j++) {
new_extreme_points[k][j] = values[j];
}
}
}
else {
// If the new size is smaller than the current size.
for (i=0; i<new_extreme_points.length; i++) {
for (j=0; j<values.length; j++) {
new_extreme_points[i][j] = extreme_points[i][j];
}
}
}
extreme_points = new_extreme_points;
}
/**
* Set an extreme point of the credal set.
*/
public void set_extreme_point(int index, double ep[]) {
extreme_points[index] = ep;
}
/**
* Methods that allow basic manipulation of non-public variables.
*/
public ProbabilityVariable get_auxiliary_variable() {
return(auxiliary_variable);
}
public double[][] get_extreme_points() {
return(extreme_points);
}
}