File size: 4,802 Bytes
158b61b |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 |
#include "Cube.h"
#include "moses/FF/FFState.h"
#include "moses/FF/StatefulFeatureFunction.h"
#include "moses/FF/StatelessFeatureFunction.h"
#include "moses/StaticData.h"
#include "SVertex.h"
namespace Moses
{
namespace Syntax
{
Cube::Cube(const SHyperedgeBundle &bundle)
: m_bundle(bundle)
{
// Create the SHyperedge for the 'corner' of the cube.
std::vector<int> coordinates(bundle.stacks.size()+1, 0);
SHyperedge *hyperedge = CreateHyperedge(coordinates);
// Add its coordinates to the set of visited coordinates.
std::pair<CoordinateSet::iterator, bool> p = m_visited.insert(coordinates);
const std::vector<int> &storedCoordinates = *p.first;
// Add the SHyperedge to the queue along with its coordinates (which will be
// needed for creating its neighbours).
m_queue.push(QueueItem(hyperedge, &storedCoordinates));
}
Cube::~Cube()
{
// Delete the SHyperedges belonging to any unpopped items. Note that the
// coordinate vectors are not deleted here since they are owned by m_visited
// (and so will be deleted by its destructor).
while (!m_queue.empty()) {
QueueItem item = m_queue.top();
m_queue.pop();
// Delete hyperedge and its head (head deletes hyperedge).
delete item.first->head; // TODO shared ownership of head vertex?
}
}
SHyperedge *Cube::Pop()
{
QueueItem item = m_queue.top();
m_queue.pop();
CreateNeighbours(*item.second);
return item.first;
}
void Cube::CreateNeighbours(const std::vector<int> &coordinates)
{
// Create a copy of the origin coordinates that will be adjusted for
// each neighbour.
std::vector<int> tmpCoordinates(coordinates);
// Create each neighbour along the vertex stack dimensions.
for (std::size_t i = 0; i < coordinates.size()-1; ++i) {
const std::size_t x = coordinates[i];
if (m_bundle.stacks[i]->size() > x+1) {
++tmpCoordinates[i];
CreateNeighbour(tmpCoordinates);
--tmpCoordinates[i];
}
}
// Create the neighbour along the translation dimension.
const std::size_t x = coordinates.back();
if (m_bundle.translations->GetSize() > x+1) {
++tmpCoordinates.back();
CreateNeighbour(tmpCoordinates);
--tmpCoordinates.back();
}
}
void Cube::CreateNeighbour(const std::vector<int> &coordinates)
{
// Add the coordinates to the set of visited coordinates if not already
// present.
std::pair<CoordinateSet::iterator, bool> p = m_visited.insert(coordinates);
if (!p.second) {
// We have visited this neighbour before, so there is nothing to do.
return;
}
SHyperedge *hyperedge = CreateHyperedge(coordinates);
const std::vector<int> &storedCoordinates = *p.first;
m_queue.push(QueueItem(hyperedge, &storedCoordinates));
}
SHyperedge *Cube::CreateHyperedge(const std::vector<int> &coordinates)
{
SHyperedge *hyperedge = new SHyperedge();
SVertex *head = new SVertex();
head->best = hyperedge;
head->pvertex = 0; // FIXME???
head->states.resize(
StatefulFeatureFunction::GetStatefulFeatureFunctions().size());
hyperedge->head = head;
hyperedge->tail.resize(coordinates.size()-1);
for (std::size_t i = 0; i < coordinates.size()-1; ++i) {
boost::shared_ptr<SVertex> pred = (*m_bundle.stacks[i])[coordinates[i]];
hyperedge->tail[i] = pred.get();
}
hyperedge->label.inputWeight = m_bundle.inputWeight;
hyperedge->label.translation =
*(m_bundle.translations->begin()+coordinates.back());
// Calculate feature deltas.
const StaticData &staticData = StaticData::Instance();
// compute values of stateless feature functions that were not
// cached in the translation option-- there is no principled distinction
const std::vector<const StatelessFeatureFunction*>& sfs =
StatelessFeatureFunction::GetStatelessFeatureFunctions();
for (unsigned i = 0; i < sfs.size(); ++i) {
if (!staticData.IsFeatureFunctionIgnored(*sfs[i])) {
sfs[i]->EvaluateWhenApplied(*hyperedge, &hyperedge->label.deltas);
}
}
const std::vector<const StatefulFeatureFunction*>& ffs =
StatefulFeatureFunction::GetStatefulFeatureFunctions();
for (unsigned i = 0; i < ffs.size(); ++i) {
if (!staticData.IsFeatureFunctionIgnored(*ffs[i])) {
head->states[i] =
ffs[i]->EvaluateWhenApplied(*hyperedge, i, &hyperedge->label.deltas);
}
}
// Calculate future score.
hyperedge->label.futureScore =
hyperedge->label.translation->GetScoreBreakdown().GetWeightedScore();
hyperedge->label.futureScore += hyperedge->label.deltas.GetWeightedScore();
for (std::vector<SVertex*>::const_iterator p = hyperedge->tail.begin();
p != hyperedge->tail.end(); ++p) {
const SVertex *pred = *p;
if (pred->best) {
hyperedge->label.futureScore += pred->best->label.futureScore;
}
}
return hyperedge;
}
} // Syntax
} // Moses
|