<commit_before>// Copyright 2011 libmv authors
// Initial revision by Matthias Fauconneau.
#include "tracker.h"
#include "klt.h"
#include <QFileDialog>
#include <QDesktopWidget>
#include <QDebug>

int main(int argc, char *argv[]) {
    QApplication app(argc, argv); Tracker window; window.show(); return app.exec();
}

Tracker::Tracker() : current(-2), klt(libmv::KLT::CreateContext()) {
    setWindowTitle("Qt Tracker");
    QToolBar* toolBar = addToolBar("Main Toolbar"); toolBar->setObjectName("mainToolbar");
    toolBar->addAction(QIcon::fromTheme("document-open"),"Open...",this,SLOT(open()));
    toolBar->addAction(QIcon::fromTheme("media-skip-backward"),"First Frame",this,SLOT(first()));
    toolBar->addAction(QIcon::fromTheme("media-seek-backward"),"Previous Frame",this,SLOT(previous()))->setShortcut(QKeySequence("Left"));
    toolBar->addWidget( &frameNumber );
    connect(&frameNumber,SIGNAL(valueChanged(int)),SLOT(seek(int)));
    playAction = toolBar->addAction(QIcon::fromTheme("media-playback-start"),QKeySequence("Play"));
    playAction->setCheckable(true); playAction->setShortcut(QKeySequence("Space"));
    connect(playAction,SIGNAL(triggered(bool)),SLOT(togglePlay(bool)));
    toolBar->addWidget( &slider ); slider.setOrientation(Qt::Horizontal);
    connect(&slider,SIGNAL(sliderMoved(int)),SLOT(seek(int)));
    toolBar->addAction(QIcon::fromTheme("media-seek-forward"),"Next Frame",this,SLOT(next()))->setShortcut(QKeySequence("Right"));
    toolBar->addAction(QIcon::fromTheme("media-skip-forward"),"Last Frame",this,SLOT(last()));
    view.setScaledContents(true); view.setMaximumSize(qApp->desktop()->availableGeometry().size());
    setCentralWidget(&view);
    connect(&playTimer,SIGNAL(timeout()),SLOT(next()));
    QStringList args = qApp->arguments(); args.removeFirst();
    if(args.isEmpty()) view.setText("No image sequence selected"); else open(args);
}

void Tracker::open() { open(QFileDialog::getOpenFileNames(this, tr("Select Images"),"","Images (*.png *.jpg);;All Files (*.*)")); }
void Tracker::open(QStringList paths) {
    if(paths.isEmpty()) return;
    images.clear(); pyramids.clear();
    foreach(QString path,paths) {
        if(QFileInfo(path).isFile()) images << path;
        else foreach(QString file,QDir(path).entryList(QStringList("*.jpg")<<"*.png",QDir::Files,QDir::Name)) images << QDir(path).filePath(file);
    }
    frameNumber.setMaximum(images.count()-1);
    slider.setMaximum(images.count()-1);
    pyramids.resize(images.count());
    first();
}

void Tracker::seek(int frame) {
    if(frame==current) return;
    if(frame<0 || frame>=images.count()) { stop(); return; }
    slider.setValue(frame); frameNumber.setValue(frame);
    QImage image(images[frame]);
    view.setPixmap(QPixmap::fromImage(image));
    if(!pyramids[frame]) pyramids[frame] = klt->MakeImagePyramid(image.constBits(),image.width(),image.height());
    if(frame==current+1) klt->Track(frame,pyramids[frame-1],pyramids[frame]);
    else klt->Detect(pyramids[frame]);
    current=frame;
}

void Tracker::first() { seek(0); }
void Tracker::previous() { seek(current-1); }
void Tracker::next() { seek(current+1); }
void Tracker::last() { seek(images.count()-1); }

void Tracker::start() { playAction->setChecked(true); playTimer.start(100); }
void Tracker::stop() { playAction->setChecked(false); playTimer.stop(); }
void Tracker::togglePlay(bool play) { if(play) start(); else stop(); }
<commit_msg>enforce google style on Qt GUI (and double line count)<commit_after>// Copyright 2011 libmv authors
// Initial revision by Matthias Fauconneau.
#include "tracker.h"
#include "klt.h"
#include <QFileDialog>
#include <QDesktopWidget>
#include <QDebug>

int main(int argc, char *argv[]) {
  QApplication app(argc, argv);
  Tracker window;
  window.show();
  return app.exec();
}

Tracker::Tracker() : current(-2), klt(libmv::KLT::CreateContext()) {
  setWindowTitle("Qt Tracker");
  QToolBar* toolBar = addToolBar("Main Toolbar");
  toolBar->setObjectName("mainToolbar");
  toolBar->addAction(QIcon::fromTheme("document-open"), "Open...",
                     this, SLOT(open()));
  toolBar->addAction(QIcon::fromTheme("media-skip-backward"), "First Frame",
                     this, SLOT(first()));
  toolBar->addAction(QIcon::fromTheme("media-seek-backward"),"Previous Frame",
                     this, SLOT(previous()))->setShortcut(QKeySequence("Left"));
  toolBar->addWidget(&frameNumber);
  connect(&frameNumber, SIGNAL(valueChanged(int)), SLOT(seek(int)));
  playAction = toolBar->addAction(QIcon::fromTheme("media-playback-start"),
                                  QKeySequence("Play"));
  playAction->setCheckable(true);
  playAction->setShortcut(QKeySequence("Space"));
  connect(playAction, SIGNAL(triggered(bool)), SLOT(togglePlay(bool)));
  toolBar->addWidget(&slider);
  slider.setOrientation(Qt::Horizontal);
  connect(&slider, SIGNAL(sliderMoved(int)), SLOT(seek(int)));
  toolBar->addAction(QIcon::fromTheme("media-seek-forward"), "Next Frame",
                     this, SLOT(next()))
      ->setShortcut(QKeySequence("Right"));
  toolBar->addAction(QIcon::fromTheme("media-skip-forward"), "Last Frame",
                     this, SLOT(last()));
  view.setScaledContents(true);
  view.setMaximumSize(qApp->desktop()->availableGeometry().size());
  setCentralWidget(&view);
  connect(&playTimer, SIGNAL(timeout()), SLOT(next()));
  QStringList args = qApp->arguments();
  args.removeFirst();
  if(args.isEmpty()) {
    view.setText("No image sequence selected");
  } else {
    open(args);
  }
}

void Tracker::open() {
  open(QFileDialog::getOpenFileNames(this, tr("Select Images"), "",
                                     "Images (*.png *.jpg);;All Files (*.*)"));
}
void Tracker::open(QStringList paths) {
  if(paths.isEmpty()) return;
  images.clear();
  pyramids.clear();
  foreach(QString path,paths) {
    if(QFileInfo(path).isFile()) {
      images << path;
    } else {
      foreach(QString file,QDir(path).entryList(QStringList("*.jpg")<<"*.png",
                                                QDir::Files,QDir::Name)) {
        images << QDir(path).filePath(file);
      }
    }
  }
  frameNumber.setMaximum(images.count()-1);
  slider.setMaximum(images.count()-1);
  pyramids.resize(images.count());
  first();
}

void Tracker::seek(int frame) {
  if(frame==current) return;
  if(frame<0 || frame>=images.count()) {
    stop();
    return;
  }
  slider.setValue(frame);
  frameNumber.setValue(frame);
  QImage image(images[frame]);
  view.setPixmap(QPixmap::fromImage(image));
  if(!pyramids[frame]) {
    pyramids[frame] = klt->MakeImagePyramid(
          image.constBits(),image.width(),image.height());
  }
  if(frame==current+1) {
    klt->Track(frame,pyramids[frame-1],pyramids[frame]);
  } else {
    klt->Detect(pyramids[frame]);
  }
  current=frame;
}

void Tracker::first() {
  seek(0);
}
void Tracker::previous() {
  seek(current-1);
}
void Tracker::next() {
  seek(current+1);
}
void Tracker::last() {
  seek(images.count()-1);
}

void Tracker::start() {
  playAction->setChecked(true);
  playTimer.start(100);
}
void Tracker::stop() {
  playAction->setChecked(false);
  playTimer.stop();
}
void Tracker::togglePlay(bool play) {
  if(play) {
    start();
  } else {
    stop();
  }
}
<|endoftext|>


<commit_before>// vim:ts=2:sw=2:expandtab:autoindent:filetype=cpp:
/*
Copyright (c) 2008 Rüdiger Sonderfeld

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/

#include "flusspferd/class.hpp"
#include "flusspferd/create.hpp"
#include "flusspferd/security.hpp"
#include "flusspferd/modules.hpp"
#include <gmpxx.h>

using namespace flusspferd;

namespace {

namespace multi_precission {
struct Integer : public flusspferd::native_object_base {
  struct class_info : flusspferd::class_info {
    static char const *constructor_name() {
      return "Integer";
    }

    static char const *full_name() {
      return "Integer";
    }

    static object create_prototype() {
      flusspferd::object proto = flusspferd::create_object();
      create_native_method(proto, "fits_int", &Integer::fits_int);
      create_native_method(proto, "get_int", &Integer::get_int);
      create_native_method(proto, "get_double", &Integer::get_double);
      create_native_method(proto, "get_string", &Integer::get_string);
      create_native_method(proto, "get_string_base", &Integer::get_string_base);
      create_native_method(proto, "sqrt", &Integer::sqrt);
      create_native_method(proto, "sgn", &Integer::sgn);
      create_native_method(proto, "abs", &Integer::abs);
      return proto;
    }
  };
  mpz_class mp;

  Integer(flusspferd::object const &self, mpz_class const &mp)
    : flusspferd::native_object_base(self), mp(mp)
  { }

  Integer(flusspferd::object const &self, flusspferd::call_context &x)
    : flusspferd::native_object_base(self)
  {
    if(x.arg.size() == 1) {
      value v = x.arg.front();
      if(v.is_double())
        mp = v.get_double();
      else if(v.is_int())
        mp = v.get_int();
      else if(v.is_string())
        mp = v.to_std_string();
      else
        mp = flusspferd::get_native<Integer>(v.get_object()).mp;
    }
    else if(x.arg.size() == 2) {
      value v = x.arg.front();
      value u = x.arg.back();
      if(v.is_string() && u.is_int())
        mp.set_str(v.to_std_string(), u.get_int());
      else
        throw flusspferd::exception("Wrong arguments! (string, int) expected.");
    }
    else
      throw flusspferd::exception("Wrong number of arguments!");
  }

  bool fits_int() /*const*/ {
    return mp.fits_sint_p();
  }
  int get_int() /*const*/ {
    assert(fits_int());
    return mp.get_si();
  }
  double get_double() /*const*/ {
    return mp.get_d();
  }
  std::string get_string() /*const*/ {
    return mp.get_str();
  }
  std::string get_string_base(int base) /*const*/ {
    return mp.get_str(base);
  }

  template<typename T>
  Integer &create_integer(T mp) /*const*/ {
    return create_native_object<Integer>(object(), mpz_class(mp));
  }

  // this should be external but js doesn't support overloading!
  Integer &sqrt() /*const*/ {
    return create_integer(::sqrt(mp));
  }

  int sgn() /*const*/ {
    return ::sgn(mp);
  }

  Integer &abs() /*const*/ {
    return create_integer(::abs(mp));
  }
};

struct Float : public flusspferd::native_object_base {
  struct class_info : flusspferd::class_info {
    static char const *constructor_name() {
      return "Float";
    }

    static char const *full_name() {
      return "Float";
    }

    static object create_prototype() {
      flusspferd::object proto = flusspferd::create_object();
      create_native_method(proto, "fits_int", &Float::fits_int);
      create_native_method(proto, "get_int", &Float::get_int);
      create_native_method(proto, "get_double", &Float::get_double);
      create_native_method(proto, "get_string", &Float::get_string);
      create_native_method(proto, "get_string_base", &Float::get_string_base);
      create_native_method(proto, "get_prec", &Float::get_prec);
      create_native_method(proto, "set_prec", &Float::set_prec);
      create_native_method(proto, "sqrt", &Float::sqrt);
      create_native_method(proto, "sgn", &Float::sgn);
      create_native_method(proto, "abs", &Float::abs);
      create_native_method(proto, "ceil", &Float::ceil);
      create_native_method(proto, "floor", &Float::floor);
      create_native_method(proto, "trunc", &Float::trunc);
      create_native_method(proto, "cmp", &Float::cmp);
      create_native_method(proto, "add", &Float::add);
      create_native_method(proto, "sub", &Float::sub);
      create_native_method(proto, "mul", &Float::mul);
      create_native_method(proto, "div", &Float::div);
      return proto;
    }
  };
  mpf_class mp;

  Float(flusspferd::object const &self, mpf_class const &mp)
    : flusspferd::native_object_base(self), mp(mp)
  { }

  void init_with_value(value v) {
    if(v.is_double())
      mp = v.get_double();
    else if(v.is_int())
      mp = v.get_int();
    else if(v.is_string())
      mp = v.to_std_string();
    else
      mp = flusspferd::get_native<Float>(v.get_object()).mp;
  }

  Float(flusspferd::object const &self, flusspferd::call_context &x)
    : flusspferd::native_object_base(self)
  {
    if(x.arg.size() == 1) {
      init_with_value(x.arg.front());
    }
    else if(x.arg.size() == 2) {
      value v = x.arg.front();
      value u = x.arg.back();
      if(v.is_string() && u.is_int())
        mp.set_str(v.to_std_string(), u.get_int());
      else {
        mp.set_prec(u.get_int());
        init_with_value(v);
      }
    }
    else if(x.arg.size() == 3) {
      value v = x.arg[0];
      value u = x.arg[1];
      value w = x.arg[2];
      if(v.is_string() && u.is_int() && w.is_int()) {
        mp.set_prec(u.get_int());
        mp.set_str(v.to_std_string(), w.get_int());
      }
      else
        throw flusspferd::exception("Wrong arguments! (string, int, int) expected.");
    }
    else
      throw flusspferd::exception("Wrong number of arguments!");
  }

  bool fits_int() /*const*/ {
    return mp.fits_sint_p();
  }
  int get_int() /*const*/ {
    assert(fits_int());
    return mp.get_si();
  }
  double get_double() /*const*/ {
    return mp.get_d();
  }
  std::string get_string() /*const*/ {
    mp_exp_t expo; // TODO handle expo
    return mp.get_str(expo);
  }
  std::string get_string_base(int base) /*const*/ {
    mp_exp_t expo; // TODO handle expo
    return mp.get_str(expo, base);
  }
  int get_prec() /*const*/ {
    return mp.get_prec();
  }
  void set_prec(int p) {
    mp.set_prec(p);
  }

  template<typename T>
  Float &create_float(T mp) /*const*/ {
    return create_native_object<Float>(object(), mpf_class(mp));
  }

  // this should be external but js doesn't support overloading!
  Float &sqrt() /*const*/ {
    return create_float(::sqrt(mp));
  }

  int sgn() /*const*/ {
    return ::sgn(mp);
  }

  Float &abs() /*const*/ {
    return create_float(::abs(mp));
  }

  Float &ceil() /*const*/ {
    return create_float(::ceil(mp));
  }

  Float &floor() /*const*/ {
    return create_float(::floor(mp));
  }

  // hypot

  Float &trunc() /*const*/ {
    return create_float(::trunc(mp));
  }

  // operators
  void cmp(flusspferd::call_context &x) /*const*/ {
    if(x.arg.empty() || x.arg.size() > 1)
      throw flusspferd::exception("Expected one parameter!");
    value v = x.arg.front();
    if(v.is_int())
      x.result = ::cmp(mp, v.get_int());
    else if(v.is_double())
      x.result = ::cmp(mp, v.get_double());
    else
      x.result = ::cmp(mp, flusspferd::get_native<Float>(v.get_object()).mp);
  }

  void add(flusspferd::call_context &x) /*const*/ {
    if(x.arg.empty() || x.arg.size() > 1)
      throw flusspferd::exception("Expected on parameter");
    value v = x.arg.front();
    if(v.is_int())
      x.result = create_float(mp + v.get_int());
    else if(v.is_double())
      x.result = create_float(mp + v.get_double());
    else if(flusspferd::is_native<Integer>(v.get_object()))
      x.result = create_float(mp + flusspferd::get_native<Integer>(v.get_object()).mp);
    else if(flusspferd::is_native<Float>(v.get_object()))
      x.result = create_float(mp + flusspferd::get_native<Float>(v.get_object()).mp);
    else
      throw flusspferd::exception("Wrong parameter type");
  }

  Float &sub(Float const &f) /*const*/ { // TODO Integer
    return create_float(mp - f.mp);
  }

  Float &mul(Float const &f) /*const*/ { // TODO Integer
    return create_float(mp * f.mp);
  }

  Float &div(Float const &f) /*const*/ { // TODO Integer
    return create_float(mp / f.mp);
  }
};
}

}/*namespace*/

FLUSSPFERD_LOADER(gmp) {
  load_class<multi_precission::Integer>(gmp);
  // TODO Rational
  load_class<multi_precission::Float>(gmp);
}
<commit_msg>plugins.gmp: added operators to Integer<commit_after>// vim:ts=2:sw=2:expandtab:autoindent:filetype=cpp:
/*
Copyright (c) 2008 Rüdiger Sonderfeld

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/

#include "flusspferd/class.hpp"
#include "flusspferd/create.hpp"
#include "flusspferd/security.hpp"
#include "flusspferd/modules.hpp"
#include <gmpxx.h>

using namespace flusspferd;

namespace {

namespace multi_precission {
struct Integer : public flusspferd::native_object_base {
  struct class_info : flusspferd::class_info {
    static char const *constructor_name() {
      return "Integer";
    }

    static char const *full_name() {
      return "Integer";
    }

    static object create_prototype() {
      flusspferd::object proto = flusspferd::create_object();
      create_native_method(proto, "fits_int", &Integer::fits_int);
      create_native_method(proto, "get_int", &Integer::get_int);
      create_native_method(proto, "get_double", &Integer::get_double);
      create_native_method(proto, "get_string", &Integer::get_string);
      create_native_method(proto, "get_string_base", &Integer::get_string_base);
      create_native_method(proto, "sqrt", &Integer::sqrt);
      create_native_method(proto, "sgn", &Integer::sgn);
      create_native_method(proto, "abs", &Integer::abs);
      create_native_method(proto, "add", &Integer::add);
      create_native_method(proto, "sub", &Integer::sub);
      create_native_method(proto, "mul", &Integer::mul);
      create_native_method(proto, "div", &Integer::div);
      return proto;
    }
  };
  mpz_class mp;

  Integer(flusspferd::object const &self, mpz_class const &mp)
    : flusspferd::native_object_base(self), mp(mp)
  { }

  Integer(flusspferd::object const &self, flusspferd::call_context &x)
    : flusspferd::native_object_base(self)
  {
    if(x.arg.size() == 1) {
      value v = x.arg.front();
      if(v.is_double())
        mp = v.get_double();
      else if(v.is_int())
        mp = v.get_int();
      else if(v.is_string())
        mp = v.to_std_string();
      else
        mp = flusspferd::get_native<Integer>(v.get_object()).mp;
    }
    else if(x.arg.size() == 2) {
      value v = x.arg.front();
      value u = x.arg.back();
      if(v.is_string() && u.is_int())
        mp.set_str(v.to_std_string(), u.get_int());
      else
        throw flusspferd::exception("Wrong arguments! (string, int) expected.");
    }
    else
      throw flusspferd::exception("Wrong number of arguments!");
  }

  bool fits_int() /*const*/ {
    return mp.fits_sint_p();
  }
  int get_int() /*const*/ {
    assert(fits_int());
    return mp.get_si();
  }
  double get_double() /*const*/ {
    return mp.get_d();
  }
  std::string get_string() /*const*/ {
    return mp.get_str();
  }
  std::string get_string_base(int base) /*const*/ {
    return mp.get_str(base);
  }

  template<typename T>
  Integer &create_integer(T mp) /*const*/ {
    return create_native_object<Integer>(object(), mpz_class(mp));
  }

  // this should be external but js doesn't support overloading!
  Integer &sqrt() /*const*/ {
    return create_integer(::sqrt(mp));
  }

  int sgn() /*const*/ {
    return ::sgn(mp);
  }

  Integer &abs() /*const*/ {
    return create_integer(::abs(mp));
  }

// TODO Float
#define OPERATOR(name, op)                            \
  void name (flusspferd::call_context &x) /*const*/ { \
    if(x.arg.empty() || x.arg.size() > 1)             \
      throw flusspferd::exception("Expected on parameter"); \
    value v = x.arg.front();                                \
    if(v.is_int())                                          \
      x.result = create_integer(mp op v.get_int());           \
    else if(v.is_double())                                  \
      x.result = create_integer(mp op v.get_double());        \
    else if(flusspferd::is_native<Integer>(v.get_object())) \
      x.result = create_integer(mp op flusspferd::get_native<Integer>(v.get_object()).mp); \
    else \
      throw flusspferd::exception("Wrong parameter type"); \
  } \
  /**/

  OPERATOR(add, +)
  OPERATOR(sub, -)
  OPERATOR(mul, *)
  OPERATOR(div, /)

#undef OPERATOR
};

struct Float : public flusspferd::native_object_base {
  struct class_info : flusspferd::class_info {
    static char const *constructor_name() {
      return "Float";
    }

    static char const *full_name() {
      return "Float";
    }

    static object create_prototype() {
      flusspferd::object proto = flusspferd::create_object();
      create_native_method(proto, "fits_int", &Float::fits_int);
      create_native_method(proto, "get_int", &Float::get_int);
      create_native_method(proto, "get_double", &Float::get_double);
      create_native_method(proto, "get_string", &Float::get_string);
      create_native_method(proto, "get_string_base", &Float::get_string_base);
      create_native_method(proto, "get_prec", &Float::get_prec);
      create_native_method(proto, "set_prec", &Float::set_prec);
      create_native_method(proto, "sqrt", &Float::sqrt);
      create_native_method(proto, "sgn", &Float::sgn);
      create_native_method(proto, "abs", &Float::abs);
      create_native_method(proto, "ceil", &Float::ceil);
      create_native_method(proto, "floor", &Float::floor);
      create_native_method(proto, "trunc", &Float::trunc);
      create_native_method(proto, "cmp", &Float::cmp);
      create_native_method(proto, "add", &Float::add);
      create_native_method(proto, "sub", &Float::sub);
      create_native_method(proto, "mul", &Float::mul);
      create_native_method(proto, "div", &Float::div);
      return proto;
    }
  };
  mpf_class mp;

  Float(flusspferd::object const &self, mpf_class const &mp)
    : flusspferd::native_object_base(self), mp(mp)
  { }

  void init_with_value(value v) {
    if(v.is_double())
      mp = v.get_double();
    else if(v.is_int())
      mp = v.get_int();
    else if(v.is_string())
      mp = v.to_std_string();
    else
      mp = flusspferd::get_native<Float>(v.get_object()).mp;
  }

  Float(flusspferd::object const &self, flusspferd::call_context &x)
    : flusspferd::native_object_base(self)
  {
    if(x.arg.size() == 1) {
      init_with_value(x.arg.front());
    }
    else if(x.arg.size() == 2) {
      value v = x.arg.front();
      value u = x.arg.back();
      if(v.is_string() && u.is_int())
        mp.set_str(v.to_std_string(), u.get_int());
      else {
        mp.set_prec(u.get_int());
        init_with_value(v);
      }
    }
    else if(x.arg.size() == 3) {
      value v = x.arg[0];
      value u = x.arg[1];
      value w = x.arg[2];
      if(v.is_string() && u.is_int() && w.is_int()) {
        mp.set_prec(u.get_int());
        mp.set_str(v.to_std_string(), w.get_int());
      }
      else
        throw flusspferd::exception("Wrong arguments! (string, int, int) expected.");
    }
    else
      throw flusspferd::exception("Wrong number of arguments!");
  }

  bool fits_int() /*const*/ {
    return mp.fits_sint_p();
  }
  int get_int() /*const*/ {
    assert(fits_int());
    return mp.get_si();
  }
  double get_double() /*const*/ {
    return mp.get_d();
  }
  std::string get_string() /*const*/ {
    mp_exp_t expo; // TODO handle expo
    return mp.get_str(expo);
  }
  std::string get_string_base(int base) /*const*/ {
    mp_exp_t expo; // TODO handle expo
    return mp.get_str(expo, base);
  }
  int get_prec() /*const*/ {
    return mp.get_prec();
  }
  void set_prec(int p) {
    mp.set_prec(p);
  }

  template<typename T>
  Float &create_float(T mp) /*const*/ {
    return create_native_object<Float>(object(), mpf_class(mp));
  }

  // this should be external but js doesn't support overloading!
  Float &sqrt() /*const*/ {
    return create_float(::sqrt(mp));
  }

  int sgn() /*const*/ {
    return ::sgn(mp);
  }

  Float &abs() /*const*/ {
    return create_float(::abs(mp));
  }

  Float &ceil() /*const*/ {
    return create_float(::ceil(mp));
  }

  Float &floor() /*const*/ {
    return create_float(::floor(mp));
  }

  // hypot

  Float &trunc() /*const*/ {
    return create_float(::trunc(mp));
  }

  // operators
  void cmp(flusspferd::call_context &x) /*const*/ {
    if(x.arg.empty() || x.arg.size() > 1)
      throw flusspferd::exception("Expected one parameter!");
    value v = x.arg.front();
    if(v.is_int())
      x.result = ::cmp(mp, v.get_int());
    else if(v.is_double())
      x.result = ::cmp(mp, v.get_double());
    else
      x.result = ::cmp(mp, flusspferd::get_native<Float>(v.get_object()).mp);
  }

#define OPERATOR(name, op)                            \
  void name (flusspferd::call_context &x) /*const*/ { \
    if(x.arg.empty() || x.arg.size() > 1)             \
      throw flusspferd::exception("Expected on parameter"); \
    value v = x.arg.front();                                \
    if(v.is_int())                                          \
      x.result = create_float(mp op v.get_int());           \
    else if(v.is_double())                                  \
      x.result = create_float(mp op v.get_double());        \
    else if(flusspferd::is_native<Integer>(v.get_object())) \
      x.result = create_float(mp op flusspferd::get_native<Integer>(v.get_object()).mp); \
    else if(flusspferd::is_native<Float>(v.get_object())) \
      x.result = create_float(mp op flusspferd::get_native<Float>(v.get_object()).mp); \
    else \
      throw flusspferd::exception("Wrong parameter type"); \
  } \
  /**/

  OPERATOR(add, +)
  OPERATOR(sub, -)
  OPERATOR(mul, *)
  OPERATOR(div, /)

#undef OPERATOR
};
}

}/*namespace*/

FLUSSPFERD_LOADER(gmp) {
  load_class<multi_precission::Integer>(gmp);
  // TODO Rational
  load_class<multi_precission::Float>(gmp);
}
<|endoftext|>


<commit_before>#include "CameraAim.h"
#include "Subsystems/Chassis.h"
#include "Subsystems/Catapult.h"
#include "OI.h"
#include "Misc/Video.h"

CameraAim::CameraAim(Target_side side)
	: m_side(side)
	, m_prevAngle(0)
	, m_gotVisual(false)
{
	Requires(Chassis::GetInstance());
}

// Called just before this Command runs the first time
void CameraAim::Initialize()
{
	frame_timer.Reset();
	frame_timer.Start();
	m_prevAngle = Chassis::GetInstance()->GetAngle();
	cycle_timer.Reset();
	cycle_timer.Start();
	RobotVideo::GetInstance()->SetHeadingQueueSize(0);
	RobotVideo::GetInstance()->SetLocationQueueSize(10);
	Chassis::GetInstance()->Shift(true);
	m_gotVisual = false;
}

/**
 * \brief Magic function that returns desired stop angle in rope inches
 *
 * The data collected from repeated shooting at the last night of the build
 * season suggest that the stop angle of the catapult is pretty much a linear
 * function. Here we are going to account for the robot's velocity related
 * to the tower.
 */
double calculateStop(double dist, double speed=0)
{
	// Top slider sets the bias from "New" (0) to "Old" (5) balls
	double bias = SmartDashboard::GetNumber("DB/Slider 0", 0) / 5;

	// Interpolated by Google Spreadsheets
	double a = -2.573e-4 -6e-7 * bias;
	double b = 0.088 -2e-3 * bias;
	double c = 10.696 +0.042 * bias;

	return a * dist * dist + b * dist + c;
}

// Called repeatedly when this Command is scheduled to run
void CameraAim::Execute()
{
	Chassis *chassis = Chassis::GetInstance();
	OI* oi = OI::GetInstance();
	if (chassis == nullptr or oi == nullptr) return;

	if (!m_gotVisual or frame_timer.Get() > Preferences::GetInstance()->GetDouble("CameraLag", AIM_COOLDOWN)) {
		float turn = 0;
		float dist = 0;
		size_t nTurns = 0;

		RobotVideo::GetInstance()->mutex_lock();
		nTurns = RobotVideo::GetInstance()->HaveHeading();
		if(nTurns > 0) {
			turn = RobotVideo::GetInstance()->GetTurn(0);
			dist = RobotVideo::GetInstance()->GetDistance(0);
		}
		if(m_side == kRight and nTurns > 1) {
			turn = RobotVideo::GetInstance()->GetTurn(1);
			dist = RobotVideo::GetInstance()->GetDistance(1);
		}
		RobotVideo::GetInstance()->mutex_unlock();

		if (nTurns > 0) {
			if (dist > 0) {
				// Call the Magic function to determine the stop angle.
				float catStop = calculateStop(dist);
				if (catStop > Catapult::TOP_ZONE) catStop = Catapult::TOP_ZONE;
				if (catStop < Catapult::SLOW_ZONE) catStop = Catapult::SLOW_ZONE;
				Catapult::GetInstance()->toSetpoint(catStop);

				// The camera offset over the distance is the adjustment angle's tangent
				turn += atan2f(Preferences::GetInstance()->GetFloat("CameraOffset",RobotVideo::CAMERA_OFFSET), dist);
			}
			chassis->HoldAngle(turn);
			frame_timer.Reset();
			m_gotVisual = true;
		}
		else {
			m_gotVisual = false;
		}
	}
	else if (cycle_timer.Get() > 0) {
		double angular_v = (chassis->GetAngle() - m_prevAngle) / cycle_timer.Get();
		if (fabs(angular_v) > Preferences::GetInstance()->GetDouble("AngularVelocity", MAX_ANGULAR_V))
			frame_timer.Reset();

		// Take this measurement for tuning purposes. Remove after the tuning is done
		SmartDashboard::PutNumber("Angular Velocity", angular_v);
	}

	m_prevAngle = chassis->GetAngle();
	cycle_timer.Reset();

	// Check the catapult output current for safety
	if (Catapult::GetInstance()->WatchCurrent()) Catapult::GetInstance()->moveCatapult(0);

	// Drive forward or back while aiming
	double moveSpeed = -oi->stickL->GetY();
	if (m_gotVisual) {
		moveSpeed *= fabs(moveSpeed); // Square it here so the drivers will feel like it's squared
		chassis->DriveStraight(moveSpeed);
	}
	else {
		// If we still have no visual the chassis is not in PID mode yet, so drive Arcade
		chassis->DriveArcade(moveSpeed, 0, true);
	}
}

// Make this return true when this Command no longer needs to run execute()
bool CameraAim::IsFinished()
{
	return false;
}

// Called once after isFinished returns true
void CameraAim::End()
{

}

// Called when another command which requires one or more of the same
// subsystems is scheduled to run
void CameraAim::Interrupted()
{

}
<commit_msg>Long distance shot hack<commit_after>#include "CameraAim.h"
#include "Subsystems/Chassis.h"
#include "Subsystems/Catapult.h"
#include "OI.h"
#include "Misc/Video.h"

CameraAim::CameraAim(Target_side side)
	: m_side(side)
	, m_prevAngle(0)
	, m_gotVisual(false)
{
	Requires(Chassis::GetInstance());
}

// Called just before this Command runs the first time
void CameraAim::Initialize()
{
	frame_timer.Reset();
	frame_timer.Start();
	m_prevAngle = Chassis::GetInstance()->GetAngle();
	cycle_timer.Reset();
	cycle_timer.Start();
	RobotVideo::GetInstance()->SetHeadingQueueSize(0);
	RobotVideo::GetInstance()->SetLocationQueueSize(10);
	Chassis::GetInstance()->Shift(true);
	m_gotVisual = false;
}

/**
 * \brief Magic function that returns desired stop angle in rope inches
 *
 * The data collected from repeated shooting at the last night of the build
 * season suggest that the stop angle of the catapult is pretty much a linear
 * function. Here we are going to account for the robot's velocity related
 * to the tower.
 */
double calculateStop(double dist, double speed=0)
{
	// Top slider sets the bias from "New" (0) to "Old" (5) balls
	double bias = SmartDashboard::GetNumber("DB/Slider 0", 0) / 5;

	if (dist > 192) return 18.4;

	// Interpolated by Google Spreadsheets
	double a = -2.573e-4 -6e-7 * bias;
	double b = 0.088 -2e-3 * bias;
	double c = 10.696 +0.042 * bias;

	return a * dist * dist + b * dist + c;
}

// Called repeatedly when this Command is scheduled to run
void CameraAim::Execute()
{
	Chassis *chassis = Chassis::GetInstance();
	OI* oi = OI::GetInstance();
	if (chassis == nullptr or oi == nullptr) return;

	if (!m_gotVisual or frame_timer.Get() > Preferences::GetInstance()->GetDouble("CameraLag", AIM_COOLDOWN)) {
		float turn = 0;
		float dist = 0;
		size_t nTurns = 0;

		RobotVideo::GetInstance()->mutex_lock();
		nTurns = RobotVideo::GetInstance()->HaveHeading();
		if(nTurns > 0) {
			turn = RobotVideo::GetInstance()->GetTurn(0);
			dist = RobotVideo::GetInstance()->GetDistance(0);
		}
		if(m_side == kRight and nTurns > 1) {
			turn = RobotVideo::GetInstance()->GetTurn(1);
			dist = RobotVideo::GetInstance()->GetDistance(1);
		}
		RobotVideo::GetInstance()->mutex_unlock();

		if (nTurns > 0) {
			if (dist > 0) {
				// Call the Magic function to determine the stop angle.
				float catStop = calculateStop(dist);
				if (catStop > Catapult::TOP_ZONE) catStop = Catapult::TOP_ZONE;
				if (catStop < Catapult::SLOW_ZONE) catStop = Catapult::SLOW_ZONE;
				Catapult::GetInstance()->toSetpoint(catStop);

				// The camera offset over the distance is the adjustment angle's tangent
				turn += atan2f(Preferences::GetInstance()->GetFloat("CameraOffset",RobotVideo::CAMERA_OFFSET), dist);
			}
			chassis->HoldAngle(turn);
			frame_timer.Reset();
			m_gotVisual = true;
		}
		else {
			m_gotVisual = false;
		}
	}
	else if (cycle_timer.Get() > 0) {
		double angular_v = (chassis->GetAngle() - m_prevAngle) / cycle_timer.Get();
		if (fabs(angular_v) > Preferences::GetInstance()->GetDouble("AngularVelocity", MAX_ANGULAR_V))
			frame_timer.Reset();

		// Take this measurement for tuning purposes. Remove after the tuning is done
		SmartDashboard::PutNumber("Angular Velocity", angular_v);
	}

	m_prevAngle = chassis->GetAngle();
	cycle_timer.Reset();

	// Check the catapult output current for safety
	if (Catapult::GetInstance()->WatchCurrent()) Catapult::GetInstance()->moveCatapult(0);

	// Drive forward or back while aiming
	double moveSpeed = -oi->stickL->GetY();
	if (m_gotVisual) {
		moveSpeed *= fabs(moveSpeed); // Square it here so the drivers will feel like it's squared
		chassis->DriveStraight(moveSpeed);
	}
	else {
		// If we still have no visual the chassis is not in PID mode yet, so drive Arcade
		chassis->DriveArcade(moveSpeed, 0, true);
	}
}

// Make this return true when this Command no longer needs to run execute()
bool CameraAim::IsFinished()
{
	return false;
}

// Called once after isFinished returns true
void CameraAim::End()
{

}

// Called when another command which requires one or more of the same
// subsystems is scheduled to run
void CameraAim::Interrupted()
{

}
<|endoftext|>


<commit_before>#include "instrumentation/converter/convergence_to_string.h"

#include <iomanip>
#include <sstream>

#include "convergence/status.h"
#include "test_helpers/test_helper_functions.h"
#include "test_helpers/gmock_wrapper.h"

namespace  {

using namespace bart;

class InstrumentationConverterConvergenceToStringTest : public ::testing::Test {
 public:
  using ConverterType = instrumentation::converter::ConvergenceToString;
  convergence::Status test_status;
  std::string GetExpectedOutput(convergence::Status&, ConverterType&,
                                std::string) const;
  void SetUp() override;
};

void InstrumentationConverterConvergenceToStringTest::SetUp() {
  test_status.is_complete = false;
  test_status.iteration_number = test_helpers::RandomDouble(0, 1000);
  test_status.max_iterations = test_helpers::RandomDouble(1000, 10000);
  test_status.delta = test_helpers::RandomDouble(1e-10, 1e-6);
  test_status.failed_index = test_helpers::RandomDouble(0, 10);
}

std::string InstrumentationConverterConvergenceToStringTest::GetExpectedOutput(
    convergence::Status& status, ConverterType& converter,
    std::string overload_format = "") const {
  using OutputTerm = ConverterType::OutputTerm;
  const auto output_term_to_string_map = converter.output_term_to_string_map();
  std::string output = overload_format;
  if (overload_format == "") {
    output = converter.output_format();
  };

  // Iteration number
  std::string iteration_num_string = output_term_to_string_map.at(OutputTerm::kIterationNum);
  auto iteration_num_index = output.find(iteration_num_string);
  if (iteration_num_index != std::string::npos) {
    output.replace(iteration_num_index,
                   iteration_num_string.size(),
                   std::to_string(status.iteration_number));
  }
  // Max iterations
  std::string iteration_max_string = output_term_to_string_map.at(OutputTerm::kIterationMax);
  auto iteration_max_index = output.find(iteration_max_string);
  if (iteration_max_index != std::string::npos) {
    output.replace(iteration_max_index,
        iteration_max_string.size(),
        std::to_string(status.max_iterations));
  }
  // Delta
  std::ostringstream delta_stream;
  delta_stream << status.delta.value();
  std::string delta_string = output_term_to_string_map.at(OutputTerm::kDelta);
  auto delta_index = output.find(delta_string);
  if (delta_index != std::string::npos) {
    output.replace(delta_index,
                   delta_string.size(),
                   delta_stream.str());
  }
  // Index
  std::string index_string = output_term_to_string_map.at(OutputTerm::kIndex);
  auto index_index = output.find(index_string);
  if (index_index != std::string::npos) {
    output.replace(index_index,
                   index_string.size(),
                   std::to_string(status.failed_index.value()));
  }

  return output;
}

TEST_F(InstrumentationConverterConvergenceToStringTest, Constructor) {
  using ConverterType = instrumentation::converter::ConvergenceToString;
  EXPECT_NO_THROW({
    ConverterType test_converter;
  });
}

TEST_F(InstrumentationConverterConvergenceToStringTest, DefaultString) {
  ConverterType test_converter;
  EXPECT_EQ(test_converter.Convert(test_status),
            GetExpectedOutput(test_status, test_converter));
}

TEST_F(InstrumentationConverterConvergenceToStringTest, ChangeString) {
  ConverterType test_converter;
  using OutputTerm = ConverterType::OutputTerm;
  const auto output_term_to_string_map = test_converter.output_term_to_string_map();

  std::string new_format = "New format: Iterations = " +
      output_term_to_string_map.at(OutputTerm::kIterationNum)
      + " end\n";
  auto returned_format = test_converter.SetOutputFormat({"New format: Iterations = ",
                                                         OutputTerm::kIterationNum,
                                                         " end\n"});
  EXPECT_EQ(new_format, returned_format);
  EXPECT_EQ(test_converter.Convert(test_status),
            GetExpectedOutput(test_status, test_converter, new_format));
}

} // namespace
<commit_msg>added tests for null delta and null index<commit_after>#include "instrumentation/converter/convergence_to_string.h"

#include <iomanip>
#include <sstream>

#include "convergence/status.h"
#include "test_helpers/test_helper_functions.h"
#include "test_helpers/gmock_wrapper.h"

namespace  {

using namespace bart;

class InstrumentationConverterConvergenceToStringTest : public ::testing::Test {
 public:
  using ConverterType = instrumentation::converter::ConvergenceToString;
  convergence::Status test_status;
  std::string GetExpectedOutput(convergence::Status&, ConverterType&,
                                std::string) const;
  void SetUp() override;
};

void InstrumentationConverterConvergenceToStringTest::SetUp() {
  test_status.is_complete = false;
  test_status.iteration_number = test_helpers::RandomDouble(0, 1000);
  test_status.max_iterations = test_helpers::RandomDouble(1000, 10000);
  test_status.delta = test_helpers::RandomDouble(1e-10, 1e-6);
  test_status.failed_index = test_helpers::RandomDouble(0, 10);
}

std::string InstrumentationConverterConvergenceToStringTest::GetExpectedOutput(
    convergence::Status& status, ConverterType& converter,
    std::string overload_format = "") const {
  using OutputTerm = ConverterType::OutputTerm;
  const auto output_term_to_string_map = converter.output_term_to_string_map();
  const auto null_character = converter.null_character();
  std::string output = overload_format;
  if (overload_format == "") {
    output = converter.output_format();
  };

  // Iteration number
  std::string iteration_num_string = output_term_to_string_map.at(OutputTerm::kIterationNum);
  auto iteration_num_index = output.find(iteration_num_string);
  if (iteration_num_index != std::string::npos) {
    output.replace(iteration_num_index,
                   iteration_num_string.size(),
                   std::to_string(status.iteration_number));
  }
  // Max iterations
  std::string iteration_max_string = output_term_to_string_map.at(OutputTerm::kIterationMax);
  auto iteration_max_index = output.find(iteration_max_string);
  if (iteration_max_index != std::string::npos) {
    output.replace(iteration_max_index,
        iteration_max_string.size(),
        std::to_string(status.max_iterations));
  }
  // Delta
  std::ostringstream delta_stream;
  if (status.delta.has_value()) {
    delta_stream << status.delta.value();
  } else {
    delta_stream << null_character;
  }
  std::string delta_string = output_term_to_string_map.at(OutputTerm::kDelta);
  auto delta_index = output.find(delta_string);
  if (delta_index != std::string::npos) {
    output.replace(delta_index,
                   delta_string.size(),
                   delta_stream.str());
  }
  // Index
  std::string index_string = output_term_to_string_map.at(OutputTerm::kIndex);
  auto index_index = output.find(index_string);
  std::string index_value;
  if (status.failed_index.has_value()) {
    index_value = std::to_string(status.failed_index.value());
  } else {
    index_value = null_character;
  }
  if (index_index != std::string::npos) {
    output.replace(index_index,
                   index_string.size(),
                   index_value);
  }

  return output;
}

TEST_F(InstrumentationConverterConvergenceToStringTest, Constructor) {
  using ConverterType = instrumentation::converter::ConvergenceToString;
  EXPECT_NO_THROW({
    ConverterType test_converter;
  });
}

TEST_F(InstrumentationConverterConvergenceToStringTest, DefaultString) {
  ConverterType test_converter;
  EXPECT_EQ(test_converter.Convert(test_status),
            GetExpectedOutput(test_status, test_converter));
}

TEST_F(InstrumentationConverterConvergenceToStringTest, NoDelta) {
  ConverterType test_converter;
  test_status.delta = std::nullopt;
  EXPECT_EQ(test_converter.Convert(test_status),
            GetExpectedOutput(test_status, test_converter));
}

TEST_F(InstrumentationConverterConvergenceToStringTest, NoIndex) {
  ConverterType test_converter;
  test_status.failed_index = std::nullopt;
  EXPECT_EQ(test_converter.Convert(test_status),
            GetExpectedOutput(test_status, test_converter));
}

TEST_F(InstrumentationConverterConvergenceToStringTest, NoDeltaOrIndex) {
  ConverterType test_converter;
  test_status.delta = std::nullopt;
  test_status.failed_index = std::nullopt;
  EXPECT_EQ(test_converter.Convert(test_status),
            GetExpectedOutput(test_status, test_converter));
}

TEST_F(InstrumentationConverterConvergenceToStringTest, ChangeString) {
  ConverterType test_converter;
  using OutputTerm = ConverterType::OutputTerm;
  const auto output_term_to_string_map = test_converter.output_term_to_string_map();

  std::string new_format = "New format: Iterations = " +
      output_term_to_string_map.at(OutputTerm::kIterationNum)
      + " end\n";
  auto returned_format = test_converter.SetOutputFormat({"New format: Iterations = ",
                                                         OutputTerm::kIterationNum,
                                                         " end\n"});
  EXPECT_EQ(new_format, returned_format);
  EXPECT_EQ(test_converter.Convert(test_status),
            GetExpectedOutput(test_status, test_converter, new_format));
}

} // namespace
<|endoftext|>


<commit_before>#include "ConnectionGeometry.hpp"

ConnectionGeometry::
ConnectionGeometry()
  : _source(10, 10)
  , _sink(100, 100)
  , _pointDiameter(10)
  //, _animationPhase(0)
  , _lineWidth(3.0)
  , _hovered(false)
{ }

QPointF const&
ConnectionGeometry::
getEndPoint(EndType endType) const
{
  Q_ASSERT(endType != EndType::NONE);

  return (endType == EndType::SOURCE ?
          _source :
          _sink);
}

void
ConnectionGeometry::
setEndPoint(EndType endType, QPointF const& point)
{
  switch (endType)
  {
    case EndType::SOURCE:
      _source = point;
      break;

    case EndType::SINK:
      _sink = point;
      break;

    default:
      break;
  }
}

QRectF
ConnectionGeometry::
boundingRect() const
{
  auto points = pointsC1C2();

  QRectF basicRect(_source, _sink);

  QRectF c1c2Rect(points.first, points.second);

  QMargins margins(_pointDiameter,
                   _pointDiameter,
                   _pointDiameter,
                   _pointDiameter);

  return basicRect.united(c1c2Rect).marginsAdded(margins);
}

std::pair<QPointF, QPointF>
ConnectionGeometry::
pointsC1C2() const
{
  double xDistance = _sink.x() - _source.x();
  double const defaultOffset = 200;

  double minimum = qMin(defaultOffset, std::abs(xDistance));

  double verticalOffset = 0;

  double ratio1 = 0.5;

  if (xDistance <= 0)
  {
    verticalOffset = -minimum;

    ratio1 = 1.0;
  }

  QPointF c1(_source.x() + minimum * ratio1,
             _source.y() + 2 * verticalOffset);

  ratio1 = 0.5;

  QPointF c2(_sink.x() - minimum * ratio1,
             _sink.y() + verticalOffset);

  return std::make_pair(c1, c2);
}
<commit_msg>Fix connection painting<commit_after>#include "ConnectionGeometry.hpp"

ConnectionGeometry::
ConnectionGeometry()
  : _source(10, 10)
  , _sink(100, 100)
  , _pointDiameter(10)
  //, _animationPhase(0)
  , _lineWidth(3.0)
  , _hovered(false)
{ }

QPointF const&
ConnectionGeometry::
getEndPoint(EndType endType) const
{
  Q_ASSERT(endType != EndType::NONE);

  return (endType == EndType::SOURCE ?
          _source :
          _sink);
}

void
ConnectionGeometry::
setEndPoint(EndType endType, QPointF const& point)
{
  switch (endType)
  {
    case EndType::SOURCE:
      _source = point;
      break;

    case EndType::SINK:
      _sink = point;
      break;

    default:
      break;
  }
}

QRectF
ConnectionGeometry::
boundingRect() const
{
  auto points = pointsC1C2();

  QRectF basicRect(_source, _sink);

  QRectF c1c2Rect(points.first, points.second);

  QMargins margins(_pointDiameter,
                   _pointDiameter,
                   _pointDiameter,
                   _pointDiameter);

  return basicRect.united(c1c2Rect).marginsAdded(margins);
}

std::pair<QPointF, QPointF>
ConnectionGeometry::
pointsC1C2() const
{
  double xDistance = _sink.x() - _source.x();
  double const defaultOffset = 200;

  double minimum = qMin(defaultOffset, std::abs(xDistance));

  double verticalOffset = 0;

  double ratio1 = 0.5;

  if (xDistance <= 0)
  {
    verticalOffset = -minimum;

    ratio1 = 1.0;
  }

  QPointF c1(_source.x() + minimum * ratio1,
             _source.y() + verticalOffset);

  //ratio1 = 0.5;

  QPointF c2(_sink.x() - minimum * ratio1,
             _sink.y() + verticalOffset);

  return std::make_pair(c1, c2);
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: WCPage.hxx,v $
 *
 *  $Revision: 1.6 $
 *
 *  last change: $Author: hr $ $Date: 2006-04-19 13:21:25 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/
#ifndef DBAUI_WIZARD_CPAGE_HXX
#define DBAUI_WIZARD_CPAGE_HXX

#ifndef DBAUI_WIZ_TABBPAGE_HXX
#include "WTabPage.hxx"
#endif
#ifndef DBAUI_WIZ_COPYTABLEDIALOG_HXX
#include "WCopyTable.hxx"
#endif
#ifndef DBAUI_ENUMTYPES_HXX
#include "QEnumTypes.hxx"
#endif
#ifndef _SV_FIXED_HXX
#include <vcl/fixed.hxx>
#endif
#ifndef _SV_GROUP_HXX
#include <vcl/group.hxx>
#endif
#ifndef _SV_FIXED_HXX
#include <vcl/fixed.hxx>
#endif
#ifndef _SV_EDIT_HXX
#include <vcl/edit.hxx>
#endif
#ifndef _SV_BUTTON_HXX
#include <vcl/button.hxx>
#endif

namespace dbaui
{
    class OWizColumnSelect;
    class OWizNormalExtend;
    //========================================================================
    class OCopyTable : public OWizardPage
    {
    protected:
        FixedText                               m_ftTableName;
        Edit                                    m_edTableName;
        FixedLine                               m_aFL_Options;
        RadioButton                             m_aRB_DefData;
        RadioButton                             m_aRB_Def;
        RadioButton                             m_aRB_View;
        RadioButton                             m_aRB_AppendData;
        CheckBox                                m_aCB_PrimaryColumn;
        FixedText                               m_aFT_KeyName;
        Edit                                    m_edKeyName;
        OCopyTableWizard::Wizard_Create_Style   m_eOldStyle;

        OWizColumnSelect*                       m_pPage2;
        OWizNormalExtend*                       m_pPage3;

        BOOL                                    m_bIsViewAllowed;
        BOOL                                    m_bPKeyAllowed;

        DECL_LINK( AppendDataClickHdl, Button* );
        DECL_LINK( RadioChangeHdl, Button* );
        DECL_LINK( KeyClickHdl, Button* );

        sal_Bool checkAppendData();

    public:
        virtual void            Reset();
        virtual void            ActivatePage();
        virtual BOOL            LeavePage();
        virtual String          GetTitle() const ;

        OCopyTable( Window * pParent, EImportMode atWhat, BOOL bIsView, OCopyTableWizard::Wizard_Create_Style nLastAction );
        virtual ~OCopyTable();

        inline BOOL IsOptionDefData()       const { return m_aRB_DefData.IsChecked(); }
        inline BOOL IsOptionDef()           const { return m_aRB_Def.IsChecked(); }
        inline BOOL IsOptionAppendData()    const { return m_aRB_AppendData.IsChecked(); }
        inline BOOL IsOptionView()          const { return m_aRB_View.IsChecked(); }
        String      GetKeyName()            const { return m_edKeyName.GetText(); }
    };
}
#endif // DBAUI_WIZARD_CPAGE_HXX

<commit_msg>INTEGRATION: CWS dba24a (1.6.196); FILE MERGED 2007/07/23 11:59:03 fs 1.6.196.1: when pasting tables, use a meaningful default in the wizard, as indicated by the current selection Issue number:  #i18907# Submitted by:  dyf@openoffice.org Reviewed by:   frank.schoenheit@sun.com<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: WCPage.hxx,v $
 *
 *  $Revision: 1.7 $
 *
 *  last change: $Author: hr $ $Date: 2007-09-26 14:50:29 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/
#ifndef DBAUI_WIZARD_CPAGE_HXX
#define DBAUI_WIZARD_CPAGE_HXX

#ifndef DBAUI_WIZ_TABBPAGE_HXX
#include "WTabPage.hxx"
#endif
#ifndef DBAUI_WIZ_COPYTABLEDIALOG_HXX
#include "WCopyTable.hxx"
#endif
#ifndef DBAUI_ENUMTYPES_HXX
#include "QEnumTypes.hxx"
#endif
#ifndef _SV_FIXED_HXX
#include <vcl/fixed.hxx>
#endif
#ifndef _SV_GROUP_HXX
#include <vcl/group.hxx>
#endif
#ifndef _SV_FIXED_HXX
#include <vcl/fixed.hxx>
#endif
#ifndef _SV_EDIT_HXX
#include <vcl/edit.hxx>
#endif
#ifndef _SV_BUTTON_HXX
#include <vcl/button.hxx>
#endif

namespace dbaui
{
    class OWizColumnSelect;
    class OWizNormalExtend;
    //========================================================================
    class OCopyTable : public OWizardPage
    {
    protected:
        FixedText                               m_ftTableName;
        Edit                                    m_edTableName;
        FixedLine                               m_aFL_Options;
        RadioButton                             m_aRB_DefData;
        RadioButton                             m_aRB_Def;
        RadioButton                             m_aRB_View;
        RadioButton                             m_aRB_AppendData;
        CheckBox                                m_aCB_PrimaryColumn;
        FixedText                               m_aFT_KeyName;
        Edit                                    m_edKeyName;
        OCopyTableWizard::Wizard_Create_Style   m_eOldStyle;

        OWizColumnSelect*                       m_pPage2;
        OWizNormalExtend*                       m_pPage3;

        BOOL                                    m_bIsViewAllowed;
        BOOL                                    m_bPKeyAllowed;

        DECL_LINK( AppendDataClickHdl, Button* );
        DECL_LINK( RadioChangeHdl, Button* );
        DECL_LINK( KeyClickHdl, Button* );

        sal_Bool checkAppendData();
        //--------dyf add
        void SetAppendDataRadio();
        //--------add end

    public:
        virtual void            Reset();
        virtual void            ActivatePage();
        virtual BOOL            LeavePage();
        virtual String          GetTitle() const ;

        OCopyTable( Window * pParent, EImportMode atWhat, BOOL bIsView );//, OCopyTableWizard::Wizard_Create_Style nLastAction );
        virtual ~OCopyTable();

        inline BOOL IsOptionDefData()       const { return m_aRB_DefData.IsChecked(); }
        inline BOOL IsOptionDef()           const { return m_aRB_Def.IsChecked(); }
        inline BOOL IsOptionAppendData()    const { return m_aRB_AppendData.IsChecked(); }
        inline BOOL IsOptionView()          const { return m_aRB_View.IsChecked(); }
        String      GetKeyName()            const { return m_edKeyName.GetText(); }

        //--------dyf add 2007/7/10
        void setCreateStyleAction();//const OCopyTableWizard::Wizard_Create_Style& _eStyle
        //--------add end
    };
}
#endif // DBAUI_WIZARD_CPAGE_HXX

<|endoftext|>


<commit_before>// Copyright (c) 2009-2019 The libsfz Authors
//
// This file is part of libsfz, a free software project.  You can redistribute it and/or modify it
// under the terms of the MIT License.

#include <sfz/error.hpp>

#include <errno.h>
#include <string.h>
#include <pn/output>
#include <sfz/encoding.hpp>

namespace sfz {

int posix_errno() { return errno; }

pn::string posix_strerror(int error) {
    if (error == 0) {
        error = errno;
    }
    static const int buf_size = 256;
    char             buf[buf_size];
    return pn::string_view{strerror_r(error, buf, buf_size)}.copy();
}

}  // namespace sfz
<commit_msg>Fix strerror_r() for mac<commit_after>// Copyright (c) 2009-2019 The libsfz Authors
//
// This file is part of libsfz, a free software project.  You can redistribute it and/or modify it
// under the terms of the MIT License.

#include <sfz/error.hpp>

#include <errno.h>
#include <string.h>
#include <pn/output>
#include <sfz/encoding.hpp>

namespace sfz {

int posix_errno() { return errno; }

pn::string posix_strerror(int error) {
    if (error == 0) {
        error = errno;
    }
    static const int buf_size = 256;
    char             buf[buf_size];
#ifdef _GNU_SOURCE
    const char* msg = strerror_r(error, buf, buf_size);
    return pn::string_view{msg}.copy();
#else
    int result = strerror_r(error, buf, buf_size);
    static_cast<void>(result);
    return pn::string_view{buf}.copy();
#endif
}

}  // namespace sfz
<|endoftext|>


<commit_before>#include "util/cli/CLIParser.hpp"

const string CLIParser::CLI_KEY_VALUE_PATTERN = string("--?([\\w\\d-]+)=([\\w\\d-]+)");
const string CLIParser::CLI_SWITCH_PATTERN = string("-?-?([\\w\\d-]+)");

Configuration & CLIParser::getConfiguration()
{
    return configuration;
}

string CLIParser::toLowerCase(string original)
{
    string value(original);
    std::transform(value.begin(), value.end(), value.begin(), ::tolower);
    return value;
}

vector<string> CLIParser::argToVec(int argc, char ** argv)
{
    vector<string> vec;
    for (int i = 0; i < argc; ++i)
    {
        vec.push_back(argv[i]);
    }
    return vec;
}

map<string, string> CLIParser::vecToMap(vector<string> arguments)
{
    map<string, string> configMap;

    if (arguments.size() > 1)
    {
        try
        {
            for (auto argument : arguments)
            {
                std::smatch sm;
                if (regex_match(argument, sm, regex(CLI_KEY_VALUE_PATTERN)))
                {
                    configMap[toLowerCase(sm[1])] = toLowerCase(sm[2]);
                } else if (regex_match(argument, sm, regex(CLI_SWITCH_PATTERN)))
                {
                    configMap[toLowerCase(sm[1])] = string("true");
                }
            }
        } catch (const std::regex_error & error)
        {
            std::cerr << "Regex error - unable to parse command line arguments" << std::endl;
            std::cerr << error.code() << ": " << error.what() << std::endl;
        }
    }
    return configMap;
}

CLIParser::CLIParser(int argc, char ** argv)
        : CLIParser(argToVec(argc, argv))
{

}

CLIParser::CLIParser(vector<string> arguments)
    : configuration(vecToMap(arguments))
{

}

CLIParser::~CLIParser()
{

}<commit_msg>Specify configuration in both cli constructors<commit_after>#include "util/cli/CLIParser.hpp"

const string CLIParser::CLI_KEY_VALUE_PATTERN = string("--?([\\w\\d-]+)=([\\w\\d-]+)");
const string CLIParser::CLI_SWITCH_PATTERN = string("-?-?([\\w\\d-]+)");

Configuration & CLIParser::getConfiguration()
{
    return configuration;
}

string CLIParser::toLowerCase(string original)
{
    string value(original);
    std::transform(value.begin(), value.end(), value.begin(), ::tolower);
    return value;
}

vector<string> CLIParser::argToVec(int argc, char ** argv)
{
    vector<string> vec;
    for (int i = 0; i < argc; ++i)
    {
        vec.push_back(argv[i]);
    }
    return vec;
}

map<string, string> CLIParser::vecToMap(vector<string> arguments)
{
    map<string, string> configMap;

    if (arguments.size() > 1)
    {
        try
        {
            for (auto argument : arguments)
            {
                std::smatch sm;
                if (regex_match(argument, sm, regex(CLI_KEY_VALUE_PATTERN)))
                {
                    configMap[toLowerCase(sm[1])] = toLowerCase(sm[2]);
                } else if (regex_match(argument, sm, regex(CLI_SWITCH_PATTERN)))
                {
                    configMap[toLowerCase(sm[1])] = string("true");
                }
            }
        } catch (const std::regex_error & error)
        {
            std::cerr << "Regex error - unable to parse command line arguments" << std::endl;
            std::cerr << error.code() << ": " << error.what() << std::endl;
        }
    }
    return configMap;
}

CLIParser::CLIParser(int argc, char ** argv)
        : configuration(vecToMap(argToVec(argc, argv)))
{

}

CLIParser::CLIParser(vector<string> arguments)
        : configuration(vecToMap(arguments))
{

}

CLIParser::~CLIParser()
{

}<|endoftext|>


<commit_before>#ifndef STAN_MCMC_HMC_NUTS_BASE_XHMC_HPP
#define STAN_MCMC_HMC_NUTS_BASE_XHMC_HPP

#include <stan/callbacks/logger.hpp>
#include <boost/math/special_functions/fpclassify.hpp>
#include <stan/mcmc/hmc/base_hmc.hpp>
#include <stan/mcmc/hmc/hamiltonians/ps_point.hpp>
#include <algorithm>
#include <cmath>
#include <limits>
#include <string>
#include <vector>

namespace stan {
  namespace mcmc {
    /**
     * a1 and a2 are running averages of the form
     *   \f$ a1 =   ( \sum_{n \in N1} w_{n} f_{n} )
     *            / ( \sum_{n \in N1}  w_{n} ) \f$
     *   \f$ a2 =   ( \sum_{n \in N2} w_{n} f_{n} )
     *            / ( \sum_{n \in N2}  w_{n} ) \f$
     * and the weights are the respective normalizing constants
     *   \f$ w1 = \sum_{n \in N1} w_{n} \f$
     *   \f$ w2 = \sum_{n \in N2} w_{n}. \f$
     *
     * This function returns the pooled average
     *   \f$ sum_a =   ( \sum_{n \in N1 \cup N2} w_{n} f_{n} )
     *               / ( \sum_{n \in N1 \cup N2}  w_{n} ) \f$
     * and the pooled weights
     *   \f$ log_sum_w = log(w1 + w2). \f$
     *
     * @param a1 First running average, f1 / w1
     * @param log_w1 Log of first summed weight
     * @param a2 Second running average
     * @param log_w2 Log of second summed weight
     * @param sum_a Average of input running averages
     * @param log_sum_w Log of summed input weights
    */
    void stable_sum(double a1, double log_w1, double a2, double log_w2,
                    double& sum_a, double& log_sum_w) {
      if (log_w2 > log_w1) {
        double e = std::exp(log_w1 - log_w2);
        sum_a = (e * a1 + a2) / (1 + e);
        log_sum_w = log_w2 + std::log(1 + e);
      } else {
        double e = std::exp(log_w2 - log_w1);
        sum_a = (a1 + e * a2) / (1 + e);
        log_sum_w = log_w1 + std::log(1 + e);
      }
    }

    /**
     * Exhaustive Hamiltonian Monte Carlo (XHMC) with multinomial sampling.
     * See http://arxiv.org/abs/1601.00225.
     */
    template <class Model, template<class, class> class Hamiltonian,
              template<class> class Integrator, class BaseRNG>
    class base_xhmc : public base_hmc<Model, Hamiltonian, Integrator, BaseRNG> {
    public:
      base_xhmc(const Model& model, BaseRNG& rng)
        : base_hmc<Model, Hamiltonian, Integrator, BaseRNG>(model, rng),
          depth_(0), max_depth_(5), max_deltaH_(1000), x_delta_(0.1),
          n_leapfrog_(0), divergent_(0), energy_(0) {
      }

      ~base_xhmc() {}

      void set_max_depth(int d) {
        if (d > 0)
          max_depth_ = d;
      }

      void set_max_deltaH(double d) {
        max_deltaH_ = d;
      }

      void set_x_delta(double d) {
      if (d > 0)
        x_delta_ = d;
      }

      int get_max_depth() { return this->max_depth_; }
      double get_max_deltaH() { return this->max_deltaH_; }
      double get_x_delta() { return this->x_delta_; }

      sample
      transition(sample& init_sample, callbacks::logger& logger) {
        // Initialize the algorithm
        this->sample_stepsize();

        this->seed(init_sample.cont_params());

        this->hamiltonian_.sample_p(this->z_, this->rand_int_);
        this->hamiltonian_.init(this->z_, logger);

        ps_point z_plus(this->z_);
        ps_point z_minus(z_plus);

        ps_point z_sample(z_plus);
        ps_point z_propose(z_plus);

        double ave = this->hamiltonian_.dG_dt(this->z_, logger);
        double log_sum_weight = 0;  // log(exp(H0 - H0))

        double H0 = this->hamiltonian_.H(this->z_);
        int n_leapfrog = 0;
        double sum_metro_prob = 1;  // exp(H0 - H0)

        // Build a trajectory until the NUTS criterion is no longer satisfied
        this->depth_ = 0;
        this->divergent_ = 0;

        while (this->depth_ < this->max_depth_) {
          // Build a new subtree in a random direction
          bool valid_subtree = false;
          double ave_subtree = 0;
          double log_sum_weight_subtree
            = -std::numeric_limits<double>::infinity();

          if (this->rand_uniform_() > 0.5) {
            this->z_.ps_point::operator=(z_plus);
            valid_subtree
              = build_tree(this->depth_, z_propose,
                           ave_subtree, log_sum_weight_subtree,
                           H0, 1, n_leapfrog, sum_metro_prob,
                           logger);
            z_plus.ps_point::operator=(this->z_);
          } else {
            this->z_.ps_point::operator=(z_minus);
            valid_subtree
              = build_tree(this->depth_, z_propose,
                           ave_subtree, log_sum_weight_subtree,
                           H0, -1, n_leapfrog, sum_metro_prob,
                           logger);
            z_minus.ps_point::operator=(this->z_);
          }

          if (!valid_subtree) break;
          stable_sum(ave, log_sum_weight,
                     ave_subtree, log_sum_weight_subtree,
                     ave, log_sum_weight);

          // Sample from an accepted subtree
          ++(this->depth_);

          double accept_prob
            = std::exp(log_sum_weight_subtree - log_sum_weight);
          if (this->rand_uniform_() < accept_prob)
            z_sample = z_propose;

          // Break if exhaustion criterion is satisfied
          if (std::fabs(ave) < x_delta_)
            break;
        }

        this->n_leapfrog_ = n_leapfrog;

        // Compute average acceptance probabilty across entire trajectory,
        // even over subtrees that may have been rejected
        double accept_prob
          = sum_metro_prob / static_cast<double>(n_leapfrog + 1);

        this->z_.ps_point::operator=(z_sample);
        this->energy_ = this->hamiltonian_.H(this->z_);
        return sample(this->z_.q, -this->z_.V, accept_prob);
      }

      void get_sampler_param_names(std::vector<std::string>& names) {
        names.push_back("stepsize__");
        names.push_back("treedepth__");
        names.push_back("n_leapfrog__");
        names.push_back("divergent__");
        names.push_back("energy__");
      }

      void get_sampler_params(std::vector<double>& values) {
        values.push_back(this->epsilon_);
        values.push_back(this->depth_);
        values.push_back(this->n_leapfrog_);
        values.push_back(this->divergent_);
        values.push_back(this->energy_);
      }

      /**
       * Recursively build a new subtree to completion or until
       * the subtree becomes invalid.  Returns validity of the
       * resulting subtree.
       *
       * @param depth Depth of the desired subtree
       * @param z_propose State proposed from subtree
       * @param ave Weighted average of dG/dt across trajectory
       * @param log_sum_weight Log of summed weights across trajectory
       * @param H0 Hamiltonian of initial state
       * @param sign Direction in time to built subtree
       * @param n_leapfrog Summed number of leapfrog evaluations
       * @param sum_metro_prob Summed Metropolis probabilities across trajectory
       * @param logger Logger for messages
      */
      int build_tree(int depth, ps_point& z_propose,
                     double& ave, double& log_sum_weight,
                     double H0, double sign, int& n_leapfrog,
                     double& sum_metro_prob,
                     callbacks::logger& logger) {
        // Base case
        if (depth == 0) {
          this->integrator_.evolve(this->z_, this->hamiltonian_,
                                   sign * this->epsilon_,
                                   logger);
          ++n_leapfrog;

          double h = this->hamiltonian_.H(this->z_);
          if (boost::math::isnan(h))
            h = std::numeric_limits<double>::infinity();

          if ((h - H0) > this->max_deltaH_) this->divergent_ = true;

          double dG_dt = this->hamiltonian_.dG_dt(this->z_, logger);

          stable_sum(ave, log_sum_weight,
                     dG_dt, H0 - h,
                     ave, log_sum_weight);

          if (H0 - h > 0)
            sum_metro_prob += 1;
          else
            sum_metro_prob += std::exp(H0 - h);

          z_propose = this->z_;

          return !this->divergent_;
        }
        // General recursion

        // Build the left subtree
        double ave_left = 0;
        double log_sum_weight_left = -std::numeric_limits<double>::infinity();

        bool valid_left
          = build_tree(depth - 1, z_propose,
                       ave_left, log_sum_weight_left,
                       H0, sign, n_leapfrog, sum_metro_prob,
                       logger);

        if (!valid_left) return false;
        stable_sum(ave, log_sum_weight,
                   ave_left, log_sum_weight_left,
                   ave, log_sum_weight);

        // Build the right subtree
        ps_point z_propose_right(this->z_);
        double ave_right = 0;
        double log_sum_weight_right = -std::numeric_limits<double>::infinity();

        bool valid_right
          = build_tree(depth - 1, z_propose_right,
                       ave_right, log_sum_weight_right,
                       H0, sign, n_leapfrog, sum_metro_prob,
                       logger);

        if (!valid_right) return false;
        stable_sum(ave, log_sum_weight,
                   ave_right, log_sum_weight_right,
                   ave, log_sum_weight);

        // Multinomial sample from right subtree
        double ave_subtree;
        double log_sum_weight_subtree;
        stable_sum(ave_left,  log_sum_weight_left,
                   ave_right, log_sum_weight_right,
                   ave_subtree, log_sum_weight_subtree);

        double accept_prob
          = std::exp(log_sum_weight_right - log_sum_weight_subtree);
        if (this->rand_uniform_() < accept_prob)
          z_propose = z_propose_right;

        return std::fabs(ave_subtree) >= x_delta_;
      }

      int depth_;
      int max_depth_;
      double max_deltaH_;
      double x_delta_;

      int n_leapfrog_;
      int divergent_;
      double energy_;
    };

  }  // mcmc
}  // stan
#endif
<commit_msg>Fix build_tree return type and divergent_ member<commit_after>#ifndef STAN_MCMC_HMC_NUTS_BASE_XHMC_HPP
#define STAN_MCMC_HMC_NUTS_BASE_XHMC_HPP

#include <stan/callbacks/logger.hpp>
#include <boost/math/special_functions/fpclassify.hpp>
#include <stan/mcmc/hmc/base_hmc.hpp>
#include <stan/mcmc/hmc/hamiltonians/ps_point.hpp>
#include <algorithm>
#include <cmath>
#include <limits>
#include <string>
#include <vector>

namespace stan {
  namespace mcmc {
    /**
     * a1 and a2 are running averages of the form
     *   \f$ a1 =   ( \sum_{n \in N1} w_{n} f_{n} )
     *            / ( \sum_{n \in N1}  w_{n} ) \f$
     *   \f$ a2 =   ( \sum_{n \in N2} w_{n} f_{n} )
     *            / ( \sum_{n \in N2}  w_{n} ) \f$
     * and the weights are the respective normalizing constants
     *   \f$ w1 = \sum_{n \in N1} w_{n} \f$
     *   \f$ w2 = \sum_{n \in N2} w_{n}. \f$
     *
     * This function returns the pooled average
     *   \f$ sum_a =   ( \sum_{n \in N1 \cup N2} w_{n} f_{n} )
     *               / ( \sum_{n \in N1 \cup N2}  w_{n} ) \f$
     * and the pooled weights
     *   \f$ log_sum_w = log(w1 + w2). \f$
     *
     * @param a1 First running average, f1 / w1
     * @param log_w1 Log of first summed weight
     * @param a2 Second running average
     * @param log_w2 Log of second summed weight
     * @param sum_a Average of input running averages
     * @param log_sum_w Log of summed input weights
    */
    void stable_sum(double a1, double log_w1, double a2, double log_w2,
                    double& sum_a, double& log_sum_w) {
      if (log_w2 > log_w1) {
        double e = std::exp(log_w1 - log_w2);
        sum_a = (e * a1 + a2) / (1 + e);
        log_sum_w = log_w2 + std::log(1 + e);
      } else {
        double e = std::exp(log_w2 - log_w1);
        sum_a = (a1 + e * a2) / (1 + e);
        log_sum_w = log_w1 + std::log(1 + e);
      }
    }

    /**
     * Exhaustive Hamiltonian Monte Carlo (XHMC) with multinomial sampling.
     * See http://arxiv.org/abs/1601.00225.
     */
    template <class Model, template<class, class> class Hamiltonian,
              template<class> class Integrator, class BaseRNG>
    class base_xhmc : public base_hmc<Model, Hamiltonian, Integrator, BaseRNG> {
    public:
      base_xhmc(const Model& model, BaseRNG& rng)
        : base_hmc<Model, Hamiltonian, Integrator, BaseRNG>(model, rng),
          depth_(0), max_depth_(5), max_deltaH_(1000), x_delta_(0.1),
          n_leapfrog_(0), divergent_(0), energy_(0) {
      }

      ~base_xhmc() {}

      void set_max_depth(int d) {
        if (d > 0)
          max_depth_ = d;
      }

      void set_max_deltaH(double d) {
        max_deltaH_ = d;
      }

      void set_x_delta(double d) {
      if (d > 0)
        x_delta_ = d;
      }

      int get_max_depth() { return this->max_depth_; }
      double get_max_deltaH() { return this->max_deltaH_; }
      double get_x_delta() { return this->x_delta_; }

      sample
      transition(sample& init_sample, callbacks::logger& logger) {
        // Initialize the algorithm
        this->sample_stepsize();

        this->seed(init_sample.cont_params());

        this->hamiltonian_.sample_p(this->z_, this->rand_int_);
        this->hamiltonian_.init(this->z_, logger);

        ps_point z_plus(this->z_);
        ps_point z_minus(z_plus);

        ps_point z_sample(z_plus);
        ps_point z_propose(z_plus);

        double ave = this->hamiltonian_.dG_dt(this->z_, logger);
        double log_sum_weight = 0;  // log(exp(H0 - H0))

        double H0 = this->hamiltonian_.H(this->z_);
        int n_leapfrog = 0;
        double sum_metro_prob = 1;  // exp(H0 - H0)

        // Build a trajectory until the NUTS criterion is no longer satisfied
        this->depth_ = 0;
        this->divergent_ = 0;

        while (this->depth_ < this->max_depth_) {
          // Build a new subtree in a random direction
          bool valid_subtree = false;
          double ave_subtree = 0;
          double log_sum_weight_subtree
            = -std::numeric_limits<double>::infinity();

          if (this->rand_uniform_() > 0.5) {
            this->z_.ps_point::operator=(z_plus);
            valid_subtree
              = build_tree(this->depth_, z_propose,
                           ave_subtree, log_sum_weight_subtree,
                           H0, 1, n_leapfrog, sum_metro_prob,
                           logger);
            z_plus.ps_point::operator=(this->z_);
          } else {
            this->z_.ps_point::operator=(z_minus);
            valid_subtree
              = build_tree(this->depth_, z_propose,
                           ave_subtree, log_sum_weight_subtree,
                           H0, -1, n_leapfrog, sum_metro_prob,
                           logger);
            z_minus.ps_point::operator=(this->z_);
          }

          if (!valid_subtree) break;
          stable_sum(ave, log_sum_weight,
                     ave_subtree, log_sum_weight_subtree,
                     ave, log_sum_weight);

          // Sample from an accepted subtree
          ++(this->depth_);

          double accept_prob
            = std::exp(log_sum_weight_subtree - log_sum_weight);
          if (this->rand_uniform_() < accept_prob)
            z_sample = z_propose;

          // Break if exhaustion criterion is satisfied
          if (std::fabs(ave) < x_delta_)
            break;
        }

        this->n_leapfrog_ = n_leapfrog;

        // Compute average acceptance probabilty across entire trajectory,
        // even over subtrees that may have been rejected
        double accept_prob
          = sum_metro_prob / static_cast<double>(n_leapfrog + 1);

        this->z_.ps_point::operator=(z_sample);
        this->energy_ = this->hamiltonian_.H(this->z_);
        return sample(this->z_.q, -this->z_.V, accept_prob);
      }

      void get_sampler_param_names(std::vector<std::string>& names) {
        names.push_back("stepsize__");
        names.push_back("treedepth__");
        names.push_back("n_leapfrog__");
        names.push_back("divergent__");
        names.push_back("energy__");
      }

      void get_sampler_params(std::vector<double>& values) {
        values.push_back(this->epsilon_);
        values.push_back(this->depth_);
        values.push_back(this->n_leapfrog_);
        values.push_back(this->divergent_);
        values.push_back(this->energy_);
      }

      /**
       * Recursively build a new subtree to completion or until
       * the subtree becomes invalid.  Returns validity of the
       * resulting subtree.
       *
       * @param depth Depth of the desired subtree
       * @param z_propose State proposed from subtree
       * @param ave Weighted average of dG/dt across trajectory
       * @param log_sum_weight Log of summed weights across trajectory
       * @param H0 Hamiltonian of initial state
       * @param sign Direction in time to built subtree
       * @param n_leapfrog Summed number of leapfrog evaluations
       * @param sum_metro_prob Summed Metropolis probabilities across trajectory
       * @param logger Logger for messages
      */
      bool build_tree(int depth, ps_point& z_propose,
                     double& ave, double& log_sum_weight,
                     double H0, double sign, int& n_leapfrog,
                     double& sum_metro_prob,
                     callbacks::logger& logger) {
        // Base case
        if (depth == 0) {
          this->integrator_.evolve(this->z_, this->hamiltonian_,
                                   sign * this->epsilon_,
                                   logger);
          ++n_leapfrog;

          double h = this->hamiltonian_.H(this->z_);
          if (boost::math::isnan(h))
            h = std::numeric_limits<double>::infinity();

          if ((h - H0) > this->max_deltaH_) this->divergent_ = true;

          double dG_dt = this->hamiltonian_.dG_dt(this->z_, logger);

          stable_sum(ave, log_sum_weight,
                     dG_dt, H0 - h,
                     ave, log_sum_weight);

          if (H0 - h > 0)
            sum_metro_prob += 1;
          else
            sum_metro_prob += std::exp(H0 - h);

          z_propose = this->z_;

          return !this->divergent_;
        }
        // General recursion

        // Build the left subtree
        double ave_left = 0;
        double log_sum_weight_left = -std::numeric_limits<double>::infinity();

        bool valid_left
          = build_tree(depth - 1, z_propose,
                       ave_left, log_sum_weight_left,
                       H0, sign, n_leapfrog, sum_metro_prob,
                       logger);

        if (!valid_left) return false;
        stable_sum(ave, log_sum_weight,
                   ave_left, log_sum_weight_left,
                   ave, log_sum_weight);

        // Build the right subtree
        ps_point z_propose_right(this->z_);
        double ave_right = 0;
        double log_sum_weight_right = -std::numeric_limits<double>::infinity();

        bool valid_right
          = build_tree(depth - 1, z_propose_right,
                       ave_right, log_sum_weight_right,
                       H0, sign, n_leapfrog, sum_metro_prob,
                       logger);

        if (!valid_right) return false;
        stable_sum(ave, log_sum_weight,
                   ave_right, log_sum_weight_right,
                   ave, log_sum_weight);

        // Multinomial sample from right subtree
        double ave_subtree;
        double log_sum_weight_subtree;
        stable_sum(ave_left,  log_sum_weight_left,
                   ave_right, log_sum_weight_right,
                   ave_subtree, log_sum_weight_subtree);

        double accept_prob
          = std::exp(log_sum_weight_right - log_sum_weight_subtree);
        if (this->rand_uniform_() < accept_prob)
          z_propose = z_propose_right;

        return std::fabs(ave_subtree) >= x_delta_;
      }

      int depth_;
      int max_depth_;
      double max_deltaH_;
      double x_delta_;

      int n_leapfrog_;
      bool divergent_;
      double energy_;
    };

  }  // mcmc
}  // stan
#endif
<|endoftext|>