#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); } }