#ifndef TFIDF_CPP
#define TFIDF_CPP

template <typename T>
T sum_of_vector(const std::vector<T>& v) {
  return accumulate(v.begin(), v.end(), 0);
}

// term frequency - inverse document frequency
class Tfidf {
  public:
    Tfidf(long sym_num)
    : thn(0), thv(0), freq(vector<long>  (sym_num, 0)),
                         a(vector<double>(sym_num, 0)) {};

    double get(long s) const {return thv - a[s];}

    // Alternate version, slightly weaker than the above according to the
    // PxTP 2013 paper evaluations.
    //double get(long s) const {return (1.0 / (1.0 + a[s]));}

    double get_sum() const { return (a.size() * thv) - sum_of_vector(a); }

    void add(const LVec &syms) {
      for (const auto& sym : syms) {
        freq[sym]++;
        a[sym] = log(freq[sym]);
      }

      thv = log(++thn);
    }

    void add_many(const LVecVec &syms) {
      for (const auto& sx : syms)
        for (const auto& sy : sx)
          freq[sy]++;

      for (unsigned i = 0; i < a.size(); ++i)
        a[i] = log(freq[i]);

      thn += syms.size();
      thv = log(thn);
    }

  private:
    long thn;           // number of theorems
    double thv;         // logarithmic number of theorems
    vector<long> freq;  // feature frequency
    vector<double> a;   // logarithmic feature frequency
};

#endif
