// Copyright 2014 Thomas Müller
// This file is part of HMMLA, which is licensed under GPLv3.
package hmmla.splitmerge;
import hmmla.hmm.Model;
import hmmla.io.Token;
import hmmla.util.Numerics;
import java.util.Iterator;
import java.util.List;
public class BackwardChart extends ForwardChart {
@Override
public synchronized void update(Iterable<Iterable<Integer>> tags,
List<Token> outputs) {
T = outputs.size() + 1;
if (T == 0) {
return;
}
if (T > maxT) {
a = new double[T][N];
maxT = T;
}
for (int t = 0; t < T; t++) {
for (int i = 0; i < N; i++) {
a[t][i] = Double.NEGATIVE_INFINITY;
}
}
Iterator<Iterable<Integer>> iterator = tags.iterator();
assert iterator.hasNext();
Iterable<Integer> last_tags = iterator.next();
double[] scores = new double[N];
for (Integer i : last_tags) {
a[T - 1][i] = _score(i, Model.BorderIndex);
}
int t = T - 2;
while (iterator.hasNext()) {
Iterable<Integer> current_tags = iterator.next();
_score(outputs, t, scores);
for (Integer i : current_tags) {
for (Integer j : last_tags) {
double score = scores[j] + a[t + 1][j] + _score(i, j);
a[t][i] = Numerics.sumLogProb(a[t][i], score);
}
}
last_tags = current_tags;
t--;
}
assert t == 0;
_score(outputs, t, scores);
for (Integer j : last_tags) {
a[t][Model.BorderIndex] = Numerics.sumLogProb(a[t][Model.BorderIndex], scores[j] + _score(Model.BorderIndex, j));
}
}
@Override
public synchronized double score(int t, int tag) {
return a[t + 1][tag];
}
@Override
public synchronized double score() {
return score(-1, Model.BorderIndex);
}
}