Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/moses-smt/mosesdecoder.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/mert
diff options
context:
space:
mode:
authorBarry Haddow <barry.haddow@gmail.com>2011-11-17 19:58:56 +0400
committerBarry Haddow <barry.haddow@gmail.com>2011-11-17 19:58:56 +0400
commitba5633c7b57b8843f9befc836db78989f3d15652 (patch)
tree4342cdcbf03d6d0ae6e42a519ebb1a67ebee8746 /mert
parent71c777f01df14c9523e20f118c90396d51678c02 (diff)
parent492fe6d97af84065fa0b4e0afa9b77a26761a11f (diff)
Merge remote branch 'origin/master' into pro
Conflicts: kenlm mert/Data.cpp mert/Data.h mert/Makefile.am mert/mert.cpp
Diffstat (limited to 'mert')
-rw-r--r--mert/BleuScorer.cpp75
-rw-r--r--mert/BleuScorer.h86
-rw-r--r--mert/CderScorer.cpp146
-rw-r--r--mert/CderScorer.h29
-rw-r--r--mert/Data.cpp65
-rw-r--r--mert/Data.h47
-rw-r--r--mert/FeatureArray.cpp21
-rw-r--r--mert/FeatureArray.h49
-rw-r--r--mert/FeatureData.cpp31
-rw-r--r--mert/FeatureData.h81
-rw-r--r--mert/FeatureStats.cpp104
-rw-r--r--mert/FeatureStats.h106
-rw-r--r--mert/FileStream.cpp65
-rw-r--r--mert/FileStream.h34
-rw-r--r--mert/Makefile.am4
-rw-r--r--mert/MergeScorer.cpp181
-rw-r--r--mert/MergeScorer.h90
-rw-r--r--mert/Optimizer.cpp582
-rw-r--r--mert/Optimizer.h131
-rw-r--r--mert/PerScorer.cpp24
-rw-r--r--mert/PerScorer.h37
-rw-r--r--mert/Point.cpp150
-rw-r--r--mert/Point.h93
-rw-r--r--mert/ScopedVector.h54
-rw-r--r--mert/ScoreArray.cpp19
-rw-r--r--mert/ScoreArray.h37
-rw-r--r--mert/ScoreData.cpp26
-rw-r--r--mert/ScoreData.h57
-rw-r--r--mert/ScoreStats.cpp89
-rw-r--r--mert/ScoreStats.h64
-rw-r--r--mert/Scorer.cpp81
-rw-r--r--mert/Scorer.h156
-rw-r--r--mert/ScorerFactory.cpp37
-rw-r--r--mert/ScorerFactory.h51
-rw-r--r--mert/TERsrc/alignmentStruct.h3
-rw-r--r--mert/TERsrc/bestShiftStruct.h4
-rw-r--r--mert/TERsrc/hashMap.h6
-rw-r--r--mert/TERsrc/hashMapInfos.h5
-rw-r--r--mert/TERsrc/hashMapStringInfos.h5
-rw-r--r--mert/TERsrc/infosHasher.h6
-rw-r--r--mert/TERsrc/stringHasher.h8
-rw-r--r--mert/TERsrc/stringInfosHasher.h8
-rw-r--r--mert/TERsrc/terAlignment.h4
-rw-r--r--mert/TERsrc/terShift.h5
-rw-r--r--mert/TERsrc/tercalc.h2
-rw-r--r--mert/TERsrc/tools.h6
-rw-r--r--mert/TerScorer.cpp34
-rw-r--r--mert/TerScorer.h50
-rw-r--r--mert/Timer.cpp38
-rw-r--r--mert/Timer.h46
-rw-r--r--mert/Types.h3
-rw-r--r--mert/Util.cpp116
-rw-r--r--mert/Util.h92
-rw-r--r--mert/evaluator.cpp226
-rwxr-xr-xmert/example/memcheck_extractor.sh16
-rwxr-xr-xmert/example/memcheck_mert.sh21
-rw-r--r--mert/extractor.cpp113
-rw-r--r--mert/gzfilebuf.h7
-rwxr-xr-xmert/mert.cpp206
59 files changed, 2072 insertions, 1860 deletions
diff --git a/mert/BleuScorer.cpp b/mert/BleuScorer.cpp
index 3c5a89789..67692eef7 100644
--- a/mert/BleuScorer.cpp
+++ b/mert/BleuScorer.cpp
@@ -1,11 +1,38 @@
#include "BleuScorer.h"
-const int BleuScorer::LENGTH = 4;
+#include <algorithm>
+#include <cmath>
+#include <climits>
+#include <fstream>
+#include <iterator>
+#include <stdexcept>
+#include "Util.h"
+BleuScorer::BleuScorer(const string& config)
+ : StatisticsBasedScorer("BLEU",config),
+ kLENGTH(4),
+ _refLengthStrategy(BLEU_CLOSEST) {
+ //configure regularisation
+ static string KEY_REFLEN = "reflen";
+ static string REFLEN_AVERAGE = "average";
+ static string REFLEN_SHORTEST = "shortest";
+ static string REFLEN_CLOSEST = "closest";
+
+ string reflen = getConfig(KEY_REFLEN,REFLEN_CLOSEST);
+ if (reflen == REFLEN_AVERAGE) {
+ _refLengthStrategy = BLEU_AVERAGE;
+ } else if (reflen == REFLEN_SHORTEST) {
+ _refLengthStrategy = BLEU_SHORTEST;
+ } else if (reflen == REFLEN_CLOSEST) {
+ _refLengthStrategy = BLEU_CLOSEST;
+ } else {
+ throw runtime_error("Unknown reference length strategy: " + reflen);
+ }
+ // cerr << "Using reference length strategy: " << reflen << endl;
+}
+
+BleuScorer::~BleuScorer() {}
-/**
- * count the ngrams of each type, up to the given length in the input line.
- **/
size_t BleuScorer::countNgrams(const string& line, counts_t& counts, unsigned int n)
{
vector<int> encoded_tokens;
@@ -24,7 +51,7 @@ size_t BleuScorer::countNgrams(const string& line, counts_t& counts, unsigned in
ngram.push_back(encoded_tokens[j]);
}
int count = 1;
- counts_it oldcount = counts.find(ngram);
+ counts_iterator oldcount = counts.find(ngram);
if (oldcount != counts.end()) {
count = (oldcount->second) + 1;
}
@@ -41,7 +68,7 @@ size_t BleuScorer::countNgrams(const string& line, counts_t& counts, unsigned in
void BleuScorer::setReferenceFiles(const vector<string>& referenceFiles)
{
//make sure reference data is clear
- _refcounts.clear();
+ _refcounts.reset();
_reflengths.clear();
_encodings.clear();
@@ -57,7 +84,7 @@ void BleuScorer::setReferenceFiles(const vector<string>& referenceFiles)
while (getline(refin,line)) {
//cerr << line << endl;
if (i == 0) {
- counts_t* counts = new counts_t(); //these get leaked
+ counts_t *counts = new counts_t; //these get leaked
_refcounts.push_back(counts);
vector<size_t> lengths;
_reflengths.push_back(lengths);
@@ -66,10 +93,10 @@ void BleuScorer::setReferenceFiles(const vector<string>& referenceFiles)
throw runtime_error("File " + referenceFiles[i] + " has too many sentences");
}
counts_t counts;
- size_t length = countNgrams(line,counts,LENGTH);
+ size_t length = countNgrams(line,counts,kLENGTH);
//for any counts larger than those already there, merge them in
- for (counts_it ci = counts.begin(); ci != counts.end(); ++ci) {
- counts_it oldcount_it = _refcounts[sid]->find(ci->first);
+ for (counts_iterator ci = counts.begin(); ci != counts.end(); ++ci) {
+ counts_iterator oldcount_it = _refcounts[sid]->find(ci->first);
int oldcount = 0;
if (oldcount_it != _refcounts[sid]->end()) {
oldcount = oldcount_it->second;
@@ -93,8 +120,8 @@ void BleuScorer::setReferenceFiles(const vector<string>& referenceFiles)
void BleuScorer::prepareStats(size_t sid, const string& text, ScoreStats& entry)
{
-// cerr << text << endl;
-// cerr << sid << endl;
+// cerr << text << endl;
+// cerr << sid << endl;
//dump_counts(*_refcounts[sid]);
if (sid >= _refcounts.size()) {
stringstream msg;
@@ -103,8 +130,8 @@ void BleuScorer::prepareStats(size_t sid, const string& text, ScoreStats& entry)
}
counts_t testcounts;
//stats for this line
- vector<float> stats(LENGTH*2);;
- size_t length = countNgrams(text,testcounts,LENGTH);
+ vector<float> stats(kLENGTH*2);;
+ size_t length = countNgrams(text,testcounts,kLENGTH);
//dump_counts(testcounts);
if (_refLengthStrategy == BLEU_SHORTEST) {
//cerr << reflengths.size() << " " << sid << endl;
@@ -137,9 +164,9 @@ void BleuScorer::prepareStats(size_t sid, const string& text, ScoreStats& entry)
}
//cerr << "computed length" << endl;
//precision on each ngram type
- for (counts_it testcounts_it = testcounts.begin();
+ for (counts_iterator testcounts_it = testcounts.begin();
testcounts_it != testcounts.end(); ++testcounts_it) {
- counts_it refcounts_it = _refcounts[sid]->find(testcounts_it->first);
+ counts_iterator refcounts_it = _refcounts[sid]->find(testcounts_it->first);
int correct = 0;
int guess = testcounts_it->second;
if (refcounts_it != _refcounts[sid]->end()) {
@@ -156,20 +183,20 @@ void BleuScorer::prepareStats(size_t sid, const string& text, ScoreStats& entry)
entry.set(stats_str);
}
-float BleuScorer::calculateScore(const vector<int>& comps)
+float BleuScorer::calculateScore(const vector<int>& comps) const
{
//cerr << "BLEU: ";
//copy(comps.begin(),comps.end(), ostream_iterator<int>(cerr," "));
float logbleu = 0.0;
- for (int i = 0; i < LENGTH; ++i) {
+ for (int i = 0; i < kLENGTH; ++i) {
if (comps[2*i] == 0) {
return 0.0;
}
logbleu += log(comps[2*i]) - log(comps[2*i+1]);
}
- logbleu /= LENGTH;
- float brevity = 1.0 - (float)comps[LENGTH*2]/comps[1];//reflength divided by test length
+ logbleu /= kLENGTH;
+ float brevity = 1.0 - (float)comps[kLENGTH*2]/comps[1];//reflength divided by test length
if (brevity < 0.0) {
logbleu += brevity;
}
@@ -177,3 +204,11 @@ float BleuScorer::calculateScore(const vector<int>& comps)
return exp(logbleu);
}
+void BleuScorer::dump_counts(counts_t& counts) const {
+ for (counts_const_iterator i = counts.begin(); i != counts.end(); ++i) {
+ cerr << "(";
+ copy(i->first.begin(), i->first.end(), ostream_iterator<int>(cerr," "));
+ cerr << ") " << i->second << ", ";
+ }
+ cerr << endl;
+}
diff --git a/mert/BleuScorer.h b/mert/BleuScorer.h
index 6481ce709..7e0e18b53 100644
--- a/mert/BleuScorer.h
+++ b/mert/BleuScorer.h
@@ -1,19 +1,14 @@
#ifndef __BLEUSCORER_H__
#define __BLEUSCORER_H__
-#include <algorithm>
-#include <cmath>
#include <iostream>
-#include <iterator>
-#include <set>
-#include <sstream>
-#include <stdexcept>
#include <string>
#include <vector>
-#include <limits.h>
+
#include "Types.h"
#include "ScoreData.h"
#include "Scorer.h"
+#include "ScopedVector.h"
using namespace std;
@@ -21,55 +16,29 @@ enum BleuReferenceLengthStrategy { BLEU_AVERAGE, BLEU_SHORTEST, BLEU_CLOSEST };
/**
- * Bleu scoring
- **/
+ * Bleu scoring
+ */
class BleuScorer: public StatisticsBasedScorer
{
public:
- BleuScorer(const string& config = "") : StatisticsBasedScorer("BLEU",config),_refLengthStrategy(BLEU_CLOSEST) {
- //configure regularisation
- static string KEY_REFLEN = "reflen";
- static string REFLEN_AVERAGE = "average";
- static string REFLEN_SHORTEST = "shortest";
- static string REFLEN_CLOSEST = "closest";
-
-
- string reflen = getConfig(KEY_REFLEN,REFLEN_CLOSEST);
- if (reflen == REFLEN_AVERAGE) {
- _refLengthStrategy = BLEU_AVERAGE;
- } else if (reflen == REFLEN_SHORTEST) {
- _refLengthStrategy = BLEU_SHORTEST;
- } else if (reflen == REFLEN_CLOSEST) {
- _refLengthStrategy = BLEU_CLOSEST;
- } else {
- throw runtime_error("Unknown reference length strategy: " + reflen);
- }
-// cerr << "Using reference length strategy: " << reflen << endl;
- }
+ explicit BleuScorer(const string& config = "");
+ ~BleuScorer();
+
virtual void setReferenceFiles(const vector<string>& referenceFiles);
virtual void prepareStats(size_t sid, const string& text, ScoreStats& entry);
- static const int LENGTH;
+ virtual float calculateScore(const vector<int>& comps) const;
- size_t NumberOfScores() {
- // cerr << "BleuScorer: " << (2 * LENGTH + 1) << endl;
- return (2 * LENGTH + 1);
- };
-
-
-//protected:
- float calculateScore(const vector<int>& comps);
+ virtual size_t NumberOfScores() const {
+ return 2 * kLENGTH + 1;
+ }
private:
- //no copy
- BleuScorer(const BleuScorer&);
- ~BleuScorer() {};
- BleuScorer& operator=(const BleuScorer&);
//Used to construct the ngram map
struct CompareNgrams {
- int operator() (const vector<int>& a, const vector<int>& b) {
+ bool operator()(const vector<int>& a, const vector<int>& b) const {
size_t i;
- size_t as = a.size();
- size_t bs = b.size();
+ const size_t as = a.size();
+ const size_t bs = b.size();
for (i = 0; i < as && i < bs; ++i) {
if (a[i] < b[i]) {
//cerr << "true" << endl;
@@ -86,26 +55,27 @@ private:
};
typedef map<vector<int>,int,CompareNgrams> counts_t;
- typedef map<vector<int>,int,CompareNgrams>::iterator counts_it;
-
- typedef vector<counts_t*> refcounts_t;
+ typedef map<vector<int>,int,CompareNgrams>::iterator counts_iterator;
+ typedef map<vector<int>,int,CompareNgrams>::iterator counts_const_iterator;
+ typedef ScopedVector<counts_t> refcounts_t;
+ /**
+ * Count the ngrams of each type, up to the given length in the input line.
+ */
size_t countNgrams(const string& line, counts_t& counts, unsigned int n);
- void dump_counts(counts_t& counts) {
- for (counts_it i = counts.begin(); i != counts.end(); ++i) {
- cerr << "(";
- copy(i->first.begin(), i->first.end(), ostream_iterator<int>(cerr," "));
- cerr << ") " << i->second << ", ";
- }
- cerr << endl;
- }
+ void dump_counts(counts_t& counts) const;
+
+ const int kLENGTH;
BleuReferenceLengthStrategy _refLengthStrategy;
// data extracted from reference files
refcounts_t _refcounts;
vector<vector<size_t> > _reflengths;
-};
+ // no copying allowed
+ BleuScorer(const BleuScorer&);
+ BleuScorer& operator=(const BleuScorer&);
+};
-#endif //__BLEUSCORER_H
+#endif // __BLEUSCORER_H__
diff --git a/mert/CderScorer.cpp b/mert/CderScorer.cpp
index 7b85da94d..fc8d69f5f 100644
--- a/mert/CderScorer.cpp
+++ b/mert/CderScorer.cpp
@@ -1,19 +1,17 @@
#include "CderScorer.h"
-
+#include <fstream>
#include <stdexcept>
-#include <iostream>
-#include <algorithm>
-CderScorer::CderScorer(const string& config)
- : StatisticsBasedScorer("CDER",config)
-{
-}
+CderScorer::CderScorer(const string& config)
+ : StatisticsBasedScorer("CDER",config) {}
+
+CderScorer::~CderScorer() {}
void CderScorer::setReferenceFiles(const vector<string>& referenceFiles)
{
//make sure reference data is clear
ref_sentences.clear();
-
+
//load reference data
for (size_t rid = 0; rid < referenceFiles.size(); ++rid) {
ifstream refin(referenceFiles[rid].c_str());
@@ -23,85 +21,81 @@ void CderScorer::setReferenceFiles(const vector<string>& referenceFiles)
ref_sentences.push_back(vector<sent_t>());
string line;
while (getline(refin,line)) {
- sent_t encoded;
- encode(line, encoded);
- ref_sentences[rid].push_back(encoded);
+ sent_t encoded;
+ encode(line, encoded);
+ ref_sentences[rid].push_back(encoded);
}
- }
+ }
}
void CderScorer::prepareStatsVector(size_t sid, const string& text, vector<int>& stats)
{
- sent_t cand;
- encode(text, cand);
-
- float max = -2;
- for (size_t rid = 0; rid < ref_sentences.size(); ++rid)
- {
- sent_t& ref = ref_sentences[rid][sid];
- vector<int> tmp = computeCD(cand, ref);
- if (calculateScore(tmp) > max)
- {
- stats = tmp;
- }
+ sent_t cand;
+ encode(text, cand);
+
+ float max = -2;
+ for (size_t rid = 0; rid < ref_sentences.size(); ++rid) {
+ sent_t& ref = ref_sentences[rid][sid];
+ vector<int> tmp = computeCD(cand, ref);
+ if (calculateScore(tmp) > max) {
+ stats = tmp;
}
+ }
}
-float CderScorer::calculateScore(const vector<int>& comps)
+float CderScorer::calculateScore(const vector<int>& comps) const
{
- if (comps.size() != 2)
- {
- throw runtime_error("Size of stat vector for CDER is not 2");
- }
+ if (comps.size() != 2)
+ {
+ throw runtime_error("Size of stat vector for CDER is not 2");
+ }
- return 1 - (comps[0] / (float) comps[1]);
+ return 1 - (comps[0] / (float) comps[1]);
}
-vector<int> CderScorer::computeCD(const sent_t& cand, const sent_t& ref)
+vector<int> CderScorer::computeCD(const sent_t& cand, const sent_t& ref) const
{
- int I = cand.size() + 1; // Number of inter-words positions in candidate sentence
- int L = ref.size() + 1; // Number of inter-words positions in reference sentence
-
-
- int l = 0;
- vector<int>* row = new vector<int>(I); // row[i] stores cost of cheapest path from (0,0) to (i,l) in CDER aligment grid.
-
- // Initialization of first row
- (*row)[0] = 0;
- for (int i = 1; i < I; ++i) (*row)[i] = 1;
-
- // Calculating costs for next row using costs from the previous row.
- while (++l < L)
- {
- vector<int>* nextRow = new vector<int>(I);
- for (int i = 0; i < I; ++i)
- {
- vector<int> possibleCosts;
- if (i > 0)
- {
- possibleCosts.push_back((*nextRow)[i-1] + 1); // Deletion
- possibleCosts.push_back((*row)[i-1] + distance(ref[l-1], cand[i-1])); // Substitution/Identity
- }
- possibleCosts.push_back((*row)[i] + 1); // Insertion
- (*nextRow)[i] = *min_element(possibleCosts.begin(), possibleCosts.end());
- }
-
- int LJ = 1 + *min_element(nextRow->begin(), nextRow->end()); // Cost of LongJumps is the same for all in the row
-
- for (int i = 0; i < I; ++i)
- {
- (*nextRow)[i] = min((*nextRow)[i], LJ); // LongJumps
- }
-
- delete row;
- row = nextRow;
- }
-
-
- vector<int> stats(2);
- stats[0] = *(row->rbegin()); // CD distance is the cost of path from (0,0) to (I,L)
- stats[1] = ref.size();
-
- delete row;
- return stats;
+ int I = cand.size() + 1; // Number of inter-words positions in candidate sentence
+ int L = ref.size() + 1; // Number of inter-words positions in reference sentence
+
+ int l = 0;
+ // row[i] stores cost of cheapest path from (0,0) to (i,l) in CDER aligment grid.
+ vector<int>* row = new vector<int>(I);
+
+ // Initialization of first row
+ (*row)[0] = 0;
+ for (int i = 1; i < I; ++i) (*row)[i] = 1;
+
+ // Calculating costs for next row using costs from the previous row.
+ while (++l < L)
+ {
+ vector<int>* nextRow = new vector<int>(I);
+ for (int i = 0; i < I; ++i)
+ {
+ vector<int> possibleCosts;
+ if (i > 0) {
+ possibleCosts.push_back((*nextRow)[i-1] + 1); // Deletion
+ possibleCosts.push_back((*row)[i-1] + distance(ref[l-1], cand[i-1])); // Substitution/Identity
+ }
+ possibleCosts.push_back((*row)[i] + 1); // Insertion
+ (*nextRow)[i] = *min_element(possibleCosts.begin(), possibleCosts.end());
+ }
+
+ // Cost of LongJumps is the same for all in the row
+ int LJ = 1 + *min_element(nextRow->begin(), nextRow->end());
+
+ for (int i = 0; i < I; ++i) {
+ (*nextRow)[i] = min((*nextRow)[i], LJ); // LongJumps
+ }
+
+ delete row;
+ row = nextRow;
+ }
+
+ vector<int> stats(2);
+ stats[0] = *(row->rbegin()); // CD distance is the cost of path from (0,0) to (I,L)
+ stats[1] = ref.size();
+
+ delete row;
+ return stats;
}
diff --git a/mert/CderScorer.h b/mert/CderScorer.h
index 1a2989b9e..359ac31e9 100644
--- a/mert/CderScorer.h
+++ b/mert/CderScorer.h
@@ -3,20 +3,20 @@
#include <algorithm>
#include <iostream>
+#include <iterator>
#include <string>
#include <vector>
#include "Types.h"
-#include "ScoreData.h"
#include "Scorer.h"
-
using namespace std;
-
class CderScorer: public StatisticsBasedScorer
{
public:
- CderScorer(const string& config);
+ explicit CderScorer(const string& config);
+ ~CderScorer();
+
virtual void setReferenceFiles(const vector<string>& referenceFiles);
virtual void prepareStats(size_t sid, const string& text, ScoreStats& entry)
{
@@ -30,30 +30,25 @@ public:
}
virtual void prepareStatsVector(size_t sid, const string& text, vector<int>& stats);
- size_t NumberOfScores() {
+ virtual size_t NumberOfScores() const {
return 2;
- };
+ }
- float calculateScore(const vector<int>& comps);
+ virtual float calculateScore(const vector<int>& comps) const;
private:
typedef vector<int> sent_t;
vector<vector<sent_t> > ref_sentences;
- vector<int> computeCD(const sent_t& cand, const sent_t& ref);
- int distance(int word1, int word2)
+ vector<int> computeCD(const sent_t& cand, const sent_t& ref) const;
+ int distance(int word1, int word2) const
{
- if (word1 == word2)
- return 0;
- else
- return 1;
+ return word1 == word2 ? 0 : 1;
}
- //no copy
+ // no copying allowed
CderScorer(const CderScorer&);
- ~CderScorer() {};
CderScorer& operator=(const CderScorer&);
};
-
-#endif
+#endif // __CDERSCORER_H__
diff --git a/mert/Data.cpp b/mert/Data.cpp
index 806308cb1..ed1100106 100644
--- a/mert/Data.cpp
+++ b/mert/Data.cpp
@@ -6,26 +6,46 @@
*
*/
+#include <algorithm>
#include <cassert>
+#include <cmath>
#include <fstream>
+#include "Data.h"
+#include "FileStream.h"
#include "Scorer.h"
#include "ScorerFactory.h"
-#include "Data.h"
#include "Util.h"
-
-Data::Data(Scorer& ptr):
- theScorer(&ptr),
- _sparse_flag(false)
+Data::Data()
+ : theScorer(NULL),
+ number_of_scores(0),
+ _sparse_flag(false),
+ scoredata(NULL),
+ featdata(NULL) {}
+
+Data::Data(Scorer& ptr)
+ : theScorer(&ptr),
+ score_type(theScorer->getName()),
+ number_of_scores(0),
+ _sparse_flag(false),
+ scoredata(new ScoreData(*theScorer)),
+ featdata(new FeatureData)
{
- score_type = (*theScorer).getName();
TRACE_ERR("Data::score_type " << score_type << std::endl);
-
TRACE_ERR("Data::Scorer type from Scorer: " << theScorer->getName() << endl);
- featdata=new FeatureData;
- scoredata=new ScoreData(*theScorer);
-};
+}
+
+Data::~Data() {
+ if (featdata) {
+ delete featdata;
+ featdata = NULL;
+ }
+ if (scoredata) {
+ delete scoredata;
+ scoredata = NULL;
+ }
+}
void Data::loadnbest(const std::string &file)
{
@@ -47,7 +67,7 @@ void Data::loadnbest(const std::string &file)
while (getline(inp,stringBuf,'\n')) {
if (stringBuf.empty()) continue;
-// TRACE_ERR("stringBuf: " << stringBuf << std::endl);
+// TRACE_ERR("stringBuf: " << stringBuf << std::endl);
getNextPound(stringBuf, substring, "|||"); //first field
sentence_index = substring;
@@ -55,7 +75,7 @@ void Data::loadnbest(const std::string &file)
getNextPound(stringBuf, substring, "|||"); //second field
theSentence = substring;
-// adding statistics for error measures
+ // adding statistics for error measures
featentry.reset();
scoreentry.clear();
@@ -73,7 +93,7 @@ void Data::loadnbest(const std::string &file)
size_t tmpidx=0;
while (!stringsupport.empty()) {
- // TRACE_ERR("Decompounding: " << substring << std::endl);
+ // TRACE_ERR("Decompounding: " << substring << std::endl);
getNextPound(stringsupport, subsubstring);
// string ending with ":" are skipped, because they are the names of the features
@@ -98,12 +118,12 @@ void Data::loadnbest(const std::string &file)
// adding features
while (!substring.empty()) {
-// TRACE_ERR("Decompounding: " << substring << std::endl);
+// TRACE_ERR("Decompounding: " << substring << std::endl);
getNextPound(substring, subsubstring);
// no ':' -> feature value that needs to be stored
if ((loc = subsubstring.find_last_of(":")) != subsubstring.length()-1) {
- featentry.add(ATOFST(subsubstring.c_str()));
+ featentry.add(ConvertStringToFeatureStatsType(subsubstring));
}
// sparse feature name? store as well
else if (subsubstring.find("_") != string::npos) {
@@ -121,22 +141,22 @@ void Data::loadnbest(const std::string &file)
}
// TODO
-void Data::mergeSparseFeatures() {
+void Data::mergeSparseFeatures() {
std::cerr << "ERROR: sparse features can only be trained with pairwise ranked optimizer (PRO), not traditional MERT\n";
exit(1);
}
void Data::createShards(size_t shard_count, float shard_size, const string& scorerconfig,
- std::vector<Data>& shards)
+ std::vector<Data>& shards)
{
assert(shard_count);
- assert(shard_size >=0);
+ assert(shard_size >= 0);
assert(shard_size <= 1);
size_t data_size = scoredata->size();
assert(data_size == featdata->size());
- shard_size *= data_size;
+ shard_size *= data_size;
for (size_t shard_id = 0; shard_id < shard_count; ++shard_id) {
vector<size_t> shard_contents;
@@ -153,9 +173,8 @@ void Data::createShards(size_t shard_count, float shard_size, const string& scor
shard_contents.push_back(rand() % data_size);
}
}
-
- ScorerFactory SF;
- Scorer* scorer = SF.getScorer(score_type, scorerconfig);
+
+ Scorer* scorer = ScorerFactory::getScorer(score_type, scorerconfig);
shards.push_back(Data(*scorer));
shards.back().score_type = score_type;
@@ -166,7 +185,5 @@ void Data::createShards(size_t shard_count, float shard_size, const string& scor
shards.back().scoredata->add(scoredata->get(shard_contents[i]));
}
//cerr << endl;
-
}
}
-
diff --git a/mert/Data.h b/mert/Data.h
index 84dcb884e..db858fc18 100644
--- a/mert/Data.h
+++ b/mert/Data.h
@@ -23,19 +23,21 @@ class Scorer;
class Data
{
-protected:
- ScoreData* scoredata;
- FeatureData* featdata;
-
private:
Scorer* theScorer;
std::string score_type;
- size_t number_of_scores; //number of scores
+ size_t number_of_scores;
bool _sparse_flag;
+protected:
+ // TODO: Use smart pointers for exceptional-safety.
+ ScoreData* scoredata;
+ FeatureData* featdata;
+
public:
- Data(Scorer& sc);
- ~Data() {};
+ explicit Data(Scorer& sc);
+ Data();
+ ~Data();
inline void clear() {
scoredata->clear();
@@ -44,10 +46,11 @@ public:
ScoreData* getScoreData() {
return scoredata;
- };
+ }
+
FeatureData* getFeatureData() {
return featdata;
- };
+ }
Scorer* getScorer() {
return theScorer;
@@ -62,7 +65,7 @@ public:
inline std::string Features() const {
return featdata->Features();
}
- inline void Features(const std::string f) {
+ inline void Features(const std::string &f) {
featdata->Features(f);
}
@@ -87,26 +90,26 @@ public:
scoredata->save(scorefile, bin);
}
- inline bool existsFeatureNames() {
+ inline bool existsFeatureNames() const {
return featdata->existsFeatureNames();
- };
+ }
- inline std::string getFeatureName(size_t idx) {
+ inline std::string getFeatureName(size_t idx) const {
return featdata->getFeatureName(idx);
- };
+ }
- inline size_t getFeatureIndex(const std::string& name) {
+ inline size_t getFeatureIndex(const std::string& name) const {
return featdata->getFeatureIndex(name);
- };
+ }
/**
- * Create shard_count shards. If shard_size == 0, then the shards are non-overlapping
- * and exhaust the data. If 0 < shard_size <= 1, then shards are chosen by sampling
- * the data (with replacement) and shard_size is interpreted as the proportion
+ * Create shard_count shards. If shard_size == 0, then the shards are non-overlapping
+ * and exhaust the data. If 0 < shard_size <= 1, then shards are chosen by sampling
+ * the data (with replacement) and shard_size is interpreted as the proportion
* of the total size.
*/
- void createShards(size_t shard_count, float shard_size, const std::string& scorerconfig,
- std::vector<Data>& shards);
+ void createShards(size_t shard_count, float shard_size, const std::string& scorerconfig,
+ std::vector<Data>& shards);
};
-#endif
+#endif // DATA_H
diff --git a/mert/FeatureArray.cpp b/mert/FeatureArray.cpp
index 91785ec91..854bcef79 100644
--- a/mert/FeatureArray.cpp
+++ b/mert/FeatureArray.cpp
@@ -6,13 +6,15 @@
*
*/
-#include <fstream>
#include "FeatureArray.h"
+#include "FileStream.h"
#include "Util.h"
-FeatureArray::FeatureArray(): idx(""), _sparse_flag(false)
-{};
+FeatureArray::FeatureArray()
+ : idx(""), number_of_features(0), _sparse_flag(false) {}
+
+FeatureArray::~FeatureArray() {}
void FeatureArray::savetxt(std::ofstream& outFile)
{
@@ -136,19 +138,16 @@ void FeatureArray::merge(FeatureArray& e)
add(e.get(i));
}
-
-
-bool FeatureArray::check_consistency()
+bool FeatureArray::check_consistency() const
{
- size_t sz = NumberOfFeatures();
-
+ const size_t sz = NumberOfFeatures();
if (sz == 0)
return true;
- for (featarray_t::iterator i=array_.begin(); i!=array_.end(); i++)
- if (i->size()!=sz)
+ for (featarray_t::const_iterator i = array_.begin(); i != array_.end(); i++) {
+ if (i->size() != sz)
return false;
-
+ }
return true;
}
diff --git a/mert/FeatureArray.h b/mert/FeatureArray.h
index 0f5f60376..1fa3c4151 100644
--- a/mert/FeatureArray.h
+++ b/mert/FeatureArray.h
@@ -9,36 +9,34 @@
#ifndef FEATURE_ARRAY_H
#define FEATURE_ARRAY_H
-#define FEATURES_TXT_BEGIN "FEATURES_TXT_BEGIN_0"
-#define FEATURES_TXT_END "FEATURES_TXT_END_0"
-#define FEATURES_BIN_BEGIN "FEATURES_BIN_BEGIN_0"
-#define FEATURES_BIN_END "FEATURES_BIN_END_0"
-
-using namespace std;
-
-#include <limits>
#include <vector>
#include <iostream>
#include <fstream>
-
-#include "Util.h"
#include "FeatureStats.h"
+using namespace std;
+
+const char FEATURES_TXT_BEGIN[] = "FEATURES_TXT_BEGIN_0";
+const char FEATURES_TXT_END[] = "FEATURES_TXT_END_0";
+const char FEATURES_BIN_BEGIN[] = "FEATURES_BIN_BEGIN_0";
+const char FEATURES_BIN_END[] = "FEATURES_BIN_END_0";
+
class FeatureArray
{
+private:
+ // idx to identify the utterance. It can differ from
+ // the index inside the vector.
+ std::string idx;
+
protected:
featarray_t array_;
size_t number_of_features;
std::string features;
bool _sparse_flag;
-private:
- std::string idx; // idx to identify the utterance, it can differ from the index inside the vector
-
public:
FeatureArray();
-
- ~FeatureArray() {};
+ ~FeatureArray();
inline void clear() {
array_.clear();
@@ -48,26 +46,26 @@ public:
return _sparse_flag;
}
- inline std::string getIndex() {
+ inline std::string getIndex() const {
return idx;
}
- inline void setIndex(const std::string & value) {
- idx=value;
+ inline void setIndex(const std::string& value) {
+ idx = value;
}
- inline FeatureStats& get(size_t i) {
+ inline FeatureStats& get(size_t i) {
return array_.at(i);
}
- inline const FeatureStats& get(size_t i)const {
+ inline const FeatureStats& get(size_t i)const {
return array_.at(i);
}
- void add(FeatureStats e) {
+ void add(FeatureStats& e) {
array_.push_back(e);
}
void merge(FeatureArray& e);
- inline size_t size() {
+ inline size_t size() const {
return array_.size();
}
inline size_t NumberOfFeatures() const {
@@ -79,7 +77,7 @@ public:
inline std::string Features() const {
return features;
}
- inline void Features(const std::string f) {
+ inline void Features(const std::string& f) {
features = f;
}
@@ -96,8 +94,7 @@ public:
void load(ifstream& inFile);
void load(const std::string &file);
- bool check_consistency();
+ bool check_consistency() const;
};
-
-#endif
+#endif // FEATURE_ARRAY_H
diff --git a/mert/FeatureData.cpp b/mert/FeatureData.cpp
index 7e8d53990..ed76bca3b 100644
--- a/mert/FeatureData.cpp
+++ b/mert/FeatureData.cpp
@@ -6,15 +6,18 @@
*
*/
-#include <fstream>
#include "FeatureData.h"
-#include "Util.h"
+#include <limits>
+#include "FileStream.h"
+#include "Util.h"
static const float MIN_FLOAT=-1.0*numeric_limits<float>::max();
static const float MAX_FLOAT=numeric_limits<float>::max();
-FeatureData::FeatureData() {};
+FeatureData::FeatureData()
+ : number_of_features(0),
+ _sparse_flag(false) {}
void FeatureData::save(std::ofstream& outFile, bool bin)
{
@@ -89,15 +92,15 @@ void FeatureData::add(FeatureArray& e)
}
}
-void FeatureData::add(FeatureStats& e, const std::string & sent_idx)
+void FeatureData::add(FeatureStats& e, const std::string& sent_idx)
{
if (exists(sent_idx)) { // array at position e.getIndex() already exists
//enlarge array at position e.getIndex()
size_t pos = getIndex(sent_idx);
-// TRACE_ERR("Inserting " << e << " in array " << sent_idx << std::endl);
+// TRACE_ERR("Inserting " << e << " in array " << sent_idx << std::endl);
array_.at(pos).add(e);
} else {
-// TRACE_ERR("Creating a new entry in the array and inserting " << e << std::endl);
+// TRACE_ERR("Creating a new entry in the array and inserting " << e << std::endl);
FeatureArray a;
a.NumberOfFeatures(number_of_features);
a.Features(features);
@@ -107,12 +110,12 @@ void FeatureData::add(FeatureStats& e, const std::string & sent_idx)
}
}
-bool FeatureData::check_consistency()
+bool FeatureData::check_consistency() const
{
if (array_.size() == 0)
return true;
- for (featdata_t::iterator i = array_.begin(); i !=array_.end(); i++)
+ for (featdata_t::const_iterator i = array_.begin(); i != array_.end(); i++)
if (!i->check_consistency()) return false;
return true;
@@ -128,20 +131,18 @@ void FeatureData::setIndex()
}
}
-
-void FeatureData::setFeatureMap(const std::string feat)
+void FeatureData::setFeatureMap(const std::string& feat)
{
number_of_features = 0;
- features=feat;
+ features = feat;
std::string substring, stringBuf;
- stringBuf=features;
+ stringBuf = features;
while (!stringBuf.empty()) {
getNextPound(stringBuf, substring);
- featname2idx_[substring]=idx2featname_.size();
- idx2featname_[idx2featname_.size()]=substring;
+ featname2idx_[substring] = idx2featname_.size();
+ idx2featname_[idx2featname_.size()] = substring;
number_of_features++;
}
}
-
diff --git a/mert/FeatureData.h b/mert/FeatureData.h
index 0fd69608e..6934cdcba 100644
--- a/mert/FeatureData.h
+++ b/mert/FeatureData.h
@@ -11,40 +11,36 @@
using namespace std;
-#include <limits>
#include <vector>
#include <iostream>
-
-#include "Util.h"
+#include <stdexcept>
#include "FeatureArray.h"
class FeatureData
{
-
-protected:
- featdata_t array_;
- idx2name idx2arrayname_; //map from index to name of array
- name2idx arrayname2idx_; //map from name to index of array
-
private:
size_t number_of_features;
std::string features;
bool _sparse_flag;
- map<std::string, size_t> featname2idx_; //map from name to index of features
- map<size_t, std::string> idx2featname_; //map from index to name of features
+ map<std::string, size_t> featname2idx_; // map from name to index of features
+ map<size_t, std::string> idx2featname_; // map from index to name of features
+
+protected:
+ featdata_t array_;
+ idx2name idx2arrayname_; // map from index to name of array
+ name2idx arrayname2idx_; // map from name to index of array
public:
FeatureData();
-
- ~FeatureData() {};
+ ~FeatureData() {}
inline void clear() {
array_.clear();
}
- inline bool hasSparseFeatures() const {
- return _sparse_flag;
+ inline bool hasSparseFeatures() const {
+ return _sparse_flag;
}
inline FeatureArray get(const std::string& idx) {
return array_.at(getIndex(idx));
@@ -56,7 +52,7 @@ public:
return array_.at(idx);
}
- inline bool exists(const std::string & sent_idx) {
+ inline bool exists(const std::string& sent_idx) {
return exists(getIndex(sent_idx));
}
inline bool exists(int sent_idx) {
@@ -73,7 +69,7 @@ public:
void add(FeatureArray& e);
void add(FeatureStats& e, const std::string& sent_idx);
- inline size_t size() {
+ inline size_t size() const {
return array_.size();
}
inline size_t NumberOfFeatures() const {
@@ -85,7 +81,7 @@ public:
inline std::string Features() const {
return features;
}
- inline void Features(const std::string f) {
+ inline void Features(const std::string& f) {
features = f;
}
@@ -98,44 +94,47 @@ public:
void load(ifstream& inFile);
void load(const std::string &file);
- bool check_consistency();
+ bool check_consistency() const;
void setIndex();
- inline int getIndex(const std::string& idx) {
- name2idx::iterator i = arrayname2idx_.find(idx);
- if (i!=arrayname2idx_.end())
+ inline int getIndex(const std::string& idx) const {
+ name2idx::const_iterator i = arrayname2idx_.find(idx);
+ if (i != arrayname2idx_.end())
return i->second;
else
return -1;
}
- inline std::string getIndex(size_t idx) {
- idx2name::iterator i = idx2arrayname_.find(idx);
- if (i!=idx2arrayname_.end())
+ inline std::string getIndex(size_t idx) const {
+ idx2name::const_iterator i = idx2arrayname_.find(idx);
+ if (i != idx2arrayname_.end())
throw runtime_error("there is no entry at index " + idx);
return i->second;
}
+ bool existsFeatureNames() const {
+ return (idx2featname_.size() > 0) ? true : false;
+ }
- bool existsFeatureNames() {
- return (idx2featname_.size() > 0)?true:false;
- };
-
- std::string getFeatureName(size_t idx) {
+ std::string getFeatureName(size_t idx) const {
if (idx >= idx2featname_.size())
throw runtime_error("Error: you required an too big index");
- return idx2featname_[idx];
- };
+ map<size_t, std::string>::const_iterator it = idx2featname_.find(idx);
+ if (it == idx2featname_.end()) {
+ throw runtime_error("Error: specified id is unknown: " + idx);
+ } else {
+ return it->second;
+ }
+ }
- size_t getFeatureIndex(const std::string& name) {
- if (featname2idx_.find(name)==featname2idx_.end())
- throw runtime_error("Error: feature " + name +" is unknown");
- return featname2idx_[name];
- };
+ size_t getFeatureIndex(const std::string& name) const {
+ map<std::string, size_t>::const_iterator it = featname2idx_.find(name);
+ if (it == featname2idx_.end())
+ throw runtime_error("Error: feature " + name + " is unknown");
+ return it->second;
+ }
- void setFeatureMap(const std::string feat);
+ void setFeatureMap(const std::string& feat);
};
-
-#endif
-
+#endif // FEATURE_DATA_H
diff --git a/mert/FeatureStats.cpp b/mert/FeatureStats.cpp
index 3d2b1d1d0..e7682518c 100644
--- a/mert/FeatureStats.cpp
+++ b/mert/FeatureStats.cpp
@@ -6,21 +6,23 @@
*
*/
-#include <cmath>
-#include <fstream>
#include "FeatureStats.h"
-#define AVAILABLE_ 8;
+#include <cmath>
+#include "Util.h"
+
+namespace {
+const int kAvailableSize = 8;
+} // namespace
SparseVector::name2id_t SparseVector::name2id_;
SparseVector::id2name_t SparseVector::id2name_;
-FeatureStatsType SparseVector::get(string name) const {
+FeatureStatsType SparseVector::get(const string& name) const {
name2id_t::const_iterator name2id_iter = name2id_.find(name);
if (name2id_iter == name2id_.end()) return 0;
size_t id = name2id_iter->second;
return get(id);
-
}
FeatureStatsType SparseVector::get(size_t id) const {
@@ -29,7 +31,7 @@ FeatureStatsType SparseVector::get(size_t id) const {
return fvector_iter->second;
}
-void SparseVector::set(string name, FeatureStatsType value) {
+void SparseVector::set(const string& name, FeatureStatsType value) {
name2id_t::const_iterator name2id_iter = name2id_.find(name);
size_t id = 0;
if (name2id_iter == name2id_.end()) {
@@ -54,10 +56,6 @@ void SparseVector::clear() {
fvector_.clear();
}
-size_t SparseVector::size() const {
- return fvector_.size();
-}
-
SparseVector& SparseVector::operator-=(const SparseVector& rhs) {
//All the elements that have values in *this
for (fvector_t::iterator i = fvector_.begin(); i != fvector_.end(); ++i) {
@@ -65,7 +63,7 @@ SparseVector& SparseVector::operator-=(const SparseVector& rhs) {
}
//Any elements in rhs, that have no value in *this
- for (fvector_t::const_iterator i = rhs.fvector_.begin();
+ for (fvector_t::const_iterator i = rhs.fvector_.begin();
i != rhs.fvector_.end(); ++i) {
if (fvector_.find(i->first) == fvector_.end()) {
fvector_[i->first] = -(i->second);
@@ -80,49 +78,59 @@ SparseVector operator-(const SparseVector& lhs, const SparseVector& rhs) {
return res;
}
-
FeatureStats::FeatureStats()
+ : available_(kAvailableSize), entries_(0),
+ array_(new FeatureStatsType[available_]) {}
+
+FeatureStats::FeatureStats(const size_t size)
+ : available_(size), entries_(size),
+ array_(new FeatureStatsType[available_])
{
- available_ = AVAILABLE_;
- entries_ = 0;
- array_ = new FeatureStatsType[available_];
-};
+ memset(array_, 0, GetArraySizeWithBytes());
+}
+
+FeatureStats::FeatureStats(std::string &theString)
+ : available_(0), entries_(0), array_(NULL)
+{
+ set(theString);
+}
FeatureStats::~FeatureStats()
{
- delete[] array_;
-};
+ if (array_) {
+ delete [] array_;
+ array_ = NULL;
+ }
+}
-FeatureStats::FeatureStats(const FeatureStats &stats)
+void FeatureStats::Copy(const FeatureStats &stats)
{
available_ = stats.available();
entries_ = stats.size();
array_ = new FeatureStatsType[available_];
- memcpy(array_,stats.getArray(),featbytes_);
+ memcpy(array_, stats.getArray(), GetArraySizeWithBytes());
map_ = stats.getSparse();
-};
+}
-FeatureStats::FeatureStats(const size_t size)
+FeatureStats::FeatureStats(const FeatureStats &stats)
{
- available_ = size;
- entries_ = size;
- array_ = new FeatureStatsType[available_];
- memset(array_,0,featbytes_);
-};
-
+ Copy(stats);
+}
-FeatureStats::FeatureStats(std::string &theString)
+FeatureStats& FeatureStats::operator=(const FeatureStats &stats)
{
- set(theString);
+ delete [] array_;
+ Copy(stats);
+ return *this;
}
void FeatureStats::expand()
{
- available_*=2;
+ available_ *= 2;
featstats_t t_ = new FeatureStatsType[available_];
- memcpy(t_,array_,featbytes_);
- delete array_;
- array_=t_;
+ memcpy(t_, array_, GetArraySizeWithBytes());
+ delete [] array_;
+ array_ = t_;
}
void FeatureStats::add(FeatureStatsType v)
@@ -131,7 +139,7 @@ void FeatureStats::add(FeatureStatsType v)
array_[entries_++]=v;
}
-void FeatureStats::addSparse(string name, FeatureStatsType v)
+void FeatureStats::addSparse(const string& name, FeatureStatsType v)
{
map_.set(name,v);
}
@@ -145,7 +153,7 @@ void FeatureStats::set(std::string &theString)
getNextPound(theString, substring);
// regular feature
if (substring.find(":") == string::npos) {
- add(ATOFST(substring.c_str()));
+ add(ConvertStringToFeatureStatsType(substring));
}
// sparse feature
else {
@@ -158,7 +166,7 @@ void FeatureStats::set(std::string &theString)
void FeatureStats::loadbin(std::ifstream& inFile)
{
- inFile.read((char*) array_, featbytes_);
+ inFile.read((char*) array_, GetArraySizeWithBytes());
}
void FeatureStats::loadtxt(std::ifstream& inFile)
@@ -170,7 +178,7 @@ void FeatureStats::loadtxt(std::ifstream& inFile)
void FeatureStats::loadtxt(const std::string &file)
{
- // TRACE_ERR("loading the stats from " << file << std::endl);
+ // TRACE_ERR("loading the stats from " << file << std::endl);
std::ifstream inFile(file.c_str(), std::ios::in); // matches a stream with a file. Opens the file
@@ -180,7 +188,7 @@ void FeatureStats::loadtxt(const std::string &file)
void FeatureStats::savetxt(const std::string &file)
{
-// TRACE_ERR("saving the stats into " << file << std::endl);
+// TRACE_ERR("saving the stats into " << file << std::endl);
std::ofstream outFile(file.c_str(), std::ios::out); // matches a stream with a file. Opens the file
@@ -190,29 +198,15 @@ void FeatureStats::savetxt(const std::string &file)
void FeatureStats::savetxt(std::ofstream& outFile)
{
-// TRACE_ERR("saving the stats" << std::endl);
+// TRACE_ERR("saving the stats" << std::endl);
outFile << *this;
}
void FeatureStats::savebin(std::ofstream& outFile)
{
- outFile.write((char*) array_, featbytes_);
-}
-
-FeatureStats& FeatureStats::operator=(const FeatureStats &stats)
-{
- delete array_;
- available_ = stats.available();
- entries_ = stats.size();
- array_ = new FeatureStatsType[available_];
- memcpy(array_,stats.getArray(),featbytes_);
- map_ = stats.getSparse();
-
- return *this;
+ outFile.write((char*) array_, GetArraySizeWithBytes());
}
-
-/**write the whole object to a stream*/
ostream& operator<<(ostream& o, const FeatureStats& e)
{
// print regular features
diff --git a/mert/FeatureStats.h b/mert/FeatureStats.h
index 6b729e4e5..44858a5a3 100644
--- a/mert/FeatureStats.h
+++ b/mert/FeatureStats.h
@@ -9,41 +9,39 @@
#ifndef FEATURE_STATS_H
#define FEATURE_STATS_H
-using namespace std;
-
-#include <limits>
-#include <vector>
+#include <cstring>
+#include <fstream>
#include <iostream>
+#include <map>
+#include <string>
+#include <vector>
+#include "Types.h"
-#include "Util.h"
-
-#define FEATURE_STATS_MIN (numeric_limits<FeatureStatsType>::min())
-#define ATOFST(str) ((FeatureStatsType) atof(str))
-
-#define featbytes_ (entries_*sizeof(FeatureStatsType))
+using namespace std;
-//Minimal sparse vector
+// Minimal sparse vector
class SparseVector {
+public:
+ typedef std::map<size_t,FeatureStatsType> fvector_t;
+ typedef std::map<std::string, size_t> name2id_t;
+ typedef std::vector<std::string> id2name_t;
+
+ FeatureStatsType get(const std::string& name) const;
+ FeatureStatsType get(size_t id) const;
+ void set(const std::string& name, FeatureStatsType value);
+ void clear();
+ size_t size() const {
+ return fvector_.size();
+ }
- public:
- typedef std::map<size_t,FeatureStatsType> fvector_t;
- typedef std::map<std::string, size_t> name2id_t;
- typedef std::vector<std::string> id2name_t;
-
- FeatureStatsType get(std::string name) const;
- FeatureStatsType get(size_t id) const;
- void set(std::string name, FeatureStatsType value);
- void clear();
- size_t size() const;
-
- void write(std::ostream& out, const std::string& sep = " ") const;
+ void write(std::ostream& out, const std::string& sep = " ") const;
- SparseVector& operator-=(const SparseVector& rhs);
+ SparseVector& operator-=(const SparseVector& rhs);
- private:
- static name2id_t name2id_;
- static id2name_t id2name_;
- fvector_t fvector_;
+private:
+ static name2id_t name2id_;
+ static id2name_t id2name_;
+ fvector_t fvector_;
};
SparseVector operator-(const SparseVector& lhs, const SparseVector& rhs);
@@ -51,32 +49,43 @@ SparseVector operator-(const SparseVector& lhs, const SparseVector& rhs);
class FeatureStats
{
private:
+ size_t available_;
+ size_t entries_;
+
+ // TODO: Use smart pointer for exceptional-safety.
featstats_t array_;
SparseVector map_;
- size_t entries_;
- size_t available_;
public:
FeatureStats();
- FeatureStats(const size_t size);
+ explicit FeatureStats(const size_t size);
+ explicit FeatureStats(std::string &theString);
+
+ ~FeatureStats();
+
+ // We intentionally allow copying.
FeatureStats(const FeatureStats &stats);
- FeatureStats(std::string &theString);
FeatureStats& operator=(const FeatureStats &stats);
- ~FeatureStats();
+ void Copy(const FeatureStats &stats);
- bool isfull() {
- return (entries_ < available_)?0:1;
+ bool isfull() const {
+ return (entries_ < available_) ? 0 : 1;
}
void expand();
void add(FeatureStatsType v);
- void addSparse(string name, FeatureStatsType v);
+ void addSparse(const string& name, FeatureStatsType v);
- inline void clear() {
- memset((void*) array_,0,featbytes_);
+ void clear() {
+ memset((void*)array_, 0, GetArraySizeWithBytes());
map_.clear();
}
+ void reset() {
+ entries_ = 0;
+ clear();
+ }
+
inline FeatureStatsType get(size_t i) {
return array_[i];
}
@@ -93,11 +102,17 @@ public:
void set(std::string &theString);
inline size_t bytes() const {
- return featbytes_;
+ return GetArraySizeWithBytes();
+ }
+
+ size_t GetArraySizeWithBytes() const {
+ return entries_ * sizeof(FeatureStatsType);
}
+
inline size_t size() const {
return entries_;
}
+
inline size_t available() const {
return available_;
}
@@ -113,15 +128,10 @@ public:
void loadtxt(ifstream& inFile);
void loadbin(ifstream& inFile);
- inline void reset() {
- entries_ = 0;
- clear();
- }
-
- /**write the whole object to a stream*/
+ /**
+ * Write the whole object to a stream.
+ */
friend ostream& operator<<(ostream& o, const FeatureStats& e);
};
-#endif
-
-
+#endif // FEATURE_STATS_H
diff --git a/mert/FileStream.cpp b/mert/FileStream.cpp
new file mode 100644
index 000000000..11fd58e26
--- /dev/null
+++ b/mert/FileStream.cpp
@@ -0,0 +1,65 @@
+#include "FileStream.h"
+
+#include <stdexcept>
+#include "gzfilebuf.h"
+
+using namespace std;
+
+namespace {
+bool IsGzipFile(const std::string &filename) {
+ return filename.size() > 3 &&
+ filename.substr(filename.size() - 3, 3) == ".gz";
+}
+} // namespace
+
+inputfilestream::inputfilestream(const std::string &filePath)
+ : std::istream(0), m_streambuf(0), is_good(false)
+{
+ // check if file is readable
+ std::filebuf* fb = new std::filebuf();
+ is_good = (fb->open(filePath.c_str(), std::ios::in) != NULL);
+
+ if (IsGzipFile(filePath)) {
+ fb->close();
+ delete fb;
+ m_streambuf = new gzfilebuf(filePath.c_str());
+ } else {
+ m_streambuf = fb;
+ }
+ this->init(m_streambuf);
+}
+
+inputfilestream::~inputfilestream()
+{
+ delete m_streambuf;
+ m_streambuf = 0;
+}
+
+void inputfilestream::close()
+{
+}
+
+outputfilestream::outputfilestream(const std::string &filePath)
+ : std::ostream(0), m_streambuf(0), is_good(false)
+{
+ // check if file is readable
+ std::filebuf* fb = new std::filebuf();
+ is_good = (fb->open(filePath.c_str(), std::ios::out) != NULL);
+
+ if (IsGzipFile(filePath)) {
+ throw runtime_error("Output to a zipped file not supported!");
+ } else {
+ m_streambuf = fb;
+ }
+ this->init(m_streambuf);
+}
+
+outputfilestream::~outputfilestream()
+{
+ delete m_streambuf;
+ m_streambuf = 0;
+}
+
+void outputfilestream::close()
+{
+}
diff --git a/mert/FileStream.h b/mert/FileStream.h
new file mode 100644
index 000000000..afa8d9a29
--- /dev/null
+++ b/mert/FileStream.h
@@ -0,0 +1,34 @@
+#ifndef FILESTREAM_H_
+#define FILESTREAM_H_
+
+#include <fstream>
+#include <streambuf>
+#include <string>
+
+class inputfilestream : public std::istream
+{
+protected:
+ std::streambuf *m_streambuf;
+ bool is_good;
+
+public:
+ explicit inputfilestream(const std::string &filePath);
+ ~inputfilestream();
+ bool good() const { return is_good; }
+ void close();
+};
+
+class outputfilestream : public std::ostream
+{
+protected:
+ std::streambuf *m_streambuf;
+ bool is_good;
+
+public:
+ explicit outputfilestream(const std::string &filePath);
+ ~outputfilestream();
+ bool good() const { return is_good; }
+ void close();
+};
+
+#endif // FILESTREAM_H_
diff --git a/mert/Makefile.am b/mert/Makefile.am
index 58baa5053..0b16a2f4f 100644
--- a/mert/Makefile.am
+++ b/mert/Makefile.am
@@ -4,6 +4,7 @@ AM_CPPFLAGS = -W -Wall -Wno-unused -ffor-scope -DTRACE_ENABLE $(BOOST_CPPFLAGS)
libmert_la_SOURCES = \
Util.cpp \
+FileStream.cpp \
Timer.cpp \
ScoreStats.cpp ScoreArray.cpp ScoreData.cpp \
ScoreDataIterator.cpp \
@@ -14,6 +15,7 @@ BleuScorer.cpp \
Point.cpp \
PerScorer.cpp \
Scorer.cpp \
+ScorerFactory.cpp \
Optimizer.cpp \
TERsrc/alignmentStruct.cpp \
TERsrc/hashMap.cpp \
@@ -38,6 +40,6 @@ pro_SOURCES = pro.cpp
extractor_LDADD = libmert.la -lm -lz
mert_LDADD = libmert.la -lm -lz $(BOOST_THREAD_LDFLAGS) $(BOOST_THREAD_LIBS)
evaluator_LDADD = libmert.la -lm -lz
-pro_LDADD = libmert.la @KENLM_LDFLAGS@ $(BOOST_LDFLAGS) $(BOOST_PROGRAM_OPTIONS_LDFLAGS) $(BOOST_PROGRAM_OPTIONS_LIBS)
+pro_LDADD = libmert.la $(top_srcdir)/util/libkenutil.la $(top_srcdir)/lm/libkenlm.la $(BOOST_LDFLAGS) $(BOOST_PROGRAM_OPTIONS_LDFLAGS) $(BOOST_PROGRAM_OPTIONS_LIBS)
pro_DEPENDENCIES = $(top_srcdir)/kenlm/libkenlm.la libmert.la
diff --git a/mert/MergeScorer.cpp b/mert/MergeScorer.cpp
index e60e5c9f1..0b9de73f1 100644
--- a/mert/MergeScorer.cpp
+++ b/mert/MergeScorer.cpp
@@ -1,109 +1,118 @@
#include "MergeScorer.h"
+
+#include <cmath>
+#include <stdexcept>
+#include "ScoreStats.h"
+#include "TerScorer.h"
+#include "BleuScorer.h"
+#include "PerScorer.h"
+#include "CderScorer.h"
+
#include "TERsrc/tercalc.h"
#include "TERsrc/terAlignment.h"
-const int MergeScorer::LENGTH = 4;
using namespace TERCpp;
-using namespace std;
+MergeScorer::MergeScorer(const string& config)
+ : StatisticsBasedScorer("MERGE",config), kLENGTH(4) {}
+MergeScorer::~MergeScorer() {}
void MergeScorer::setReferenceFiles(const vector<string>& referenceFiles)
{
- throw runtime_error("MERGE Scorer can be used only in mert execution");
- exit(0);
+ throw runtime_error("MERGE Scorer can be used only in mert execution");
+ exit(0);
}
void MergeScorer::prepareStats(size_t sid, const string& text, ScoreStats& entry)
{
- throw runtime_error("MergeScorer::prepareStats : MERGE Scorer can be used only in mert execution");
- exit(0);
+ throw runtime_error("MergeScorer::prepareStats : MERGE Scorer can be used only in mert execution");
+ exit(0);
}
+
/*
float MergeScorer::calculateScore(const vector<int>& comps)
{
- throw runtime_error("MergeScorer::calculateScore : MERGE Scorer can be used only in mert execution");
+ throw runtime_error("MergeScorer::calculateScore : MERGE Scorer can be used only in mert execution");
exit(0);
}
*/
-float MergeScorer::calculateScore(const std::vector< int >& comps)
+
+float MergeScorer::calculateScore(const std::vector< int >& comps) const
{
- float result=0.0;
- float weight=1.0;
- float resultTmp=0.0;
- vector<int> vecLine;
- vector<string> vecScorerType;
- vector<float> weightsModifier;
- int pos=0;
- int weightIncrement=0;
- string initfile="merge.init";
- string line;
- ifstream opt(initfile.c_str());
- float denom=0.0;
- if (opt.fail()) {
- cerr<<"MergeScorer::calculateScore : could not open initfile: " << initfile << endl;
- exit(3);
- }
- while (getline ( opt, line ))
- {
- vector<string> vecLine=stringToVector(line, " ");
- if ((int)vecLine.size()!=4)
- {
- cerr<<"MergeScorer::calculateScore : Error in initfile: " << initfile << endl;
- exit(4);
- }
- vecScorerType.push_back(vecLine.at(0));
- weightsModifier.push_back(atof(vecLine.at(1).c_str()));
- denom+=abs(atof(vecLine.at(1).c_str()));
- }
- for (weightIncrement = 0; weightIncrement < (int) weightsModifier.size(); weightIncrement++)
- {
- if (vecScorerType.at(weightIncrement).compare("BLEU")==0)
- {
- BleuScorer* scorer01= new BleuScorer("");
- weight=weightsModifier.at(weightIncrement) / denom;
- vecLine.clear();
- vecLine=subVector(comps, pos,pos+(int)(scorer01->NumberOfScores()));
- pos=pos+(int)(scorer01->NumberOfScores());
- resultTmp=(scorer01->calculateScore(vecLine));
- result+=(weight * resultTmp);
-
- }
- else if (vecScorerType.at(weightIncrement).compare("TER")==0)
- {
- TerScorer* scorer02= new TerScorer("");
- weight=weightsModifier.at(weightIncrement) / denom;
- vecLine.clear();
- vecLine=subVector(comps, pos,pos+(int)(scorer02->NumberOfScores()));
- pos=pos+(int)(scorer02->NumberOfScores());
- resultTmp=(scorer02->calculateScore(vecLine));
- result+=(weight * resultTmp);
- }
- else if (vecScorerType.at(weightIncrement).compare("PER")==0)
- {
- PerScorer* scorer03= new PerScorer("");
- weight=weightsModifier.at(weightIncrement) / denom;
- vecLine.clear();
- vecLine=subVector(comps, pos,pos+(int)(scorer03->NumberOfScores()));
- pos=pos+(int)(scorer03->NumberOfScores());
- resultTmp=(scorer03->calculateScore(vecLine));
- result+=(weight * result);
- }
- else if (vecScorerType.at(weightIncrement).compare("CER")==0)
- {
- CderScorer* scorer04= new CderScorer("");
- weight=weightsModifier.at(weightIncrement) / denom;
- vecLine.clear();
- vecLine=subVector(comps, pos,pos+(int)(scorer04->NumberOfScores()));
- pos=pos+(int)(scorer04->NumberOfScores());
- resultTmp=(scorer04->calculateScore(vecLine));
- result+=(weight * resultTmp);
- }
+ float result=0.0;
+ float weight=1.0;
+ float resultTmp=0.0;
+ vector<int> vecLine;
+ vector<string> vecScorerType;
+ vector<float> weightsModifier;
+ int pos=0;
+ int weightIncrement=0;
+ string initfile="merge.init";
+ string line;
+ ifstream opt(initfile.c_str());
+ float denom=0.0;
+ if (opt.fail()) {
+ cerr<<"MergeScorer::calculateScore : could not open initfile: " << initfile << endl;
+ exit(3);
+ }
+ while (getline (opt, line)) {
+ vector<string> vecLine=stringToVector(line, " ");
+ if ((int)vecLine.size() != 4) {
+ cerr<<"MergeScorer::calculateScore : Error in initfile: " << initfile << endl;
+ exit(4);
+ }
+ vecScorerType.push_back(vecLine.at(0));
+ weightsModifier.push_back(atof(vecLine.at(1).c_str()));
+ denom+=abs(atof(vecLine.at(1).c_str()));
+ }
+ for (weightIncrement = 0; weightIncrement < (int) weightsModifier.size(); weightIncrement++)
+ {
+ if (vecScorerType.at(weightIncrement).compare("BLEU")==0)
+ {
+ BleuScorer* scorer01= new BleuScorer("");
+ weight=weightsModifier.at(weightIncrement) / denom;
+ vecLine.clear();
+ vecLine=subVector(comps, pos,pos+(int)(scorer01->NumberOfScores()));
+ pos=pos+(int)(scorer01->NumberOfScores());
+ resultTmp=(scorer01->calculateScore(vecLine));
+ result+=(weight * resultTmp);
- else
- {
- throw runtime_error("MergeScorer::calculateScore : Scorer unknown");
- exit(0);
- }
- }
- return result;
+ }
+ else if (vecScorerType.at(weightIncrement).compare("TER")==0)
+ {
+ TerScorer* scorer02= new TerScorer("");
+ weight=weightsModifier.at(weightIncrement) / denom;
+ vecLine.clear();
+ vecLine=subVector(comps, pos,pos+(int)(scorer02->NumberOfScores()));
+ pos=pos+(int)(scorer02->NumberOfScores());
+ resultTmp=(scorer02->calculateScore(vecLine));
+ result+=(weight * resultTmp);
+ }
+ else if (vecScorerType.at(weightIncrement).compare("PER")==0)
+ {
+ PerScorer* scorer03= new PerScorer("");
+ weight=weightsModifier.at(weightIncrement) / denom;
+ vecLine.clear();
+ vecLine=subVector(comps, pos,pos+(int)(scorer03->NumberOfScores()));
+ pos=pos+(int)(scorer03->NumberOfScores());
+ resultTmp=(scorer03->calculateScore(vecLine));
+ result+=(weight * result);
+ }
+ else if (vecScorerType.at(weightIncrement).compare("CER")==0)
+ {
+ CderScorer* scorer04= new CderScorer("");
+ weight=weightsModifier.at(weightIncrement) / denom;
+ vecLine.clear();
+ vecLine=subVector(comps, pos,pos+(int)(scorer04->NumberOfScores()));
+ pos=pos+(int)(scorer04->NumberOfScores());
+ resultTmp=(scorer04->calculateScore(vecLine));
+ result+=(weight * resultTmp);
+ }
+ else
+ {
+ throw runtime_error("MergeScorer::calculateScore : Scorer unknown");
+ exit(0);
+ }
+ }
+ return result;
}
diff --git a/mert/MergeScorer.h b/mert/MergeScorer.h
index 6b31a1119..10e034ac6 100644
--- a/mert/MergeScorer.h
+++ b/mert/MergeScorer.h
@@ -1,73 +1,53 @@
#ifndef __MERGESCORER_H__
#define __MERGESCORER_H__
-// #include <stdio.h>
-#include <algorithm>
-#include <cmath>
#include <iostream>
-#include <iterator>
#include <set>
-#include <sstream>
-#include <stdexcept>
#include <string>
#include <vector>
-#include <limits.h>
-#include "Types.h"
-#include "ScoreData.h"
+
#include "Scorer.h"
-#include "TerScorer.h"
-#include "BleuScorer.h"
-#include "PerScorer.h"
-#include "CderScorer.h"
-//#include "TERsrc/tercalc.h"
-//#include "TERsrc/terAlignment.h"
using namespace std;
-using namespace TERCpp;
// enum MergeReferenceLengthStrategy { MERGE_AVERAGE, MERGE_SHORTEST, MERGE_CLOSEST };
+class PerScorer;
+class ScoreStats;
/**
- * Bleu scoring
- **/
+ * Merge scoring.
+ */
class MergeScorer: public StatisticsBasedScorer {
-
- public:
- MergeScorer(const string& config = "") : StatisticsBasedScorer("MERGE",config){}
- virtual void setReferenceFiles(const vector<string>& referenceFiles);
- virtual void prepareStats(size_t sid, const string& text, ScoreStats& entry);
- static const int LENGTH;
- virtual void whoami()
- {
- cerr << "I AM MergeScorer" << std::endl;
- }
-// size_t NumberOfScores(){ cerr << "MergeScorer: " << (2 * LENGTH + 1) << endl; return (2 * LENGTH + 1); };
-
-
- protected:
-/* friend float PerScorer::calculateScore(const vector<int>& comps);
- friend float BleuScorer::calculateScore(const vector<int>& comps);
- friend float TerScorer::calculateScore(const vector<int>& comps);
- friend float CderScorer::calculateScore(const vector<int>& comps);
-*/ friend class PerScorer;
- float calculateScore(const vector<int>& comps);
-// float calculateScore(const vector<float>& comps);
-
- private:
- string javaEnv;
- string tercomEnv;
- //no copy
- MergeScorer(const MergeScorer&);
- ~MergeScorer(){};
- MergeScorer& operator=(const MergeScorer&);
- // data extracted from reference files
- vector<size_t> _reflengths;
- vector<multiset<int> > _reftokens;
- vector<vector<int> > m_references;
- string m_pid;
-
+public:
+ explicit MergeScorer(const string& config = "");
+ ~MergeScorer();
+
+ virtual void setReferenceFiles(const vector<string>& referenceFiles);
+ virtual void prepareStats(size_t sid, const string& text, ScoreStats& entry);
+ virtual void whoami() const {
+ cerr << "I AM MergeScorer" << std::endl;
+ }
+
+protected:
+ friend class PerScorer;
+ virtual float calculateScore(const vector<int>& comps) const;
+
+ private:
+ const int kLENGTH;
+
+ string javaEnv;
+ string tercomEnv;
+
+ // data extracted from reference files
+ vector<size_t> _reflengths;
+ vector<multiset<int> > _reftokens;
+ vector<vector<int> > m_references;
+ string m_pid;
+
+ // no copying allowed
+ MergeScorer(const MergeScorer&);
+ MergeScorer& operator=(const MergeScorer&);
};
-
-#endif //__TERSCORER_H
+#endif //__TERSCORER_H
diff --git a/mert/Optimizer.cpp b/mert/Optimizer.cpp
index 040d60e60..cd9703ddd 100644
--- a/mert/Optimizer.cpp
+++ b/mert/Optimizer.cpp
@@ -1,226 +1,236 @@
+#include "Optimizer.h"
+
+#include <cmath>
#include <cassert>
#include <vector>
#include <limits>
-#include <list>
+#include <map>
#include <cfloat>
#include <iostream>
-#include "Optimizer.h"
+#include "Point.h"
+#include "Util.h"
using namespace std;
-static const float MIN_FLOAT=-1.0*numeric_limits<float>::max();
-static const float MAX_FLOAT=numeric_limits<float>::max();
+static const float MIN_FLOAT = -1.0 * numeric_limits<float>::max();
+static const float MAX_FLOAT = numeric_limits<float>::max();
+namespace {
-
-void Optimizer::SetScorer(Scorer *S)
+/**
+ * Compute the intersection of 2 lines.
+ */
+inline float intersect(float m1, float b1, float m2, float b2)
{
- if(scorer)
- delete scorer;
- scorer=S;
+ float isect = (b2 - b1) / (m1 - m2);
+ if (!isfinite(isect)) {
+ isect = MAX_FLOAT;
+ }
+ return isect;
}
-void Optimizer::SetFData(FeatureData *F)
-{
- if(FData)
- delete FData;
- FData=F;
-};
+} // namespace
-Optimizer::Optimizer(unsigned Pd,vector<unsigned> i2O,vector<parameter_t> start, unsigned int nrandom):scorer(NULL),FData(NULL),number_of_random_directions(nrandom)
+
+void Optimizer::SetScorer(Scorer *_scorer)
{
- //warning: the init vector is a full set of parameters, of dimension pdim!
+ scorer = _scorer;
+}
- Point::pdim=Pd;
+void Optimizer::SetFData(FeatureData *_FData)
+{
+ FData = _FData;
+}
- assert(start.size()==Pd);
- Point::dim=i2O.size();
- Point::optindices=i2O;
- if (Point::pdim>Point::dim) {
- for (unsigned int i=0; i<Point::pdim; i++) {
+Optimizer::Optimizer(unsigned Pd, vector<unsigned> i2O, vector<parameter_t> start, unsigned int nrandom)
+ : scorer(NULL), FData(NULL), number_of_random_directions(nrandom)
+{
+ // Warning: the init vector is a full set of parameters, of dimension pdim!
+ Point::pdim = Pd;
+
+ assert(start.size() == Pd);
+ Point::dim = i2O.size();
+ Point::optindices = i2O;
+ if (Point::pdim > Point::dim) {
+ for (unsigned int i = 0; i < Point::pdim; i++) {
unsigned int j = 0;
- while (j<Point::dim && i!=i2O[j])
+ while (j < Point::dim && i != i2O[j])
j++;
- if (j==Point::dim)//the index i wasnt found on optindices, it is a fixed index, we use the value of the start vector
- Point::fixedweights[i]=start[i];
+ // The index i wasnt found on optindices, it is a fixed index,
+ // we use the value of the start vector.
+ if (j == Point::dim)
+ Point::fixedweights[i] = start[i];
}
}
-};
-
-Optimizer::~Optimizer()
-{
- delete scorer;
- delete FData;
}
-statscore_t Optimizer::GetStatScore(const Point& param)const
+Optimizer::~Optimizer() {}
+
+statscore_t Optimizer::GetStatScore(const Point& param) const
{
vector<unsigned> bests;
- Get1bests(param,bests);
+ Get1bests(param, bests);
//copy(bests.begin(),bests.end(),ostream_iterator<unsigned>(cerr," "));
statscore_t score = GetStatScore(bests);
return score;
-};
-
-/**compute the intersection of 2 lines*/
-float intersect (float m1, float b1,float m2,float b2)
-{
- float isect = ((b2-b1)/(m1-m2));
- if (!isfinite(isect)) {
- isect = MAX_FLOAT;
- }
- return isect;
}
-map<float,diff_t >::iterator AddThreshold(map<float,diff_t >& thresholdmap,float newt,pair<unsigned,unsigned> newdiff)
+map<float,diff_t >::iterator AddThreshold(map<float,diff_t >& thresholdmap, float newt, pair<unsigned,unsigned> newdiff)
{
- map<float,diff_t>::iterator it=thresholdmap.find(newt);
- if(it!=thresholdmap.end()) {
- //the threshold already exists!! this is very unlikely
- if(it->second.back().first==newdiff.first)
- it->second.back().second=newdiff.second;//there was already a diff for this sentence, we change the 1 best;
+ map<float,diff_t>::iterator it = thresholdmap.find(newt);
+ if (it != thresholdmap.end()) {
+ // the threshold already exists!! this is very unlikely
+ if (it->second.back().first == newdiff.first)
+ // there was already a diff for this sentence, we change the 1 best;
+ it->second.back().second = newdiff.second;
else
it->second.push_back(newdiff);
} else {
- //normal case
- pair< map<float,diff_t >::iterator,bool > ins=thresholdmap.insert(threshold(newt,diff_t(1,newdiff)));
- assert(ins.second);//we really inserted something
- it=ins.first;
+ // normal case
+ pair<map<float,diff_t>::iterator, bool> ins = thresholdmap.insert(threshold(newt, diff_t(1, newdiff)));
+ assert(ins.second); // we really inserted something
+ it = ins.first;
}
return it;
-};
-
+}
-statscore_t Optimizer::LineOptimize(const Point& origin,const Point& direction,Point& bestpoint)const
+statscore_t Optimizer::LineOptimize(const Point& origin, const Point& direction, Point& bestpoint) const
{
-
-// we are looking for the best Point on the line y=Origin+x*direction
- float min_int=0.0001;
+ // We are looking for the best Point on the line y=Origin+x*direction
+ float min_int = 0.0001;
//typedef pair<unsigned,unsigned> diff;//first the sentence that changes, second is the new 1best for this sentence
//list<threshold> thresholdlist;
map<float,diff_t> thresholdmap;
- thresholdmap[MIN_FLOAT]=diff_t();
- vector<unsigned> first1best;//the vector of nbests for x=-inf
- for(unsigned int S=0; S<size(); S++) {
- map<float,diff_t >::iterator previnserted=thresholdmap.begin();
- //first we determine the translation with the best feature score for each sentence and each value of x
+ thresholdmap[MIN_FLOAT] = diff_t();
+ vector<unsigned> first1best; // the vector of nbests for x=-inf
+ for (unsigned int S = 0; S < size(); S++) {
+ map<float,diff_t >::iterator previnserted = thresholdmap.begin();
+ // First, we determine the translation with the best feature score
+ // for each sentence and each value of x.
//cerr << "Sentence " << S << endl;
- multimap<float,unsigned> gradient;
+ multimap<float, unsigned> gradient;
vector<float> f0;
f0.resize(FData->get(S).size());
- for(unsigned j=0; j<FData->get(S).size(); j++) {
- gradient.insert(pair<float,unsigned>(direction*(FData->get(S,j)),j));//gradient of the feature function for this particular target sentence
- f0[j]=origin*FData->get(S,j);//compute the feature function at the origin point
+ for (unsigned j = 0; j < FData->get(S).size(); j++) {
+ // gradient of the feature function for this particular target sentence
+ gradient.insert(pair<float, unsigned>(direction * (FData->get(S,j)), j));
+ // compute the feature function at the origin point
+ f0[j] = origin * FData->get(S, j);
}
- //now lets compute the 1best for each value of x
+ // Now let's compute the 1best for each value of x.
// vector<pair<float,unsigned> > onebest;
- multimap<float,unsigned>::iterator gradientit=gradient.begin();
- multimap<float,unsigned>::iterator highest_f0=gradient.begin();
+ multimap<float,unsigned>::iterator gradientit = gradient.begin();
+ multimap<float,unsigned>::iterator highest_f0 = gradient.begin();
- float smallest=gradientit->first;//smallest gradient
- //several candidates can have the lowest slope (eg for word penalty where the gradient is an integer )
+ float smallest = gradientit->first;//smallest gradient
+ // Several candidates can have the lowest slope (e.g., for word penalty where the gradient is an integer).
gradientit++;
- while(gradientit!=gradient.end()&&gradientit->first==smallest) {
+ while (gradientit != gradient.end() && gradientit->first == smallest) {
// cerr<<"ni"<<gradientit->second<<endl;;
//cerr<<"fos"<<f0[gradientit->second]<<" "<<f0[index]<<" "<<index<<endl;
- if(f0[gradientit->second]>f0[highest_f0->second])
- highest_f0=gradientit;//the highest line is the one with he highest f0
+ if (f0[gradientit->second] > f0[highest_f0->second])
+ highest_f0 = gradientit;//the highest line is the one with he highest f0
gradientit++;
}
gradientit = highest_f0;
first1best.push_back(highest_f0->second);
- //now we look for the intersections points indicating a change of 1 best
- //we use the fact that the function is convex, which means that the gradient can only go up
- while(gradientit!=gradient.end()) {
- map<float,unsigned>::iterator leftmost=gradientit;
- float m=gradientit->first;
- float b=f0[gradientit->second];
- multimap<float,unsigned>::iterator gradientit2=gradientit;
+ // Now we look for the intersections points indicating a change of 1 best.
+ // We use the fact that the function is convex, which means that the gradient can only go up.
+ while (gradientit != gradient.end()) {
+ map<float,unsigned>::iterator leftmost = gradientit;
+ float m = gradientit->first;
+ float b = f0[gradientit->second];
+ multimap<float,unsigned>::iterator gradientit2 = gradientit;
gradientit2++;
- float leftmostx=MAX_FLOAT;
- for(; gradientit2!=gradient.end(); gradientit2++) {
+ float leftmostx = MAX_FLOAT;
+ for (; gradientit2 != gradient.end(); gradientit2++) {
//cerr<<"--"<<d++<<' '<<gradientit2->first<<' '<<gradientit2->second<<endl;
- //look for all candidate with a gradient bigger than the current one and find the one with the leftmost intersection
+ // Look for all candidate with a gradient bigger than the current one, and
+ // find the one with the leftmost intersection.
float curintersect;
- if(m!=gradientit2->first) {
- curintersect=intersect(m,b,gradientit2->first,f0[gradientit2->second]);
+ if (m != gradientit2->first) {
+ curintersect = intersect(m, b, gradientit2->first, f0[gradientit2->second]);
//cerr << "curintersect: " << curintersect << " leftmostx: " << leftmostx << endl;
- if(curintersect<=leftmostx) {
- //we have found an intersection to the left of the leftmost we had so far.
- //we might have curintersect==leftmostx for example is 2 candidates are the same
- //in that case its better its better to update leftmost to gradientit2 to avoid some recomputing later
- leftmostx=curintersect;
- leftmost=gradientit2;//this is the new reference
+ if (curintersect<=leftmostx) {
+ // We have found an intersection to the left of the leftmost we had so far.
+ // We might have curintersect==leftmostx for example is 2 candidates are the same
+ // in that case its better its better to update leftmost to gradientit2 to avoid some recomputing later.
+ leftmostx = curintersect;
+ leftmost = gradientit2; // this is the new reference
}
}
}
if (leftmost == gradientit) {
- //we didn't find any more intersections
- //the rightmost bestindex is the one with the highest slope.
- assert(abs(leftmost->first-gradient.rbegin()->first)<0.0001);//they should be egal but there might be
- //a small difference due to rounding error
+ // We didn't find any more intersections.
+ // The rightmost bestindex is the one with the highest slope.
+
+ // They should be equal but there might be.
+ assert(abs(leftmost->first-gradient.rbegin()->first) < 0.0001);
+ // A small difference due to rounding error
break;
}
- //we have found the next intersection!
-
- pair<unsigned,unsigned> newd(S,leftmost->second);//new onebest for Sentence S is leftmost->second
-
- if(leftmostx-previnserted->first<min_int) {
- /* Require that the intersection Point be at least min_int
- to the right of the previous one(for this sentence). If not, we replace the
- previous intersection Point with this one. Yes, it can even
- happen that the new intersection Point is slightly to the
- left of the old one, because of numerical imprecision.
- we do not check that we are to the right of the penultimate point also. it this happen the 1best the inteval will be wrong
- we are going to replace previnsert by the new one because we do not want to keep
- 2 very close threshold: if the minima is there it could be an artifact
- */
- map<float,diff_t>::iterator tit=thresholdmap.find(leftmostx);
- if(tit==previnserted) {
- //the threshold is the same as before can happen if 2 candidates are the same for example
- assert(previnserted->second.back().first==newd.first);
- previnserted->second.back()=newd;//just replace the 1 best fors sentence S
- //previnsert doesnt change
+ // We have found the next intersection!
+
+ pair<unsigned,unsigned> newd(S, leftmost->second);//new onebest for Sentence S is leftmost->second
+
+ if (leftmostx-previnserted->first < min_int) {
+ // Require that the intersection Point be at least min_int to the right of the previous
+ // one (for this sentence). If not, we replace the previous intersection Point with
+ // this one.
+ // Yes, it can even happen that the new intersection Point is slightly to the left of
+ // the old one, because of numerical imprecision. We do not check that we are to the
+ // right of the penultimate point also. It this happen the 1best the interval will
+ // be wrong we are going to replace previnsert by the new one because we do not want to keep
+ // 2 very close threshold: if the minima is there it could be an artifact.
+
+ map<float,diff_t>::iterator tit = thresholdmap.find(leftmostx);
+ if (tit == previnserted) {
+ // The threshold is the same as before can happen if 2 candidates are the same for example.
+ assert(previnserted->second.back().first == newd.first);
+ previnserted->second.back()=newd; // just replace the 1 best for sentence S
+ // previnsert doesn't change
} else {
- if(tit==thresholdmap.end()) {
- thresholdmap[leftmostx]=previnserted->second;//We keep the diffs at previnsert
- thresholdmap.erase(previnserted);//erase old previnsert
- previnserted=thresholdmap.find(leftmostx);//point previnsert to the new threshold
- previnserted->second.back()=newd;//we update the diff for sentence S
- } else { //threshold already exists but is not the previous one.
- //we append the diffs in previnsert to tit before destroying previnsert
+ if (tit == thresholdmap.end()) {
+ thresholdmap[leftmostx]=previnserted->second; // We keep the diffs at previnsert
+ thresholdmap.erase(previnserted); // erase old previnsert
+ previnserted = thresholdmap.find(leftmostx); // point previnsert to the new threshold
+ previnserted->second.back()=newd; // We update the diff for sentence S
+ // Threshold already exists but is not the previous one.
+ } else {
+ // We append the diffs in previnsert to tit before destroying previnsert.
tit->second.insert(tit->second.end(),previnserted->second.begin(),previnserted->second.end());
- assert(tit->second.back().first==newd.first);
- tit->second.back()=newd;//change diff for sentence S
- thresholdmap.erase(previnserted);//erase old previnsert
- previnserted=tit;//point previnsert to the new threshold
+ assert(tit->second.back().first == newd.first);
+ tit->second.back()=newd; // change diff for sentence S
+ thresholdmap.erase(previnserted); // erase old previnsert
+ previnserted = tit; // point previnsert to the new threshold
}
}
assert(previnserted != thresholdmap.end());
} else { //normal insertion process
- previnserted=AddThreshold(thresholdmap,leftmostx,newd);
+ previnserted = AddThreshold(thresholdmap, leftmostx, newd);
}
- gradientit=leftmost;
- } //while(gradientit!=gradient.end()){
- } //loop on S
- //now the thresholdlist is up to date:
- //it contains a list of all the parameter_ts where the function changed its value, along with the nbest list for the interval after each threshold
+ gradientit = leftmost;
+ } // while (gradientit!=gradient.end()){
+ } // loop on S
+
+ // Now the thresholdlist is up to date: it contains a list of all the parameter_ts where
+ // the function changed its value, along with the nbest list for the interval after each threshold.
map<float,diff_t >::iterator thrit;
- if(verboselevel()>6) {
- cerr << "Thresholds:(" <<thresholdmap.size()<<")"<< endl;
- for (thrit = thresholdmap.begin(); thrit!=thresholdmap.end(); thrit++) {
+ if (verboselevel() > 6) {
+ cerr << "Thresholds:(" << thresholdmap.size() << ")" << endl;
+ for (thrit = thresholdmap.begin(); thrit != thresholdmap.end(); thrit++) {
cerr << "x: " << thrit->first << " diffs";
for (size_t j = 0; j < thrit->second.size(); ++j) {
cerr << " " <<thrit->second[j].first << "," << thrit->second[j].second;
@@ -229,31 +239,33 @@ statscore_t Optimizer::LineOptimize(const Point& origin,const Point& direction,P
}
}
- //last thing to do is compute the Stat score (ie BLEU) and find the minimum
- thrit=thresholdmap.begin();
- ++thrit;//first diff corrrespond to MIN_FLOAT and first1best
+ // Last thing to do is compute the Stat score (i.e., BLEU) and find the minimum.
+ thrit = thresholdmap.begin();
+ ++thrit; // first diff corrrespond to MIN_FLOAT and first1best
diffs_t diffs;
- for(; thrit!=thresholdmap.end(); thrit++)
+ for (; thrit != thresholdmap.end(); thrit++)
diffs.push_back(thrit->second);
- vector<statscore_t> scores=GetIncStatScore(first1best,diffs);
+ vector<statscore_t> scores = GetIncStatScore(first1best, diffs);
+
+ thrit = thresholdmap.begin();
+ statscore_t bestscore = MIN_FLOAT;
+ float bestx = MIN_FLOAT;
- thrit=thresholdmap.begin();
- statscore_t bestscore=MIN_FLOAT;
- float bestx=MIN_FLOAT;
- assert(scores.size()==thresholdmap.size());//we skipped the first el of thresholdlist but GetIncStatScore return 1 more for first1best
- for(unsigned int sc=0; sc!=scores.size(); sc++) {
+ // We skipped the first el of thresholdlist but GetIncStatScore return 1 more for first1best.
+ assert(scores.size() == thresholdmap.size());
+ for (unsigned int sc = 0; sc != scores.size(); sc++) {
//cerr << "x=" << thrit->first << " => " << scores[sc] << endl;
if (scores[sc] > bestscore) {
- //This is the score for the interval [lit2->first, (lit2+1)->first]
- //unless we're at the last score, when it's the score
- //for the interval [lit2->first,+inf]
+ // This is the score for the interval [lit2->first, (lit2+1)->first]
+ // unless we're at the last score, when it's the score
+ // for the interval [lit2->first,+inf].
bestscore = scores[sc];
- //if we're not in [-inf,x1] or [xn,+inf] then just take the value
- //if x which splits the interval in half. For the rightmost interval,
- //take x to be the last interval boundary + 0.1, and for the leftmost
- //interval, take x to be the first interval boundary - 1000.
- //These values are taken from cmert.
+ // If we're not in [-inf,x1] or [xn,+inf], then just take the value
+ // if x which splits the interval in half. For the rightmost interval,
+ // take x to be the last interval boundary + 0.1, and for the leftmost
+ // interval, take x to be the first interval boundary - 1000.
+ // These values are taken from cmert.
float leftx = thrit->first;
if (thrit == thresholdmap.begin()) {
leftx = MIN_FLOAT;
@@ -268,7 +280,7 @@ statscore_t Optimizer::LineOptimize(const Point& origin,const Point& direction,P
if (leftx == MIN_FLOAT) {
bestx = rightx-1000;
} else if (rightx == MAX_FLOAT) {
- bestx = leftx+0.1;
+ bestx = leftx + 0.1;
} else {
bestx = 0.5 * (rightx + leftx);
}
@@ -277,37 +289,39 @@ statscore_t Optimizer::LineOptimize(const Point& origin,const Point& direction,P
++thrit;
}
- if(abs(bestx)<0.00015) {
- bestx=0.0;//the origin of the line is the best point!we put it back at 0 so we do not propagate rounding erros
- //finally! we manage to extract the best score;
- //now we convert bestx (position on the line) to a point!
- if(verboselevel()>4)
- cerr<<"best point on line at origin"<<endl;
+ if (abs(bestx) < 0.00015) {
+ // The origin of the line is the best point! We put it back at 0
+ // so we do not propagate rounding erros.
+ bestx = 0.0;
+
+ // Finally, we manage to extract the best score;
+ // now we convert bestx (position on the line) to a point.
+ if (verboselevel() > 4)
+ cerr << "best point on line at origin" << endl;
}
- if(verboselevel()>3) {
+ if (verboselevel() > 3) {
// cerr<<"end Lineopt, bestx="<<bestx<<endl;
}
- bestpoint=direction*bestx+origin;
- bestpoint.score=bestscore;
+ bestpoint = direction * bestx + origin;
+ bestpoint.SetScore(bestscore);
return bestscore;
-};
-
+}
-void Optimizer::Get1bests(const Point& P,vector<unsigned>& bests)const
+void Optimizer::Get1bests(const Point& P, vector<unsigned>& bests) const
{
assert(FData);
bests.clear();
bests.resize(size());
- for(unsigned i=0; i<size(); i++) {
- float bestfs=MIN_FLOAT;
- unsigned idx=0;
+ for (unsigned i = 0; i < size(); i++) {
+ float bestfs = MIN_FLOAT;
+ unsigned idx = 0;
unsigned j;
- for(j=0; j<FData->get(i).size(); j++) {
- float curfs=P*FData->get(i,j);
- if(curfs>bestfs) {
- bestfs=curfs;
- idx=j;
+ for (j = 0; j < FData->get(i).size(); j++) {
+ float curfs = P * FData->get(i, j);
+ if (curfs > bestfs) {
+ bestfs = curfs;
+ idx = j;
}
}
bests[i]=idx;
@@ -315,173 +329,169 @@ void Optimizer::Get1bests(const Point& P,vector<unsigned>& bests)const
}
-statscore_t Optimizer::Run(Point& P)const
+statscore_t Optimizer::Run(Point& P) const
{
- if(!FData) {
- cerr<<"error trying to optimize without Features loaded"<<endl;
+ if (!FData) {
+ cerr << "error trying to optimize without Features loaded" << endl;
exit(2);
}
- if(!scorer) {
- cerr<<"error trying to optimize without a Scorer loaded"<<endl;
+ if (!scorer) {
+ cerr << "error trying to optimize without a Scorer loaded" << endl;
exit(2);
}
- if (scorer->getReferenceSize()!=FData->size()) {
- cerr<<"error length mismatch between feature file and score file"<<endl;
+ if (scorer->getReferenceSize() != FData->size()) {
+ cerr << "error length mismatch between feature file and score file" << endl;
exit(2);
}
- statscore_t score=GetStatScore(P);
- P.score=score;
+ P.SetScore(GetStatScore(P));
+
+ if (verboselevel () > 2) {
+ cerr << "Starting point: " << P << " => " << P.GetScore() << endl;
+ }
+ statscore_t score = TrueRun(P);
- if(verboselevel()>2)
- cerr<<"Starting point: "<< P << " => "<< P.score << endl;
- statscore_t s=TrueRun(P);
- P.score=s;//just in case its not done in TrueRun
- if (verboselevel()>2)
- cerr<<"Ending point: "<< P <<" => "<< s << endl;
- return s;
+ // just in case its not done in TrueRun
+ P.SetScore(score);
+ if (verboselevel() > 2) {
+ cerr << "Ending point: " << P << " => " << score << endl;
+ }
+ return score;
}
-vector<statscore_t> Optimizer::GetIncStatScore(vector<unsigned> thefirst,vector<vector <pair<unsigned,unsigned> > > thediffs)const
+vector<statscore_t> Optimizer::GetIncStatScore(vector<unsigned> thefirst, vector<vector <pair<unsigned,unsigned> > > thediffs) const
{
assert(scorer);
vector<statscore_t> theres;
- scorer->score(thefirst,thediffs,theres);
+ scorer->score(thefirst, thediffs, theres);
return theres;
-};
-
-
+}
-//---------------- code for the powell optimizer
-float SimpleOptimizer::eps=0.0001;
-statscore_t SimpleOptimizer::TrueRun(Point& P)const
+statscore_t SimpleOptimizer::TrueRun(Point& P) const
{
-
- statscore_t prevscore=0;
- statscore_t bestscore=MIN_FLOAT;
- Point best;
-
- //If P is already defined and provides a score
- //we must improve over this score
- if(P.score>bestscore) {
- bestscore=P.score;
- best=P;
+ statscore_t prevscore = 0;
+ statscore_t bestscore = MIN_FLOAT;
+ Point best;
+
+ // If P is already defined and provides a score,
+ // We must improve over this score.
+ if (P.GetScore() > bestscore) {
+ bestscore = P.GetScore();
+ best = P;
}
- int nrun=0;
+ int nrun = 0;
do {
++nrun;
- if(verboselevel()>2&&nrun>1)
- cerr<<"last diff="<<bestscore-prevscore<<" nrun "<<nrun<<endl;
- prevscore=bestscore;
+ if (verboselevel() > 2 && nrun > 1)
+ cerr << "last diff=" << bestscore-prevscore << " nrun " << nrun << endl;
+ prevscore = bestscore;
Point linebest;
- for(unsigned int d=0; d<Point::getdim()+number_of_random_directions; d++) {
- if(verboselevel()>4) {
+ for (unsigned int d = 0; d < Point::getdim()+number_of_random_directions; d++) {
+ if (verboselevel() > 4) {
// cerr<<"minimizing along direction "<<d<<endl;
- cerr<<"starting point: " << P << " => " << prevscore << endl;
+ cerr << "starting point: " << P << " => " << prevscore << endl;
}
Point direction;
- if (d<Point::getdim()) { // regular updates along one dimension
- for(unsigned int i=0; i<Point::getdim(); i++)
+ if (d < Point::getdim()) { // regular updates along one dimension
+ for (unsigned int i = 0; i < Point::getdim(); i++)
direction[i]=0.0;
direction[d]=1.0;
}
else { // random direction update
direction.Randomize();
}
- statscore_t curscore=LineOptimize(P,direction,linebest);//find the minimum on the line
- if(verboselevel()>5) {
- cerr<<"direction: "<< d << " => " << curscore << endl;
- cerr<<"\tending point: "<< linebest << " => " << curscore << endl;
+ statscore_t curscore = LineOptimize(P, direction, linebest);//find the minimum on the line
+ if (verboselevel() > 5) {
+ cerr << "direction: " << d << " => " << curscore << endl;
+ cerr << "\tending point: "<< linebest << " => " << curscore << endl;
}
- if(curscore>bestscore) {
- bestscore=curscore;
- best=linebest;
- if(verboselevel()>3) {
- cerr<<"new best dir:"<<d<<" ("<<nrun<<")"<<endl;
- cerr<<"new best Point "<<best<< " => " <<curscore<<endl;
+ if (curscore > bestscore) {
+ bestscore = curscore;
+ best = linebest;
+ if (verboselevel() > 3) {
+ cerr << "new best dir:" << d << " (" << nrun << ")" << endl;
+ cerr << "new best Point " << best << " => " << curscore << endl;
}
}
}
- P=best;//update the current vector with the best point on all line tested
- if(verboselevel()>3)
- cerr<<nrun<<"\t"<<P<<endl;
- } while(bestscore-prevscore>eps);
-
- if(verboselevel()>2) {
- cerr<<"end Powell Algo, nrun="<<nrun<<endl;
- cerr<<"last diff="<<bestscore-prevscore<<endl;
- cerr<<"\t"<<P<<endl;
+ P = best; //update the current vector with the best point on all line tested
+ if (verboselevel() > 3)
+ cerr << nrun << "\t" << P << endl;
+ } while (bestscore-prevscore > kEPS);
+
+ if (verboselevel() > 2) {
+ cerr << "end Powell Algo, nrun=" << nrun << endl;
+ cerr << "last diff=" << bestscore-prevscore << endl;
+ cerr << "\t" << P << endl;
}
return bestscore;
}
-//---------------- code for the optimizer with random directions
-float RandomDirectionOptimizer::eps=0.0001;
-statscore_t RandomDirectionOptimizer::TrueRun(Point& P)const
+statscore_t RandomDirectionOptimizer::TrueRun(Point& P) const
{
- statscore_t prevscore=P.score;
+ statscore_t prevscore = P.GetScore();
// do specified number of random direction optimizations
unsigned int nrun = 0;
unsigned int nrun_no_change = 0;
- for(; nrun_no_change<number_of_random_directions; nrun++, nrun_no_change++)
+ for (; nrun_no_change < number_of_random_directions; nrun++, nrun_no_change++)
{
// choose a random direction in which to optimize
Point direction;
direction.Randomize();
//find the minimum on the line
- statscore_t score=LineOptimize(P,direction,P);
- if(verboselevel()>4) {
- cerr<<"direction: "<< direction << " => " << score;
- cerr<<" ("<< (score-prevscore) << ")" << endl;
- cerr<<"\tending point: "<< P << " => " << score << endl;
+ statscore_t score = LineOptimize(P, direction, P);
+ if (verboselevel() > 4) {
+ cerr << "direction: " << direction << " => " << score;
+ cerr << " (" << (score-prevscore) << ")" << endl;
+ cerr << "\tending point: " << P << " => " << score << endl;
}
- if (score-prevscore > eps)
- nrun_no_change=0;
+ if (score-prevscore > kEPS)
+ nrun_no_change = 0;
prevscore = score;
}
- if(verboselevel()>2) {
- cerr<<"end Powell Algo, nrun="<<nrun<<endl;
+ if (verboselevel() > 2) {
+ cerr << "end Powell Algo, nrun=" << nrun << endl;
}
return prevscore;
}
-/**RandomOptimizer to use as beaseline and test.\n
-Just return a random point*/
-statscore_t RandomOptimizer::TrueRun(Point& P)const
+statscore_t RandomOptimizer::TrueRun(Point& P) const
{
P.Randomize();
- statscore_t score=GetStatScore(P);
- P.score=score;
+ statscore_t score = GetStatScore(P);
+ P.SetScore(score);
return score;
}
+
//--------------------------------------
+
vector<string> OptimizerFactory::typenames;
void OptimizerFactory::SetTypeNames()
{
- if(typenames.empty()) {
+ if (typenames.empty()) {
typenames.resize(NOPTIMIZER);
typenames[POWELL]="powell";
typenames[RANDOM_DIRECTION]="random-direction";
typenames[RANDOM]="random";
- //add new type there
+ // Add new type there
}
}
vector<string> OptimizerFactory::GetTypeNames()
{
- if(typenames.empty())
+ if (typenames.empty())
SetTypeNames();
return typenames;
}
@@ -489,38 +499,38 @@ vector<string> OptimizerFactory::GetTypeNames()
OptimizerFactory::OptType OptimizerFactory::GetOType(string type)
{
unsigned int thetype;
- if(typenames.empty())
+ if (typenames.empty())
SetTypeNames();
- for(thetype=0; thetype<typenames.size(); thetype++)
- if(typenames[thetype]==type)
+ for (thetype = 0; thetype < typenames.size(); thetype++)
+ if (typenames[thetype] == type)
break;
return((OptType)thetype);
-};
+}
-Optimizer* OptimizerFactory::BuildOptimizer(unsigned dim,vector<unsigned> i2o,vector<parameter_t> start,string type, unsigned int nrandom)
+Optimizer* OptimizerFactory::BuildOptimizer(unsigned dim, vector<unsigned> i2o, vector<parameter_t> start, string type, unsigned int nrandom)
{
- OptType T=GetOType(type);
- if(T==NOPTIMIZER) {
- cerr<<"Error: unknown Optimizer type "<<type<<endl;
- cerr<<"Known Algorithm are:"<<endl;
+ OptType T = GetOType(type);
+ if (T == NOPTIMIZER) {
+ cerr << "Error: unknown Optimizer type " << type << endl;
+ cerr << "Known Algorithm are:" << endl;
unsigned int thetype;
- for(thetype=0; thetype<typenames.size(); thetype++)
- cerr<<typenames[thetype]<<endl;
+ for (thetype = 0; thetype < typenames.size(); thetype++)
+ cerr << typenames[thetype] << endl;
throw ("unknown Optimizer Type");
}
- switch((OptType)T) {
- case POWELL:
- return new SimpleOptimizer(dim,i2o,start,nrandom);
- break;
- case RANDOM_DIRECTION:
- return new RandomDirectionOptimizer(dim,i2o,start,nrandom);
- break;
- case RANDOM:
- return new RandomOptimizer(dim,i2o,start,nrandom);
- break;
- default:
- cerr<<"Error: unknown optimizer"<<type<<endl;
- return NULL;
+ switch ((OptType)T) {
+ case POWELL:
+ return new SimpleOptimizer(dim, i2o, start, nrandom);
+ break;
+ case RANDOM_DIRECTION:
+ return new RandomDirectionOptimizer(dim, i2o, start, nrandom);
+ break;
+ case RANDOM:
+ return new RandomOptimizer(dim, i2o, start, nrandom);
+ break;
+ default:
+ cerr << "Error: unknown optimizer" << type << endl;
+ return NULL;
}
}
diff --git a/mert/Optimizer.h b/mert/Optimizer.h
index 9920be77f..aa588994d 100644
--- a/mert/Optimizer.h
+++ b/mert/Optimizer.h
@@ -1,93 +1,130 @@
#ifndef OPTIMIZER_H
#define OPTIMIZER_H
+
#include <vector>
-#include "FeatureStats.h"
+#include <string>
#include "FeatureData.h"
-#include "FeatureArray.h"
#include "Scorer.h"
-#include "Point.h"
#include "Types.h"
+using namespace std;
typedef float featurescore;
-using namespace std;
-/**abstract virtual class*/
+class Point;
+
+/**
+ * Abstract optimizer class.
+ */
class Optimizer
{
protected:
- Scorer * scorer; //no accessor for them only child can use them
- FeatureData * FData;//no accessor for them only child can use them
+ Scorer *scorer; // no accessor for them only child can use them
+ FeatureData *FData; // no accessor for them only child can use them
unsigned int number_of_random_directions;
+
public:
- Optimizer(unsigned Pd,vector<unsigned> i2O,vector<parameter_t> start,unsigned int nrandom);
- void SetScorer(Scorer *S);
- void SetFData(FeatureData *F);
+ Optimizer(unsigned Pd, vector<unsigned> i2O, vector<parameter_t> start, unsigned int nrandom);
+ void SetScorer(Scorer *_scorer);
+ void SetFData(FeatureData *_FData);
virtual ~Optimizer();
- unsigned size()const {
- return (FData?FData->size():0);
+ unsigned size() const {
+ return FData ? FData->size() : 0;
}
- /**Generic wrapper around TrueRun to check a few things. Non virtual*/
- statscore_t Run(Point&)const;
- /**main function that perform an optimization*/
- virtual statscore_t TrueRun(Point&)const=0;
- /**given a set of lambdas, get the nbest for each sentence*/
- void Get1bests(const Point& param,vector<unsigned>& bests)const;
- /**given a set of nbests, get the Statistical score*/
- statscore_t GetStatScore(const vector<unsigned>& nbests)const {
+
+ /**
+ * Generic wrapper around TrueRun to check a few things. Non virtual.
+ */
+ statscore_t Run(Point&) const;
+
+ /**
+ * Main function that performs an optimization.
+ */
+ virtual statscore_t TrueRun(Point&) const = 0;
+
+ /**
+ * Given a set of lambdas, get the nbest for each sentence.
+ */
+ void Get1bests(const Point& param,vector<unsigned>& bests) const;
+
+ /**
+ * Given a set of nbests, get the Statistical score.
+ */
+ statscore_t GetStatScore(const vector<unsigned>& nbests) const {
return scorer->score(nbests);
- };
- /**given a set of lambdas, get the total statistical score*/
- statscore_t GetStatScore(const Point& param)const;
- vector<statscore_t > GetIncStatScore(vector<unsigned> ref,vector<vector <pair<unsigned,unsigned> > >)const;
- statscore_t LineOptimize(const Point& start,const Point& direction,Point& best)const;//Get the optimal Lambda and the best score in a particular direction from a given Point
+ }
+
+ statscore_t GetStatScore(const Point& param) const;
+
+ vector<statscore_t> GetIncStatScore(vector<unsigned> ref, vector<vector<pair<unsigned,unsigned> > >) const;
+
+ /**
+ * Get the optimal Lambda and the best score in a particular direction from a given Point.
+ */
+ statscore_t LineOptimize(const Point& start, const Point& direction, Point& best) const;
};
-/**default basic optimizer*/
-class SimpleOptimizer: public Optimizer
+/**
+ * Default basic optimizer.
+ * This class implements Powell's method.
+ */
+class SimpleOptimizer : public Optimizer
{
private:
- static float eps;
+ const float kEPS;
public:
- SimpleOptimizer(unsigned dim,vector<unsigned> i2O,vector<parameter_t> start,unsigned int nrandom):Optimizer(dim,i2O,start,nrandom) {};
- virtual statscore_t TrueRun(Point&)const;
+ SimpleOptimizer(unsigned dim, vector<unsigned> i2O, vector<parameter_t> start, unsigned int nrandom)
+ : Optimizer(dim, i2O, start,nrandom), kEPS(0.0001) {}
+ virtual statscore_t TrueRun(Point&) const;
};
-/**optimizer with random directions*/
-class RandomDirectionOptimizer: public Optimizer
+/**
+ * An optimizer with random directions.
+ */
+class RandomDirectionOptimizer : public Optimizer
{
private:
- static float eps;
+ const float kEPS;
public:
- RandomDirectionOptimizer(unsigned dim,vector<unsigned> i2O,vector<parameter_t> start,unsigned int nrandom):Optimizer(dim,i2O,start,nrandom) {};
- virtual statscore_t TrueRun(Point&)const;
+ RandomDirectionOptimizer(unsigned dim, vector<unsigned> i2O, vector<parameter_t> start, unsigned int nrandom)
+ : Optimizer(dim, i2O, start, nrandom), kEPS(0.0001) {}
+ virtual statscore_t TrueRun(Point&) const;
};
-/**dumb baseline optimizer: just picks a random point and quits*/
-class RandomOptimizer: public Optimizer
+/**
+ * Dumb baseline optimizer: just picks a random point and quits.
+ */
+class RandomOptimizer : public Optimizer
{
public:
- RandomOptimizer(unsigned dim,vector<unsigned> i2O,vector<parameter_t> start, unsigned int nrandom):Optimizer(dim,i2O,start,nrandom) {};
- virtual statscore_t TrueRun(Point&)const;
+ RandomOptimizer(unsigned dim, vector<unsigned> i2O, vector<parameter_t> start, unsigned int nrandom)
+ : Optimizer(dim, i2O, start, nrandom) {}
+ virtual statscore_t TrueRun(Point&) const;
};
class OptimizerFactory
{
public:
- // unsigned dim;
- //Point Start;
static vector<string> GetTypeNames();
- static Optimizer* BuildOptimizer(unsigned dim,vector<unsigned>tooptimize,vector<parameter_t> start,string type,unsigned int nrandom);
+ static Optimizer* BuildOptimizer(unsigned dim, vector<unsigned> tooptimize, vector<parameter_t> start, string type, unsigned int nrandom);
+
private:
- enum OptType {POWELL=0,RANDOM_DIRECTION=1,RANDOM,NOPTIMIZER}; //Add new optimizer here BEFORE NOPTIMZER
+ OptimizerFactory() {}
+ ~OptimizerFactory() {}
+
+ // Add new optimizer here BEFORE NOPTIMZER
+ enum OptType {
+ POWELL = 0,
+ RANDOM_DIRECTION = 1,
+ RANDOM,
+ NOPTIMIZER
+ };
+
static OptType GetOType(string);
static vector<string> typenames;
static void SetTypeNames();
-
};
-
-#endif
-
+#endif // OPTIMIZER_H
diff --git a/mert/PerScorer.cpp b/mert/PerScorer.cpp
index fe3f6c135..765cb0876 100644
--- a/mert/PerScorer.cpp
+++ b/mert/PerScorer.cpp
@@ -1,10 +1,22 @@
#include "PerScorer.h"
+#include <fstream>
+#include <stdexcept>
+
+#include "ScoreStats.h"
+#include "Util.h"
+
+using namespace std;
+
+PerScorer::PerScorer(const string& config)
+ : StatisticsBasedScorer("PER",config) {}
+
+PerScorer::~PerScorer() {}
void PerScorer::setReferenceFiles(const vector<string>& referenceFiles)
{
- // for each line in the reference file, create a multiset of the
- // word ids
+ // For each line in the reference file, create a multiset of
+ // the word ids.
if (referenceFiles.size() != 1) {
throw runtime_error("PER only supports a single reference");
}
@@ -40,8 +52,8 @@ void PerScorer::prepareStats(size_t sid, const string& text, ScoreStats& entry)
msg << "Sentence id (" << sid << ") not found in reference set";
throw runtime_error(msg.str());
}
- //calculate correct, output_length and ref_length for
- //the line and store it in entry
+ // Calculate correct, output_length and ref_length for
+ // the line and store it in entry
vector<int> testtokens;
encode(text,testtokens);
multiset<int> testtokens_all(testtokens.begin(),testtokens.end());
@@ -59,12 +71,12 @@ void PerScorer::prepareStats(size_t sid, const string& text, ScoreStats& entry)
entry.set(stats_str);
}
-float PerScorer::calculateScore(const vector<int>& comps)
+float PerScorer::calculateScore(const vector<int>& comps) const
{
float denom = comps[2];
float num = comps[0] - max(0,comps[1]-comps[2]);
if (denom == 0) {
- //shouldn't happen!
+ // This shouldn't happen!
return 0.0;
} else {
return num/denom;
diff --git a/mert/PerScorer.h b/mert/PerScorer.h
index 8f6e6e7a4..800a3caf1 100644
--- a/mert/PerScorer.h
+++ b/mert/PerScorer.h
@@ -1,52 +1,47 @@
#ifndef __PERSCORER_H__
#define __PERSCORER_H__
-#include <algorithm>
-#include <cmath>
#include <iostream>
-#include <iterator>
#include <set>
#include <sstream>
-#include <stdexcept>
#include <string>
#include <vector>
#include "Types.h"
-#include "ScoreData.h"
#include "Scorer.h"
-
using namespace std;
+class ScoreStats;
+
/**
- * Implementation of position-independent word error rate. This is defined
- * as 1 - (correct - max(0,output_length - ref_length)) / ref_length
- * In fact, we ignore the " 1 - " so that it can be maximised.
- **/
+ * An implementation of position-independent word error rate.
+ * This is defined as
+ * 1 - (correct - max(0,output_length - ref_length)) / ref_length
+ * In fact, we ignore the " 1 - " so that it can be maximised.
+ */
class PerScorer: public StatisticsBasedScorer
{
public:
- PerScorer(const string& config = "") : StatisticsBasedScorer("PER",config) {}
+ explicit PerScorer(const string& config = "");
+ ~PerScorer();
+
virtual void setReferenceFiles(const vector<string>& referenceFiles);
virtual void prepareStats(size_t sid, const string& text, ScoreStats& entry);
- virtual void whoami() {
+ virtual void whoami() const {
cerr << "I AM PerScorer" << std::endl;
}
- size_t NumberOfScores() {
+ virtual size_t NumberOfScores() const {
// cerr << "PerScorer: 3" << endl;
return 3;
- };
-
-//protected:
+ }
- virtual float calculateScore(const vector<int>& comps) ;
+ virtual float calculateScore(const vector<int>& comps) const;
private:
-
- //no copy
+ // no copying allowed
PerScorer(const PerScorer&);
- ~PerScorer() {};
PerScorer& operator=(const PerScorer&);
// data extracted from reference files
@@ -54,4 +49,4 @@ private:
vector<multiset<int> > _reftokens;
};
-#endif //__PERSCORER_H
+#endif // __PERSCORER_H__
diff --git a/mert/Point.cpp b/mert/Point.cpp
index 109ca954a..71338966a 100644
--- a/mert/Point.cpp
+++ b/mert/Point.cpp
@@ -1,60 +1,32 @@
#include "Point.h"
-#include<cmath>
-#include<cstdlib>
+
+#include <cmath>
+#include <cstdlib>
#include <cassert>
-using namespace std;
+#include <limits>
+#include "FeatureStats.h"
+using namespace std;
vector<unsigned> Point::optindices;
-unsigned Point::dim=0;
+unsigned Point::dim = 0;
map<unsigned,statscore_t> Point::fixedweights;
-unsigned Point::pdim=0;
-unsigned Point::ncall=0;
+unsigned Point::pdim = 0;
+unsigned Point::ncall = 0;
vector<parameter_t> Point::m_min;
vector<parameter_t> Point::m_max;
-void Point::Randomize()
-{
- assert(m_min.size()==Point::dim);
- assert(m_max.size()==Point::dim);
- for (unsigned int i=0; i<size(); i++)
- operator[](i)= m_min[i]
- + (float)random()/(float)RAND_MAX * (float)(m_max[i]-m_min[i]);
-}
-
-void Point::NormalizeL2()
-{
- parameter_t norm=0.0;
- for (unsigned int i=0; i<size(); i++)
- norm+= operator[](i)*operator[](i);
- if(norm!=0.0) {
- norm=sqrt(norm);
- for (unsigned int i=0; i<size(); i++)
- operator[](i)/=norm;
- }
-}
-
-
-void Point::NormalizeL1()
-{
- parameter_t norm=0.0;
- for (unsigned int i=0; i<size(); i++)
- norm+= abs(operator[](i));
- if(norm!=0.0) {
- for (unsigned int i=0; i<size(); i++)
- operator[](i)/=norm;
- }
-}
+Point::Point() : vector<parameter_t>(dim), score_(0.0) {}
//Can initialize from a vector of dim or pdim
Point::Point(const vector<parameter_t>& init,
- const vector<parameter_t>& min,
- const vector<parameter_t>& max
- ):vector<parameter_t>(Point::dim)
+ const vector<parameter_t>& min,
+ const vector<parameter_t>& max)
+ : vector<parameter_t>(Point::dim), score_(0.0)
{
m_min.resize(Point::dim);
m_max.resize(Point::dim);
@@ -72,12 +44,23 @@ Point::Point(const vector<parameter_t>& init,
m_max[i] = max[optindices[i]];
}
}
-};
+}
+Point::~Point() {}
+
+void Point::Randomize()
+{
+ assert(m_min.size()==Point::dim);
+ assert(m_max.size()==Point::dim);
+ for (unsigned int i=0; i<size(); i++) {
+ operator[](i) = m_min[i] +
+ (float)random()/(float)RAND_MAX * (float)(m_max[i]-m_min[i]);
+ }
+}
-double Point::operator*(const FeatureStats& F)const
+double Point::operator*(const FeatureStats& F) const
{
- ncall++;//to track performance
+ ncall++; // to track performance
double prod=0.0;
if(OptimizeAll())
for (unsigned i=0; i<size(); i++)
@@ -90,43 +73,71 @@ double Point::operator*(const FeatureStats& F)const
}
return prod;
}
-Point Point::operator+(const Point& p2)const
+
+Point Point::operator+(const Point& p2) const
{
- assert(p2.size()==size());
+ assert(p2.size() == size());
Point Res(*this);
- for(unsigned i=0; i<size(); i++)
- Res[i]+=p2[i];
- Res.score=numeric_limits<statscore_t>::max();
+ for (unsigned i = 0; i < size(); i++) {
+ Res[i] += p2[i];
+ }
+
+ Res.score_ = numeric_limits<statscore_t>::max();
return Res;
-};
+}
void Point::operator+=(const Point& p2)
{
- assert(p2.size()==size());
- for(unsigned i=0; i<size(); i++)
- operator[](i)+=p2[i];
- score=numeric_limits<statscore_t>::max();
-};
-
+ assert(p2.size() == size());
+ for (unsigned i = 0; i < size(); i++) {
+ operator[](i) += p2[i];
+ }
+ score_ = numeric_limits<statscore_t>::max();
+}
-Point Point::operator*(float l)const
+Point Point::operator*(float l) const
{
Point Res(*this);
- for(unsigned i=0; i<size(); i++)
- Res[i]*=l;
- Res.score=numeric_limits<statscore_t>::max();
+ for (unsigned i = 0; i < size(); i++) {
+ Res[i] *= l;
+ }
+ Res.score_ = numeric_limits<statscore_t>::max();
return Res;
-};
+}
-ostream& operator<<(ostream& o,const Point& P)
+ostream& operator<<(ostream& o, const Point& P)
{
- vector<parameter_t> w=P.GetAllWeights();
-// o << "[" << Point::pdim << "] ";
- for(unsigned int i=0; i<Point::pdim; i++)
+ vector<parameter_t> w = P.GetAllWeights();
+ for (unsigned int i = 0; i < Point::pdim; i++) {
o << w[i] << " ";
-// o << "=> " << P.GetScore();
+ }
return o;
-};
+}
+
+void Point::NormalizeL2()
+{
+ parameter_t norm=0.0;
+ for (unsigned int i=0; i<size(); i++)
+ norm+= operator[](i)*operator[](i);
+ if(norm!=0.0) {
+ norm=sqrt(norm);
+ for (unsigned int i=0; i<size(); i++)
+ operator[](i)/=norm;
+ }
+}
+
+
+void Point::NormalizeL1()
+{
+ parameter_t norm=0.0;
+ for (unsigned int i=0; i<size(); i++)
+ norm+= abs(operator[](i));
+ if(norm!=0.0) {
+ for (unsigned int i=0; i<size(); i++)
+ operator[](i)/=norm;
+ }
+}
+
vector<parameter_t> Point::GetAllWeights()const
{
@@ -141,7 +152,4 @@ vector<parameter_t> Point::GetAllWeights()const
w[it->first]=it->second;
}
return w;
-};
-
-
-
+}
diff --git a/mert/Point.h b/mert/Point.h
index da2da56b1..55d173215 100644
--- a/mert/Point.h
+++ b/mert/Point.h
@@ -1,31 +1,52 @@
#ifndef POINT_H
#define POINT_H
+
+#include <fstream>
+#include <map>
#include <vector>
#include "Types.h"
-#include "FeatureStats.h"
-#include <cassert>
-
+class FeatureStats;
class Optimizer;
-/**class that handle the subset of the Feature weight on which we run the optimization*/
-
-class Point:public vector<parameter_t>
+/**
+ * A class that handles the subset of the Feature weight on which
+ * we run the optimization.
+ */
+class Point : public vector<parameter_t>
{
friend class Optimizer;
private:
- /**The indices over which we optimize*/
+ /**
+ * The indices over which we optimize.
+ */
static vector<unsigned int> optindices;
- /**dimension of optindices and of the parent vector*/
+
+ /**
+ * Dimension of optindices and of the parent vector.
+ */
static unsigned int dim;
- /**fixed weights in case of partial optimzation*/
+
+ /**
+ * Fixed weights in case of partial optimzation.
+ */
static map<unsigned int,parameter_t> fixedweights;
- /**total size of the parameter space; we have pdim=FixedWeight.size()+optinidices.size()*/
+
+ /**
+ * Total size of the parameter space; we have
+ * pdim = FixedWeight.size() + optinidices.size().
+ */
static unsigned int pdim;
static unsigned int ncall;
- /**The limits for randomization, both vectors are of full length, pdim*/
+
+ /**
+ * The limits for randomization, both vectors are of full length, pdim.
+ */
static vector<parameter_t> m_min;
static vector<parameter_t> m_max;
+
+ statscore_t score_;
+
public:
static unsigned int getdim() {
return dim;
@@ -41,32 +62,42 @@ public:
}
static bool OptimizeAll() {
return fixedweights.empty();
- };
- statscore_t score;
- Point():vector<parameter_t>(dim) {};
+ }
+
+ Point();
Point(const vector<parameter_t>& init,
- const vector<parameter_t>& min,
- const vector<parameter_t>& max
- );
+ const vector<parameter_t>& min,
+ const vector<parameter_t>& max);
+ ~Point();
+
void Randomize();
- double operator*(const FeatureStats&)const;//compute the feature function
- Point operator+(const Point&)const;
+ // Compute the feature function
+ double operator*(const FeatureStats&) const;
+ Point operator+(const Point&) const;
void operator+=(const Point&);
- Point operator*(float)const;
- /**write the Whole featureweight to a stream (ie pdim float)*/
+ Point operator*(float) const;
+
+ /**
+ * Write the Whole featureweight to a stream (ie pdim float).
+ */
friend ostream& operator<<(ostream& o,const Point& P);
- void Normalize() {
- NormalizeL2();
- };
+
+ void Normalize() { NormalizeL2(); }
void NormalizeL2();
void NormalizeL1();
- /**return a vector of size pdim where all weights have been put(including fixed ones)*/
- vector<parameter_t> GetAllWeights()const;
- statscore_t GetScore()const {
- return score;
- };
-};
-#endif
+ /**
+ * Return a vector of size pdim where all weights have been
+ * put (including fixed ones).
+ */
+ vector<parameter_t> GetAllWeights() const;
+
+ statscore_t GetScore() const {
+ return score_;
+ }
+
+ void SetScore(statscore_t score) { score_ = score; }
+};
+#endif // POINT_H
diff --git a/mert/ScopedVector.h b/mert/ScopedVector.h
new file mode 100644
index 000000000..1fbce88b7
--- /dev/null
+++ b/mert/ScopedVector.h
@@ -0,0 +1,54 @@
+#ifndef SCOPEDVECTOR_H_
+#define SCOPEDVECTOR_H_
+
+#include <vector>
+
+template <class T>
+class ScopedVector {
+ public:
+ typedef typename std::vector<T*>::iterator iterator;
+ typedef typename std::vector<T*>::const_iterator const_iterator;
+
+ ScopedVector() {}
+ virtual ~ScopedVector() { reset(); }
+
+ bool empty() const { return vec_.empty(); }
+
+ void push_back(T *e) { vec_.push_back(e); }
+
+ void reset() {
+ for (iterator it = vec_.begin(); it != vec_.end(); ++it) {
+ delete *it;
+ }
+ vec_.clear();
+ }
+
+ void reserve(size_t capacity) { vec_.reserve(capacity); }
+ void resize(size_t size) { vec_.resize(size); }
+
+ size_t size() const {return vec_.size(); }
+
+ iterator begin() { return vec_.begin(); }
+ const_iterator begin() const { return vec_.begin(); }
+
+ iterator end() { return vec_.end(); }
+ const_iterator end() const { return vec_.end(); }
+
+ std::vector<T*>& get() { return vec_; }
+ const std::vector<T*>& get() const { return vec_; }
+
+ std::vector<T*>* operator->() { return &vec_; }
+ const std::vector<T*>* operator->() const { return &vec_; }
+
+ T*& operator[](size_t i) { return vec_[i]; }
+ const T* operator[](size_t i) const { return vec_[i]; }
+
+ private:
+ std::vector<T*> vec_;
+
+ // no copying allowed.
+ ScopedVector<T>(const ScopedVector<T>&);
+ void operator=(const ScopedVector<T>&);
+};
+
+#endif // SCOPEDVECTOR_H_
diff --git a/mert/ScoreArray.cpp b/mert/ScoreArray.cpp
index 92824c818..b26b93114 100644
--- a/mert/ScoreArray.cpp
+++ b/mert/ScoreArray.cpp
@@ -6,12 +6,13 @@
*
*/
-#include <fstream>
#include "ScoreArray.h"
#include "Util.h"
+#include "FileStream.h"
-ScoreArray::ScoreArray(): idx("")
-{};
+
+ScoreArray::ScoreArray()
+ : number_of_scores(0), idx("") {}
void ScoreArray::savetxt(std::ofstream& outFile, const std::string& sctype)
{
@@ -132,17 +133,15 @@ void ScoreArray::merge(ScoreArray& e)
add(e.get(i));
}
-bool ScoreArray::check_consistency()
+bool ScoreArray::check_consistency() const
{
- size_t sz = NumberOfScores();
-
+ const size_t sz = NumberOfScores();
if (sz == 0)
return true;
- for (scorearray_t::iterator i=array_.begin(); i!=array_.end(); i++)
- if (i->size()!=sz)
+ for (scorearray_t::const_iterator i = array_.begin(); i != array_.end(); ++i) {
+ if (i->size() != sz)
return false;
+ }
return true;
}
-
-
diff --git a/mert/ScoreArray.h b/mert/ScoreArray.h
index 71ea2b51a..1240a704a 100644
--- a/mert/ScoreArray.h
+++ b/mert/ScoreArray.h
@@ -9,21 +9,19 @@
#ifndef SCORE_ARRAY_H
#define SCORE_ARRAY_H
-#define SCORES_TXT_BEGIN "SCORES_TXT_BEGIN_0"
-#define SCORES_TXT_END "SCORES_TXT_END_0"
-#define SCORES_BIN_BEGIN "SCORES_BIN_BEGIN_0"
-#define SCORES_BIN_END "SCORES_BIN_END_0"
-
using namespace std;
-#include <limits>
#include <vector>
#include <iostream>
-#include <fstream>
+#include <string>
-#include "Util.h"
#include "ScoreStats.h"
+const char SCORES_TXT_BEGIN[] = "SCORES_TXT_BEGIN_0";
+const char SCORES_TXT_END[] = "SCORES_TXT_END_0";
+const char SCORES_BIN_BEGIN[] = "SCORES_BIN_BEGIN_0";
+const char SCORES_BIN_END[] = "SCORES_BIN_END_0";
+
class ScoreArray
{
protected:
@@ -32,19 +30,19 @@ protected:
size_t number_of_scores;
private:
- std::string idx; // idx to identify the utterance, it can differ from the index inside the vector
-
+ // idx to identify the utterance.
+ // It can differ from the index inside the vector.
+ std::string idx;
public:
ScoreArray();
-
- ~ScoreArray() {};
+ ~ScoreArray() {}
inline void clear() {
array_.clear();
}
- inline std::string getIndex() {
+ inline std::string getIndex() const {
return idx;
}
inline void setIndex(const std::string& value) {
@@ -68,12 +66,13 @@ public:
inline std::string name() const {
return score_type;
- };
+ }
+
inline void name(std::string &sctype) {
score_type = sctype;
- };
+ }
- inline size_t size() {
+ inline size_t size() const {
return array_.size();
}
inline size_t NumberOfScores() const {
@@ -96,9 +95,7 @@ public:
void load(ifstream& inFile);
void load(const std::string &file);
- bool check_consistency();
+ bool check_consistency() const;
};
-
-#endif
-
+#endif // SCORE_ARRAY_H
diff --git a/mert/ScoreData.cpp b/mert/ScoreData.cpp
index bdbfd18bf..e79595d06 100644
--- a/mert/ScoreData.cpp
+++ b/mert/ScoreData.cpp
@@ -6,20 +6,20 @@
*
*/
-#include <fstream>
#include "ScoreData.h"
#include "Scorer.h"
#include "Util.h"
-
+#include "FileStream.h"
ScoreData::ScoreData(Scorer& ptr):
theScorer(&ptr)
{
score_type = theScorer->getName();
- theScorer->setScoreData(this);//this is not dangerous: we dont use the this pointer in SetScoreData
+ // This is not dangerous: we don't use the this pointer in SetScoreData.
+ theScorer->setScoreData(this);
number_of_scores = theScorer->NumberOfScores();
// TRACE_ERR("ScoreData: number_of_scores: " << number_of_scores << std::endl);
-};
+}
void ScoreData::save(std::ofstream& outFile, bool bin)
{
@@ -33,7 +33,8 @@ void ScoreData::save(const std::string &file, bool bin)
if (file.empty()) return;
TRACE_ERR("saving the array into " << file << std::endl);
- std::ofstream outFile(file.c_str(), std::ios::out); // matches a stream with a file. Opens the file
+ // matches a stream with a file. Opens the file.
+ std::ofstream outFile(file.c_str(), std::ios::out);
ScoreStats entry;
@@ -94,29 +95,28 @@ void ScoreData::add(ScoreArray& e)
void ScoreData::add(const ScoreStats& e, const std::string& sent_idx)
{
if (exists(sent_idx)) { // array at position e.getIndex() already exists
- //enlarge array at position e.getIndex()
+ // Enlarge array at position e.getIndex()
size_t pos = getIndex(sent_idx);
- // TRACE_ERR("Inserting in array " << sent_idx << std::endl);
+ // TRACE_ERR("Inserting in array " << sent_idx << std::endl);
array_.at(pos).add(e);
- // TRACE_ERR("size: " << size() << " -> " << a.size() << std::endl);
+ // TRACE_ERR("size: " << size() << " -> " << a.size() << std::endl);
} else {
- // TRACE_ERR("Creating a new entry in the array" << std::endl);
+ // TRACE_ERR("Creating a new entry in the array" << std::endl);
ScoreArray a;
a.NumberOfScores(number_of_scores);
a.add(e);
a.setIndex(sent_idx);
add(a);
- // TRACE_ERR("size: " << size() << " -> " << a.size() << std::endl);
+ // TRACE_ERR("size: " << size() << " -> " << a.size() << std::endl);
}
}
-
-bool ScoreData::check_consistency()
+bool ScoreData::check_consistency() const
{
if (array_.size() == 0)
return true;
- for (scoredata_t::iterator i = array_.begin(); i !=array_.end(); i++)
+ for (scoredata_t::const_iterator i = array_.begin(); i != array_.end(); ++i)
if (!i->check_consistency()) return false;
return true;
diff --git a/mert/ScoreData.h b/mert/ScoreData.h
index 500cd5c9b..cb4fb30f9 100644
--- a/mert/ScoreData.h
+++ b/mert/ScoreData.h
@@ -9,14 +9,15 @@
#ifndef SCORE_DATA_H
#define SCORE_DATA_H
-using namespace std;
-
-#include <limits>
+#include <fstream>
#include <vector>
#include <iostream>
-
-#include "Util.h"
+#include <stdexcept>
+#include <string>
#include "ScoreArray.h"
+#include "ScoreStats.h"
+
+using namespace std;
class Scorer;
@@ -24,18 +25,20 @@ class ScoreData
{
protected:
scoredata_t array_;
- idx2name idx2arrayname_; //map from index to name of array
- name2idx arrayname2idx_; //map from name to index of array
+ idx2name idx2arrayname_; // map from index to name of array
+ name2idx arrayname2idx_; // map from name to index of array
private:
+ // Do not allow the user to instanciate without arguments.
+ ScoreData() {}
+
Scorer* theScorer;
std::string score_type;
size_t number_of_scores;
public:
ScoreData(Scorer& sc);
-
- ~ScoreData() {};
+ ~ScoreData() {}
inline void clear() {
array_.clear();
@@ -51,11 +54,11 @@ public:
return array_.at(idx);
}
- inline bool exists(const std::string & sent_idx) {
+ inline bool exists(const std::string& sent_idx) const {
return exists(getIndex(sent_idx));
}
- inline bool exists(int sent_idx) {
- return (sent_idx>-1 && sent_idx<(int)array_.size())?true:false;
+ inline bool exists(int sent_idx) const {
+ return (sent_idx > -1 && sent_idx < (int)array_.size()) ? true : false;
}
inline ScoreStats& get(size_t i, size_t j) {
@@ -65,20 +68,21 @@ public:
return array_.at(i).get(j);
}
- inline std::string name() {
+ inline std::string name() const {
return score_type;
- };
- inline std::string name(std::string &sctype) {
+ }
+
+ inline std::string name(const std::string &sctype) {
return score_type = sctype;
- };
+ }
void add(ScoreArray& e);
void add(const ScoreStats& e, const std::string& sent_idx);
- inline size_t NumberOfScores() {
+ inline size_t NumberOfScores() const {
return number_of_scores;
}
- inline size_t size() {
+ inline size_t size() const {
return array_.size();
}
@@ -91,23 +95,22 @@ public:
void load(ifstream& inFile);
void load(const std::string &file);
- bool check_consistency();
+ bool check_consistency() const;
void setIndex();
- inline int getIndex(const std::string& idx) {
- name2idx::iterator i = arrayname2idx_.find(idx);
- if (i!=arrayname2idx_.end())
+ inline int getIndex(const std::string& idx) const {
+ name2idx::const_iterator i = arrayname2idx_.find(idx);
+ if (i != arrayname2idx_.end())
return i->second;
else
return -1;
}
- inline std::string getIndex(size_t idx) {
- idx2name::iterator i = idx2arrayname_.find(idx);
- if (i!=idx2arrayname_.end())
+ inline std::string getIndex(size_t idx) const {
+ idx2name::const_iterator i = idx2arrayname_.find(idx);
+ if (i != idx2arrayname_.end())
throw runtime_error("there is no entry at index " + idx);
return i->second;
}
};
-
-#endif
+#endif // SCORE_DATA_H
diff --git a/mert/ScoreStats.cpp b/mert/ScoreStats.cpp
index d3b28de36..eb1750983 100644
--- a/mert/ScoreStats.cpp
+++ b/mert/ScoreStats.cpp
@@ -6,53 +6,65 @@
*
*/
-#include <fstream>
+#include "Util.h"
#include "ScoreStats.h"
-#define AVAILABLE_ 8;
-
+namespace {
+const int kAvailableSize = 8;
+} // namespace
ScoreStats::ScoreStats()
+ : available_(kAvailableSize), entries_(0),
+ array_(new ScoreStatsType[available_]) {}
+
+ScoreStats::ScoreStats(const size_t size)
+ : available_(size), entries_(size),
+ array_(new ScoreStatsType[available_])
{
- available_ = AVAILABLE_;
- entries_ = 0;
- array_ = new ScoreStatsType[available_];
-};
+ memset(array_, 0, GetArraySizeWithBytes());
+}
+
+ScoreStats::ScoreStats(std::string &theString)
+ : available_(0), entries_(0), array_(NULL)
+{
+ set(theString);
+}
ScoreStats::~ScoreStats()
{
- delete[] array_;
-};
+ if (array_) {
+ delete [] array_;
+ array_ = NULL;
+ }
+}
-ScoreStats::ScoreStats(const ScoreStats &stats)
+void ScoreStats::Copy(const ScoreStats &stats)
{
available_ = stats.available();
entries_ = stats.size();
array_ = new ScoreStatsType[available_];
- memcpy(array_,stats.getArray(),scorebytes_);
-};
-
+ memcpy(array_, stats.getArray(), GetArraySizeWithBytes());
+}
-ScoreStats::ScoreStats(const size_t size)
+ScoreStats::ScoreStats(const ScoreStats &stats)
{
- available_ = size;
- entries_ = size;
- array_ = new ScoreStatsType[available_];
- memset(array_,0,scorebytes_);
-};
+ Copy(stats);
+}
-ScoreStats::ScoreStats(std::string &theString)
+ScoreStats& ScoreStats::operator=(const ScoreStats &stats)
{
- set(theString);
+ delete [] array_;
+ Copy(stats);
+ return *this;
}
void ScoreStats::expand()
{
- available_*=2;
- scorestats_t t_ = new ScoreStatsType[available_];
- memcpy(t_,array_,scorebytes_);
- delete array_;
- array_=t_;
+ available_ *= 2;
+ scorestats_t buf = new ScoreStatsType[available_];
+ memcpy(buf, array_, GetArraySizeWithBytes());
+ delete [] array_;
+ array_ = buf;
}
void ScoreStats::add(ScoreStatsType v)
@@ -68,13 +80,13 @@ void ScoreStats::set(std::string &theString)
while (!theString.empty()) {
getNextPound(theString, substring);
- add(ATOSST(substring.c_str()));
+ add(ConvertStringToScoreStatsType(substring));
}
}
void ScoreStats::loadbin(std::ifstream& inFile)
{
- inFile.read((char*) array_, scorebytes_);
+ inFile.read((char*)array_, GetArraySizeWithBytes());
}
void ScoreStats::loadtxt(std::ifstream& inFile)
@@ -86,7 +98,7 @@ void ScoreStats::loadtxt(std::ifstream& inFile)
void ScoreStats::loadtxt(const std::string &file)
{
-// TRACE_ERR("loading the stats from " << file << std::endl);
+// TRACE_ERR("loading the stats from " << file << std::endl);
std::ifstream inFile(file.c_str(), std::ios::in); // matches a stream with a file. Opens the file
@@ -96,7 +108,7 @@ void ScoreStats::loadtxt(const std::string &file)
void ScoreStats::savetxt(const std::string &file)
{
-// TRACE_ERR("saving the stats into " << file << std::endl);
+// TRACE_ERR("saving the stats into " << file << std::endl);
std::ofstream outFile(file.c_str(), std::ios::out); // matches a stream with a file. Opens the file
@@ -111,27 +123,12 @@ void ScoreStats::savetxt(std::ofstream& outFile)
void ScoreStats::savebin(std::ofstream& outFile)
{
- outFile.write((char*) array_, scorebytes_);
+ outFile.write((char*)array_, GetArraySizeWithBytes());
}
-
-ScoreStats& ScoreStats::operator=(const ScoreStats &stats)
-{
- delete array_;
- available_ = stats.available();
- entries_ = stats.size();
- array_ = new ScoreStatsType[available_];
- memcpy(array_,stats.getArray(),scorebytes_);
-
- return *this;
-}
-
-
-/**write the whole object to a stream*/
ostream& operator<<(ostream& o, const ScoreStats& e)
{
for (size_t i=0; i< e.size(); i++)
o << e.get(i) << " ";
return o;
}
-
diff --git a/mert/ScoreStats.h b/mert/ScoreStats.h
index 9ceee4c6b..43a6f1f23 100644
--- a/mert/ScoreStats.h
+++ b/mert/ScoreStats.h
@@ -9,44 +9,51 @@
#ifndef SCORE_STATS_H
#define SCORE_STATS_H
-using namespace std;
-
-#include <limits>
#include <vector>
#include <iostream>
+#include <fstream>
#include <cstdlib>
+#include <cstring>
-#include "Util.h"
+#include "Types.h"
-#define SCORE_STATS_MIN (numeric_limits<ScoreStatsType>::min())
-#define ATOSST(str) ((ScoreStatsType) atoi(str))
-
-#define scorebytes_ (entries_*sizeof(ScoreStatsType))
+using namespace std;
class ScoreStats
{
private:
- scorestats_t array_;
- size_t entries_;
size_t available_;
+ size_t entries_;
+
+ // TODO: Use smart pointer for exceptional-safety.
+ scorestats_t array_;
public:
ScoreStats();
- ScoreStats(const size_t size);
+ explicit ScoreStats(const size_t size);
+ explicit ScoreStats(std::string &theString);
+ ~ScoreStats();
+
+ // We intentionally allow copying.
ScoreStats(const ScoreStats &stats);
- ScoreStats(std::string &theString);
ScoreStats& operator=(const ScoreStats &stats);
- ~ScoreStats();
+ void Copy(const ScoreStats &stats);
- bool isfull() {
- return (entries_ < available_)?0:1;
+ bool isfull() const {
+ return (entries_ < available_) ? 0 : 1;
}
+
void expand();
void add(ScoreStatsType v);
- inline void clear() {
- memset((void*) array_,0,scorebytes_);
+ void clear() {
+ memset((void*)array_, 0, GetArraySizeWithBytes());
+ }
+
+ void reset() {
+ entries_ = 0;
+ clear();
}
inline ScoreStatsType get(size_t i) {
@@ -62,8 +69,13 @@ public:
void set(std::string &theString);
inline size_t bytes() const {
- return scorebytes_;
+ return GetArraySizeWithBytes();
+ }
+
+ size_t GetArraySizeWithBytes() const {
+ return entries_ * sizeof(ScoreStatsType);
}
+
inline size_t size() const {
return entries_;
}
@@ -78,22 +90,14 @@ public:
savetxt("/dev/stdout");
}
-
-
void loadtxt(const std::string &file);
void loadtxt(ifstream& inFile);
void loadbin(ifstream& inFile);
-
- inline void reset() {
- entries_ = 0;
- clear();
- }
-
- /**write the whole object to a stream*/
+ /**
+ * Write the whole object to a stream.
+ */
friend ostream& operator<<(ostream& o, const ScoreStats& e);
};
-
-#endif
-
+#endif // SCORE_STATS_H
diff --git a/mert/Scorer.cpp b/mert/Scorer.cpp
index 82bf6e680..55e1cd748 100644
--- a/mert/Scorer.cpp
+++ b/mert/Scorer.cpp
@@ -1,4 +1,27 @@
#include "Scorer.h"
+#include <limits>
+
+Scorer::Scorer(const string& name, const string& config)
+ : _name(name), _scoreData(0), _preserveCase(true) {
+// cerr << "Scorer config string: " << config << endl;
+ size_t start = 0;
+ while (start < config.size()) {
+ size_t end = config.find(",",start);
+ if (end == string::npos) {
+ end = config.size();
+ }
+ string nv = config.substr(start,end-start);
+ size_t split = nv.find(":");
+ if (split == string::npos) {
+ throw runtime_error("Missing colon when processing scorer config: " + config);
+ }
+ string name = nv.substr(0,split);
+ string value = nv.substr(split+1,nv.size()-split-1);
+ cerr << "name: " << name << " value: " << value << endl;
+ _config[name] = value;
+ start = end+1;
+ }
+}
//regularisation strategies
static float score_min(const statscores_t& scores, size_t start, size_t end)
@@ -15,7 +38,7 @@ static float score_min(const statscores_t& scores, size_t start, size_t end)
static float score_average(const statscores_t& scores, size_t start, size_t end)
{
if ((end - start) < 1) {
- //shouldn't happen
+ // this shouldn't happen
return 0;
}
float total = 0;
@@ -26,13 +49,50 @@ static float score_average(const statscores_t& scores, size_t start, size_t end)
return total / (end - start);
}
+StatisticsBasedScorer::StatisticsBasedScorer(const string& name, const string& config)
+ : Scorer(name,config) {
+ //configure regularisation
+ static string KEY_TYPE = "regtype";
+ static string KEY_WINDOW = "regwin";
+ static string KEY_CASE = "case";
+ static string TYPE_NONE = "none";
+ static string TYPE_AVERAGE = "average";
+ static string TYPE_MINIMUM = "min";
+ static string TRUE = "true";
+ static string FALSE = "false";
+
+ string type = getConfig(KEY_TYPE,TYPE_NONE);
+ if (type == TYPE_NONE) {
+ _regularisationStrategy = REG_NONE;
+ } else if (type == TYPE_AVERAGE) {
+ _regularisationStrategy = REG_AVERAGE;
+ } else if (type == TYPE_MINIMUM) {
+ _regularisationStrategy = REG_MINIMUM;
+ } else {
+ throw runtime_error("Unknown scorer regularisation strategy: " + type);
+ }
+ // cerr << "Using scorer regularisation strategy: " << type << endl;
+
+ string window = getConfig(KEY_WINDOW,"0");
+ _regularisationWindow = atoi(window.c_str());
+ // cerr << "Using scorer regularisation window: " << _regularisationWindow << endl;
+
+ string preservecase = getConfig(KEY_CASE,TRUE);
+ if (preservecase == TRUE) {
+ _preserveCase = true;
+ } else if (preservecase == FALSE) {
+ _preserveCase = false;
+ }
+ // cerr << "Using case preservation: " << _preserveCase << endl;
+}
+
void StatisticsBasedScorer::score(const candidates_t& candidates, const diffs_t& diffs,
- statscores_t& scores)
+ statscores_t& scores) const
{
if (!_scoreData) {
throw runtime_error("Score data not loaded");
}
- //calculate the score for the candidates
+ // calculate the score for the candidates
if (_scoreData->size() == 0) {
throw runtime_error("Score data is empty");
}
@@ -57,7 +117,7 @@ void StatisticsBasedScorer::score(const candidates_t& candidates, const diffs_t
scores.push_back(calculateScore(totals));
candidates_t last_candidates(candidates);
- //apply each of the diffs, and get new scores
+ // apply each of the diffs, and get new scores
for (size_t i = 0; i < diffs.size(); ++i) {
for (size_t j = 0; j < diffs[i].size(); ++j) {
size_t sid = diffs[i][j].first;
@@ -73,15 +133,15 @@ void StatisticsBasedScorer::score(const candidates_t& candidates, const diffs_t
scores.push_back(calculateScore(totals));
}
- //regularisation. This can either be none, or the min or average as described in
- //Cer, Jurafsky and Manning at WMT08
+ // Regularisation. This can either be none, or the min or average as described in
+ // Cer, Jurafsky and Manning at WMT08.
if (_regularisationStrategy == REG_NONE || _regularisationWindow <= 0) {
- //no regularisation
+ // no regularisation
return;
}
- //window size specifies the +/- in each direction
- statscores_t raw_scores(scores);//copy scores
+ // window size specifies the +/- in each direction
+ statscores_t raw_scores(scores); // copy scores
for (size_t i = 0; i < scores.size(); ++i) {
size_t start = 0;
if (i >= _regularisationWindow) {
@@ -95,6 +155,3 @@ void StatisticsBasedScorer::score(const candidates_t& candidates, const diffs_t
}
}
}
-
-
-
diff --git a/mert/Scorer.h b/mert/Scorer.h
index 8d3a4c15c..c36f2e03a 100644
--- a/mert/Scorer.h
+++ b/mert/Scorer.h
@@ -1,12 +1,7 @@
#ifndef __SCORER_H__
#define __SCORER_H__
-#include <algorithm>
-#include <cmath>
#include <iostream>
-#include <iterator>
-#include <limits>
-#include <set>
#include <sstream>
#include <stdexcept>
#include <string>
@@ -21,52 +16,31 @@ enum ScorerRegularisationStrategy {REG_NONE, REG_AVERAGE, REG_MINIMUM};
class ScoreStats;
/**
- * Superclass of all scorers and dummy implementation. In order to add a new
- * scorer it should be sufficient to override prepareStats(), setReferenceFiles()
- * and score() (or calculateScore()).
-**/
+ * Superclass of all scorers and dummy implementation.
+ *
+ * In order to add a new scorer it should be sufficient to override the members
+ * prepareStats(), setReferenceFiles() and score() (or calculateScore()).
+ */
class Scorer
{
private:
string _name;
public:
-
- Scorer(const string& name, const string& config): _name(name), _scoreData(0), _preserveCase(true) {
-// cerr << "Scorer config string: " << config << endl;
- size_t start = 0;
- while (start < config.size()) {
- size_t end = config.find(",",start);
- if (end == string::npos) {
- end = config.size();
- }
- string nv = config.substr(start,end-start);
- size_t split = nv.find(":");
- if (split == string::npos) {
- throw runtime_error("Missing colon when processing scorer config: " + config);
- }
- string name = nv.substr(0,split);
- string value = nv.substr(split+1,nv.size()-split-1);
- cerr << "name: " << name << " value: " << value << endl;
- _config[name] = value;
- start = end+1;
- }
-
- };
- virtual ~Scorer() {};
-
+ Scorer(const string& name, const string& config);
+ virtual ~Scorer() {}
/**
- * returns the number of statistics needed for the computation of the score
- **/
- virtual size_t NumberOfScores() {
+ * Return the number of statistics needed for the computation of the score.
+ */
+ virtual size_t NumberOfScores() const {
cerr << "Scorer: 0" << endl;
return 0;
- };
+ }
/**
- * set the reference files. This must be called before prepareStats.
- **/
+ * Set the reference files. This must be called before prepareStats().
+ */
virtual void setReferenceFiles(const vector<string>& referenceFiles) {
//do nothing
}
@@ -74,7 +48,7 @@ public:
/**
* Process the given guessed text, corresponding to the given reference sindex
* and add the appropriate statistics to the entry.
- **/
+ */
virtual void prepareStats(size_t sindex, const string& text, ScoreStats& entry)
{}
@@ -86,11 +60,11 @@ public:
}
/**
- * Score using each of the candidate index, then go through the diffs
- * applying each in turn, and calculating a new score each time.
- **/
+ * Score using each of the candidate index, then go through the diffs
+ * applying each in turn, and calculating a new score each time.
+ */
virtual void score(const candidates_t& candidates, const diffs_t& diffs,
- statscores_t& scores) {
+ statscores_t& scores) const {
//dummy impl
if (!_scoreData) {
throw runtime_error("score data not loaded");
@@ -101,12 +75,11 @@ public:
}
}
-
/**
- * Calculate the score of the sentences corresponding to the list of candidate
- * indices. Each index indicates the 1-best choice from the n-best list.
- **/
- float score(const candidates_t& candidates) {
+ * Calculate the score of the sentences corresponding to the list of candidate
+ * indices. Each index indicates the 1-best choice from the n-best list.
+ */
+ float score(const candidates_t& candidates) const {
diffs_t diffs;
statscores_t scores;
score(candidates, diffs, scores);
@@ -117,17 +90,16 @@ public:
return _name;
}
- size_t getReferenceSize() {
+ size_t getReferenceSize() const {
if (_scoreData) {
return _scoreData->size();
}
return 0;
}
-
/**
- * Set the score data, prior to scoring.
- **/
+ * Set the score data, prior to scoring.
+ */
void setScoreData(ScoreData* data) {
_scoreData = data;
}
@@ -142,11 +114,11 @@ protected:
bool _preserveCase;
/**
- * Value of config variable. If not provided, return default.
- **/
- string getConfig(const string& key, const string& def="") {
- map<string,string>::iterator i = _config.find(key);
- if (i == _config.end()) {
+ * Get value of config variable. If not provided, return default.
+ */
+ string getConfig(const string& key, const string& def="") const {
+ map<string,string>::const_iterator i = _config.find(key);
+ if (i == _config.end()) {
return def;
} else {
return i->second;
@@ -156,8 +128,8 @@ protected:
/**
* Tokenise line and encode.
- * Note: We assume that all tokens are separated by single spaces
- **/
+ * Note: We assume that all tokens are separated by single spaces.
+ */
void encode(const string& line, vector<int>& encoded) {
//cerr << line << endl;
istringstream in (line);
@@ -185,70 +157,30 @@ protected:
private:
map<string,string> _config;
-
-
};
-
/**
- * Abstract base class for scorers that work by adding statistics across all
- * outout sentences, then apply some formula, e.g. bleu, per. **/
+ * Abstract base class for Scorers that work by adding statistics across all
+ * outout sentences, then apply some formula, e.g., BLEU, PER.
+ */
class StatisticsBasedScorer : public Scorer
{
-
public:
- StatisticsBasedScorer(const string& name, const string& config): Scorer(name,config) {
- //configure regularisation
- static string KEY_TYPE = "regtype";
- static string KEY_WINDOW = "regwin";
- static string KEY_CASE = "case";
- static string TYPE_NONE = "none";
- static string TYPE_AVERAGE = "average";
- static string TYPE_MINIMUM = "min";
- static string TRUE = "true";
- static string FALSE = "false";
-
-
- string type = getConfig(KEY_TYPE,TYPE_NONE);
- if (type == TYPE_NONE) {
- _regularisationStrategy = REG_NONE;
- } else if (type == TYPE_AVERAGE) {
- _regularisationStrategy = REG_AVERAGE;
- } else if (type == TYPE_MINIMUM) {
- _regularisationStrategy = REG_MINIMUM;
- } else {
- throw runtime_error("Unknown scorer regularisation strategy: " + type);
- }
-// cerr << "Using scorer regularisation strategy: " << type << endl;
-
- string window = getConfig(KEY_WINDOW,"0");
- _regularisationWindow = atoi(window.c_str());
-// cerr << "Using scorer regularisation window: " << _regularisationWindow << endl;
-
- string preservecase = getConfig(KEY_CASE,TRUE);
- if (preservecase == TRUE) {
- _preserveCase = true;
- } else if (preservecase == FALSE) {
- _preserveCase = false;
- }
-// cerr << "Using case preservation: " << _preserveCase << endl;
-
-
- }
- ~StatisticsBasedScorer() {};
+ StatisticsBasedScorer(const string& name, const string& config);
+ virtual ~StatisticsBasedScorer() {}
virtual void score(const candidates_t& candidates, const diffs_t& diffs,
- statscores_t& scores);
+ statscores_t& scores) const;
protected:
- //calculate the actual score
- virtual statscore_t calculateScore(const vector<int>& totals) = 0;
+ /**
+ * Calculate the actual score.
+ */
+ virtual statscore_t calculateScore(const vector<int>& totals) const = 0;
- //regularisation
+ // regularisation
ScorerRegularisationStrategy _regularisationStrategy;
size_t _regularisationWindow;
-
};
-
-#endif //__SCORER_H
+#endif // __SCORER_H__
diff --git a/mert/ScorerFactory.cpp b/mert/ScorerFactory.cpp
new file mode 100644
index 000000000..2f47092ef
--- /dev/null
+++ b/mert/ScorerFactory.cpp
@@ -0,0 +1,37 @@
+#include "ScorerFactory.h"
+
+#include <stdexcept>
+#include "Scorer.h"
+#include "BleuScorer.h"
+#include "PerScorer.h"
+#include "TerScorer.h"
+#include "CderScorer.h"
+#include "MergeScorer.h"
+
+using namespace std;
+
+vector<string> ScorerFactory::getTypes() {
+ vector<string> types;
+ types.push_back(string("BLEU"));
+ types.push_back(string("PER"));
+ types.push_back(string("TER"));
+ types.push_back(string("CDER"));
+ types.push_back(string("MERGE"));
+ return types;
+}
+
+Scorer* ScorerFactory::getScorer(const string& type, const string& config) {
+ if (type == "BLEU") {
+ return (BleuScorer*) new BleuScorer(config);
+ } else if (type == "PER") {
+ return (PerScorer*) new PerScorer(config);
+ } else if (type == "TER") {
+ return (TerScorer*) new TerScorer(config);
+ } else if (type == "CDER") {
+ return (CderScorer*) new CderScorer(config);
+ } else if (type == "MERGE") {
+ return (MergeScorer*) new MergeScorer(config);
+ } else {
+ throw runtime_error("Unknown scorer type: " + type);
+ }
+}
diff --git a/mert/ScorerFactory.h b/mert/ScorerFactory.h
index 9bab8d933..f6054c770 100644
--- a/mert/ScorerFactory.h
+++ b/mert/ScorerFactory.h
@@ -1,54 +1,21 @@
#ifndef __SCORER_FACTORY_H
#define __SCORER_FACTORY_H
-#include <algorithm>
-#include <cmath>
-#include <iostream>
-#include <iterator>
-#include <set>
-#include <sstream>
-#include <stdexcept>
-#include <string>
#include <vector>
-#include "Types.h"
-#include "Scorer.h"
-#include "BleuScorer.h"
-#include "PerScorer.h"
-#include "TerScorer.h"
-#include "CderScorer.h"
-#include "MergeScorer.h"
+#include <string>
-using namespace std;
+class Scorer;
class ScorerFactory
{
-
public:
- vector<string> getTypes() {
- vector<string> types;
- types.push_back(string("BLEU"));
- types.push_back(string("PER"));
- types.push_back(string("TER"));
- types.push_back(string("CDER"));
- types.push_back(string("MERGE"));
- return types;
- }
+ static std::vector<std::string> getTypes();
+
+ static Scorer* getScorer(const std::string& type, const std::string& config = "");
- Scorer* getScorer(const string& type, const string& config = "") {
- if (type == "BLEU") {
- return (BleuScorer*) new BleuScorer(config);
- } else if (type == "PER") {
- return (PerScorer*) new PerScorer(config);
- } else if (type == "TER") {
- return (TerScorer*) new TerScorer(config);
- } else if (type == "CDER") {
- return (CderScorer*) new CderScorer(config);
- } else if (type == "MERGE") {
- return (MergeScorer*) new MergeScorer(config);
- } else {
- throw runtime_error("Unknown scorer type: " + type);
- }
- }
+private:
+ ScorerFactory() {}
+ ~ScorerFactory() {}
};
-#endif //__SCORER_FACTORY_H
+#endif // __SCORER_FACTORY_H
diff --git a/mert/TERsrc/alignmentStruct.h b/mert/TERsrc/alignmentStruct.h
index c635d624c..27e8c35d3 100644
--- a/mert/TERsrc/alignmentStruct.h
+++ b/mert/TERsrc/alignmentStruct.h
@@ -43,4 +43,5 @@ public:
};
}
-#endif \ No newline at end of file
+
+#endif // __TERCPPALIGNMENTSTRUCT_H__
diff --git a/mert/TERsrc/bestShiftStruct.h b/mert/TERsrc/bestShiftStruct.h
index 550d2f532..141ebdeb8 100644
--- a/mert/TERsrc/bestShiftStruct.h
+++ b/mert/TERsrc/bestShiftStruct.h
@@ -1,7 +1,6 @@
#ifndef __BESTSHIFTSTRUCT_H__
#define __BESTSHIFTSTRUCT_H__
-
#include <vector>
#include <stdio.h>
#include <string>
@@ -47,4 +46,5 @@ public:
};
}
-#endif
+
+#endif // __BESTSHIFTSTRUCT_H__
diff --git a/mert/TERsrc/hashMap.h b/mert/TERsrc/hashMap.h
index 1892c5591..c3e4578e5 100644
--- a/mert/TERsrc/hashMap.h
+++ b/mert/TERsrc/hashMap.h
@@ -1,8 +1,10 @@
/*
* Generic hashmap manipulation functions
*/
+
#ifndef __HASHMAP_H__
#define __HASHMAP_H__
+
#include "stringHasher.h"
#include <vector>
#include <string>
@@ -36,8 +38,6 @@ public:
string printStringHashForLexicon();
};
-
}
-
-#endif
+#endif // __HASHMAP_H__
diff --git a/mert/TERsrc/hashMapInfos.h b/mert/TERsrc/hashMapInfos.h
index c18a2ae82..f4a46acf8 100644
--- a/mert/TERsrc/hashMapInfos.h
+++ b/mert/TERsrc/hashMapInfos.h
@@ -3,6 +3,7 @@
*/
#ifndef __HASHMAPINFOS_H__
#define __HASHMAPINFOS_H__
+
#include "infosHasher.h"
#include <vector>
#include <string>
@@ -36,8 +37,6 @@ public:
string printStringHashForLexicon();
};
-
}
-
-#endif
+#endif // __HASHMAPINFOS_H__
diff --git a/mert/TERsrc/hashMapStringInfos.h b/mert/TERsrc/hashMapStringInfos.h
index 918e8ccb5..7912be0a2 100644
--- a/mert/TERsrc/hashMapStringInfos.h
+++ b/mert/TERsrc/hashMapStringInfos.h
@@ -3,6 +3,7 @@
*/
#ifndef __HASHMAPSTRINGINFOS_H__
#define __HASHMAPSTRINGINFOS_H__
+
#include "stringInfosHasher.h"
#include <vector>
#include <string>
@@ -36,8 +37,6 @@ public:
string printStringHashForLexicon();
};
-
}
-
-#endif
+#endif // __HASHMAPSTRINGINFOS_H__
diff --git a/mert/TERsrc/infosHasher.h b/mert/TERsrc/infosHasher.h
index d03a9bdc6..8bc2ccd00 100644
--- a/mert/TERsrc/infosHasher.h
+++ b/mert/TERsrc/infosHasher.h
@@ -1,7 +1,7 @@
#ifndef __INFOSHASHER_H__
#define __INFOSHASHER_H__
+
#include <string>
-// #include <ext/hash_map>
#include <stdio.h>
#include <iostream>
#include <vector>
@@ -26,6 +26,6 @@ public:
};
-
}
-#endif \ No newline at end of file
+
+#endif // __INFOSHASHER_H__
diff --git a/mert/TERsrc/stringHasher.h b/mert/TERsrc/stringHasher.h
index a995c0cc7..0894812f0 100644
--- a/mert/TERsrc/stringHasher.h
+++ b/mert/TERsrc/stringHasher.h
@@ -1,7 +1,7 @@
#ifndef __STRINGHASHER_H__
#define __STRINGHASHER_H__
+
#include <string>
-//#include <ext/hash_map>
#include <iostream>
using namespace std;
@@ -21,10 +21,8 @@ public:
string getKey();
string getValue();
void setValue ( string value );
-
-
};
-
}
-#endif
+
+#endif // __STRINGHASHER_H__
diff --git a/mert/TERsrc/stringInfosHasher.h b/mert/TERsrc/stringInfosHasher.h
index c7a705659..e9324cc47 100644
--- a/mert/TERsrc/stringInfosHasher.h
+++ b/mert/TERsrc/stringInfosHasher.h
@@ -1,7 +1,7 @@
#ifndef __STRINGINFOSHASHER_H__
#define __STRINGINFOSHASHER_H__
+
#include <string>
-// #include <ext/hash_map>
#include <iostream>
#include <vector>
@@ -21,10 +21,8 @@ public:
string getKey();
vector<string> getValue();
void setValue ( vector<string> value );
-
-
};
-
}
-#endif \ No newline at end of file
+
+#endif // __STRINGINFOSHASHER_H__
diff --git a/mert/TERsrc/terAlignment.h b/mert/TERsrc/terAlignment.h
index 7c91e3aae..bca00ead3 100644
--- a/mert/TERsrc/terAlignment.h
+++ b/mert/TERsrc/terAlignment.h
@@ -1,7 +1,6 @@
#ifndef __TERCPPTERALIGNMENT_H__
#define __TERCPPTERALIGNMENT_H__
-
#include <vector>
#include <stdio.h>
#include <string.h>
@@ -48,4 +47,5 @@ public:
};
}
-#endif \ No newline at end of file
+
+#endif // __TERCPPTERALIGNMENT_H__
diff --git a/mert/TERsrc/terShift.h b/mert/TERsrc/terShift.h
index e4ce27f19..a54ba633d 100644
--- a/mert/TERsrc/terShift.h
+++ b/mert/TERsrc/terShift.h
@@ -1,14 +1,12 @@
#ifndef __TERCPPTERSHIFT_H__
#define __TERCPPTERSHIFT_H__
-
#include <vector>
#include <stdio.h>
#include <string>
#include <sstream>
#include "tools.h"
-
using namespace std;
using namespace Tools;
@@ -42,4 +40,5 @@ public:
};
}
-#endif \ No newline at end of file
+
+#endif // __TERCPPTERSHIFT_H__
diff --git a/mert/TERsrc/tercalc.h b/mert/TERsrc/tercalc.h
index e66d75a98..cf205ccbb 100644
--- a/mert/TERsrc/tercalc.h
+++ b/mert/TERsrc/tercalc.h
@@ -79,4 +79,4 @@ public:
}
-#endif
+#endif // _TERCPPTERCALC_H___
diff --git a/mert/TERsrc/tools.h b/mert/TERsrc/tools.h
index af2204771..df681a2b2 100644
--- a/mert/TERsrc/tools.h
+++ b/mert/TERsrc/tools.h
@@ -1,7 +1,6 @@
#ifndef __TERCPPTOOLS_H__
#define __TERCPPTOOLS_H__
-
#include <vector>
#include <iostream>
#include <stdio.h>
@@ -9,7 +8,6 @@
#include <string>
#include <sstream>
-
using namespace std;
namespace Tools
@@ -61,5 +59,7 @@ string normalizeStd(string str);
string printParams(param p);
// };
param copyParam(param p);
+
}
-#endif
+
+#endif // __TERCPPTOOLS_H__
diff --git a/mert/TerScorer.cpp b/mert/TerScorer.cpp
index 8e8eb9b63..3f4ca65e8 100644
--- a/mert/TerScorer.cpp
+++ b/mert/TerScorer.cpp
@@ -1,16 +1,25 @@
#include "TerScorer.h"
+
+#include <cmath>
+#include <sstream>
+#include <stdexcept>
+
+#include "ScoreStats.h"
#include "TERsrc/tercalc.h"
#include "TERsrc/terAlignment.h"
+#include "Util.h"
-const int TerScorer::LENGTH = 2;
using namespace TERCpp;
-using namespace std;
+TerScorer::TerScorer(const string& config)
+ : StatisticsBasedScorer("TER",config), kLENGTH(2) {}
+
+TerScorer::~TerScorer() {}
void TerScorer::setReferenceFiles ( const vector<string>& referenceFiles )
{
// for each line in the reference file, create a multiset of the
- // word ids
+ // word ids.
for ( int incRefs = 0; incRefs < ( int ) referenceFiles.size(); incRefs++ ) {
stringstream convert;
m_references.clear();
@@ -78,26 +87,14 @@ void TerScorer::prepareStats ( size_t sid, const string& text, ScoreStats& entry
}
ostringstream stats;
-// multiplication by 100 in order to keep the average precision in the TER calculation
+ // multiplication by 100 in order to keep the average precision
+ // in the TER calculation.
stats << result.numEdits*100.0 << " " << result.averageWords*100.0 << " " << result.scoreAv()*100.0 << " " ;
string stats_str = stats.str();
entry.set ( stats_str );
}
-float TerScorer::calculateScore ( const vector<int>& comps )
-{
- float denom = 1.0 * comps[1];
- float num = -1.0 * comps[0];
- if ( denom == 0 ) {
-// shouldn't happen!
- return 1.0;
- } else {
- return (1.0+(num / denom));
- }
-}
-
-/*
-float TerScorer::calculateScore ( const vector<float>& comps )
+float TerScorer::calculateScore(const vector<int>& comps) const
{
float denom = 1.0 * comps[1];
float num = -1.0 * comps[0];
@@ -108,4 +105,3 @@ float TerScorer::calculateScore ( const vector<float>& comps )
return (1.0+(num / denom));
}
}
-*/
diff --git a/mert/TerScorer.h b/mert/TerScorer.h
index 566aa99b0..0e9996a99 100644
--- a/mert/TerScorer.h
+++ b/mert/TerScorer.h
@@ -1,59 +1,49 @@
#ifndef __TERSCORER_H__
#define __TERSCORER_H__
-// #include <stdio.h>
-#include <algorithm>
-#include <cmath>
#include <iostream>
-#include <iterator>
#include <set>
-#include <sstream>
-#include <stdexcept>
#include <string>
#include <vector>
-#include <limits.h>
+
#include "Types.h"
-#include "ScoreData.h"
#include "Scorer.h"
-#include "TERsrc/tercalc.h"
-#include "TERsrc/terAlignment.h"
using namespace std;
-using namespace TERCpp;
// enum TerReferenceLengthStrategy { TER_AVERAGE, TER_SHORTEST, TER_CLOSEST };
+class ScoreStats;
/**
- * Bleu scoring
- **/
+ * TER scoring
+ */
class TerScorer: public StatisticsBasedScorer
{
public:
- TerScorer(const string& config = "") : StatisticsBasedScorer("TER",config) {}
+ explicit TerScorer(const string& config = "");
+ ~TerScorer();
+
virtual void setReferenceFiles(const vector<string>& referenceFiles);
virtual void prepareStats(size_t sid, const string& text, ScoreStats& entry);
- static const int LENGTH;
- virtual void whoami() {
+
+ virtual void whoami() const {
cerr << "I AM TerScorer" << std::endl;
}
- size_t NumberOfScores() {
- // cerr << "TerScorer: " << (LENGTH + 1) << endl;
- return (LENGTH + 1);
- };
+ virtual size_t NumberOfScores() const {
+ // cerr << "TerScorer: " << (LENGTH + 1) << endl;
+ return kLENGTH + 1;
+ }
-//protected:
- float calculateScore(const vector<int>& comps);
-// float calculateScore(const vector<float>& comps);
+ virtual float calculateScore(const vector<int>& comps) const;
private:
+ const int kLENGTH;
+
string javaEnv;
string tercomEnv;
- //no copy
- TerScorer(const TerScorer&);
- ~TerScorer() {};
- TerScorer& operator=(const TerScorer&);
+
// data extracted from reference files
vector<size_t> _reflengths;
vector<multiset<int> > _reftokens;
@@ -61,7 +51,9 @@ private:
vector<vector<vector<int> > > m_multi_references;
string m_pid;
+ // no copying allowed
+ TerScorer(const TerScorer&);
+ TerScorer& operator=(const TerScorer&);
};
-
-#endif //__TERSCORER_H
+#endif // __TERSCORER_H__
diff --git a/mert/Timer.cpp b/mert/Timer.cpp
index 74db1b1e2..373eb4a2e 100644
--- a/mert/Timer.cpp
+++ b/mert/Timer.cpp
@@ -1,15 +1,6 @@
-#include <ctime>
-#include <iostream>
-#include <iomanip>
-#include "Util.h"
#include "Timer.h"
+#include "Util.h"
-/***
- * Return the total time that the timer has been in the "running"
- * state since it was first "started" or last "restarted". For
- * "short" time periods (less than an hour), the actual cpu time
- * used is reported instead of the elapsed time.
- */
double Timer::elapsed_time()
{
time_t now;
@@ -17,22 +8,11 @@ double Timer::elapsed_time()
return difftime(now, start_time);
}
-/***
- * Return the total time that the timer has been in the "running"
- * state since it was first "started" or last "restarted". For
- * "short" time periods (less than an hour), the actual cpu time
- * used is reported instead of the elapsed time.
- * This function is the public version of elapsed_time()
- */
double Timer::get_elapsed_time()
{
return elapsed_time();
}
-/***
- * Start a timer. If it is already running, let it continue running.
- * Print an optional message.
- */
void Timer::start(const char* msg)
{
// Print an optional message, something like "Starting timer t";
@@ -82,9 +62,7 @@ inline void Timer::stop(const char* msg)
running = false;
}
*/
-/***
- * Print out an optional message followed by the current timer timing.
- */
+
void Timer::check(const char* msg)
{
// Print an optional message, something like "Checking timer t";
@@ -93,15 +71,3 @@ void Timer::check(const char* msg)
// TRACE_ERR( "[" << std::setiosflags(std::ios::fixed) << std::setprecision(2) << (running ? elapsed_time() : 0) << "] seconds\n");
TRACE_ERR( "[" << (running ? elapsed_time() : 0) << "] seconds\n");
}
-
-/***
- * Allow timers to be printed to ostreams using the syntax 'os << t'
- * for an ostream 'os' and a timer 't'. For example, "cout << t" will
- * print out the total amount of time 't' has been "running".
- */
-std::ostream& operator<<(std::ostream& os, Timer& t)
-{
- //os << std::setprecision(2) << std::setiosflags(std::ios::fixed) << (t.running ? t.elapsed_time() : 0);
- os << (t.running ? t.elapsed_time() : 0);
- return os;
-}
diff --git a/mert/Timer.h b/mert/Timer.h
index a9ec890c5..403547620 100644
--- a/mert/Timer.h
+++ b/mert/Timer.h
@@ -4,32 +4,64 @@
#include <ctime>
#include <iostream>
#include <iomanip>
-#include "Util.h"
class Timer
{
+ /**
+ * Allow timers to be printed to ostreams using the syntax 'os << t'
+ * for an ostream 'os' and a timer 't'. For example, "cout << t" will
+ * print out the total amount of time 't' has been "running".
+ */
friend std::ostream& operator<<(std::ostream& os, Timer& t);
private:
bool running;
time_t start_time;
- //TODO in seconds?
+ /**
+ * Return the total time that the timer has been in the "running"
+ * state since it was first "started" or last "restarted". For
+ * "short" time periods (less than an hour), the actual cpu time
+ * used is reported instead of the elapsed time.
+ * TODO in seconds?
+ */
double elapsed_time();
public:
- /***
- * 'running' is initially false. A timer needs to be explicitly started
- * using 'start' or 'restart'
+ /**
+ * 'running' is initially false. A timer needs to be explicitly started
+ * using 'start' or 'restart'.
*/
Timer() : running(false), start_time(0) { }
+ /**
+ * Start a timer. If it is already running, let it continue running.
+ * Print an optional message.
+ */
void start(const char* msg = 0);
// void restart(const char* msg = 0);
// void stop(const char* msg = 0);
+
+ /**
+ * Print out an optional message followed by the current timer timing.
+ */
void check(const char* msg = 0);
- double get_elapsed_time();
+ /**
+ * Return the total time that the timer has been in the "running"
+ * state since it was first "started" or last "restarted". For
+ * "short" time periods (less than an hour), the actual cpu time
+ * used is reported instead of the elapsed time.
+ * This function is the public version of elapsed_time()
+ */
+ double get_elapsed_time();
};
-#endif // TIMER_H
+inline std::ostream& operator<<(std::ostream& os, Timer& t)
+{
+ //os << std::setprecision(2) << std::setiosflags(std::ios::fixed) << (t.running ? t.elapsed_time() : 0);
+ os << (t.running ? t.elapsed_time() : 0);
+ return os;
+}
+
+#endif // TIMER_H
diff --git a/mert/Types.h b/mert/Types.h
index 659da2334..1d0fd0dd0 100644
--- a/mert/Types.h
+++ b/mert/Types.h
@@ -1,5 +1,6 @@
#ifndef TYPE_H
#define TYPE_H
+
#include <vector>
#include <map>
#include <string>
@@ -39,4 +40,4 @@ typedef vector<ScoreArray> scoredata_t;
typedef map<size_t, std::string> idx2name;
typedef map<std::string, size_t> name2idx;
-#endif
+#endif // TYPE_H
diff --git a/mert/Util.cpp b/mert/Util.cpp
index ffc8a4c7e..3769c71e7 100644
--- a/mert/Util.cpp
+++ b/mert/Util.cpp
@@ -6,17 +6,24 @@
*
*/
-#include <stdexcept>
#include "Util.h"
-
#include "Timer.h"
using namespace std;
-//global variable
+// global variables
Timer g_timer;
-int verbose=0;
+int verbose = 0;
+
+namespace {
+
+bool FindDelimiter(const std::string &str, const std::string &delim, size_t *pos)
+{
+ *pos = str.find(delim);
+ return *pos != std::string::npos ? true : false;
+}
+} // namespace
int verboselevel()
{
@@ -25,26 +32,27 @@ int verboselevel()
int setverboselevel(int v)
{
- verbose=v;
+ verbose = v;
return verbose;
}
-int getNextPound(std::string &theString, std::string &substring, const std::string delimiter)
+size_t getNextPound(std::string &str, std::string &substr,
+ const std::string &delimiter)
{
- unsigned int pos = 0;
+ size_t pos = 0;
- //skip all occurrences of delimiter
- while ( pos == 0 ) {
- if ((pos = theString.find(delimiter)) != std::string::npos) {
- substring.assign(theString, 0, pos);
- theString.erase(0,pos + delimiter.size());
+ // skip all occurrences of delimiter
+ while (pos == 0) {
+ if (FindDelimiter(str, delimiter, &pos)) {
+ substr.assign(str, 0, pos);
+ str.erase(0, pos + delimiter.size());
} else {
- substring.assign(theString);
- theString.assign("");
+ substr.assign(str);
+ str.assign("");
}
}
- return (pos);
-};
+ return pos;
+}
void split(const std::string &s, char delim, std::vector<std::string> &elems) {
std::stringstream ss(s);
@@ -54,79 +62,36 @@ void split(const std::string &s, char delim, std::vector<std::string> &elems) {
}
}
-inputfilestream::inputfilestream(const std::string &filePath)
- : std::istream(0),
- m_streambuf(0)
-{
- //check if file is readable
- std::filebuf* fb = new std::filebuf();
- _good=(fb->open(filePath.c_str(), std::ios::in)!=NULL);
-
- if (filePath.size() > 3 &&
- filePath.substr(filePath.size() - 3, 3) == ".gz") {
- fb->close();
- delete fb;
- m_streambuf = new gzfilebuf(filePath.c_str());
- } else {
- m_streambuf = fb;
+void Tokenize(const char *str, const char delim,
+ std::vector<std::string> *res) {
+ while (1) {
+ const char *begin = str;
+ while (*str != delim && *str) str++;
+ res->push_back(std::string(begin, str));
+ if (*str++ == 0) break;
}
- this->init(m_streambuf);
-}
-
-inputfilestream::~inputfilestream()
-{
- delete m_streambuf;
- m_streambuf = 0;
-}
-
-void inputfilestream::close()
-{
-}
-
-outputfilestream::outputfilestream(const std::string &filePath)
- : std::ostream(0),
- m_streambuf(0)
-{
- //check if file is readable
- std::filebuf* fb = new std::filebuf();
- _good=(fb->open(filePath.c_str(), std::ios::out)!=NULL);
-
- if (filePath.size() > 3 && filePath.substr(filePath.size() - 3, 3) == ".gz") {
- throw runtime_error("Output to a zipped file not supported!");
- } else {
- m_streambuf = fb;
- }
- this->init(m_streambuf);
-}
-
-outputfilestream::~outputfilestream()
-{
- delete m_streambuf;
- m_streambuf = 0;
-}
-
-void outputfilestream::close()
-{
}
int swapbytes(char *p, int sz, int n)
{
char c, *l, *h;
- if((n<1) || (sz<2)) return 0;
- for(; n--; p+=sz) for(h=(l=p)+sz; --h>l; l++) {
- c=*h;
- *h=*l;
- *l=c;
+ if((n < 1) || (sz < 2)) return 0;
+ for (; n--; p += sz) {
+ for (h = (l = p) + sz; --h > l; l++) {
+ c = *h;
+ *h = *l;
+ *l = c;
}
+ }
return 0;
-};
+}
void ResetUserTime()
{
g_timer.start();
-};
+}
void PrintUserTime(const std::string &message)
{
@@ -137,4 +102,3 @@ double GetUserTime()
{
return g_timer.get_elapsed_time();
}
-
diff --git a/mert/Util.h b/mert/Util.h
index 592344ddb..da68685c3 100644
--- a/mert/Util.h
+++ b/mert/Util.h
@@ -9,15 +9,9 @@
#ifndef UTIL_H
#define UTIL_H
-using namespace std;
-
+#include <cstdlib>
#include <stdexcept>
#include <limits>
-
-#define US_NOSET (numeric_limits<unsigned short>::max())
-
-#define MAX_LINE 1024
-
#include <vector>
#include <map>
#include <iostream>
@@ -25,15 +19,12 @@ using namespace std;
#include <string>
#include <cstring>
-#include <fstream>
-#include "gzfilebuf.h"
-
#include "Types.h"
-#include "ScoreStats.h"
-#include "FeatureStats.h"
-class ScoreStats;
-class FeatureStats;
+using namespace std;
+
+#define US_NOSET (numeric_limits<unsigned short>::max())
+#define MAX_LINE 1024
#ifdef TRACE_ENABLE
#define TRACE_ERR(str) { std::cerr << str; }
@@ -41,14 +32,28 @@ class FeatureStats;
#define TRACE_ERR(str) { }
#endif
-#define DELIMITER_SYMBOL " "
+const char kDefaultDelimiterSymbol[] = " ";
int verboselevel();
int setverboselevel(int v);
-int getNextPound(std::string &theString, std::string &substring, const std::string delimiter=DELIMITER_SYMBOL);
+/**
+ * Find the specified delimiter for the string 'str', and 'str' is assigned
+ * to a substring object that starts at the position of first occurrence of
+ * the delimiter in 'str'. 'substr' is copied from 'str' ranging from
+ * the start position of 'str' to the position of first occurrence of
+ * the delimiter.
+ *
+ * It returns the position of first occurrence in the queried string.
+ * If the content is not found, std::string::npos is returned.
+ */
+size_t getNextPound(std::string &str, std::string &substr,
+ const std::string &delimiter = kDefaultDelimiterSymbol);
+
void split(const std::string &s, char delim, std::vector<std::string> &elems);
+void Tokenize(const char *str, const char delim, std::vector<std::string> *res);
+
template<typename T>
inline T Scan(const std::string &input)
{
@@ -56,37 +61,7 @@ inline T Scan(const std::string &input)
T ret;
stream >> ret;
return ret;
-};
-
-class inputfilestream : public std::istream
-{
-protected:
- std::streambuf *m_streambuf;
- bool _good;
-public:
-
- inputfilestream(const std::string &filePath);
- ~inputfilestream();
- bool good() {
- return _good;
- }
- void close();
-};
-
-class outputfilestream : public std::ostream
-{
-protected:
- std::streambuf *m_streambuf;
- bool _good;
-public:
-
- outputfilestream(const std::string &filePath);
- ~outputfilestream();
- bool good() {
- return _good;
- }
- void close();
-};
+}
template<typename T>
inline std::string stringify(T x)
@@ -97,10 +72,29 @@ inline std::string stringify(T x)
return o.str();
}
+inline ScoreStatsType ConvertCharToScoreStatsType(const char *str)
+{
+ return std::atoi(str);
+}
+
+inline ScoreStatsType ConvertStringToScoreStatsType(const std::string& str)
+{
+ return ConvertCharToScoreStatsType(str.c_str());
+}
+
+inline FeatureStatsType ConvertCharToFeatureStatsType(const char *str)
+{
+ return static_cast<FeatureStatsType>(std::atof(str));
+}
+
+inline FeatureStatsType ConvertStringToFeatureStatsType(const std::string &str)
+{
+ return ConvertCharToFeatureStatsType(str.c_str());
+}
+
// Utilities to measure decoding time
void ResetUserTime();
void PrintUserTime(const std::string &message);
double GetUserTime();
-#endif
-
+#endif // UTIL_H
diff --git a/mert/evaluator.cpp b/mert/evaluator.cpp
index f766fb19f..c1d6039da 100644
--- a/mert/evaluator.cpp
+++ b/mert/evaluator.cpp
@@ -1,3 +1,4 @@
+#include <fstream>
#include <iostream>
#include <string>
#include <vector>
@@ -33,10 +34,8 @@ void usage()
cerr<<"[--rseed|-r] the random seed for bootstraping (defaults to system clock)"<<endl;
cerr<<"[--help|-h] print this message and exit"<<endl;
exit(1);
-
}
-
static struct option long_options[] = {
{"sctype",required_argument,0,'s'},
{"scconfig",required_argument,0,'c'},
@@ -65,27 +64,27 @@ int main(int argc, char** argv)
int c;
while ((c=getopt_long (argc,argv, "s:c:R:C:b:r:h", long_options, &option_index)) != -1) {
switch(c) {
- case 's':
- scorerType = string(optarg);
- break;
- case 'c':
- scorerConfig = string(optarg);
- break;
- case 'R':
- reference = string(optarg);
- break;
- case 'C':
- candidate = string(optarg);
- break;
- case 'b':
- bootstrap = atoi(optarg);
- break;
- case 'r':
- seed = strtol(optarg, NULL, 10);
- hasSeed = true;
- break;
- default:
- usage();
+ case 's':
+ scorerType = string(optarg);
+ break;
+ case 'c':
+ scorerConfig = string(optarg);
+ break;
+ case 'R':
+ reference = string(optarg);
+ break;
+ case 'C':
+ candidate = string(optarg);
+ break;
+ case 'b':
+ bootstrap = atoi(optarg);
+ break;
+ case 'r':
+ seed = strtol(optarg, NULL, 10);
+ hasSeed = true;
+ break;
+ default:
+ usage();
}
}
@@ -101,29 +100,30 @@ int main(int argc, char** argv)
}
try {
- vector<string> refFiles;
- vector<string> candFiles;
+ vector<string> refFiles;
+ vector<string> candFiles;
+
+ if (reference.length() == 0) throw runtime_error("You have to specify at least one reference file.");
+ split(reference,',',refFiles);
- if (reference.length() == 0) throw runtime_error("You have to specify at least one reference file.");
- split(reference,',',refFiles);
+ if (candidate.length() == 0) throw runtime_error("You have to specify at least one candidate file.");
+ split(candidate,',',candFiles);
- if (candidate.length() == 0) throw runtime_error("You have to specify at least one candidate file.");
- split(candidate,',',candFiles);
+ scorer = ScorerFactory::getScorer(scorerType,scorerConfig);
+ cerr << "Using scorer: " << scorer->getName() << endl;
- ScorerFactory sfactory;
- scorer = sfactory.getScorer(scorerType,scorerConfig);
- cerr << "Using scorer: " << scorer->getName() << endl;
+ scorer->setReferenceFiles(refFiles);
+ PrintUserTime("Reference files loaded");
- scorer->setReferenceFiles(refFiles);
- PrintUserTime("Reference files loaded");
-
- for (vector<string>::const_iterator it = candFiles.begin(); it != candFiles.end(); ++it)
- {
- evaluate(*it);
- }
+ for (vector<string>::const_iterator it = candFiles.begin(); it != candFiles.end(); ++it)
+ {
+ evaluate(*it);
+ }
- PrintUserTime("Evaluation done");
+ PrintUserTime("Evaluation done");
+
+ delete scorer;
return EXIT_SUCCESS;
} catch (const exception& e) {
@@ -135,89 +135,91 @@ int main(int argc, char** argv)
void evaluate(const string& candFile)
{
- ifstream cand(candFile.c_str());
- if (!cand.good()) throw runtime_error("Error opening candidate file");
-
- vector<ScoreStats> entries;
-
- // Loading sentences and preparing statistics
- ScoreStats scoreentry;
- string line;
- while (getline(cand, line))
- {
- scorer->prepareStats(entries.size(), line, scoreentry);
- entries.push_back(scoreentry);
- }
-
- PrintUserTime("Candidate file " + candFile + " loaded and stats prepared");
-
- int n = entries.size();
- if (bootstrap)
- {
- vector<float> scores;
- for (int i = 0; i < bootstrap; ++i)
- {
- ScoreData* scoredata = new ScoreData(*scorer);
- for (int j = 0; j < n; ++j)
- {
- int randomIndex = random() % n;
- string str_j = int2string(j);
- scoredata->add(entries[randomIndex], str_j);
- }
- scorer->setScoreData(scoredata);
- candidates_t candidates(n, 0);
- float score = scorer->score(candidates);
- scores.push_back(score);
- delete scoredata;
- }
-
- float avg = average(scores);
- float dev = stdDeviation(scores, avg);
-
- cout.setf(ios::fixed,ios::floatfield);
- cout.precision(4);
- cout << "File: " << candFile << "\t" << scorer->getName() << " Average score: " << avg << "\tStandard deviation: " << dev << endl;
- }
- else
- {
- ScoreData* scoredata = new ScoreData(*scorer);
- for (int sid = 0; sid < n; ++sid)
- {
- string str_sid = int2string(sid);
- scoredata->add(entries[sid], str_sid);
- }
- scorer->setScoreData(scoredata);
- candidates_t candidates(n, 0);
- float score = scorer->score(candidates);
- delete scoredata;
-
- cout.setf(ios::fixed,ios::floatfield);
- cout.precision(4);
- cout << "File: " << candFile << "\t" << scorer->getName() << " Score: " << score << endl;
- }
+ ifstream cand(candFile.c_str());
+ if (!cand.good()) throw runtime_error("Error opening candidate file");
+
+ vector<ScoreStats> entries;
+
+ // Loading sentences and preparing statistics
+ ScoreStats scoreentry;
+ string line;
+ while (getline(cand, line))
+ {
+ scorer->prepareStats(entries.size(), line, scoreentry);
+ entries.push_back(scoreentry);
+ }
+
+ PrintUserTime("Candidate file " + candFile + " loaded and stats prepared");
+
+ int n = entries.size();
+ if (bootstrap)
+ {
+ vector<float> scores;
+ for (int i = 0; i < bootstrap; ++i)
+ {
+ // TODO: Use smart pointer for exceptional-safety.
+ ScoreData* scoredata = new ScoreData(*scorer);
+ for (int j = 0; j < n; ++j)
+ {
+ int randomIndex = random() % n;
+ string str_j = int2string(j);
+ scoredata->add(entries[randomIndex], str_j);
+ }
+ scorer->setScoreData(scoredata);
+ candidates_t candidates(n, 0);
+ float score = scorer->score(candidates);
+ scores.push_back(score);
+ delete scoredata;
+ }
+
+ float avg = average(scores);
+ float dev = stdDeviation(scores, avg);
+
+ cout.setf(ios::fixed,ios::floatfield);
+ cout.precision(4);
+ cout << "File: " << candFile << "\t" << scorer->getName() << " Average score: " << avg << "\tStandard deviation: " << dev << endl;
+ }
+ else
+ {
+ // TODO: Use smart pointer for exceptional-safety.
+ ScoreData* scoredata = new ScoreData(*scorer);
+ for (int sid = 0; sid < n; ++sid)
+ {
+ string str_sid = int2string(sid);
+ scoredata->add(entries[sid], str_sid);
+ }
+ scorer->setScoreData(scoredata);
+ candidates_t candidates(n, 0);
+ float score = scorer->score(candidates);
+ delete scoredata;
+
+ cout.setf(ios::fixed,ios::floatfield);
+ cout.precision(4);
+ cout << "File: " << candFile << "\t" << scorer->getName() << " Score: " << score << endl;
+ }
}
string int2string(int n)
{
- stringstream ss;
- ss << n;
- return ss.str();
+ stringstream ss;
+ ss << n;
+ return ss.str();
}
float average(const vector<float>& list)
{
- float sum = 0;
- for (vector<float>::const_iterator it = list.begin(); it != list.end(); ++it)
- sum += *it;
-
- return sum / list.size();
+ float sum = 0;
+ for (vector<float>::const_iterator it = list.begin(); it != list.end(); ++it)
+ sum += *it;
+
+ return sum / list.size();
}
float stdDeviation(const vector<float>& list, float avg)
{
- vector<float> tmp;
- for (vector<float>::const_iterator it = list.begin(); it != list.end(); ++it)
- tmp.push_back(pow(*it - avg, 2));
+ vector<float> tmp;
+ for (vector<float>::const_iterator it = list.begin(); it != list.end(); ++it)
+ tmp.push_back(pow(*it - avg, 2));
- return sqrt(average(tmp));
+ return sqrt(average(tmp));
}
diff --git a/mert/example/memcheck_extractor.sh b/mert/example/memcheck_extractor.sh
new file mode 100755
index 000000000..ac613da25
--- /dev/null
+++ b/mert/example/memcheck_extractor.sh
@@ -0,0 +1,16 @@
+#!/bin/sh
+extractor=../extractor
+
+VALGRIND_OPTS="--leak-check=full --leak-resolution=high \
+--show-reachable=yes --track-origins=yes"
+VALGRIND="valgrind $VALGRIND_OPTS"
+
+for datafile in NBEST REF.0 REF.1 REF.2; do
+ if ! [ -f $datafile ]; then
+ echo "Error: $datafile does not exist."
+ exit 1
+ fi
+done
+
+$VALGRIND $extractor --nbest NBEST --reference REF.0,REF.1,REF.2 \
+ --ffile FEATSTAT --scfile SCORESTAT --sctype BLEU
diff --git a/mert/example/memcheck_mert.sh b/mert/example/memcheck_mert.sh
new file mode 100755
index 000000000..d0b7655be
--- /dev/null
+++ b/mert/example/memcheck_mert.sh
@@ -0,0 +1,21 @@
+#!/bin/sh
+VALGRIND_OPTS="--leak-check=full --leak-resolution=high \
+--show-reachable=yes --track-origins=yes"
+VALGRIND="valgrind $VALGRIND_OPTS"
+
+size=15
+extractor=../extractor
+mert=../mert
+
+# Make sure you need to run extractor.
+for f in SCORESTAT FEATSTAT; do
+ if ! [ -f "$f" ]; then
+ echo "Error: $f does not exist. Now we are running extractor."
+ $extractor --nbest NBEST --reference REF.0,REF.1,REF.2 \
+ --ffile FEATSTAT --scfile SCORESTAT --sctype BLEU
+ break
+ fi
+done
+
+$VALGRIND $mert -r 1234 --ifile init.opt --scfile SCORESTAT \
+ --ffile FEATSTAT -d $size --verbose 4 -n 5
diff --git a/mert/extractor.cpp b/mert/extractor.cpp
index ef17b9d16..37c46d2dd 100644
--- a/mert/extractor.cpp
+++ b/mert/extractor.cpp
@@ -78,92 +78,74 @@ int main(int argc, char** argv)
int c;
while ((c=getopt_long (argc,argv, "s:r:n:S:F:R:E:v:hb", long_options, &option_index)) != -1) {
switch(c) {
- case 's':
- scorerType = string(optarg);
- break;
- case 'c':
- scorerConfig = string(optarg);
- break;
- case 'r':
- referenceFile = string(optarg);
- break;
- case 'b':
- binmode = true;
- break;
- case 'n':
- nbestFile = string(optarg);
- break;
- case 'S':
- scoreDataFile = string(optarg);
- break;
- case 'F':
- featureDataFile = string(optarg);
- break;
- case 'E':
- prevFeatureDataFile = string(optarg);
- break;
- case 'R':
- prevScoreDataFile = string(optarg);
- break;
- case 'v':
- verbosity = atoi(optarg);
- break;
- default:
- usage();
+ case 's':
+ scorerType = string(optarg);
+ break;
+ case 'c':
+ scorerConfig = string(optarg);
+ break;
+ case 'r':
+ referenceFile = string(optarg);
+ break;
+ case 'b':
+ binmode = true;
+ break;
+ case 'n':
+ nbestFile = string(optarg);
+ break;
+ case 'S':
+ scoreDataFile = string(optarg);
+ break;
+ case 'F':
+ featureDataFile = string(optarg);
+ break;
+ case 'E':
+ prevFeatureDataFile = string(optarg);
+ break;
+ case 'R':
+ prevScoreDataFile = string(optarg);
+ break;
+ case 'v':
+ verbosity = atoi(optarg);
+ break;
+ default:
+ usage();
}
}
try {
-
-//check whether score statistics file is specified
+ // check whether score statistics file is specified
if (scoreDataFile.length() == 0) {
throw runtime_error("Error: output score statistics file is not specified");
}
-//check wheter feature file is specified
+ // check wheter feature file is specified
if (featureDataFile.length() == 0) {
throw runtime_error("Error: output feature file is not specified");
}
-//check whether reference file is specified when nbest is specified
+ // check whether reference file is specified when nbest is specified
if ((nbestFile.length() > 0 && referenceFile.length() == 0)) {
throw runtime_error("Error: reference file is not specified; you can not score the nbest");
}
-
vector<string> nbestFiles;
if (nbestFile.length() > 0) {
- std::string substring;
- while (!nbestFile.empty()) {
- getNextPound(nbestFile, substring, ",");
- nbestFiles.push_back(substring);
- }
+ Tokenize(nbestFile.c_str(), ',', &nbestFiles);
}
vector<string> referenceFiles;
if (referenceFile.length() > 0) {
- std::string substring;
- while (!referenceFile.empty()) {
- getNextPound(referenceFile, substring, ",");
- referenceFiles.push_back(substring);
- }
+ Tokenize(referenceFile.c_str(), ',', &referenceFiles);
}
vector<string> prevScoreDataFiles;
if (prevScoreDataFile.length() > 0) {
- std::string substring;
- while (!prevScoreDataFile.empty()) {
- getNextPound(prevScoreDataFile, substring, ",");
- prevScoreDataFiles.push_back(substring);
- }
+ Tokenize(prevScoreDataFile.c_str(), ',', &prevScoreDataFiles);
}
vector<string> prevFeatureDataFiles;
if (prevFeatureDataFile.length() > 0) {
- std::string substring;
- while (!prevFeatureDataFile.empty()) {
- getNextPound(prevFeatureDataFile, substring, ",");
- prevFeatureDataFiles.push_back(substring);
- }
+ Tokenize(prevFeatureDataFile.c_str(), ',', &prevFeatureDataFiles);
}
if (prevScoreDataFiles.size() != prevFeatureDataFiles.size()) {
@@ -175,10 +157,10 @@ int main(int argc, char** argv)
else cerr << "Binary write mode is NOT selected" << endl;
TRACE_ERR("Scorer type: " << scorerType << endl);
- ScorerFactory sfactory;
- Scorer* scorer = sfactory.getScorer(scorerType,scorerConfig);
+ // ScorerFactory sfactory;
+ Scorer* scorer = ScorerFactory::getScorer(scorerType,scorerConfig);
- //load references
+ // load references
if (referenceFiles.size() > 0)
scorer->setReferenceFiles(referenceFiles);
@@ -186,14 +168,14 @@ int main(int argc, char** argv)
Data data(*scorer);
- //load old data
+ // load old data
for (size_t i=0; i < prevScoreDataFiles.size(); i++) {
data.load(prevFeatureDataFiles.at(i), prevScoreDataFiles.at(i));
}
PrintUserTime("Previous data loaded");
- //computing score statistics of each nbest file
+ // computing score statistics of each nbest file
for (size_t i=0; i < nbestFiles.size(); i++) {
data.loadnbest(nbestFiles.at(i));
}
@@ -207,9 +189,10 @@ int main(int argc, char** argv)
data.save(featureDataFile, scoreDataFile, binmode);
PrintUserTime("Stopping...");
- /*
- timer.stop("Stopping...");
- */
+
+ // timer.stop("Stopping...");
+
+ delete scorer;
return EXIT_SUCCESS;
} catch (const exception& e) {
diff --git a/mert/gzfilebuf.h b/mert/gzfilebuf.h
index 48b0ab036..f9cd8a446 100644
--- a/mert/gzfilebuf.h
+++ b/mert/gzfilebuf.h
@@ -3,11 +3,12 @@
#include <streambuf>
#include <zlib.h>
+#include <cstring>
class gzfilebuf : public std::streambuf
{
public:
- gzfilebuf(const char *filename) {
+ explicit gzfilebuf(const char *filename) {
_gzf = gzopen(filename, "rb");
setg (_buff+sizeof(int), // beginning of putback area
_buff+sizeof(int), // read position
@@ -32,7 +33,7 @@ protected:
throw;
}
- //read one character
+ // read one character
virtual int_type underflow () {
// is read position before end of _buff?
if (gptr() < egptr()) {
@@ -81,4 +82,4 @@ private:
char _buff[_buffsize];
};
-#endif
+#endif // _GZFILEBUF_H_
diff --git a/mert/mert.cpp b/mert/mert.cpp
index 91fa71e7b..98f2e986c 100755
--- a/mert/mert.cpp
+++ b/mert/mert.cpp
@@ -1,5 +1,5 @@
/**
-\description The is the main for the new version of the mert algorithm developed during the 2nd MT marathon
+ * \description The is the main for the new version of the mert algorithm developed during the 2nd MT marathon
*/
#include <limits>
@@ -59,7 +59,7 @@ static struct option long_options[] = {
{"nrandom",1,0,'m'},
{"rseed",required_argument,0,'r'},
{"optimize",1,0,'o'},
- {"pro",required_argument,0,'p'},
+ {"pro",required_argument,0,'p'},
{"type",1,0,'t'},
{"sctype",1,0,'s'},
{"scconfig",required_argument,0,'c'},
@@ -78,40 +78,50 @@ static struct option long_options[] = {
int option_index;
/**
- * Runs an optimisation, or a random restart.
-**/
-class OptimizationTask : public Moses::Task
+ * Runs an optimisation, or a random restart.
+ */
+class OptimizationTask : public Moses::Task
{
- public:
- OptimizationTask(Optimizer* optimizer, const Point& point) :
- m_optimizer(optimizer), m_point(point) {}
+ public:
+ OptimizationTask(Optimizer* optimizer, const Point& point) :
+ m_optimizer(optimizer), m_point(point) {}
- bool DeleteAfterExecution() {
- return false;
- }
+ ~OptimizationTask() {}
- void Run() {
- m_score = m_optimizer->Run(m_point);
+ void resetOptimizer() {
+ if (m_optimizer) {
+ delete m_optimizer;
+ m_optimizer = NULL;
}
+ }
- statscore_t getScore() const {
- return m_score;
- }
+ bool DeleteAfterExecution() {
+ return false;
+ }
- const Point& getPoint() const {
- return m_point;
- }
+ void Run() {
+ m_score = m_optimizer->Run(m_point);
+ }
- private:
- Optimizer* m_optimizer;
- Point m_point;
- statscore_t m_score;
+ statscore_t getScore() const {
+ return m_score;
+ }
+
+ const Point& getPoint() const {
+ return m_point;
+ }
+
+ private:
+ // Do not allow the user to instanciate without arguments.
+ OptimizationTask() {}
+
+ Optimizer* m_optimizer;
+ Point m_point;
+ statscore_t m_score;
};
int main (int argc, char **argv)
{
-
-
ResetUserTime();
/*
@@ -142,64 +152,64 @@ int main (int argc, char **argv)
vector<vector<parameter_t> > start_list;
vector<parameter_t> min;
vector<parameter_t> max;
- //note: those mins and max are the bound for the starting points of the algorithm, not strict bound on the result!
+ // NOTE: those mins and max are the bound for the starting points of the algorithm, not strict bound on the result!
while ((c=getopt_long (argc, argv, "o:r:d:n:m:t:s:S:F:v:p:", long_options, &option_index)) != -1) {
switch (c) {
- case 'o':
- tooptimizestr = string(optarg);
- break;
- case 'd':
- pdim = strtol(optarg, NULL, 10);
- break;
- case 'n':
- ntry=strtol(optarg, NULL, 10);
- break;
- case 'm':
- nrandom=strtol(optarg, NULL, 10);
- break;
- case 'r':
- seed=strtol(optarg, NULL, 10);
- hasSeed = true;
- break;
- case 't':
- type=string(optarg);
- break;
- case's':
- scorertype=string(optarg);
- break;
- case 'c':
- scorerconfig = string(optarg);
- break;
- case 'S':
- scorerfile=string(optarg);
- break;
- case 'F':
- featurefile=string(optarg);
- break;
- case 'i':
- initfile=string(optarg);
- break;
- case 'v':
- setverboselevel(strtol(optarg,NULL,10));
- break;
+ case 'o':
+ tooptimizestr = string(optarg);
+ break;
+ case 'd':
+ pdim = strtol(optarg, NULL, 10);
+ break;
+ case 'n':
+ ntry=strtol(optarg, NULL, 10);
+ break;
+ case 'm':
+ nrandom=strtol(optarg, NULL, 10);
+ break;
+ case 'r':
+ seed=strtol(optarg, NULL, 10);
+ hasSeed = true;
+ break;
+ case 't':
+ type=string(optarg);
+ break;
+ case's':
+ scorertype=string(optarg);
+ break;
+ case 'c':
+ scorerconfig = string(optarg);
+ break;
+ case 'S':
+ scorerfile=string(optarg);
+ break;
+ case 'F':
+ featurefile=string(optarg);
+ break;
+ case 'i':
+ initfile=string(optarg);
+ break;
+ case 'v':
+ setverboselevel(strtol(optarg,NULL,10));
+ break;
#ifdef WITH_THREADS
- case 'T':
- threads = strtol(optarg, NULL, 10);
- if (threads < 1) threads = 1;
- break;
+ case 'T':
+ threads = strtol(optarg, NULL, 10);
+ if (threads < 1) threads = 1;
+ break;
#endif
- case 'a':
- shard_count = strtof(optarg,NULL);
- break;
- case 'b':
- shard_size = strtof(optarg,NULL);
- break;
- case 'h':
- usage(0);
- break;
- default:
- usage(1);
+ case 'a':
+ shard_count = strtof(optarg,NULL);
+ break;
+ case 'b':
+ shard_size = strtof(optarg,NULL);
+ break;
+ case 'h':
+ usage(0);
+ break;
+ default:
+ usage(1);
}
}
if (pdim < 0)
@@ -265,29 +275,20 @@ int main (int argc, char **argv)
vector<string> ScoreDataFiles;
if (scorerfile.length() > 0) {
- std::string substring;
- while (!scorerfile.empty()) {
- getNextPound(scorerfile, substring, ",");
- ScoreDataFiles.push_back(substring);
- }
+ Tokenize(scorerfile.c_str(), ',', &ScoreDataFiles);
}
vector<string> FeatureDataFiles;
if (featurefile.length() > 0) {
- std::string substring;
- while (!featurefile.empty()) {
- getNextPound(featurefile, substring, ",");
- FeatureDataFiles.push_back(substring);
- }
+ Tokenize(featurefile.c_str(), ',', &FeatureDataFiles);
}
if (ScoreDataFiles.size() != FeatureDataFiles.size()) {
throw runtime_error("Error: there is a different number of previous score and feature files");
}
- //it make sense to know what parameter set were used to generate the nbest
- ScorerFactory SF;
- Scorer *TheScorer=SF.getScorer(scorertype,scorerconfig);
+ // it make sense to know what parameter set were used to generate the nbest
+ Scorer *TheScorer = ScorerFactory::getScorer(scorertype,scorerconfig);
//load data
Data D(*TheScorer);
@@ -307,8 +308,7 @@ int main (int argc, char **argv)
if (tooptimizestr.length() > 0) {
cerr << "Weights to optimize: " << tooptimizestr << endl;
- //parse string to get weights to optimize
- //and set them as active
+ // Parse string to get weights to optimize, and set them as active
std::string substring;
int index;
while (!tooptimizestr.empty()) {
@@ -365,17 +365,17 @@ int main (int argc, char **argv)
allTasks.resize(shard_count);
}
- //launch tasks
+ // launch tasks
for (size_t i = 0 ; i < allTasks.size(); ++i) {
Data& data = D;
if (shard_count) data = shards[i]; //use the sharded data if it exists
vector<OptimizationTask*>& tasks = allTasks[i];
- Optimizer *O=OptimizerFactory::BuildOptimizer(pdim,tooptimize,start_list[0],type,nrandom);
+ Optimizer *O = OptimizerFactory::BuildOptimizer(pdim,tooptimize,start_list[0],type,nrandom);
O->SetScorer(data.getScorer());
O->SetFData(data.getFeatureData());
//A task for each start point
for (size_t j = 0; j < startingPoints.size(); ++j) {
- OptimizationTask* task = new OptimizationTask(O,startingPoints[j]);
+ OptimizationTask* task = new OptimizationTask(O, startingPoints[j]);
tasks.push_back(task);
#ifdef WITH_THREADS
pool.Submit(task);
@@ -385,8 +385,7 @@ int main (int argc, char **argv)
}
}
-
- //wait for all threads to finish
+ // wait for all threads to finish
#ifdef WITH_THREADS
pool.Stop(true);
#endif
@@ -394,7 +393,7 @@ int main (int argc, char **argv)
statscore_t total = 0;
Point totalP;
- //collect results
+ // collect results
for (size_t i = 0; i < allTasks.size(); ++i) {
statscore_t best=0, mean=0, var=0;
Point bestP;
@@ -406,7 +405,6 @@ int main (int argc, char **argv)
bestP = allTasks[i][j]->getPoint();
best = score;
}
- delete allTasks[i][j];
}
mean/=(float)ntry;
@@ -436,5 +434,13 @@ int main (int argc, char **argv)
ofstream res("weights.txt");
res<<finalP<<endl;
+ for (size_t i = 0; i < allTasks.size(); ++i) {
+ allTasks[i][0]->resetOptimizer();
+ for (size_t j = 0; j < allTasks[i].size(); ++j) {
+ delete allTasks[i][j];
+ }
+ }
+
+ delete TheScorer;
PrintUserTime("Stopping...");
}