#ifndef _SPARSE_VECTOR_H_ #define _SPARSE_VECTOR_H_ // this is a modified version of code originally written // by Phil Blunsom #include #include #include #include #include "fdict.h" template class SparseVector { public: SparseVector() {} const T operator[](int index) const { typename std::map::const_iterator found = _values.find(index); if (found == _values.end()) return T(0); else return found->second; } void set_value(int index, const T &value) { _values[index] = value; } void add_value(int index, const T &value) { _values[index] += value; } T value(int index) const { typename std::map::const_iterator found = _values.find(index); if (found != _values.end()) return found->second; else return T(0); } void store(std::valarray* target) const { (*target) *= 0; for (typename std::map::const_iterator it = _values.begin(); it != _values.end(); ++it) { if (it->first >= target->size()) break; (*target)[it->first] = it->second; } } int max_index() const { if (_values.empty()) return 0; typename std::map::const_iterator found =_values.end(); --found; return found->first; } // dot product with a unit vector of the same length // as the sparse vector T dot() const { T sum = 0; for (typename std::map::const_iterator it = _values.begin(); it != _values.end(); ++it) sum += it->second; return sum; } template S dot(const SparseVector &vec) const { S sum = 0; for (typename std::map::const_iterator it = _values.begin(); it != _values.end(); ++it) { typename std::map::const_iterator found = vec._values.find(it->first); if (found != vec._values.end()) sum += it->second * found->second; } return sum; } template S dot(const std::vector &vec) const { S sum = 0; for (typename std::map::const_iterator it = _values.begin(); it != _values.end(); ++it) { if (it->first < static_cast(vec.size())) sum += it->second * vec[it->first]; } return sum; } template S dot(const S *vec) const { // this is not range checked! S sum = 0; for (typename std::map::const_iterator it = _values.begin(); it != _values.end(); ++it) sum += it->second * vec[it->first]; std::cout << "dot(*vec) " << sum << std::endl; return sum; } T l1norm() const { T sum = 0; for (typename std::map::const_iterator it = _values.begin(); it != _values.end(); ++it) sum += fabs(it->second); return sum; } T l2norm() const { T sum = 0; for (typename std::map::const_iterator it = _values.begin(); it != _values.end(); ++it) sum += it->second * it->second; return sqrt(sum); } SparseVector &operator+=(const SparseVector &other) { for (typename std::map::const_iterator it = other._values.begin(); it != other._values.end(); ++it) { T v = (_values[it->first] += it->second); if (v == 0) _values.erase(it->first); } return *this; } SparseVector &operator-=(const SparseVector &other) { for (typename std::map::const_iterator it = other._values.begin(); it != other._values.end(); ++it) { T v = (_values[it->first] -= it->second); if (v == 0) _values.erase(it->first); } return *this; } SparseVector &operator-=(const double &x) { for (typename std::map::iterator it = _values.begin(); it != _values.end(); ++it) it->second -= x; return *this; } SparseVector &operator+=(const double &x) { for (typename std::map::iterator it = _values.begin(); it != _values.end(); ++it) it->second += x; return *this; } SparseVector &operator/=(const double &x) { for (typename std::map::iterator it = _values.begin(); it != _values.end(); ++it) it->second /= x; return *this; } SparseVector &operator*=(const T& x) { for (typename std::map::iterator it = _values.begin(); it != _values.end(); ++it) it->second *= x; return *this; } SparseVector operator+(const double &x) const { SparseVector result = *this; return result += x; } SparseVector operator-(const double &x) const { SparseVector result = *this; return result -= x; } SparseVector operator/(const double &x) const { SparseVector result = *this; return result /= x; } std::ostream &operator<<(std::ostream &out) const { for (typename std::map::const_iterator it = _values.begin(); it != _values.end(); ++it) out << (it == _values.begin() ? "" : ";") << FD::Convert(it->first) << '=' << it->second; return out; } bool operator<(const SparseVector &other) const { typename std::map::const_iterator it = _values.begin(); typename std::map::const_iterator other_it = other._values.begin(); for (; it != _values.end() && other_it != other._values.end(); ++it, ++other_it) { if (it->first < other_it->first) return true; if (it->first > other_it->first) return false; if (it->second < other_it->second) return true; if (it->second > other_it->second) return false; } return _values.size() < other._values.size(); } int num_active() const { return _values.size(); } bool empty() const { return _values.empty(); } typedef typename std::map::const_iterator const_iterator; const_iterator begin() const { return _values.begin(); } const_iterator end() const { return _values.end(); } void clear() { _values.clear(); } void swap(SparseVector& other) { _values.swap(other._values); } private: std::map _values; }; template SparseVector operator+(const SparseVector& a, const SparseVector& b) { SparseVector result = a; return result += b; } template SparseVector operator*(const SparseVector& a, const double& b) { SparseVector result = a; return result *= b; } template SparseVector operator*(const SparseVector& a, const T& b) { SparseVector result = a; return result *= b; } template SparseVector operator*(const double& a, const SparseVector& b) { SparseVector result = b; return result *= a; } template std::ostream &operator<<(std::ostream &out, const SparseVector &vec) { return vec.operator<<(out); } namespace B64 { void Encode(double objective, const SparseVector& v, std::ostream* out); // returns false if failed to decode bool Decode(double* objective, SparseVector* v, const char* data, size_t size); } #endif