package edu.stanford.nlp.sequences;
import edu.stanford.nlp.math.ArrayMath;
/**
* @author grenager
* Date: Dec 14, 2004
*/
public class FactoredSequenceModel implements SequenceModel {
SequenceModel model1;
SequenceModel model2;
/**
* Computes the distribution over values of the element at position pos in the sequence,
* conditioned on the values of the elements in all other positions of the provided sequence.
*
* @param sequence the sequence containing the rest of the values to condition on
* @param pos the position of the element to give a distribution for
* @return an array of type double, representing a probability distribution; must sum to 1.0
*/
public double[] scoresOf(int[] sequence, int pos) {
double[] dist1 = model1.scoresOf(sequence, pos);
double[] dist2 = model2.scoresOf(sequence, pos);
double[] dist = ArrayMath.pairwiseAdd(dist1, dist2);
// if (pos > 0 && pos < sequence.length - 1) {
// System.err.println("position: "+pos+" ["+sequence[pos-1]+","+sequence[pos]+","+sequence[pos+1]+"]");
// System.err.println(java.util.Arrays.toString(sequence));
// for (int i = 0; i < dist.length; i++) {
// System.err.println(i+": "+dist1[i]+" "+dist2[i]+" "+dist[i]);
// }
// System.err.println();
// }
return dist;
}
public double scoreOf(int[] sequence, int pos) {
return scoresOf(sequence, pos)[sequence[pos]];
}
/**
* Computes the score assigned by this model to the provided sequence. Typically this will be a
* probability in log space (since the probabilities are small).
*
* @param sequence the sequence to compute a score for
* @return the score for the sequence
*/
public double scoreOf(int[] sequence) {
return model1.scoreOf(sequence) + model2.scoreOf(sequence);
}
/**
* @return the length of the sequence
*/
public int length() {
return model1.length();
}
public int leftWindow() {
return model1.leftWindow();
}
public int rightWindow() {
return 0; //To change body of implemented methods use File | Settings | File Templates.
}
public int[] getPossibleValues(int position) {
return model1.getPossibleValues(position);
}
public FactoredSequenceModel(SequenceModel model1, SequenceModel model2) {
//if (model1.leftWindow() != model2.leftWindow()) throw new RuntimeException("Two models must have same window size");
if (model1.getPossibleValues(0).length != model2.getPossibleValues(0).length) throw new RuntimeException("Two models must have the same number of classes");
if (model1.length() != model2.length()) throw new RuntimeException("Two models must have the same sequence length");
this.model1 = model1;
this.model2 = model2;
}
}