mosesdecoder/mert/MiraFeatureVector.cpp

147 lines
3.6 KiB
C++
Raw Normal View History

#include <cmath>
#include "MiraFeatureVector.h"
using namespace std;
MiraFeatureVector::MiraFeatureVector(const FeatureDataItem& vec)
: m_dense(vec.dense)
{
vector<size_t> sparseFeats = vec.sparse.feats();
bool bFirst = true;
size_t lastFeat = 0;
for(size_t i=0;i<sparseFeats.size();i++)
{
size_t feat = m_dense.size() + sparseFeats[i];
m_sparseFeats.push_back(feat);
m_sparseVals.push_back(vec.sparse.get(sparseFeats[i]));
// Check ordered property
if(bFirst) {
bFirst = false;
}
else {
if(lastFeat>=feat) {
cerr << "Error: Feature indeces must be strictly ascending coming out of SparseVector" << endl;
exit(1);
}
}
lastFeat = feat;
}
}
MiraFeatureVector::MiraFeatureVector(const MiraFeatureVector& other)
: m_dense(other.m_dense),
m_sparseFeats(other.m_sparseFeats),
m_sparseVals(other.m_sparseVals)
{
if(m_sparseVals.size()!=m_sparseFeats.size()) {
cerr << "Error: mismatching sparse feat and val sizes" << endl;
exit(1);
}
}
MiraFeatureVector::MiraFeatureVector(const vector<ValType>& dense,
const vector<size_t>& sparseFeats,
const vector<ValType>& sparseVals)
: m_dense(dense),
m_sparseFeats(sparseFeats),
m_sparseVals(sparseVals)
{
if(m_sparseVals.size()!=m_sparseFeats.size()) {
cerr << "Error: mismatching sparse feat and val sizes" << endl;
exit(1);
}
}
ValType MiraFeatureVector::val(size_t index) const {
if(index < m_dense.size())
return m_dense[index];
else
return m_sparseVals[index];
}
size_t MiraFeatureVector::feat(size_t index) const {
if(index < m_dense.size())
return index;
else
return m_sparseFeats[index];
}
size_t MiraFeatureVector::size() const {
return m_dense.size() + m_sparseVals.size();
}
ValType MiraFeatureVector::sqrNorm() const {
ValType toRet = 0.0;
for(size_t i=0;i<m_dense.size();i++)
toRet += m_dense[i]*m_dense[i];
for(size_t i=0;i<m_sparseVals.size();i++)
toRet += m_sparseVals[i] * m_sparseVals[i];
return toRet;
}
MiraFeatureVector operator-(const MiraFeatureVector& a, const MiraFeatureVector& b)
{
// Dense subtraction
vector<ValType> dense;
if(a.m_dense.size()!=b.m_dense.size()) {
cerr << "Mismatching dense vectors passed to MiraFeatureVector subtraction" << endl;
exit(1);
}
for(size_t i=0;i<a.m_dense.size();i++) {
dense.push_back(a.m_dense[i] - b.m_dense[i]);
}
// Sparse subtraction
size_t i=0;
size_t j=0;
vector<ValType> sparseVals;
vector<size_t> sparseFeats;
while(i < a.m_sparseFeats.size() && j < b.m_sparseFeats.size()) {
if(a.m_sparseFeats[i] < b.m_sparseFeats[j]) {
sparseFeats.push_back(a.m_sparseFeats[i]);
sparseVals.push_back(a.m_sparseVals[i]);
i++;
}
else if(b.m_sparseFeats[j] < a.m_sparseFeats[i]) {
sparseFeats.push_back(b.m_sparseFeats[j]);
sparseVals.push_back(-b.m_sparseVals[j]);
j++;
}
else {
ValType newVal = a.m_sparseVals[i] - b.m_sparseVals[j];
if(abs(newVal)>1e-6) {
sparseFeats.push_back(a.m_sparseFeats[i]);
sparseVals.push_back(newVal);
}
i++;
j++;
}
}
while(i<a.m_sparseFeats.size()) {
sparseFeats.push_back(a.m_sparseFeats[i]);
sparseVals.push_back(a.m_sparseVals[i]);
i++;
}
while(j<b.m_sparseFeats.size()) {
sparseFeats.push_back(b.m_sparseFeats[j]);
sparseVals.push_back(-b.m_sparseVals[j]);
j++;
}
// Create and return vector
return MiraFeatureVector(dense,sparseFeats,sparseVals);
}
// --Emacs trickery--
// Local Variables:
// mode:c++
// c-basic-offset:2
// End: