summaryrefslogtreecommitdiff
path: root/fast/sparse_vector.hh
blob: dd7f3cfbb59e4a614889f3ff7c02947f6f46e5ea (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
#pragma once

#include <unordered_map>
#include <vector>
#include <sstream>

typedef double score_t; // FIXME
typedef double weight_t;

using namespace std;


namespace Sv {

template<typename K, typename V>
struct SparseVector {
  unordered_map<K, V> m_;
  V zero = 0.0;

  void
  insert(K k, V v) { m_[k] = v; };

  weight_t 
  dot(SparseVector& other)
  {
  };

  V&
  operator[](const K& k)
  {
    return at(k);
  };

  const V&
  at(const K& k) const
  {
     if (m_.find(k) == m_.end())
      return zero;
    else
      return m_.at(k);
  }

  SparseVector
  operator+(const SparseVector& other) const
  {
    SparseVector<K,V> v;
    v.m_.insert(m_.begin(), m_.end());
    v.m_.insert(other.m_.begin(), other.m_.end());
    for (auto it = v.m_.begin(); it != v.m_.end(); it++)
      v.m_[it->first] = this->at(it->first) + other.at(it->first);
    return v;
  };

  SparseVector&
  operator+=(const SparseVector& other)
  {
    for (auto it = other.m_.begin(); it != other.m_.end(); it++)
      m_[it->first] += it->second;
    return *this;
  };

  SparseVector
  operator-(const SparseVector& other) const
  {
    SparseVector<K,V> v;
    v.m_.insert(m_.begin(), m_.end());
    v.m_.insert(other.m_.begin(), other.m_.end());
    for (auto it = v.m_.begin(); it != v.m_.end(); it++)
      v.m_[it->first] = this->at(it->first) - other.at(it->first);
    return v;
  };

  SparseVector&
  operator-=(const SparseVector& other)
  {
    for (auto it = other.m_.begin(); it != other.m_.end(); it++)
      m_[it->first] -= it->second;
    return *this;
  };

  SparseVector
  operator*(V f) const
  {
    SparseVector<K,V> v;
    for (auto it = m_.begin(); it != m_.end(); it++)
      v.m_[it->first] = this->at(it->first) * f;
    return v;
  };

  SparseVector&
  operator*=(V f)
  {
    for (auto it = m_.begin(); it != m_.end(); it++)
      m_[it->first] *= f;
    return *this;
  };

  string
  repr() const
  {
    ostringstream os; 
    os << "SparseVector<{";
    for (auto it = m_.begin(); it != m_.end(); it ++) {
      os << "'" << it->first << "'=" << it->second;
      if (next(it) != m_.end())
        os << ", ";
    }
    os << "}>";
    return os.str();
  };

  friend ostream&
  operator<<(ostream& os, const SparseVector& v) { return os << v.repr(); }
};

} // namespace