summaryrefslogtreecommitdiff
path: root/gi/pf/quasi_model2.h
blob: 0095289f85a4ad15f8fd39cc94e4ca45450f90f6 (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
#ifndef _QUASI_MODEL2_H_
#define _QUASI_MODEL2_H_

#include <vector>
#include <cmath>
#include "prob.h"
#include "array2d.h"

struct QuasiModel2 {
  explicit QuasiModel2(double alpha, double pnull = 0.1) :
      alpha_(alpha),
      pnull_(pnull),
      pnotnull_(1 - pnull),
      z_(1000,1000) {}
  // a_j = 0 => NULL; src_len does *not* include null
  prob_t Pa_j(unsigned a_j, unsigned j, unsigned src_len, unsigned trg_len) const {
    if (!a_j) return pnull_;
    std::vector<prob_t>& zv = z_(src_len, trg_len);
    if (zv.size() == 0)
      zv.resize(trg_len);
    
    prob_t& z = zv[j];
    if (z.is_0()) z = ComputeZ(j, src_len, trg_len);

    prob_t p;
    p.logeq(-fabs(double(a_j - 1) / src_len - double(j) / trg_len) * alpha_);
    p *= pnotnull_;
    p /= z;
    return p;
  }
 private:
  prob_t ComputeZ(unsigned j, unsigned src_len, unsigned trg_len) const {
    prob_t p, z = prob_t::Zero();
    for (int a_j = 1; a_j <= src_len; ++a_j) {
      p.logeq(-fabs(double(a_j - 1) / src_len - double(j) / trg_len) * alpha_);
      z += p;
    }
    return z;
  }
  double alpha_;
  const prob_t pnull_;
  const prob_t pnotnull_;
  mutable Array2D<std::vector<prob_t> > z_;
};

#endif