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
#include "Binding.hpp"
#include "algo.hpp"

namespace macrovsa {
  Binding::Binding(const Symbol& y, const Symbol& x, bool b, bool normalized) : Symbol("B_(" + y.getName() + (b ? "" : "~") + ")(" + x.getName() + ")", binding), y_(clone(y)), x_(clone(x)), b_(b), normalized_(normalized)
  {
    x_->setBelief(x_->getBelief().tau * y_->getBelief().tau, y_->getBelief().tau * x_->getBelief().sigma + x_->getBelief().tau * y_->getBelief().sigma);
    y_->setBelief(1, 0);
    setBelief(x_->getBelief().tau, algo::sigma_04 * fabs(x_->getBelief().tau) + x_->getBelief().sigma);
  }
  Binding::Binding(const Binding& symbol) : Binding(*symbol.y_, *symbol.x_, symbol.b_, symbol.normalized_)
  {}
  Binding::~Binding()
  {
    delete x_, delete y_;
  }
  void Binding::setBelief(double tau, double sigma)
  {
    Symbol::setBelief(tau, sigma);
    x_->setBelief(tau, sigma - algo::sigma_04 * fabs(x_->getBelief().tau));
  }
  bool Binding::equals(const Symbol& symbol, char what) const
  {
    if(symbol.getType() == binding) {
      const Binding& s = dynamic_cast < const Binding& > (symbol);
      return x_->equals(*s.x_, what) && y_->equals(*s.y_, what);
    }
    return false;
  }
  std::string Binding::asString() const
  {
    return ("B_(" + y_->asString() + (b_ ? "" : "~") + ")(" + x_->asString() + ")") + asStringTail();
  }
  void Binding::setVector(double *vector) const
  {
    static double dimension_sqrt_sqrt;
    // Indexes buffers {alpha|beta}[i] for binding {alpha|beta}[dimension + i] for unbinding
    static unsigned int *alpha = NULL, *beta = NULL, *sigma = NULL, current_dimension = -1;
    if(current_dimension != dimension) {
      dimension_sqrt_sqrt = sqrt(dimension_sqrt);
      delete[] alpha;
      delete[] beta;
      delete[] sigma;
      alpha = new unsigned int[dimension], beta = new unsigned int[dimension], sigma = new unsigned int[dimension];
      for(unsigned int i = 0; i < dimension; i++) {
        alpha[i] = dimension_sqrt * (i / dimension_sqrt);
        beta[i] = dimension_sqrt * (i % dimension_sqrt);
        sigma[i] = dimension_sqrt * (i % dimension_sqrt) + (i / dimension_sqrt);
      }
      current_dimension = dimension;
    }
    const double *x = x_->getVector(), *y = y_->getVector();
    for(unsigned int i = 0; i < dimension; i++) {
      vector[i] = 0;
      if(b_) {
        for(unsigned int j = 0; j < dimension_sqrt; j++) {
          vector[i] += y[j + beta[i]] * x[j + alpha[i]];
        }
      } else {
        for(unsigned int j = 0; j < dimension_sqrt; j++) {
          vector[i] += y[sigma[j + beta[i]]] * x[j + alpha[i]];
        }
      }
      vector[i] *= dimension_sqrt_sqrt;
    }
    if(normalized_) {
      double m = 0;
      for(unsigned int i = 0; i < dimension; i++) {
        m += vector[i] * vector[i];
      }
      if(m > 0) {
        m = sqrt(m);
        for(unsigned int i = 0; i < dimension; i++) {
          vector[i] /= m;
        }
      }
    }
  }
  double Binding::getComputationTIme()
   {
     return 0.048 + 0.28e-4 * pow(dimension, 1.35);
   }
}