00001 #include <cmath>
00002 #include <iomanip>
00003
00004 #include "MiraFeatureVector.h"
00005
00006 using namespace std;
00007
00008 namespace MosesTuning
00009 {
00010
00011
00012 void MiraFeatureVector::InitSparse(const SparseVector& sparse, size_t ignoreLimit)
00013 {
00014 vector<size_t> sparseFeats = sparse.feats();
00015 bool bFirst = true;
00016 size_t lastFeat = 0;
00017 m_sparseFeats.reserve(sparseFeats.size());
00018 m_sparseVals.reserve(sparseFeats.size());
00019 for(size_t i=0; i<sparseFeats.size(); i++) {
00020 if (sparseFeats[i] < ignoreLimit) continue;
00021 size_t feat = m_dense.size() + sparseFeats[i];
00022 m_sparseFeats.push_back(feat);
00023 m_sparseVals.push_back(sparse.get(sparseFeats[i]));
00024
00025
00026 if(bFirst) {
00027 bFirst = false;
00028 } else {
00029 if(lastFeat>=feat) {
00030 cerr << "Error: Feature indeces must be strictly ascending coming out of SparseVector" << endl;
00031 exit(1);
00032 }
00033 }
00034 lastFeat = feat;
00035 }
00036 }
00037
00038 MiraFeatureVector::MiraFeatureVector(const FeatureDataItem& vec)
00039 : m_dense(vec.dense)
00040 {
00041 InitSparse(vec.sparse);
00042 }
00043
00044 MiraFeatureVector::MiraFeatureVector(const SparseVector& sparse, size_t num_dense)
00045 {
00046 m_dense.resize(num_dense);
00047
00048 for (size_t id = 0; id < num_dense; ++id) {
00049 m_dense[id] = sparse.get(id);
00050 }
00051 InitSparse(sparse,num_dense);
00052 }
00053
00054 MiraFeatureVector::MiraFeatureVector(const MiraFeatureVector& other)
00055 : m_dense(other.m_dense),
00056 m_sparseFeats(other.m_sparseFeats),
00057 m_sparseVals(other.m_sparseVals)
00058 {
00059 if(m_sparseVals.size()!=m_sparseFeats.size()) {
00060 cerr << "Error: mismatching sparse feat and val sizes" << endl;
00061 exit(1);
00062 }
00063 }
00064
00065 MiraFeatureVector::MiraFeatureVector(const vector<ValType>& dense,
00066 const vector<size_t>& sparseFeats,
00067 const vector<ValType>& sparseVals)
00068 : m_dense(dense),
00069 m_sparseFeats(sparseFeats),
00070 m_sparseVals(sparseVals)
00071 {
00072 if(m_sparseVals.size()!=m_sparseFeats.size()) {
00073 cerr << "Error: mismatching sparse feat and val sizes" << endl;
00074 exit(1);
00075 }
00076 }
00077
00078 ValType MiraFeatureVector::val(size_t index) const
00079 {
00080 if(index < m_dense.size())
00081 return m_dense[index];
00082 else
00083 return m_sparseVals[index-m_dense.size()];
00084 }
00085
00086 size_t MiraFeatureVector::feat(size_t index) const
00087 {
00088 if(index < m_dense.size())
00089 return index;
00090 else
00091 return m_sparseFeats[index-m_dense.size()];
00092 }
00093
00094 size_t MiraFeatureVector::size() const
00095 {
00096 return m_dense.size() + m_sparseVals.size();
00097 }
00098
00099
00100 ValType MiraFeatureVector::sqrNorm() const
00101 {
00102 ValType toRet = 0.0;
00103 for(size_t i=0; i<m_dense.size(); i++)
00104 toRet += m_dense[i]*m_dense[i];
00105 for(size_t i=0; i<m_sparseVals.size(); i++)
00106 toRet += m_sparseVals[i] * m_sparseVals[i];
00107 return toRet;
00108 }
00109
00110 MiraFeatureVector operator-(const MiraFeatureVector& a, const MiraFeatureVector& b)
00111 {
00112
00113 vector<ValType> dense;
00114 if(a.m_dense.size()!=b.m_dense.size()) {
00115 cerr << "Mismatching dense vectors passed to MiraFeatureVector subtraction" << endl;
00116 exit(1);
00117 }
00118 for(size_t i=0; i<a.m_dense.size(); i++) {
00119 dense.push_back(a.m_dense[i] - b.m_dense[i]);
00120 }
00121
00122
00123 size_t i=0;
00124 size_t j=0;
00125 vector<ValType> sparseVals;
00126 vector<size_t> sparseFeats;
00127 while(i < a.m_sparseFeats.size() && j < b.m_sparseFeats.size()) {
00128
00129 if(a.m_sparseFeats[i] < b.m_sparseFeats[j]) {
00130 sparseFeats.push_back(a.m_sparseFeats[i]);
00131 sparseVals.push_back(a.m_sparseVals[i]);
00132 i++;
00133 }
00134
00135 else if(b.m_sparseFeats[j] < a.m_sparseFeats[i]) {
00136 sparseFeats.push_back(b.m_sparseFeats[j]);
00137 sparseVals.push_back(-b.m_sparseVals[j]);
00138 j++;
00139 }
00140
00141 else {
00142 ValType newVal = a.m_sparseVals[i] - b.m_sparseVals[j];
00143 if(abs(newVal)>1e-6) {
00144 sparseFeats.push_back(a.m_sparseFeats[i]);
00145 sparseVals.push_back(newVal);
00146 }
00147 i++;
00148 j++;
00149 }
00150 }
00151
00152 while(i<a.m_sparseFeats.size()) {
00153 sparseFeats.push_back(a.m_sparseFeats[i]);
00154 sparseVals.push_back(a.m_sparseVals[i]);
00155 i++;
00156 }
00157
00158 while(j<b.m_sparseFeats.size()) {
00159 sparseFeats.push_back(b.m_sparseFeats[j]);
00160 sparseVals.push_back(-b.m_sparseVals[j]);
00161 j++;
00162 }
00163
00164
00165 return MiraFeatureVector(dense,sparseFeats,sparseVals);
00166 }
00167
00168 bool operator==(const MiraFeatureVector& a,const MiraFeatureVector& b)
00169 {
00170 ValType eps = 1e-8;
00171
00172 if (a.m_dense.size() != b.m_dense.size()) return false;
00173 for (size_t i = 0; i < a.m_dense.size(); ++i) {
00174 if (fabs(a.m_dense[i]-b.m_dense[i]) < eps) return false;
00175 }
00176 if (a.m_sparseFeats.size() != b.m_sparseFeats.size()) return false;
00177 for (size_t i = 0; i < a.m_sparseFeats.size(); ++i) {
00178 if (a.m_sparseFeats[i] != b.m_sparseFeats[i]) return false;
00179 if (fabs(a.m_sparseVals[i] != b.m_sparseVals[i])) return false;
00180 }
00181 return true;
00182
00183 }
00184
00185 ostream& operator<<(ostream& o, const MiraFeatureVector& e)
00186 {
00187 for(size_t i=0; i<e.size(); i++) {
00188 if(i>0) o << " ";
00189 o << e.feat(i) << ":" << e.val(i);
00190 }
00191 return o;
00192 }
00193
00194
00195
00196
00197
00198
00199
00200 }
00201