package experimental.ising; import java.util.ArrayList; import java.util.Arrays; import java.util.LinkedList; import java.util.List; public class BinaryFactor extends Factor { private int size1; private int size2; protected double[][] potential; protected double[][] factorBelief; private List<Integer> features; // first variable id private int i; // second variable id private int j; public BinaryFactor(int size1, int size2, int i, int j) { this.setSize1(size1); this.setSize2(size2); this.setPotential(new double[this.size1][this.size2]); this.setFactorBelief(new double[this.size1][this.size2]); this.setFeatures(new LinkedList<Integer>()); for (int n = 0; n < this.size1; ++n) { for (int m = 0; m < this.size2; ++m) { this.potential[n][m] = 1.0; } } this.setI(i); this.setJ(j); this.setNeighbors(new ArrayList<Variable>()); this.setMessageIds(new ArrayList<Integer>()); this.setMessages(new ArrayList<Message>()); for (int one = 0; one < this.size1; ++one) { for (int two = 0; two< this.size2; ++two) { this.potential[one][two] = 1.0; } } } /** * Computes the belief at the factor - necessary * for computation of the Bethe free energy */ @Override public void computeFactorBelief() { Message m1_in = this.neighbors.get(0).getMessages().get(this.messageIds.get(0)); Message m2_in = this.neighbors.get(1).getMessages().get(this.messageIds.get(1)); double Z = 0.0; for (int i = 0; i < this.size1; ++i) { for (int j = 0; j < this.size2; ++j) { this.factorBelief[i][j] = this.potential[i][j] * m1_in.measure[i] * m2_in.measure[j]; Z += this.factorBelief[i][j] ; } } for (int i = 0; i < this.size1; ++i) { for (int j = 0; j < this.size2; ++j) { this.factorBelief[i][j] /= Z; } } } @Override public void passMessage() { // outgoing messages Message m1_out = this.messages.get(0); Message m2_out = this.messages.get(1); // incoming messages Message m1_in = this.neighbors.get(0).getMessages().get(this.messageIds.get(0)); Message m2_in = this.neighbors.get(1).getMessages().get(this.messageIds.get(1)); // zero out m1_out.toZeros(); m2_out.toZeros(); // pass messages for (int n = 0; n < this.size1; ++n) { for (int m = 0; m < this.size2; ++m) { m2_out.measure[m] += this.potential[n][m] * m1_in.measure[n]; m1_out.measure[n] += this.potential[n][m] * m2_in.measure[m]; } } } @Override public void renormalize() { double Z = 0.0; for (int i = 0; i < this.size1; ++i) { for (int j = 0; j < this.size2; ++j) { Z += this.potential[i][j]; } } System.out.println(Arrays.deepToString(this.potential)); for (int i = 0; i < this.size1; ++i) { for (int j = 0; j < this.size2; ++j) { this.potential[i][j] /= Z; } } System.out.println(Arrays.deepToString(this.potential)); } public int getI() { return i; } public void setI(int i) { this.i = i; } public int getJ() { return j; } public void setJ(int j) { this.j = j; } public int getSize1() { return size1; } public void setSize1(int size1) { this.size1 = size1; } public int getSize2() { return size2; } public void setSize2(int size2) { this.size2 = size2; } public double[][] getPotential() { return potential; } public void setPotential(double[][] potential) { this.potential = potential; } public void setPotential(int n, int m, double value) { this.potential[n][m] = value; } public void setFactorBelief(double[][] factorBelief) { this.factorBelief = factorBelief; } public List<Integer> getFeatures() { return features; } public void setFeatures(List<Integer> features) { this.features = features; } }