|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#include <algorithm> |
|
#include <iostream> |
|
#include <vector> |
|
#include "StaticData.h" |
|
#include "ChartTranslationOptionList.h" |
|
#include "ChartTranslationOptions.h" |
|
#include "ChartCellCollection.h" |
|
#include "Range.h" |
|
#include "InputType.h" |
|
#include "InputPath.h" |
|
|
|
using namespace std; |
|
|
|
namespace Moses |
|
{ |
|
|
|
ChartTranslationOptionList:: |
|
ChartTranslationOptionList(size_t ruleLimit, const InputType &input) |
|
: m_size(0) |
|
, m_ruleLimit(ruleLimit) |
|
{ |
|
m_scoreThreshold = std::numeric_limits<float>::infinity(); |
|
} |
|
|
|
ChartTranslationOptionList::~ChartTranslationOptionList() |
|
{ |
|
RemoveAllInColl(m_collection); |
|
} |
|
|
|
void ChartTranslationOptionList::Clear() |
|
{ |
|
m_size = 0; |
|
m_scoreThreshold = std::numeric_limits<float>::infinity(); |
|
} |
|
|
|
class ChartTranslationOptionOrderer |
|
{ |
|
public: |
|
bool operator()(const ChartTranslationOptions* itemA, const ChartTranslationOptions* itemB) const { |
|
return itemA->GetEstimateOfBestScore() > itemB->GetEstimateOfBestScore(); |
|
} |
|
}; |
|
|
|
void ChartTranslationOptionList::Add(const TargetPhraseCollection &tpc, |
|
const StackVec &stackVec, |
|
const Range &range) |
|
{ |
|
if (tpc.IsEmpty()) { |
|
return; |
|
} |
|
|
|
for (size_t i = 0; i < stackVec.size(); ++i) { |
|
const ChartCellLabel &chartCellLabel = *stackVec[i]; |
|
size_t numHypos = chartCellLabel.GetStack().cube->size(); |
|
if (numHypos == 0) { |
|
return; |
|
} |
|
} |
|
|
|
const TargetPhrase &targetPhrase = **(tpc.begin()); |
|
float score = targetPhrase.GetFutureScore(); |
|
for (StackVec::const_iterator p = stackVec.begin(); p != stackVec.end(); ++p) { |
|
score += (*p)->GetBestScore(this); |
|
} |
|
|
|
|
|
|
|
if (m_ruleLimit && m_size > m_ruleLimit && score < m_scoreThreshold) { |
|
return; |
|
} |
|
|
|
|
|
if (m_size == m_collection.size()) { |
|
|
|
m_collection.push_back(new ChartTranslationOptions(tpc, stackVec, |
|
range, score)); |
|
} else { |
|
|
|
*(m_collection[m_size]) = ChartTranslationOptions(tpc, stackVec, |
|
range, score); |
|
} |
|
++m_size; |
|
|
|
|
|
if (!m_ruleLimit || m_size <= m_ruleLimit) { |
|
m_scoreThreshold = (score < m_scoreThreshold) ? score : m_scoreThreshold; |
|
} |
|
|
|
|
|
if (m_ruleLimit && m_size == m_ruleLimit * 2) { |
|
NTH_ELEMENT4(m_collection.begin(), |
|
m_collection.begin() + m_ruleLimit - 1, |
|
m_collection.begin() + m_size, |
|
ChartTranslationOptionOrderer()); |
|
m_scoreThreshold = m_collection[m_ruleLimit-1]->GetEstimateOfBestScore(); |
|
m_size = m_ruleLimit; |
|
} |
|
} |
|
|
|
void |
|
ChartTranslationOptionList:: |
|
AddPhraseOOV(TargetPhrase &phrase, |
|
std::list<TargetPhraseCollection::shared_ptr > &waste_memory, |
|
const Range &range) |
|
{ |
|
TargetPhraseCollection::shared_ptr tpc(new TargetPhraseCollection); |
|
tpc->Add(&phrase); |
|
waste_memory.push_back(tpc); |
|
StackVec empty; |
|
Add(*tpc, empty, range); |
|
} |
|
|
|
void ChartTranslationOptionList::ApplyThreshold(float const threshold) |
|
{ |
|
if (m_ruleLimit && m_size > m_ruleLimit) { |
|
|
|
|
|
assert(m_size < m_ruleLimit * 2); |
|
|
|
|
|
NTH_ELEMENT4(m_collection.begin(), |
|
m_collection.begin()+m_ruleLimit, |
|
m_collection.begin()+m_size, |
|
ChartTranslationOptionOrderer()); |
|
m_size = m_ruleLimit; |
|
} |
|
|
|
|
|
|
|
float scoreThreshold = -std::numeric_limits<float>::infinity(); |
|
|
|
CollType::const_iterator iter; |
|
for (iter = m_collection.begin(); iter != m_collection.begin()+m_size; ++iter) { |
|
const ChartTranslationOptions *transOpt = *iter; |
|
float score = transOpt->GetEstimateOfBestScore(); |
|
scoreThreshold = (score > scoreThreshold) ? score : scoreThreshold; |
|
} |
|
|
|
scoreThreshold += threshold; |
|
|
|
CollType::iterator bound = std::partition(m_collection.begin(), |
|
m_collection.begin()+m_size, |
|
ScoreThresholdPred(scoreThreshold)); |
|
|
|
m_size = std::distance(m_collection.begin(), bound); |
|
} |
|
|
|
float ChartTranslationOptionList::GetBestScore(const ChartCellLabel *chartCell) const |
|
{ |
|
const HypoList *stack = chartCell->GetStack().cube; |
|
assert(stack); |
|
assert(!stack->empty()); |
|
const ChartHypothesis &bestHypo = **(stack->begin()); |
|
return bestHypo.GetFutureScore(); |
|
} |
|
|
|
void ChartTranslationOptionList::EvaluateWithSourceContext(const InputType &input, const InputPath &inputPath) |
|
{ |
|
|
|
CollType::iterator iter; |
|
for (iter = m_collection.begin(); iter != m_collection.begin() + m_size; ++iter) { |
|
ChartTranslationOptions &transOpts = **iter; |
|
transOpts.EvaluateWithSourceContext(input, inputPath); |
|
} |
|
|
|
|
|
size_t numDiscard = 0; |
|
for (size_t i = 0; i < m_size; ++i) { |
|
ChartTranslationOptions *transOpts = m_collection[i]; |
|
if (transOpts->GetSize() == 0) { |
|
|
|
++numDiscard; |
|
} else if (numDiscard) { |
|
SwapTranslationOptions(i - numDiscard, i); |
|
|
|
} |
|
} |
|
|
|
size_t newSize = m_size - numDiscard; |
|
m_size = newSize; |
|
} |
|
|
|
void ChartTranslationOptionList::SwapTranslationOptions(size_t a, size_t b) |
|
{ |
|
ChartTranslationOptions *transOptsA = m_collection[a]; |
|
ChartTranslationOptions *transOptsB = m_collection[b]; |
|
m_collection[a] = transOptsB; |
|
m_collection[b] = transOptsA; |
|
} |
|
|
|
std::ostream& operator<<(std::ostream &out, const ChartTranslationOptionList &obj) |
|
{ |
|
for (size_t i = 0; i < obj.m_collection.size(); ++i) { |
|
const ChartTranslationOptions &transOpts = *obj.m_collection[i]; |
|
out << transOpts << endl; |
|
} |
|
return out; |
|
} |
|
|
|
} |
|
|