<commit_before>#ifndef JARNGREIPR_GEOMETRY_DIHEDRAL
#define JARNGREIPR_GEOMETRY_DIHEDRAL
#include "angle.hpp"

namespace jarngreipr
{

template<typename coordT>
typename scalar_type_of<coordT>::type dihedral_angle(
        const coordT& p1, const coordT& p2, const coordT& p3, const coordT& p4)
{
    const auto r_ij = p1 - p2;
    const auto r_kj = p3 - p2;
    const auto r_lk = p4 - p3;
    const auto r_kj_lensq_inv = 1. / mjolnir::length_sq(r_kj);

    const auto n = mjolnir::cross_product(r_kj, -1e0 * r_lk);

    const auto R = r_ij - (mjolnir::dot_product(r_ij, r_kj) * r_kj_lensq_inv) * r_kj;
    const auto S = r_lk - (mjolnir::dot_product(r_lk, r_kj) * r_kj_lensq_inv) * r_kj;

    const auto cos_RS = mjolnir::dot_product(R, S) *
        mjolnir::fast_inv_sqrt(mjolnir::length_sq(R) * mjolnir::length_sq(S));

    const auto cos_phi = (-1e0 <= cos_RS && cos_RS <= 1e0)
                         ? cos_RS : std::copysign(1.0, cos_RS);
    const auto phi = std::copysign(std::acos(cos_phi), mjolnir::dot_product(r_ij, n));

    return cos_phi;
}

} // jarngreipr
#endif /* JARNGREIPR_GEOMETRY_DIHEDRAL */
<commit_msg>fix jarngreipr/dihedral<commit_after>#ifndef JARNGREIPR_GEOMETRY_DIHEDRAL
#define JARNGREIPR_GEOMETRY_DIHEDRAL
#include "angle.hpp"

namespace jarngreipr
{

template<typename coordT>
typename scalar_type_of<coordT>::type dihedral_angle(
        const coordT& p1, const coordT& p2, const coordT& p3, const coordT& p4)
{
    const auto r_ij = p1 - p2;
    const auto r_kj = p3 - p2;
    const auto r_lk = p4 - p3;
    const auto r_kj_lensq_inv = 1. / mjolnir::length_sq(r_kj);

    const auto n = mjolnir::cross_product(r_kj, -1e0 * r_lk);

    const auto R = r_ij - (mjolnir::dot_product(r_ij, r_kj) * r_kj_lensq_inv) * r_kj;
    const auto S = r_lk - (mjolnir::dot_product(r_lk, r_kj) * r_kj_lensq_inv) * r_kj;

    const auto cos_RS = mjolnir::dot_product(R, S) *
        mjolnir::fast_inv_sqrt(mjolnir::length_sq(R) * mjolnir::length_sq(S));

    const auto cos_phi = (-1e0 <= cos_RS && cos_RS <= 1e0)
                         ? cos_RS : std::copysign(1.0, cos_RS);
    const auto phi = std::copysign(std::acos(cos_phi), mjolnir::dot_product(r_ij, n));

    return phi;
}

} // jarngreipr
#endif /* JARNGREIPR_GEOMETRY_DIHEDRAL */
<|endoftext|>


<commit_before>#include <event2/thread.h>
#include <functional>
#include <gflags/gflags.h>
#include <glog/logging.h>
#include <iostream>
#include <memory>

#include "util/etcd.h"
#include "util/libevent_wrapper.h"

namespace libevent = cert_trans::libevent;

using cert_trans::EtcdClient;
using std::bind;
using std::cout;
using std::endl;
using std::make_shared;
using std::placeholders::_1;
using std::shared_ptr;
using std::string;

DEFINE_string(etcd, "127.0.0.1", "etcd server address");
DEFINE_int32(etcd_port, 4001, "etcd server port");
DEFINE_string(key, "/foo", "path to watch");

void Notify(const std::vector<EtcdClient::Watcher::Update>& updates) {
  for (const auto& update : updates) {
    if (update.exists_) {
      cout << "key changed: " << update.node_.ToString();
    } else {
      cout << "key deleted: " << update.node_.ToString();
    }
  }
}

int main(int argc, char* argv[]) {
  google::ParseCommandLineFlags(&argc, &argv, true);
  google::InitGoogleLogging(argv[0]);
  evthread_use_pthreads();

  const shared_ptr<libevent::Base> event_base(make_shared<libevent::Base>());
  EtcdClient etcd(event_base, FLAGS_etcd, FLAGS_etcd_port);
  EtcdClient::Watcher watcher(&etcd, FLAGS_key, bind(&Notify, _1));

  event_base->Dispatch();

  return 0;
}
<commit_msg>Have newlines at the end of notifications in etcd_watch.<commit_after>#include <event2/thread.h>
#include <functional>
#include <gflags/gflags.h>
#include <glog/logging.h>
#include <iostream>
#include <memory>

#include "util/etcd.h"
#include "util/libevent_wrapper.h"

namespace libevent = cert_trans::libevent;

using cert_trans::EtcdClient;
using std::bind;
using std::cout;
using std::endl;
using std::make_shared;
using std::placeholders::_1;
using std::shared_ptr;
using std::string;

DEFINE_string(etcd, "127.0.0.1", "etcd server address");
DEFINE_int32(etcd_port, 4001, "etcd server port");
DEFINE_string(key, "/foo", "path to watch");

void Notify(const std::vector<EtcdClient::Watcher::Update>& updates) {
  for (const auto& update : updates) {
    if (update.exists_) {
      cout << "key changed: " << update.node_.ToString() << endl;
    } else {
      cout << "key deleted: " << update.node_.ToString() << endl;
    }
  }
}

int main(int argc, char* argv[]) {
  google::ParseCommandLineFlags(&argc, &argv, true);
  google::InitGoogleLogging(argv[0]);
  evthread_use_pthreads();

  const shared_ptr<libevent::Base> event_base(make_shared<libevent::Base>());
  EtcdClient etcd(event_base, FLAGS_etcd, FLAGS_etcd_port);
  EtcdClient::Watcher watcher(&etcd, FLAGS_key, bind(&Notify, _1));

  event_base->Dispatch();

  return 0;
}
<|endoftext|>


<commit_before>#ifndef STAN_MATH_PRIM_MAT_FUN_COV_DOT_PROD_HPP
#define STAN_MATH_PRIM_MAT_FUN_COV_DOT_PROD_HPP

#include <stan/math/prim/mat/fun/Eigen.hpp>
#include <stan/math/prim/scal/err/check_finite.hpp>
#include <stan/math/prim/scal/err/check_nonnegative.hpp>
#include <stan/math/prim/scal/err/check_not_nan.hpp>
#include <stan/math/prim/scal/meta/return_type.hpp>
#include <stan/math/prim/mat/fun/dot_product.hpp>
#include <stan/math/prim/mat/fun/dot_self.hpp>
#include <boost/utility/enable_if.hpp>
#include <stan/math/prim/scal/meta/is_vector_like.hpp>
#include <stan/math/prim/scal/meta/is_constant.hpp>
#include <stan/math/prim/mat/meta/length.hpp>
#include <stan/math/prim/scal/fun/square.hpp>
#include <vector>

namespace stan {
namespace math {

/**
 * Returns a dot product covariance matrix. A member of Stan's Gaussian Process
 * Library.
 *
 * \f$k(x,x') = \sigma^2 + x \cdot x'\f$
 *
 * A dot product covariance matrix is the same covariance matrix
 * as in bayesian regression with \f$N(0,1)\f$ priors on regression coefficients
 * and a \f$N(0,\sigma^2)\f$ prior on the constant function. See Rasmussen and
 * Williams et al 2006, Chapter 4.
 *
 * @tparam T_x type of std::vector of elements
 * @tparam T_sigma type of sigma
 *
 * @param x std::vector of elements that can be used in dot product.
 *    This function assumes each element of x is the same size.
 * @param sigma constant function that can be used in stan::math::square
 * @return dot product covariance matrix that is positive semi-definite
 * @throw std::domain_error if sigma < 0, nan, inf or
 *   x is nan or infinite
 */
template <typename T_x, typename T_sigma>
Eigen::Matrix<typename return_type<T_x, T_sigma>::type, Eigen::Dynamic,
              Eigen::Dynamic>
gp_dot_prod_cov(const std::vector<Eigen::Matrix<T_x, Eigen::Dynamic, 1>> &x,
                const T_sigma &sigma) {
  using stan::math::dot_product;
  using stan::math::square;

  check_not_nan("gp_dot_prod_cov", "sigma", sigma);
  check_nonnegative("gp_dot_prod_cov", "sigma", sigma);
  check_finite("gp_dot_prod_cov", "sigma", sigma);

  size_t x_size = x.size();
  for (size_t i = 0; i < x_size; ++i) {
      check_not_nan("gp_dot_prod_cov", "x", x[i]);
      check_finite("gp_dot_prod_cov", "x", x[i]);
  }

  Eigen::Matrix<typename stan::return_type<T_x, T_sigma>::type, Eigen::Dynamic,
                Eigen::Dynamic>
      cov(x_size, x_size);
  if (x_size == 0)
    return cov;

  T_sigma sigma_sq = square(sigma);

  for (size_t i = 0; i < (x_size - 1); ++i) {
    cov(i, i) = sigma_sq + dot_self(x[i]);
    for (size_t j = i + 1; j < x_size; ++j) {
      cov(i, j) = sigma_sq + dot_product(x[i], x[j]);
      cov(j, i) = cov(i, j);
    }
  }
  cov(x_size - 1, x_size - 1) = sigma_sq + dot_self(x[x_size - 1]);
  return cov;
}

/**
 * Returns a dot product covariance matrix. A member of Stan's Gaussian
 * Process Library.
 *
 * \f$k(x,x') = \sigma^2 + x \cdot x'\f$
 *
 * A dot product covariance matrix is the same covariance matrix
 * as in bayesian regression with \f$N(0,1)\f$ priors on regression coefficients
 * and a \f$N(0,\sigma^2)\f$ prior on the constant function. See Rasmussen and
 * Williams et al 2006, Chapter 4.
 *
 * @tparam T_x type of std::vector of double
 * @tparam T_sigma type of sigma
 *
 * @param x std::vector of elements that can be used in transpose
 *   and multiply
 *    This function assumes each element of x is the same size.
 * @param sigma constant function that can be used in stan::math::square
 * @return dot product covariance matrix that is positive semi-definite
 * @throw std::domain_error if sigma < 0, nan, inf or
 *   x is nan or infinite
 */
template <typename T_x, typename T_sigma>
Eigen::Matrix<typename return_type<T_x, T_sigma>::type, Eigen::Dynamic,
              Eigen::Dynamic>
gp_dot_prod_cov(const std::vector<T_x> &x, const T_sigma &sigma) {
  using stan::math::dot_product;
  using stan::math::square;

  check_not_nan("gp_dot_prod_cov", "sigma", sigma);
  check_nonnegative("gp_dot_prod_cov", "sigma", sigma);
  check_finite("gp_dot_prod_cov", "sigma", sigma);

  size_t x_size = x.size();
  check_not_nan("gp_dot_prod_cov", "x", x);
  check_finite("gp_dot_prod_cov", "x", x);

  Eigen::Matrix<typename stan::return_type<T_x, T_sigma>::type, Eigen::Dynamic,
                Eigen::Dynamic>
      cov(x_size, x_size);
  if (x_size == 0)
    return cov;

  T_sigma sigma_sq = square(sigma);

  for (size_t i = 0; i < (x_size - 1); ++i) {
    cov(i, i) = sigma_sq + x[i] * x[i];
    for (size_t j = i + 1; j < x_size; ++j) {
      cov(i, j) = sigma_sq + x[i] * x[j];
      cov(j, i) = cov(i, j);
    }
  }
  cov(x_size - 1, x_size - 1) = sigma_sq + x[x_size - 1] * x[x_size - 1];
  return cov;
}

/**
 * Returns a dot product covariance matrix of differing
 * x's. A member of Stan's Gaussian Process Library.
 *
 * \f$k(x,x') = \sigma^2 + x \cdot x'\f$
 *
 * A dot product covariance matrix is the same covariance matrix
 * as in bayesian regression with \f$N(0,1)\f$ priors on regression coefficients
 * and a \f$N(0,\sigma^2)\f$ prior on the constant function. See Rasmussen and
 * Williams et al 2006, Chapter 4.
 *
 * @tparam T_x1 type of first std::vector of elements
 * @tparam T_x2 type of second std::vector of elements
 * @tparam T_sigma type of sigma
 *
 * @param x1 std::vector of elements that can be used in dot_product
 * @param x2 std::vector of elements that can be used in dot_product
 * @param sigma constant function that can be used in stan::math::square
 * @return dot product covariance matrix that is not always symmetric
 * @throw std::domain_error if sigma < 0, nan or inf
 *   or if x1 or x2 are nan or inf
 */
template <typename T_x1, typename T_x2, typename T_sigma>
Eigen::Matrix<typename return_type<T_x1, T_x2, T_sigma>::type, Eigen::Dynamic,
              Eigen::Dynamic>
gp_dot_prod_cov(const std::vector<Eigen::Matrix<T_x1, Eigen::Dynamic, 1>> &x1,
                const std::vector<Eigen::Matrix<T_x2, Eigen::Dynamic, 1>> &x2,
                const T_sigma &sigma) {
  using stan::math::dot_product;
  using stan::math::square;

  check_not_nan("gp_dot_prod_cov", "sigma", sigma);
  check_nonnegative("gp_dot_prod_cov", "sigma", sigma);
  check_finite("gp_dot_prod_cov", "sigma", sigma);

  size_t x1_size = x1.size();
  size_t x2_size = x2.size();
  for (size_t i = 0; i < x1_size; ++i) {
      check_not_nan("gp_dot_prod_cov", "x1", x1[i]);
      check_finite("gp_dot_prod_cov", "x1", x1[i]);
  }
  for (size_t i = 0; i < x2_size; ++i) {
      check_not_nan("gp_dot_prod_cov", "x2", x2[i]);
      check_finite("gp_dot_prod_cov", "x2", x2[i]);
  }
  Eigen::Matrix<typename return_type<T_x1, T_x2, T_sigma>::type, Eigen::Dynamic,
                Eigen::Dynamic>
      cov(x1_size, x2_size);

  if (x1_size == 0 || x2_size == 0)
    return cov;

  T_sigma sigma_sq = square(sigma);

  for (size_t i = 0; i < x1_size; ++i) {
    for (size_t j = 0; j < x2_size; ++j) {
      cov(i, j) = sigma_sq + dot_product(x1[i], x2[j]);
    }
  }
  return cov;
}

/**
 * Returns a dot product covariance matrix of
 * differing x's. A member of Stan's Gaussian Process Library.
 *
 * \f$k(x,x') = \sigma^2 + x \cdot x'\f$
 *
 * A dot product covariance matrix is the same covariance matrix
 * as in bayesian regression with \f$N(0,1)\f$ priors on regression coefficients
 * and a \f$N(0,\sigma^2)\f$ prior on the constant function. See Rasmussen and
 * Williams et al 2006, Chapter 4.
 *
 * @tparam T_x1 type of first std::vector of double
 * @tparam T_x2 type of second std::vector of double
 * @tparam T_sigma type of sigma
 *
 * @param x1 std::vector of elements that can be used in dot_product
 * @param x2 std::vector of elements that can be used in dot_product
 * @param sigma is the constant function that can be used in stan::math::square
 * @return dot product covariance matrix that is not always symmetric
 * @throw std::domain_error if sigma < 0, nan or inf
 *   or if x1 or x2 are nan or inf
 */
template <typename T_x1, typename T_x2, typename T_sigma>
Eigen::Matrix<typename return_type<T_x1, T_x2, T_sigma>::type, Eigen::Dynamic,
              Eigen::Dynamic>
gp_dot_prod_cov(const std::vector<T_x1> &x1, const std::vector<T_x2> &x2,
                const T_sigma &sigma) {
  using stan::math::square;

  check_not_nan("gp_dot_prod_cov", "sigma", sigma);
  check_nonnegative("gp_dot_prod_cov", "sigma", sigma);
  check_finite("gp_dot_prod_cov", "sigma", sigma);

  size_t x1_size = x1.size();
  size_t x2_size = x2.size();
  check_not_nan("gp_dot_prod_cov", "x1", x1);
  check_finite("gp_dot_prod_cov", "x1", x1);
  check_not_nan("gp_dot_prod_cov", "x2", x2);
  check_finite("gp_dot_prod_cov", "x2", x2);

  Eigen::Matrix<typename stan::return_type<T_x1, T_x2, T_sigma>::type,
                Eigen::Dynamic, Eigen::Dynamic>
      cov(x1_size, x2_size);

  if (x1_size == 0 || x2_size == 0)
    return cov;

  T_sigma sigma_sq = square(sigma);

  for (size_t i = 0; i < x1_size; ++i) {
    for (size_t j = 0; j < x2_size; ++j) {
      cov(i, j) = sigma_sq + x1[i] * x2[j];
    }
  }
  return cov;
}
}  // namespace math
}  // namespace stan
#endif
<commit_msg>resolve merge conflict<commit_after>#ifndef STAN_MATH_PRIM_MAT_FUN_COV_DOT_PROD_HPP
#define STAN_MATH_PRIM_MAT_FUN_COV_DOT_PROD_HPP

#include <boost/utility/enable_if.hpp>
#include <stan/math/prim/mat/fun/Eigen.hpp>
#include <stan/math/prim/mat/fun/dot_product.hpp>
#include <stan/math/prim/mat/fun/dot_self.hpp>
#include <stan/math/prim/mat/meta/length.hpp>
#include <stan/math/prim/scal/err/check_finite.hpp>
#include <stan/math/prim/scal/err/check_nonnegative.hpp>
#include <stan/math/prim/scal/err/check_not_nan.hpp>
#include <stan/math/prim/scal/fun/square.hpp>
#include <stan/math/prim/scal/meta/is_constant.hpp>
#include <stan/math/prim/scal/meta/is_vector_like.hpp>
#include <stan/math/prim/scal/meta/return_type.hpp>
#include <vector>

namespace stan {
namespace math {

/**
 * Returns a dot product covariance matrix. A member of Stan's Gaussian Process
 * Library.
 *
 * \f$k(x,x') = \sigma^2 + x \cdot x'\f$
 *
 * A dot product covariance matrix is the same covariance matrix
 * as in bayesian regression with \f$N(0,1)\f$ priors on regression coefficients
 * and a \f$N(0,\sigma^2)\f$ prior on the constant function. See Rasmussen and
 * Williams et al 2006, Chapter 4.
 *
 * @tparam T_x type of std::vector of elements
 * @tparam T_sigma type of sigma
 *
 * @param x std::vector of elements that can be used in dot product.
 *    This function assumes each element of x is the same size.
 * @param sigma constant function that can be used in stan::math::square
 * @return dot product covariance matrix that is positive semi-definite
 * @throw std::domain_error if sigma < 0, nan, inf or
 *   x is nan or infinite
 */
template <typename T_x, typename T_sigma>
Eigen::Matrix<typename return_type<T_x, T_sigma>::type, Eigen::Dynamic,
              Eigen::Dynamic>
gp_dot_prod_cov(const std::vector<Eigen::Matrix<T_x, Eigen::Dynamic, 1>> &x,
                const T_sigma &sigma) {
  using stan::math::dot_product;
  using stan::math::square;

  check_not_nan("gp_dot_prod_cov", "sigma", sigma);
  check_nonnegative("gp_dot_prod_cov", "sigma", sigma);
  check_finite("gp_dot_prod_cov", "sigma", sigma);

  size_t x_size = x.size();
  for (size_t i = 0; i < x_size; ++i) {
    check_not_nan("gp_dot_prod_cov", "x", x[i]);
    check_finite("gp_dot_prod_cov", "x", x[i]);
  }

  Eigen::Matrix<typename stan::return_type<T_x, T_sigma>::type, Eigen::Dynamic,
                Eigen::Dynamic>
      cov(x_size, x_size);
  if (x_size == 0)
    return cov;

  T_sigma sigma_sq = square(sigma);

  for (size_t i = 0; i < (x_size - 1); ++i) {
    cov(i, i) = sigma_sq + dot_self(x[i]);
    for (size_t j = i + 1; j < x_size; ++j) {
      cov(i, j) = sigma_sq + dot_product(x[i], x[j]);
      cov(j, i) = cov(i, j);
    }
  }
  cov(x_size - 1, x_size - 1) = sigma_sq + dot_self(x[x_size - 1]);
  return cov;
}

/**
 * Returns a dot product covariance matrix. A member of Stan's Gaussian
 * Process Library.
 *
 * \f$k(x,x') = \sigma^2 + x \cdot x'\f$
 *
 * A dot product covariance matrix is the same covariance matrix
 * as in bayesian regression with \f$N(0,1)\f$ priors on regression coefficients
 * and a \f$N(0,\sigma^2)\f$ prior on the constant function. See Rasmussen and
 * Williams et al 2006, Chapter 4.
 *
 * @tparam T_x type of std::vector of double
 * @tparam T_sigma type of sigma
 *
 * @param x std::vector of elements that can be used in transpose
 *   and multiply
 *    This function assumes each element of x is the same size.
 * @param sigma constant function that can be used in stan::math::square
 * @return dot product covariance matrix that is positive semi-definite
 * @throw std::domain_error if sigma < 0, nan, inf or
 *   x is nan or infinite
 */
template <typename T_x, typename T_sigma>
Eigen::Matrix<typename return_type<T_x, T_sigma>::type, Eigen::Dynamic,
              Eigen::Dynamic>
gp_dot_prod_cov(const std::vector<T_x> &x, const T_sigma &sigma) {
  using stan::math::dot_product;
  using stan::math::square;

  check_not_nan("gp_dot_prod_cov", "sigma", sigma);
  check_nonnegative("gp_dot_prod_cov", "sigma", sigma);
  check_finite("gp_dot_prod_cov", "sigma", sigma);

  size_t x_size = x.size();
  check_not_nan("gp_dot_prod_cov", "x", x);
  check_finite("gp_dot_prod_cov", "x", x);

  Eigen::Matrix<typename stan::return_type<T_x, T_sigma>::type, Eigen::Dynamic,
                Eigen::Dynamic>
      cov(x_size, x_size);
  if (x_size == 0)
    return cov;

  T_sigma sigma_sq = square(sigma);

  for (size_t i = 0; i < (x_size - 1); ++i) {
    cov(i, i) = sigma_sq + x[i] * x[i];
    for (size_t j = i + 1; j < x_size; ++j) {
      cov(i, j) = sigma_sq + x[i] * x[j];
      cov(j, i) = cov(i, j);
    }
  }
  cov(x_size - 1, x_size - 1) = sigma_sq + x[x_size - 1] * x[x_size - 1];
  return cov;
}

/**
 * Returns a dot product covariance matrix of differing
 * x's. A member of Stan's Gaussian Process Library.
 *
 * \f$k(x,x') = \sigma^2 + x \cdot x'\f$
 *
 * A dot product covariance matrix is the same covariance matrix
 * as in bayesian regression with \f$N(0,1)\f$ priors on regression coefficients
 * and a \f$N(0,\sigma^2)\f$ prior on the constant function. See Rasmussen and
 * Williams et al 2006, Chapter 4.
 *
 * @tparam T_x1 type of first std::vector of elements
 * @tparam T_x2 type of second std::vector of elements
 * @tparam T_sigma type of sigma
 *
 * @param x1 std::vector of elements that can be used in dot_product
 * @param x2 std::vector of elements that can be used in dot_product
 * @param sigma constant function that can be used in stan::math::square
 * @return dot product covariance matrix that is not always symmetric
 * @throw std::domain_error if sigma < 0, nan or inf
 *   or if x1 or x2 are nan or inf
 */
template <typename T_x1, typename T_x2, typename T_sigma>
Eigen::Matrix<typename return_type<T_x1, T_x2, T_sigma>::type, Eigen::Dynamic,
              Eigen::Dynamic>
gp_dot_prod_cov(const std::vector<Eigen::Matrix<T_x1, Eigen::Dynamic, 1>> &x1,
                const std::vector<Eigen::Matrix<T_x2, Eigen::Dynamic, 1>> &x2,
                const T_sigma &sigma) {
  using stan::math::dot_product;
  using stan::math::square;

  check_not_nan("gp_dot_prod_cov", "sigma", sigma);
  check_nonnegative("gp_dot_prod_cov", "sigma", sigma);
  check_finite("gp_dot_prod_cov", "sigma", sigma);

  size_t x1_size = x1.size();
  size_t x2_size = x2.size();
  for (size_t i = 0; i < x1_size; ++i) {
    check_not_nan("gp_dot_prod_cov", "x1", x1[i]);
    check_finite("gp_dot_prod_cov", "x1", x1[i]);
  }
  for (size_t i = 0; i < x2_size; ++i) {
    check_not_nan("gp_dot_prod_cov", "x2", x2[i]);
    check_finite("gp_dot_prod_cov", "x2", x2[i]);
  }
  Eigen::Matrix<typename return_type<T_x1, T_x2, T_sigma>::type, Eigen::Dynamic,
                Eigen::Dynamic>
      cov(x1_size, x2_size);

  if (x1_size == 0 || x2_size == 0)
    return cov;

  T_sigma sigma_sq = square(sigma);

  for (size_t i = 0; i < x1_size; ++i) {
    for (size_t j = 0; j < x2_size; ++j) {
      cov(i, j) = sigma_sq + dot_product(x1[i], x2[j]);
    }
  }
  return cov;
}

/**
 * Returns a dot product covariance matrix of
 * differing x's. A member of Stan's Gaussian Process Library.
 *
 * \f$k(x,x') = \sigma^2 + x \cdot x'\f$
 *
 * A dot product covariance matrix is the same covariance matrix
 * as in bayesian regression with \f$N(0,1)\f$ priors on regression coefficients
 * and a \f$N(0,\sigma^2)\f$ prior on the constant function. See Rasmussen and
 * Williams et al 2006, Chapter 4.
 *
 * @tparam T_x1 type of first std::vector of double
 * @tparam T_x2 type of second std::vector of double
 * @tparam T_sigma type of sigma
 *
 * @param x1 std::vector of elements that can be used in dot_product
 * @param x2 std::vector of elements that can be used in dot_product
 * @param sigma is the constant function that can be used in stan::math::square
 * @return dot product covariance matrix that is not always symmetric
 * @throw std::domain_error if sigma < 0, nan or inf
 *   or if x1 or x2 are nan or inf
 */
template <typename T_x1, typename T_x2, typename T_sigma>
Eigen::Matrix<typename return_type<T_x1, T_x2, T_sigma>::type, Eigen::Dynamic,
              Eigen::Dynamic>
gp_dot_prod_cov(const std::vector<T_x1> &x1, const std::vector<T_x2> &x2,
                const T_sigma &sigma) {
  using stan::math::square;

  check_not_nan("gp_dot_prod_cov", "sigma", sigma);
  check_nonnegative("gp_dot_prod_cov", "sigma", sigma);
  check_finite("gp_dot_prod_cov", "sigma", sigma);

  size_t x1_size = x1.size();
  size_t x2_size = x2.size();
  check_not_nan("gp_dot_prod_cov", "x1", x1);
  check_finite("gp_dot_prod_cov", "x1", x1);
  check_not_nan("gp_dot_prod_cov", "x2", x2);
  check_finite("gp_dot_prod_cov", "x2", x2);

  Eigen::Matrix<typename stan::return_type<T_x1, T_x2, T_sigma>::type,
                Eigen::Dynamic, Eigen::Dynamic>
      cov(x1_size, x2_size);

  if (x1_size == 0 || x2_size == 0)
    return cov;

  T_sigma sigma_sq = square(sigma);

  for (size_t i = 0; i < x1_size; ++i) {
    for (size_t j = 0; j < x2_size; ++j) {
      cov(i, j) = sigma_sq + x1[i] * x2[j];
    }
  }
  return cov;
}
} // namespace math
} // namespace stan
#endif
<|endoftext|>


<commit_before>#ifndef STAN_MATH_PRIM_MAT_FUN_COV_DOT_PROD_HPP
#define STAN_MATH_PRIM_MAT_FUN_COV_DOT_PROD_HPP

#include <stan/math/prim/mat/fun/Eigen.hpp>
#include <stan/math/prim/mat/fun/value_of.hpp>
#include <stan/math/prim/scal/err/check_finite.hpp>
#include <stan/math/prim/scal/err/check_nonnegative.hpp>
#include <stan/math/prim/scal/err/check_not_nan.hpp>
#include <stan/math/prim/scal/fun/square.hpp>
#include <stan/math/prim/scal/meta/return_type.hpp>
#include <stan/math/rev/mat/fun/dot_product.hpp>
#include <vector>

namespace stan {
namespace math {

/**
 * Returns a dot product kernel.
 *
 * @tparam T_x type of std::vector of elements
 * @tparam T_sigma type of sigma
 *
 * @param x std::vector of elements that can be used in dot product
 *    This function assumes each element of x is the same size.
 * @param sigma
 * @return dot product kernel
 * @throw std::domain_error if sigma < 0, nan, inf or
 *   x is nan or infinite
 */
template <typename T_x, typename T_sigma>
inline typename Eigen::Matrix<typename stan::return_type<T_x, T_sigma>::type,
                              Eigen::Dynamic, Eigen::Dynamic>
gp_dot_prod_cov(const std::vector<T_x> &x, const T_sigma &sigma) {
  using stan::math::dot_product;
  using stan::math::square;

  check_not_nan("gp_dot_prod_cov", "sigma", sigma);
  check_nonnegative("gp_dot_prod_cov", "sigma", sigma);
  check_finite("gp_dot_prod_cov", "sigma", sigma);

  for (size_t n = 0; n < x.size(); ++n) {
    check_not_nan("gp_dot_prod_cov", "x", x[n]);
    check_finite("gp_dot_prod_cov", "x", x[n]);
  }

  Eigen::Matrix<typename stan::return_type<T_x, T_sigma>::type, Eigen::Dynamic,
                Eigen::Dynamic>
      cov(x.size(), x.size());
  int x_size = x.size();
  if (x_size == 0)
    return cov;

  T_sigma sigma_sq = square(sigma);

  for (int i = 0; i < (x_size - 1); ++i) {
    cov(i, i) = sigma_sq + dot_product(x[i], x[i]);
    for (int j = i + 1; j < x_size; ++j) {
      cov(i, j) = sigma_sq + dot_product(x[i], x[j]);
      cov(j, i) = cov(i, j);
    }
  }
  cov(x_size - 1, x_size - 1)
      = sigma_sq + dot_product(x[x_size - 1], x[x_size - 1]);
  return cov;
}

/**
 * Returns a dot product kernel.
 *
 * @tparam T_x type of std::vector of double
 * @tparam T_sigma type of sigma
 *
 * @param x std::vector of elements that can be used in transpose
 *   and multiply
 *    This function assumes each element of x is the same size.
 * @param sigma
 * @return dot product kernel
 * @throw std::domain_error if sigma < 0, nan, inf or
 *   x is nan or infinite
 */
template <typename T_sigma>
inline typename Eigen::Matrix<typename stan::return_type<double, T_sigma>::type,
                              Eigen::Dynamic, Eigen::Dynamic>
gp_dot_prod_cov(const std::vector<double> &x, const T_sigma &sigma) {
  using stan::math::dot_product;
  using stan::math::square;

  check_not_nan("gp_dot_prod_cov", "sigma", sigma);
  check_nonnegative("gp_dot_prod_cov", "sigma", sigma);
  check_finite("gp_dot_prod_cov", "sigma", sigma);

  for (size_t n = 0; n < x.size(); ++n) {
    check_not_nan("gp_dot_prod_cov", "x", x[n]);
    check_finite("gp_dot_prod_cov", "x", x[n]);
  }

  Eigen::Matrix<typename stan::return_type<double, T_sigma>::type,
                Eigen::Dynamic, Eigen::Dynamic>
      cov(x.size(), x.size());
  int x_size = x.size();
  if (x_size == 0)
    return cov;

  T_sigma sigma_sq = square(sigma);

  for (int i = 0; i < (x_size - 1); ++i) {
    cov(i, i) = sigma_sq + x[i] * x[i];
    for (int j = i + 1; j < x_size; ++j) {
      cov(i, j) = sigma_sq + x[i] * x[j];
      cov(j, i) = cov(i, j);
    }
  }
  cov(x_size - 1, x_size - 1) = sigma_sq + x[x_size - 1] * x[x_size - 1];
  return cov;
}

/**
 * Returns a dot product kernel.
 *
 * @tparam T_x1 type of first std::vector of elements
 * @tparam T_x2 type of second std::vector of elements
 * @tparam T_sigma type of sigma
 *
 * @param x1 std::vector of elements that can be used in dot_product
 * @param x2 std::vector of elements that can be used in dot_product
 * @param sigma
 * @return dot product kernel
 * @throw std::domain_error if sigma < 0, nan or inf
 *   or if x1 or x2 are nan or inf
 */
template <typename T_x1, typename T_x2, typename T_sigma>
inline typename Eigen::Matrix<
    typename stan::return_type<T_x1, T_x2, T_sigma>::type, Eigen::Dynamic,
    Eigen::Dynamic>
gp_dot_prod_cov(const std::vector<T_x1> &x1, const std::vector<T_x2> &x2,
                const T_sigma &sigma) {
  using stan::math::dot_product;
  using stan::math::square;

  check_not_nan("gp_dot_prod_cov", "sigma", sigma);
  check_nonnegative("gp_dot_prod_cov", "sigma", sigma);
  check_finite("gp_dot_prod_cov", "sigma", sigma);

  for (size_t n = 0; n < x1.size(); ++n) {
    check_not_nan("gp_dot_prod_cov", "x1", x1[n]);
    check_finite("gp_dot_prod_cov", "x1", x1[n]);
  }
  for (size_t n = 0; n < x2.size(); ++n) {
    check_not_nan("gp_dot_prod_cov", "x2", x2[n]);
    check_finite("gp_dot_prod_cov", "x2", x2[n]);
  }
  Eigen::Matrix<typename stan::return_type<T_x1, T_x2, T_sigma>::type,
                Eigen::Dynamic, Eigen::Dynamic>
      cov(x1.size(), x2.size());

  if (x1.size() == 0 || x2.size() == 0)
    return cov;

  T_sigma sigma_sq = square(sigma);

  for (size_t i = 0; i < x1.size(); ++i) {
    for (size_t j = 0; j < x2.size(); ++j) {
      cov(i, j) = sigma_sq + dot_product(x1[i], x2[j]);
    }
  }
  return cov;
}

/**
 * Returns a dot product kernel.
 *
 * @tparam T_x1 type of first std::vector of double
 * @tparam T_x2 type of second std::vector of double
 * @tparam T_sigma type of sigma
 *
 * @param x1 std::vector of elements that can be used in dot_product
 * @param x2 std::vector of elements that can be used in dot_product
 * @param sigma
 * @return dot product kernel
 * @throw std::domain_error if sigma < 0, nan or inf
 *   or if x1 or x2 are nan or inf
 */
template <typename T_sigma>
inline typename Eigen::Matrix<typename stan::return_type<double, T_sigma>::type,
                              Eigen::Dynamic, Eigen::Dynamic>
gp_dot_prod_cov(const std::vector<double> &x1, const std::vector<double> &x2,
                const T_sigma &sigma) {
  using stan::math::square;

  check_not_nan("gp_dot_prod_cov", "sigma", sigma);
  check_nonnegative("gp_dot_prod_cov", "sigma", sigma);
  check_finite("gp_dot_prod_cov", "sigma", sigma);

  for (size_t n = 0; n < x1.size(); ++n) {
    check_not_nan("gp_dot_prod_cov", "x1", x1[n]);
    check_finite("gp_dot_prod_cov", "x1", x1[n]);
  }
  for (size_t n = 0; n < x2.size(); ++n) {
    check_not_nan("gp_dot_prod_cov", "x2", x2[n]);
    check_finite("gp_dot_prod_cov", "x2", x2[n]);
  }
  Eigen::Matrix<typename stan::return_type<double, T_sigma>::type,
                Eigen::Dynamic, Eigen::Dynamic>
      cov(x1.size(), x2.size());

  if (x1.size() == 0 || x2.size() == 0)
    return cov;

  T_sigma sigma_sq = square(sigma);

  for (size_t i = 0; i < x1.size(); ++i) {
    for (size_t j = 0; j < x2.size(); ++j) {
      cov(i, j) = sigma_sq + x1[i] * x2[j];
    }
  }
  return cov;
}
}  // namespace math
}  // namespace stan
#endif
<commit_msg>update docs, fix some style issues, address PR reviews<commit_after>#ifndef STAN_MATH_PRIM_MAT_FUN_COV_DOT_PROD_HPP
#define STAN_MATH_PRIM_MAT_FUN_COV_DOT_PROD_HPP

#include <stan/math/prim/mat/fun/Eigen.hpp>
#include <stan/math/prim/mat/fun/value_of.hpp>
#include <stan/math/prim/scal/err/check_finite.hpp>
#include <stan/math/prim/scal/err/check_nonnegative.hpp>
#include <stan/math/prim/scal/err/check_not_nan.hpp>
#include <stan/math/prim/scal/fun/square.hpp>
#include <stan/math/prim/scal/meta/return_type.hpp>
#include <stan/math/rev/mat/fun/dot_product.hpp>
#include <vector>

namespace stan {
namespace math {

/**
 * Returns a dot product covariance matrix.
 *
 * $k(x,x') = \sigma^2 + x * x'$
 *
 * A dot product covariance matrix is the same covariance matrix
 * as in bayesian regression with N(0,1) priors on regression coefficients
 * and a N(0,\sigma^2) prior on the constant function. See Rasmussen and
 * Williams et al 2006, Chapter 4.
 *
 * @tparam T_x type of std::vector of elements
 * @tparam T_sigma type of sigma
 *
 * @param x std::vector of elements that can be used in dot product.
 *    This function assumes each element of x is the same size.
 * @param sigma is the constant function that can be used in stan::math::square
 * @return dot product dot product covariance matrix that is positive semi-definite
 * @throw std::domain_error if sigma < 0, nan, inf or
 *   x is nan or infinite
 */
template <typename T_x, typename T_sigma>
inline typename Eigen::Matrix<typename stan::return_type<T_x, T_sigma>::type,
                              Eigen::Dynamic, Eigen::Dynamic>
gp_dot_prod_cov(const std::vector<T_x> &x, const T_sigma &sigma) {
  using stan::math::dot_product;
  using stan::math::square;

  check_not_nan("gp_dot_prod_cov", "sigma", sigma);
  check_nonnegative("gp_dot_prod_cov", "sigma", sigma);
  check_finite("gp_dot_prod_cov", "sigma", sigma);

  size_t x_size = x.size();
  for(size_t i = 0; i < x_size; ++i)
    check_not_nan("gp_dot_prod_cov", "x", x[i]);

  check_finite("gp_dot_prod_cov", "x", x);

  Eigen::Matrix<typename stan::return_type<T_x, T_sigma>::type, Eigen::Dynamic,
                Eigen::Dynamic>
      cov(x_size, x_size);
  if (x_size == 0)
    return cov;

  T_sigma sigma_sq = square(sigma);

  for (size_t i = 0; i < (x_size - 1); ++i) {
    cov(i, i) = sigma_sq + dot_self(x[i]);
    for (size_t j = i + 1; j < x_size; ++j) {
      cov(i, j) = sigma_sq + dot_product(x[i], x[j]);
      cov(j, i) = cov(i, j);
    }
  }
  cov(x_size - 1, x_size - 1) = sigma_sq + dot_self(x[x_size - 1]);
  return cov;
}

/**
 * Returns a dot product covariance matrix.
 *
 * $k(x,x') = \sigma^2 + x * x'$
 *
 * A dot product covariance matrix is the same covariance matrix
 * as in bayesian regression with N(0,1) priors on regression coefficients
 * and a N(0,\sigma^2) prior on the constant function. See Rasmussen and
 * Williams et al 2006, Chapter 4.
 *
 * @tparam T_x type of std::vector of double
 * @tparam T_sigma type of sigma
 *
 * @param x std::vector of elements that can be used in transpose
 *   and multiply
 *    This function assumes each element of x is the same size.
 * @param sigma is the constant function that can be used in stan::math::square
 * @return dot product covariance matrix that is positive semi-definite
 * @throw std::domain_error if sigma < 0, nan, inf or
 *   x is nan or infinite
 */
template <typename T_sigma>
inline typename Eigen::Matrix<typename stan::return_type<double, T_sigma>::type,
                              Eigen::Dynamic, Eigen::Dynamic>
gp_dot_prod_cov(const std::vector<double> &x, const T_sigma &sigma) {
  using stan::math::dot_product;
  using stan::math::square;

  check_not_nan("gp_dot_prod_cov", "sigma", sigma);
  check_nonnegative("gp_dot_prod_cov", "sigma", sigma);
  check_finite("gp_dot_prod_cov", "sigma", sigma);

  size_t x_size = x.size();
  for(size_t i = 0; i < x_size; ++i)
    check_not_nan("gp_dot_prod_cov", "x", x[i]);

  check_finite("gp_dot_prod_cov", "x", x);

  Eigen::Matrix<typename stan::return_type<double, T_sigma>::type,
                Eigen::Dynamic, Eigen::Dynamic>
      cov(x_size, x_size);
  if (x_size == 0)
    return cov;

  T_sigma sigma_sq = square(sigma);

  for (size_t i = 0; i < (x_size - 1); ++i) {
    cov(i, i) = sigma_sq + x[i] * x[i];
    for (size_t j = i + 1; j < x_size; ++j) {
      cov(i, j) = sigma_sq + x[i] * x[j];
      cov(j, i) = cov(i, j);
    }
  }
  cov(x_size - 1, x_size - 1) = sigma_sq + x[x_size - 1] * x[x_size - 1];
  return cov;
}

/**
 * Returns a dot product covariance matrix of differing
 * x lengths.
 *
 * $k(x,x') = \sigma^2 + x * x'$
 *
 * A dot product covariance matrix is the same covariance matrix
 * as in bayesian regression with N(0,1) priors on regression coefficients
 * and a N(0,\sigma^2) prior on the constant function. See Rasmussen and
 * Williams et al 2006, Chapter 4.
 *
 * @tparam T_x1 type of first std::vector of elements
 * @tparam T_x2 type of second std::vector of elements
 * @tparam T_sigma type of sigma
 *
 * @param x1 std::vector of elements that can be used in dot_product
 * @param x2 std::vector of elements that can be used in dot_product
 * @param sigma is the constant function that can be used in stan::math::square
 * @return dot product covariance matrix, that is non-symmetric
 * @throw std::domain_error if sigma < 0, nan or inf
 *   or if x1 or x2 are nan or inf
 */
template <typename T_x1, typename T_x2, typename T_sigma>
inline typename Eigen::Matrix<
    typename stan::return_type<T_x1, T_x2, T_sigma>::type, Eigen::Dynamic,
    Eigen::Dynamic>
gp_dot_prod_cov(const std::vector<T_x1> &x1, const std::vector<T_x2> &x2,
                const T_sigma &sigma) {
  using stan::math::dot_product;
  using stan::math::square;

  check_not_nan("gp_dot_prod_cov", "sigma", sigma);
  check_nonnegative("gp_dot_prod_cov", "sigma", sigma);
  check_finite("gp_dot_prod_cov", "sigma", sigma);

  size_t x1_size = x1.size();
  size_t x2_size = x2.size();
  for(size_t i = 0; i < x1_size; ++i)
    check_not_nan("gp_dot_prod_cov", "x1", x1[i]);

  check_finite("gp_dot_prod_cov", "x1", x1);

  for(size_t i = 0; i < x2_size; ++i)
    check_not_nan("gp_dot_prod_cov", "x2", x2[i]);

  check_finite("gp_dot_prod_cov", "x2", x2);

  Eigen::Matrix<typename stan::return_type<T_x1, T_x2, T_sigma>::type,
                Eigen::Dynamic, Eigen::Dynamic>
      cov(x1_size, x2_size);

  if (x1_size == 0 || x2_size == 0)
    return cov;

  T_sigma sigma_sq = square(sigma);

  for (size_t i = 0; i < x1_size; ++i) {
    for (size_t j = 0; j < x2_size; ++j) {
      cov(i, j) = sigma_sq + dot_product(x1[i], x2[j]);
    }
  }
  return cov;
}

/**
 * Returns a dot product covariance matrix of
 * differing x lengths.
 *
 * $k(x,x') = \sigma^2 + x * x'$
 *
 * A dot product covariance matrix is the same covariance matrix
 * as in bayesian regression with N(0,1) priors on regression coefficients
 * and a N(0,\sigma^2) prior on the constant function. See Rasmussen and
 * Williams et al 2006, Chapter 4.
 *
 * @tparam T_x1 type of first std::vector of double
 * @tparam T_x2 type of second std::vector of double
 * @tparam T_sigma type of sigma
 *
 * @param x1 std::vector of elements that can be used in dot_product
 * @param x2 std::vector of elements that can be used in dot_product
 * @param sigma is the constant function that can be used in stan::math::square
 * @return dot product covariance matrix that is non-symmetric
 * @throw std::domain_error if sigma < 0, nan or inf
 *   or if x1 or x2 are nan or inf
 */
template <typename T_sigma>
inline typename Eigen::Matrix<typename stan::return_type<double, T_sigma>::type,
                              Eigen::Dynamic, Eigen::Dynamic>
gp_dot_prod_cov(const std::vector<double> &x1, const std::vector<double> &x2,
                const T_sigma &sigma) {
  using stan::math::square;

  check_not_nan("gp_dot_prod_cov", "sigma", sigma);
  check_nonnegative("gp_dot_prod_cov", "sigma", sigma);
  check_finite("gp_dot_prod_cov", "sigma", sigma);

  size_t x1_size = x1.size();
  size_t x2_size = x2.size();
  for(size_t i = 0; i < x1_size; ++i)
    check_not_nan("gp_dot_prod_cov", "x1", x1[i]);

  check_finite("gp_dot_prod_cov", "x1", x1);

  for(size_t i = 0; i < x2_size; ++i)
    check_not_nan("gp_dot_prod_cov", "x2", x2[i]);

  check_finite("gp_dot_prod_cov", "x2", x2);

  Eigen::Matrix<typename stan::return_type<double, T_sigma>::type,
                Eigen::Dynamic, Eigen::Dynamic>
      cov(x1_size, x2_size);

  if (x1_size == 0 || x2_size == 0)
    return cov;

  T_sigma sigma_sq = square(sigma);

  for (size_t i = 0; i < x1_size; ++i) {
    for (size_t j = 0; j < x2_size; ++j) {
      cov(i, j) = sigma_sq + x1[i] * x2[j];
    }
  }
  return cov;
}
}  // namespace math
}  // namespace stan
#endif
<|endoftext|>


<commit_before>#include <iostream>
#include <dlfcn.h>

typedef void* (*getSEATDInstance_t)(void*);

int main(int argc, char** argv)
{
    using std::cout;
    using std::cerr;

    // open the library
    cout << "Opening " << argv[1] << "...\n";
    void* handle = dlopen(argv[1], RTLD_LAZY);

    if ( !handle ) {
        cerr << "Cannot open library: " << dlerror() << '\n';
        return 1;
    }

    // load the symbol
    cout << "Loading symbol...\n";

    // reset errors
    const char* err = dlerror();
    if ( err )
        cerr << "Errors: " << dlerror() << '\n';
    getSEATDInstance_t getSEATDInstance = (getSEATDInstance_t)dlsym(handle, "getSEATDInstance");
    const char *dlsym_error = dlerror();
    if ( dlsym_error ) {
        cerr << "Cannot load symbol 'getSEATDInstance': " << dlsym_error << '\n';
        dlclose(handle);
        return 1;
    }

    // use it to do the calculation
    cout << "Creating D instance...\n";
    char str[80];
    memcpy(str, "from C++ to D", 14);
    printf("sending pointer %x\n", str);
    void* instance = getSEATDInstance(str);
    printf("recieved pointer %x\n", instance);

    // close the library
    cout << "Closing library...\n";
    dlclose(handle);
}
<commit_msg>- updated export name<commit_after>#include <iostream>
#include <dlfcn.h>

typedef void* (*seatdGetInstance_t)(void*);

int main(int argc, char** argv)
{
    using std::cout;
    using std::cerr;

    // open the library
    cout << "Opening " << argv[1] << "...\n";
    void* handle = dlopen(argv[1], RTLD_LAZY);

    if ( !handle ) {
        cerr << "Cannot open library: " << dlerror() << '\n';
        return 1;
    }

    // load the symbol
    cout << "Loading symbol...\n";

    // reset errors
    const char* err = dlerror();
    if ( err )
        cerr << "Errors: " << dlerror() << '\n';
    seatdGetInstance_t seatdGetInstance = (seatdGetInstance_t)dlsym(handle, "seatdGetInstance");
    const char *dlsym_error = dlerror();
    if ( dlsym_error ) {
        cerr << "Cannot load symbol 'seatdGetInstance': " << dlsym_error << '\n';
        dlclose(handle);
        return 1;
    }

    // use it to do the calculation
    cout << "Creating D instance...\n";
    char str[80];
    memcpy(str, "from C++ to D", 14);
    printf("sending pointer %x\n", str);
    void* instance = seatdGetInstance(str);
    printf("successfully recieved pointer %x\n", instance);

    // close the library
    cout << "Closing library...\n";
    dlclose(handle);
}
<|endoftext|>


<commit_before>//* This file is part of the MOOSE framework
//* https://www.mooseframework.org
//*
//* All rights reserved, see COPYRIGHT for full restrictions
//* https://github.com/idaholab/moose/blob/master/COPYRIGHT
//*
//* Licensed under LGPL 2.1, please see LICENSE for details
//* https://www.gnu.org/licenses/lgpl-2.1.html

#include "FVAnisotropicDiffusion.h"
#include "RelationshipManager.h"

registerMooseObject("MooseApp", FVAnisotropicDiffusion);

InputParameters
FVAnisotropicDiffusion::validParams()
{
  InputParameters params = FVFluxKernel::validParams();
  params.addClassDescription(
      "Computes residual for anisotropic diffusion operator for finite volume method.");
  params.addRequiredParam<MooseFunctorName>("coeff", "diffusion coefficient");
  params.set<unsigned short>("ghost_layers") = 2;
  return params;
}

FVAnisotropicDiffusion::FVAnisotropicDiffusion(const InputParameters & params)
  : FVFluxKernel(params), _coeff(getFunctor<ADRealVectorValue>("coeff"))
{
#ifndef MOOSE_GLOBAL_AD_INDEXING
  mooseError("FVAnisotropicDiffusion is not supported by local AD indexing. In order to use this "
             "object, please run "
             "the configure script in the root MOOSE directory with the configure option "
             "'--with-ad-indexing-type=global'. Note that global indexing is now the default "
             "configuration for AD indexing type.");
#endif

  if ((_var.faceInterpolationMethod() == Moose::FV::InterpMethod::SkewCorrectedAverage) &&
      (_tid == 0))
  {
    auto & factory = _app.getFactory();

    auto rm_params = factory.getValidParams("ElementSideNeighborLayers");

    rm_params.set<std::string>("for_whom") = name();
    rm_params.set<MooseMesh *>("mesh") = &const_cast<MooseMesh &>(_mesh);
    rm_params.set<Moose::RelationshipManagerType>("rm_type") =
        Moose::RelationshipManagerType::GEOMETRIC | Moose::RelationshipManagerType::ALGEBRAIC |
        Moose::RelationshipManagerType::COUPLING;
    FVKernel::setRMParams(
        _pars, rm_params, std::max((unsigned short)(3), _pars.get<unsigned short>("ghost_layers")));
    mooseAssert(rm_params.areAllRequiredParamsValid(),
                "All relationship manager parameters should be valid.");

    auto rm_obj = factory.create<RelationshipManager>(
        "ElementSideNeighborLayers", name() + "_skew_correction", rm_params);

    // Delete the resources created on behalf of the RM if it ends up not being added to the
    // App.
    if (!_app.addRelationshipManager(rm_obj))
      factory.releaseSharedObjects(*rm_obj);
  }
}

ADReal
FVAnisotropicDiffusion::computeQpResidual()
{
  ADReal r = 0;
  const auto face_elem = elemFromFace();
  const auto face_neighbor = neighborFromFace();
  const auto & grad_T = _var.adGradSln(
      *_face_info, _var.faceInterpolationMethod() == Moose::FV::InterpMethod::SkewCorrectedAverage);
  ADRealVectorValue k_face_inv, k_elem_inv, k_neigh_inv;
  const auto k_elem = _coeff(face_elem), k_neighbor = _coeff(face_neighbor);
  for (const auto i : make_range(Moose::dim))
  {
    k_elem_inv(i) = 1.0 / k_elem(i);
    k_neigh_inv(i) = 1.0 / k_neighbor(i);
  }

  Moose::FV::interpolate(
      Moose::FV::InterpMethod::Average, k_face_inv, k_elem_inv, k_neigh_inv, *_face_info, true);
  for (const auto i : make_range(Moose::dim))
    r += _normal(i) * grad_T(i) / k_face_inv(i);
  return -r;
}
<commit_msg>FPE in test caused by i=2 (z-direction) in 2D problem, changing loop indexing (#21832)<commit_after>//* This file is part of the MOOSE framework
//* https://www.mooseframework.org
//*
//* All rights reserved, see COPYRIGHT for full restrictions
//* https://github.com/idaholab/moose/blob/master/COPYRIGHT
//*
//* Licensed under LGPL 2.1, please see LICENSE for details
//* https://www.gnu.org/licenses/lgpl-2.1.html

#include "FVAnisotropicDiffusion.h"
#include "RelationshipManager.h"

registerMooseObject("MooseApp", FVAnisotropicDiffusion);

InputParameters
FVAnisotropicDiffusion::validParams()
{
  InputParameters params = FVFluxKernel::validParams();
  params.addClassDescription(
      "Computes residual for anisotropic diffusion operator for finite volume method.");
  params.addRequiredParam<MooseFunctorName>("coeff", "diffusion coefficient");
  params.set<unsigned short>("ghost_layers") = 2;
  return params;
}

FVAnisotropicDiffusion::FVAnisotropicDiffusion(const InputParameters & params)
  : FVFluxKernel(params), _coeff(getFunctor<ADRealVectorValue>("coeff"))
{
#ifndef MOOSE_GLOBAL_AD_INDEXING
  mooseError("FVAnisotropicDiffusion is not supported by local AD indexing. In order to use this "
             "object, please run "
             "the configure script in the root MOOSE directory with the configure option "
             "'--with-ad-indexing-type=global'. Note that global indexing is now the default "
             "configuration for AD indexing type.");
#endif

  if ((_var.faceInterpolationMethod() == Moose::FV::InterpMethod::SkewCorrectedAverage) &&
      (_tid == 0))
  {
    auto & factory = _app.getFactory();

    auto rm_params = factory.getValidParams("ElementSideNeighborLayers");

    rm_params.set<std::string>("for_whom") = name();
    rm_params.set<MooseMesh *>("mesh") = &const_cast<MooseMesh &>(_mesh);
    rm_params.set<Moose::RelationshipManagerType>("rm_type") =
        Moose::RelationshipManagerType::GEOMETRIC | Moose::RelationshipManagerType::ALGEBRAIC |
        Moose::RelationshipManagerType::COUPLING;
    FVKernel::setRMParams(
        _pars, rm_params, std::max((unsigned short)(3), _pars.get<unsigned short>("ghost_layers")));
    mooseAssert(rm_params.areAllRequiredParamsValid(),
                "All relationship manager parameters should be valid.");

    auto rm_obj = factory.create<RelationshipManager>(
        "ElementSideNeighborLayers", name() + "_skew_correction", rm_params);

    // Delete the resources created on behalf of the RM if it ends up not being added to the
    // App.
    if (!_app.addRelationshipManager(rm_obj))
      factory.releaseSharedObjects(*rm_obj);
  }
}

ADReal
FVAnisotropicDiffusion::computeQpResidual()
{
  ADReal r = 0;
  const auto face_elem = elemFromFace();
  const auto face_neighbor = neighborFromFace();
  const auto & grad_T = _var.adGradSln(
      *_face_info, _var.faceInterpolationMethod() == Moose::FV::InterpMethod::SkewCorrectedAverage);
  ADRealVectorValue k_face_inv, k_elem_inv, k_neigh_inv;
  const auto k_elem = _coeff(face_elem), k_neighbor = _coeff(face_neighbor);
  for (unsigned int i = 0; i < LIBMESH_DIM; ++i)
  {
    mooseAssert(k_elem(i) != 0, "Diffusion coefficient is equal to zero");
    mooseAssert(k_neighbor(i) != 0, "Diffusion coefficient is equal to zero");
    k_elem_inv(i) = 1.0 / k_elem(i);
    k_neigh_inv(i) = 1.0 / k_neighbor(i);
  }

  Moose::FV::interpolate(
      Moose::FV::InterpMethod::Average, k_face_inv, k_elem_inv, k_neigh_inv, *_face_info, true);
  for (const auto i : make_range(Moose::dim))
    r += _normal(i) * grad_T(i) / k_face_inv(i);
  return -r;
}
<|endoftext|>


<commit_before>#include "input_cursor.h"
#include "CommonStates.h"

namespace ui
{
	input_cursor::input_cursor(std::shared_ptr<core_ui> core, const std::shared_ptr<render::platform::font> font,  const std::shared_ptr<render::platform::sprite_batch>& spriteBatch, std::wstring path)
		: control(core, font, spriteBatch)
		, m_pressedAnimID(0)
		, m_defaultAnimID(0)
		, m_currentAnimID(0)
	{
		if ( spriteBatch == nullptr )
		{
			m_spriteBatch = std::shared_ptr<render::platform::sprite_batch>(new render::platform::sprite_batch(core->GetDevice()->GetImmediateContext()));
		}

		if (!path.empty())
		{
			m_texture = std::shared_ptr<render::texture>(new render::texture(m_core->GetDevice(), path));
			m_rectangle.SetSize(math::vector2(m_texture->Width(), m_texture->Height()));
		}
	}

	void input_cursor::Load(const std::wstring& path)
	{
		m_spriteSheet = std::unique_ptr<render::spritesheet>(new render::spritesheet(m_core->GetDevice(), path));

		auto& defaultAnim = m_spriteSheet->CreateAnimation(L"default", m_defaultAnimID);
		defaultAnim.AddFrame(math::rectangle(178, 448, 16, 16), 0.f);
		defaultAnim.Loop() = false;

		auto& pressedAnim = m_spriteSheet->CreateAnimation(L"pressed", m_pressedAnimID);
		pressedAnim.AddFrame(math::rectangle(196, 448, 16, 16), 0.f);
		pressedAnim.Loop() = false;

		m_sprite = m_spriteSheet->Create();
		m_sprite->Play(m_defaultAnimID);
		m_currentAnimID = m_defaultAnimID;
	}

	bool input_cursor::HandleInput(float /*deltaTime*/, input::input_state& inputState)
	{
		auto mouse = inputState.GetMouse();
		if (mouse)
		{
			if (m_currentAnimID != m_pressedAnimID && mouse->ButtonPressed(input::mouse::eButton::Left))
			{
				m_sprite->Play(m_pressedAnimID);
				m_currentAnimID = m_pressedAnimID;
				return true;
			}
			else
			if (m_currentAnimID == m_pressedAnimID && mouse->ButtonReleased(input::mouse::eButton::Left))
			{
				m_currentAnimID = m_defaultAnimID;
				m_sprite->Play(m_defaultAnimID);
				return true;
			}
		}

		return false;
	}

	void input_cursor::Update(float deltaTime)
	{
		control::Update(deltaTime);

		m_sprite->Update(deltaTime);
	}

	void input_cursor::Draw()
	{
		if (m_texture)
		{
			DirectX::CommonStates states(m_core->GetDevice()->GetDevice());
			m_spriteBatch->Begin(DirectX::SpriteSortMode::SpriteSortMode_Deferred, states.NonPremultiplied(), nullptr, states.DepthNone());

			m_spriteBatch->Draw(*m_texture->GetView(), m_rectangle, nullptr);

			m_spriteBatch->End();
		}

		if (m_sprite)
		{
			m_sprite->Draw(m_rectangle.Position());
		}
	}

	void input_cursor::SetTexture(std::shared_ptr<render::texture> texture)
	{
		m_texture = nullptr;
		m_texture = texture;
	}

}<commit_msg>Fixing crash in 3D Menu sample caused by latest update to sprites.<commit_after>#include "input_cursor.h"
#include "CommonStates.h"

namespace ui
{
	input_cursor::input_cursor(std::shared_ptr<core_ui> core, const std::shared_ptr<render::platform::font> font,  const std::shared_ptr<render::platform::sprite_batch>& spriteBatch, std::wstring path)
		: control(core, font, spriteBatch)
		, m_pressedAnimID(0)
		, m_defaultAnimID(0)
		, m_currentAnimID(0)
	{
		if ( spriteBatch == nullptr )
		{
			m_spriteBatch = std::shared_ptr<render::platform::sprite_batch>(new render::platform::sprite_batch(core->GetDevice()->GetImmediateContext()));
		}

		if (!path.empty())
		{
			m_texture = std::shared_ptr<render::texture>(new render::texture(m_core->GetDevice(), path));
			m_rectangle.SetSize(math::vector2(m_texture->Width(), m_texture->Height()));
		}
	}

	void input_cursor::Load(const std::wstring& path)
	{
		m_spriteSheet = std::unique_ptr<render::spritesheet>(new render::spritesheet(m_core->GetDevice(), path));

		auto& defaultAnim = m_spriteSheet->CreateAnimation(L"default", m_defaultAnimID);
		defaultAnim.AddFrame(math::rectangle(178, 448, 16, 16), 0.f);
		defaultAnim.Loop() = false;

		auto& pressedAnim = m_spriteSheet->CreateAnimation(L"pressed", m_pressedAnimID);
		pressedAnim.AddFrame(math::rectangle(196, 448, 16, 16), 0.f);
		pressedAnim.Loop() = false;

		m_sprite = m_spriteSheet->Create();
		m_sprite->Play(m_defaultAnimID);
		m_currentAnimID = m_defaultAnimID;
	}

	bool input_cursor::HandleInput(float /*deltaTime*/, input::input_state& inputState)
	{
		auto mouse = inputState.GetMouse();
		if (mouse)
		{
			if (m_currentAnimID != m_pressedAnimID && mouse->ButtonPressed(input::mouse::eButton::Left))
			{
				m_sprite->Play(m_pressedAnimID);
				m_currentAnimID = m_pressedAnimID;
				return true;
			}
			else
			if (m_currentAnimID == m_pressedAnimID && mouse->ButtonReleased(input::mouse::eButton::Left))
			{
				m_currentAnimID = m_defaultAnimID;
				m_sprite->Play(m_defaultAnimID);
				return true;
			}
		}

		return false;
	}

	void input_cursor::Update(float deltaTime)
	{
		control::Update(deltaTime);

		if (m_sprite)
		{
			m_sprite->Update(deltaTime);
		}
	}

	void input_cursor::Draw()
	{
		if (m_texture)
		{
			DirectX::CommonStates states(m_core->GetDevice()->GetDevice());
			m_spriteBatch->Begin(DirectX::SpriteSortMode::SpriteSortMode_Deferred, states.NonPremultiplied(), nullptr, states.DepthNone());

			m_spriteBatch->Draw(*m_texture->GetView(), m_rectangle, nullptr);

			m_spriteBatch->End();
		}

		if (m_sprite)
		{
			m_sprite->Draw(m_rectangle.Position());
		}
	}

	void input_cursor::SetTexture(std::shared_ptr<render::texture> texture)
	{
		m_texture = nullptr;
		m_texture = texture;
	}

}<|endoftext|>


<commit_before>/****************************************************************************
 *
 *   Copyright (c) 2013-2015 PX4 Development Team. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 * 3. Neither the name PX4 nor the names of its contributors may be
 *    used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 ****************************************************************************/

/**
 * @file main.cpp
 *
 * Example implementation of a rover steering controller.
 *
 * @author Lorenz Meier <lorenz@px4.io>
 */

#include <px4_config.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <math.h>
#include <poll.h>
#include <time.h>
#include <drivers/drv_hrt.h>
#include <uORB/uORB.h>
#include <uORB/topics/vehicle_global_position.h>
#include <uORB/topics/position_setpoint_triplet.h>
#include <uORB/topics/vehicle_attitude.h>
#include <uORB/topics/vehicle_status.h>
#include <uORB/topics/vehicle_attitude_setpoint.h>
#include <uORB/topics/manual_control_setpoint.h>
#include <uORB/topics/actuator_controls.h>
#include <uORB/topics/vehicle_global_position.h>
#include <uORB/topics/parameter_update.h>
#include <systemlib/param/param.h>
#include <systemlib/pid/pid.h>
#include <geo/geo.h>
#include <systemlib/perf_counter.h>
#include <systemlib/systemlib.h>
#include <systemlib/err.h>

/* process-specific header files */
#include "params.h"

/* Prototypes */

/**
 * Daemon management function.
 *
 * This function allows to start / stop the background task (daemon).
 * The purpose of it is to be able to start the controller on the
 * command line, query its status and stop it, without giving up
 * the command line to one particular process or the need for bg/fg
 * ^Z support by the shell.
 */
extern "C" __EXPORT int rover_steering_control_main(int argc, char *argv[]);

struct params {
	float yaw_p;
};

struct param_handles {
	param_t yaw_p;
};

/**
 * Initialize all parameter handles and values
 *
 */
int parameters_init(struct param_handles *h);

/**
 * Update all parameters
 *
 */
int parameters_update(const struct param_handles *h, struct params *p);

/**
 * Mainloop of daemon.
 */
int rover_steering_control_thread_main(int argc, char *argv[]);

/**
 * Print the correct usage.
 */
static void usage(const char *reason);

/**
 * Control roll and pitch angle.
 *
 * This very simple roll and pitch controller takes the current roll angle
 * of the system and compares it to a reference. Pitch is controlled to zero and yaw remains
 * uncontrolled (tutorial code, not intended for flight).
 *
 * @param att_sp The current attitude setpoint - the values the system would like to reach.
 * @param att The current attitude. The controller should make the attitude match the setpoint
 */
void control_attitude(const struct vehicle_attitude_setpoint_s *att_sp, const struct vehicle_attitude_s *att,
		      struct actuator_controls_s *actuators);

/* Variables */
static bool thread_should_exit = false;		/**< Daemon exit flag */
static bool thread_running = false;		/**< Daemon status flag */
static int deamon_task;				/**< Handle of deamon task / thread */
static struct params pp;
static struct param_handles ph;

int parameters_init(struct param_handles *h)
{
	/* PID parameters */
	h->yaw_p 	=	param_find("RV_YAW_P");

	return OK;
}

int parameters_update(const struct param_handles *h, struct params *p)
{
	param_get(h->yaw_p, &(p->yaw_p));

	return OK;
}

void control_attitude(const struct vehicle_attitude_setpoint_s *att_sp, const struct vehicle_attitude_s *att,
		      struct actuator_controls_s *actuators)
{
	/*
	 * The PX4 architecture provides a mixer outside of the controller.
	 * The mixer is fed with a default vector of actuator controls, representing
	 * moments applied to the vehicle frame. This vector
	 * is structured as:
	 *
	 * Control Group 0 (attitude):
	 *
	 *    0  -  roll   (-1..+1)
	 *    1  -  pitch  (-1..+1)
	 *    2  -  yaw    (-1..+1)
	 *    3  -  thrust ( 0..+1)
	 *    4  -  flaps  (-1..+1)
	 *    ...
	 *
	 * Control Group 1 (payloads / special):
	 *
	 *    ...
	 */

	/* set r/p zero */
	actuators->control[0] = 0.0f;
	actuators->control[1] = 0.0f;

	/*
	 * Calculate roll error and apply P gain
	 */
	float yaw_err = att->yaw - att_sp->yaw_body;
	actuators->control[2] = yaw_err * pp.yaw_p;

	/* copy throttle */
	actuators->control[3] = att_sp->thrust;

	actuators->timestamp = hrt_absolute_time();
}

/* Main Thread */
int rover_steering_control_thread_main(int argc, char *argv[])
{
	/* read arguments */
	bool verbose = false;

	for (int i = 1; i < argc; i++) {
		if (strcmp(argv[i], "-v") == 0 || strcmp(argv[i], "--verbose") == 0) {
			verbose = true;
		}
	}

	/* initialize parameters, first the handles, then the values */
	parameters_init(&ph);
	parameters_update(&ph, &pp);

	/*
	 * PX4 uses a publish/subscribe design pattern to enable
	 * multi-threaded communication.
	 *
	 * The most elegant aspect of this is that controllers and
	 * other processes can either 'react' to new data, or run
	 * at their own pace.
	 *
	 * PX4 developer guide:
	 * https://pixhawk.ethz.ch/px4/dev/shared_object_communication
	 *
	 * Wikipedia description:
	 * http://en.wikipedia.org/wiki/Publish–subscribe_pattern
	 *
	 */

	/*
	 * Declare and safely initialize all structs to zero.
	 *
	 * These structs contain the system state and things
	 * like attitude, position, the current waypoint, etc.
	 */
	struct vehicle_attitude_s att;
	memset(&att, 0, sizeof(att));
	struct vehicle_attitude_setpoint_s att_sp;
	memset(&att_sp, 0, sizeof(att_sp));
	struct vehicle_global_position_s global_pos;
	memset(&global_pos, 0, sizeof(global_pos));
	struct manual_control_setpoint_s manual_sp;
	memset(&manual_sp, 0, sizeof(manual_sp));
	struct vehicle_status_s vstatus;
	memset(&vstatus, 0, sizeof(vstatus));
	struct position_setpoint_s global_sp;
	memset(&global_sp, 0, sizeof(global_sp));

	/* output structs - this is what is sent to the mixer */
	struct actuator_controls_s actuators;
	memset(&actuators, 0, sizeof(actuators));

	/* publish actuator controls with zero values */
	for (unsigned i = 0; i < (sizeof(actuators.control) / sizeof(actuators.control[0])); i++) {
		actuators.control[i] = 0.0f;
	}

	struct vehicle_attitude_setpoint_s _att_sp = {};

	/*
	 * Advertise that this controller will publish actuator
	 * control values and the rate setpoint
	 */
	orb_advert_t actuator_pub = orb_advertise(ORB_ID_VEHICLE_ATTITUDE_CONTROLS, &actuators);

	/* subscribe to topics. */
	int att_sub = orb_subscribe(ORB_ID(vehicle_attitude));

	int global_pos_sub = orb_subscribe(ORB_ID(vehicle_global_position));

	int manual_sp_sub = orb_subscribe(ORB_ID(manual_control_setpoint));

	int vstatus_sub = orb_subscribe(ORB_ID(vehicle_status));

	int att_sp_sub = orb_subscribe(ORB_ID(vehicle_attitude_setpoint));

	int param_sub = orb_subscribe(ORB_ID(parameter_update));

	/* Setup of loop */

	struct pollfd fds[2];

	fds[0].fd = param_sub;

	fds[0].events = POLLIN;

	fds[1].fd = att_sub;

	fds[1].events = POLLIN;

	while (!thread_should_exit) {

		/*
		 * Wait for a sensor or param update, check for exit condition every 500 ms.
		 * This means that the execution will block here without consuming any resources,
		 * but will continue to execute the very moment a new attitude measurement or
		 * a param update is published. So no latency in contrast to the polling
		 * design pattern (do not confuse the poll() system call with polling).
		 *
		 * This design pattern makes the controller also agnostic of the attitude
		 * update speed - it runs as fast as the attitude updates with minimal latency.
		 */
		int ret = poll(fds, 2, 500);

		if (ret < 0) {
			/*
			 * Poll error, this will not really happen in practice,
			 * but its good design practice to make output an error message.
			 */
			warnx("poll error");

		} else if (ret == 0) {
			/* no return value = nothing changed for 500 ms, ignore */
		} else {

			/* only update parameters if they changed */
			if (fds[0].revents & POLLIN) {
				/* read from param to clear updated flag (uORB API requirement) */
				struct parameter_update_s update;
				orb_copy(ORB_ID(parameter_update), param_sub, &update);

				/* if a param update occured, re-read our parameters */
				parameters_update(&ph, &pp);
			}

			/* only run controller if attitude changed */
			if (fds[1].revents & POLLIN) {

				/* Check if there is a new position measurement or position setpoint */
				bool pos_updated;
				orb_check(global_pos_sub, &pos_updated);
				bool att_sp_updated;
				orb_check(att_sp_sub, &att_sp_updated);
				bool manual_sp_updated;
				orb_check(manual_sp_sub, &manual_sp_updated);

				/* get a local copy of attitude */
				orb_copy(ORB_ID(vehicle_attitude), att_sub, &att);

				if (att_sp_updated) {
					orb_copy(ORB_ID(vehicle_attitude_setpoint), att_sp_sub, &_att_sp);
				}

				/* control attitude / heading */
				control_attitude(&_att_sp, &att, &actuators);

				if (manual_sp_updated)
					/* get the RC (or otherwise user based) input */
				{
					orb_copy(ORB_ID(manual_control_setpoint), manual_sp_sub, &manual_sp);
				}

				// XXX copy from manual depending on flight / usage mode to override

				/* get the system status and the flight mode we're in */
				orb_copy(ORB_ID(vehicle_status), vstatus_sub, &vstatus);

				/* sanity check and publish actuator outputs */
				if (isfinite(actuators.control[0]) &&
				    isfinite(actuators.control[1]) &&
				    isfinite(actuators.control[2]) &&
				    isfinite(actuators.control[3])) {
					orb_publish(ORB_ID_VEHICLE_ATTITUDE_CONTROLS, actuator_pub, &actuators);

					if (verbose) {
						warnx("published");
					}
				}
			}
		}
	}

	warnx("exiting, stopping all motors.");
	thread_running = false;

	/* kill all outputs */
	for (unsigned i = 0; i < (sizeof(actuators.control) / sizeof(actuators.control[0])); i++) {
		actuators.control[i] = 0.0f;
	}

	actuators.timestamp = hrt_absolute_time();

	orb_publish(ORB_ID_VEHICLE_ATTITUDE_CONTROLS, actuator_pub, &actuators);

	fflush(stdout);

	return 0;
}

/* Startup Functions */

static void
usage(const char *reason)
{
	if (reason) {
		fprintf(stderr, "%s\n", reason);
	}

	fprintf(stderr, "usage: rover_steering_control {start|stop|status}\n\n");
	exit(1);
}

/**
 * The daemon app only briefly exists to start
 * the background job. The stack size assigned in the
 * Makefile does only apply to this management task.
 *
 * The actual stack size should be set in the call
 * to px4_task_spawn_cmd().
 */
int rover_steering_control_main(int argc, char *argv[])
{
	if (argc < 2) {
		usage("missing command");
	}

	if (!strcmp(argv[1], "start")) {

		if (thread_running) {
			warnx("running");
			/* this is not an error */
			exit(0);
		}

		thread_should_exit = false;
		deamon_task = px4_task_spawn_cmd("rover_steering_control",
						 SCHED_DEFAULT,
						 SCHED_PRIORITY_MAX - 20,
						 2048,
						 rover_steering_control_thread_main,
						 (argv) ? (char *const *)&argv[2] : (char *const *)NULL);
		thread_running = true;
		exit(0);
	}

	if (!strcmp(argv[1], "stop")) {
		thread_should_exit = true;
		exit(0);
	}

	if (!strcmp(argv[1], "status")) {
		if (thread_running) {
			warnx("running");

		} else {
			warnx("not started");
		}

		exit(0);
	}

	usage("unrecognized command");
	exit(1);
}

<commit_msg>fixed rover example<commit_after>/****************************************************************************
 *
 *   Copyright (c) 2013-2015 PX4 Development Team. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 * 3. Neither the name PX4 nor the names of its contributors may be
 *    used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 ****************************************************************************/

/**
 * @file main.cpp
 *
 * Example implementation of a rover steering controller.
 *
 * @author Lorenz Meier <lorenz@px4.io>
 */

#include <px4_config.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <math.h>
#include <poll.h>
#include <time.h>
#include <drivers/drv_hrt.h>
#include <uORB/uORB.h>
#include <uORB/topics/vehicle_global_position.h>
#include <uORB/topics/position_setpoint_triplet.h>
#include <uORB/topics/vehicle_attitude.h>
#include <uORB/topics/vehicle_status.h>
#include <uORB/topics/vehicle_attitude_setpoint.h>
#include <uORB/topics/manual_control_setpoint.h>
#include <uORB/topics/actuator_controls.h>
#include <uORB/topics/vehicle_global_position.h>
#include <uORB/topics/parameter_update.h>
#include <systemlib/param/param.h>
#include <systemlib/pid/pid.h>
#include <geo/geo.h>
#include <systemlib/perf_counter.h>
#include <systemlib/systemlib.h>
#include <systemlib/err.h>
#include <matrix/math.hpp>

/* process-specific header files */
#include "params.h"

/* Prototypes */

/**
 * Daemon management function.
 *
 * This function allows to start / stop the background task (daemon).
 * The purpose of it is to be able to start the controller on the
 * command line, query its status and stop it, without giving up
 * the command line to one particular process or the need for bg/fg
 * ^Z support by the shell.
 */
extern "C" __EXPORT int rover_steering_control_main(int argc, char *argv[]);

struct params {
	float yaw_p;
};

struct param_handles {
	param_t yaw_p;
};

/**
 * Initialize all parameter handles and values
 *
 */
int parameters_init(struct param_handles *h);

/**
 * Update all parameters
 *
 */
int parameters_update(const struct param_handles *h, struct params *p);

/**
 * Mainloop of daemon.
 */
int rover_steering_control_thread_main(int argc, char *argv[]);

/**
 * Print the correct usage.
 */
static void usage(const char *reason);

/**
 * Control roll and pitch angle.
 *
 * This very simple roll and pitch controller takes the current roll angle
 * of the system and compares it to a reference. Pitch is controlled to zero and yaw remains
 * uncontrolled (tutorial code, not intended for flight).
 *
 * @param att_sp The current attitude setpoint - the values the system would like to reach.
 * @param att The current attitude. The controller should make the attitude match the setpoint
 */
void control_attitude(const struct vehicle_attitude_setpoint_s *att_sp, const struct vehicle_attitude_s *att,
		      struct actuator_controls_s *actuators);

/* Variables */
static bool thread_should_exit = false;		/**< Daemon exit flag */
static bool thread_running = false;		/**< Daemon status flag */
static int deamon_task;				/**< Handle of deamon task / thread */
static struct params pp;
static struct param_handles ph;

int parameters_init(struct param_handles *h)
{
	/* PID parameters */
	h->yaw_p 	=	param_find("RV_YAW_P");

	return OK;
}

int parameters_update(const struct param_handles *h, struct params *p)
{
	param_get(h->yaw_p, &(p->yaw_p));

	return OK;
}

void control_attitude(const struct vehicle_attitude_setpoint_s *att_sp, const struct vehicle_attitude_s *att,
		      struct actuator_controls_s *actuators)
{
	/*
	 * The PX4 architecture provides a mixer outside of the controller.
	 * The mixer is fed with a default vector of actuator controls, representing
	 * moments applied to the vehicle frame. This vector
	 * is structured as:
	 *
	 * Control Group 0 (attitude):
	 *
	 *    0  -  roll   (-1..+1)
	 *    1  -  pitch  (-1..+1)
	 *    2  -  yaw    (-1..+1)
	 *    3  -  thrust ( 0..+1)
	 *    4  -  flaps  (-1..+1)
	 *    ...
	 *
	 * Control Group 1 (payloads / special):
	 *
	 *    ...
	 */

	/* set r/p zero */
	actuators->control[0] = 0.0f;
	actuators->control[1] = 0.0f;

	/*
	 * Calculate roll error and apply P gain
	 */
	matrix::Quaternion<float> q(&att->q[0]);
	matrix::Euler<float> euler(q);
	matrix::Quaternion<float> q_sp(&att_sp->q_d[0]);
	matrix::Euler<float> euler_sp(q_sp);
	float yaw_err = euler(2) - euler_sp(2);
	actuators->control[2] = yaw_err * pp.yaw_p;

	/* copy throttle */
	actuators->control[3] = att_sp->thrust;

	actuators->timestamp = hrt_absolute_time();
}

/* Main Thread */
int rover_steering_control_thread_main(int argc, char *argv[])
{
	/* read arguments */
	bool verbose = false;

	for (int i = 1; i < argc; i++) {
		if (strcmp(argv[i], "-v") == 0 || strcmp(argv[i], "--verbose") == 0) {
			verbose = true;
		}
	}

	/* initialize parameters, first the handles, then the values */
	parameters_init(&ph);
	parameters_update(&ph, &pp);

	/*
	 * PX4 uses a publish/subscribe design pattern to enable
	 * multi-threaded communication.
	 *
	 * The most elegant aspect of this is that controllers and
	 * other processes can either 'react' to new data, or run
	 * at their own pace.
	 *
	 * PX4 developer guide:
	 * https://pixhawk.ethz.ch/px4/dev/shared_object_communication
	 *
	 * Wikipedia description:
	 * http://en.wikipedia.org/wiki/Publish–subscribe_pattern
	 *
	 */

	/*
	 * Declare and safely initialize all structs to zero.
	 *
	 * These structs contain the system state and things
	 * like attitude, position, the current waypoint, etc.
	 */
	struct vehicle_attitude_s att;
	memset(&att, 0, sizeof(att));
	struct vehicle_attitude_setpoint_s att_sp;
	memset(&att_sp, 0, sizeof(att_sp));
	struct vehicle_global_position_s global_pos;
	memset(&global_pos, 0, sizeof(global_pos));
	struct manual_control_setpoint_s manual_sp;
	memset(&manual_sp, 0, sizeof(manual_sp));
	struct vehicle_status_s vstatus;
	memset(&vstatus, 0, sizeof(vstatus));
	struct position_setpoint_s global_sp;
	memset(&global_sp, 0, sizeof(global_sp));

	/* output structs - this is what is sent to the mixer */
	struct actuator_controls_s actuators;
	memset(&actuators, 0, sizeof(actuators));

	/* publish actuator controls with zero values */
	for (unsigned i = 0; i < (sizeof(actuators.control) / sizeof(actuators.control[0])); i++) {
		actuators.control[i] = 0.0f;
	}

	struct vehicle_attitude_setpoint_s _att_sp = {};

	/*
	 * Advertise that this controller will publish actuator
	 * control values and the rate setpoint
	 */
	orb_advert_t actuator_pub = orb_advertise(ORB_ID_VEHICLE_ATTITUDE_CONTROLS, &actuators);

	/* subscribe to topics. */
	int att_sub = orb_subscribe(ORB_ID(vehicle_attitude));

	int global_pos_sub = orb_subscribe(ORB_ID(vehicle_global_position));

	int manual_sp_sub = orb_subscribe(ORB_ID(manual_control_setpoint));

	int vstatus_sub = orb_subscribe(ORB_ID(vehicle_status));

	int att_sp_sub = orb_subscribe(ORB_ID(vehicle_attitude_setpoint));

	int param_sub = orb_subscribe(ORB_ID(parameter_update));

	/* Setup of loop */

	struct pollfd fds[2];

	fds[0].fd = param_sub;

	fds[0].events = POLLIN;

	fds[1].fd = att_sub;

	fds[1].events = POLLIN;

	while (!thread_should_exit) {

		/*
		 * Wait for a sensor or param update, check for exit condition every 500 ms.
		 * This means that the execution will block here without consuming any resources,
		 * but will continue to execute the very moment a new attitude measurement or
		 * a param update is published. So no latency in contrast to the polling
		 * design pattern (do not confuse the poll() system call with polling).
		 *
		 * This design pattern makes the controller also agnostic of the attitude
		 * update speed - it runs as fast as the attitude updates with minimal latency.
		 */
		int ret = poll(fds, 2, 500);

		if (ret < 0) {
			/*
			 * Poll error, this will not really happen in practice,
			 * but its good design practice to make output an error message.
			 */
			warnx("poll error");

		} else if (ret == 0) {
			/* no return value = nothing changed for 500 ms, ignore */
		} else {

			/* only update parameters if they changed */
			if (fds[0].revents & POLLIN) {
				/* read from param to clear updated flag (uORB API requirement) */
				struct parameter_update_s update;
				orb_copy(ORB_ID(parameter_update), param_sub, &update);

				/* if a param update occured, re-read our parameters */
				parameters_update(&ph, &pp);
			}

			/* only run controller if attitude changed */
			if (fds[1].revents & POLLIN) {

				/* Check if there is a new position measurement or position setpoint */
				bool pos_updated;
				orb_check(global_pos_sub, &pos_updated);
				bool att_sp_updated;
				orb_check(att_sp_sub, &att_sp_updated);
				bool manual_sp_updated;
				orb_check(manual_sp_sub, &manual_sp_updated);

				/* get a local copy of attitude */
				orb_copy(ORB_ID(vehicle_attitude), att_sub, &att);

				if (att_sp_updated) {
					orb_copy(ORB_ID(vehicle_attitude_setpoint), att_sp_sub, &_att_sp);
				}

				/* control attitude / heading */
				control_attitude(&_att_sp, &att, &actuators);

				if (manual_sp_updated)
					/* get the RC (or otherwise user based) input */
				{
					orb_copy(ORB_ID(manual_control_setpoint), manual_sp_sub, &manual_sp);
				}

				// XXX copy from manual depending on flight / usage mode to override

				/* get the system status and the flight mode we're in */
				orb_copy(ORB_ID(vehicle_status), vstatus_sub, &vstatus);

				/* sanity check and publish actuator outputs */
				if (PX4_ISFINITE(actuators.control[0]) &&
				    PX4_ISFINITE(actuators.control[1]) &&
				    PX4_ISFINITE(actuators.control[2]) &&
				    PX4_ISFINITE(actuators.control[3])) {
					orb_publish(ORB_ID_VEHICLE_ATTITUDE_CONTROLS, actuator_pub, &actuators);

					if (verbose) {
						warnx("published");
					}
				}
			}
		}
	}

	warnx("exiting, stopping all motors.");
	thread_running = false;

	/* kill all outputs */
	for (unsigned i = 0; i < (sizeof(actuators.control) / sizeof(actuators.control[0])); i++) {
		actuators.control[i] = 0.0f;
	}

	actuators.timestamp = hrt_absolute_time();

	orb_publish(ORB_ID_VEHICLE_ATTITUDE_CONTROLS, actuator_pub, &actuators);

	fflush(stdout);

	return 0;
}

/* Startup Functions */

static void
usage(const char *reason)
{
	if (reason) {
		fprintf(stderr, "%s\n", reason);
	}

	fprintf(stderr, "usage: rover_steering_control {start|stop|status}\n\n");
	exit(1);
}

/**
 * The daemon app only briefly exists to start
 * the background job. The stack size assigned in the
 * Makefile does only apply to this management task.
 *
 * The actual stack size should be set in the call
 * to px4_task_spawn_cmd().
 */
int rover_steering_control_main(int argc, char *argv[])
{
	if (argc < 2) {
		usage("missing command");
	}

	if (!strcmp(argv[1], "start")) {

		if (thread_running) {
			warnx("running");
			/* this is not an error */
			exit(0);
		}

		thread_should_exit = false;
		deamon_task = px4_task_spawn_cmd("rover_steering_control",
						 SCHED_DEFAULT,
						 SCHED_PRIORITY_MAX - 20,
						 2048,
						 rover_steering_control_thread_main,
						 (argv) ? (char *const *)&argv[2] : (char *const *)NULL);
		thread_running = true;
		exit(0);
	}

	if (!strcmp(argv[1], "stop")) {
		thread_should_exit = true;
		exit(0);
	}

	if (!strcmp(argv[1], "status")) {
		if (thread_running) {
			warnx("running");

		} else {
			warnx("not started");
		}

		exit(0);
	}

	usage("unrecognized command");
	exit(1);
}

<|endoftext|>


<commit_before>/*
* Copyright (c) 2021, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
* See full license text in LICENSE file at top of project tree
*/

#include <map>
#include <vector>
#include <string>
#include <memory>
#include "I18N.h"

// Russian localization file

namespace i2p
{
namespace i18n
{
namespace russian // language
{
	// See for language plural forms here:
	// https://localization-guide.readthedocs.io/en/latest/l10n/pluralforms.html
	static int plural (int n) {
		return n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;
	}

	static std::map<std::string, std::string> strings
	{
		// HTTP Proxy
		{"Proxy error", "Ошибка прокси"},
		{"Proxy info", "Информация прокси"},
		{"Proxy error: Host not found", "Ошибка прокси: Адрес не найден"},
		{"Remote host not found in router's addressbook", "Запрошенный адрес не найден в адресной книге роутера"},
		{"You may try to find this host on jump services below", "Вы можете попробовать найти адрес на джамп сервисах ниже"},
		{"Invalid request", "Некорректный запрос"},
		{"Proxy unable to parse your request", "Прокси не может разобрать ваш запрос"},
		{"addresshelper is not supported", "addresshelper не поддерживается"},
		{"Host", "Адрес"},
		{"added to router's addressbook from helper", "добавлен в адресную книгу роутера через хелпер"},
		{"already in router's addressbook", "уже в адресной книге роутера"},
		{"Click", "Нажмите"},
		{"here", "здесь"},
		{"to proceed", "чтобы продолжить"},
		{"to update record", "чтобы обновить запись"},
		{"Addresshelper found", "Найден addresshelper"},
		{"invalid request uri", "некорректный URI запроса"},
		{"Can't detect destination host from request", "Не удалось определить адрес назначения из запроса"},
		{"Outproxy failure", "Ошибка внешнего прокси"},
		{"bad outproxy settings", "некорректные настройки внешнего прокси"},
		{"not inside I2P network, but outproxy is not enabled", "не в I2P сети, но внешний прокси не включен"},
		{"unknown outproxy url", "неизвестный URL внешнего прокси"},
		{"cannot resolve upstream proxy", "не удается определить вышестоящий прокси"},
		{"hostname too long", "имя хоста слишком длинное"},
		{"cannot connect to upstream socks proxy", "не удается подключиться к вышестоящему SOCKS прокси"},
		{"Cannot negotiate with socks proxy", "Не удается договориться с вышестоящим SOCKS прокси"},
		{"CONNECT error", "Ошибка CONNECT запроса"},
		{"Failed to Connect", "Не удалось подключиться"},
		{"socks proxy error", "ошибка SOCKS прокси"},
		{"failed to send request to upstream", "не удалось отправить запрос вышестоящему прокси"},
		{"No Reply From socks proxy", "Нет ответа от SOCKS прокси сервера"},
		{"cannot connect", "не удалось подключиться"},
		{"http out proxy not implemented", "поддержка внешнего HTTP прокси сервера не реализована"},
		{"cannot connect to upstream http proxy", "не удалось подключиться к вышестоящему HTTP прокси серверу"},
		{"Host is down", "Адрес недоступен"},
		{"Can't create connection to requested host, it may be down. Please try again later.",
			"Не удалось установить соединение к запрошенному адресу, возможно он не в сети. Попробуйте повторить запрос позже."},

		// Webconsole //
		// cssStyles
		{"Disabled", "Выключено"},
		{"Enabled", "Включено"},
		// ShowTraffic
		{"KiB", "КиБ"},
		{"MiB", "МиБ"},
		{"GiB", "ГиБ"},
		// ShowTunnelDetails
		{"building", "строится"},
		{"failed", "неудачный"},
		{"expiring", "истекает"},
		{"established", "работает"},
		{"exploratory", "исследовательский"},
		{"unknown", "неизвестно"},
		{"i2pd webconsole", "Веб-консоль i2pd"},
		// ShowPageHead
		{"Main page", "Главная"},
		{"Router commands", "Команды роутера"},
		{"Local destinations", "Локальные назнач."},
		{"LeaseSets", "Лизсеты"},
		{"Tunnels", "Туннели"},
		{"Transit tunnels", "Транзит. туннели"},
		{"Transports", "Транспорты"},
		{"I2P tunnels", "I2P туннели"},
		{"SAM sessions", "SAM сессии"},
		// Network Status
		{"OK", "OK"},
		{"Testing", "Тестирование"},
		{"Firewalled", "Файрвол"},
		{"Unknown", "Неизвестно"},
		{"Proxy", "Прокси"},
		{"Mesh", "MESH-сеть"},
		{"Error", "Ошибка"},
		{"Clock skew", "Не точное время"},
		{"Offline", "Оффлайн"},
		{"Symmetric NAT", "Симметричный NAT"},
		// Status
		{"Uptime", "В сети"},
		{"Network status", "Сетевой статус"},
		{"Network status v6", "Сетевой статус v6"},
		{"Stopping in", "Остановка через"},
		{"Family", "Семейство"},
		{"Tunnel creation success rate", "Успешно построенных туннелей"},
		{"Received", "Получено"},
		{"Sent", "Отправлено"},
		{"Transit", "Транзит"},
		{"KiB/s", "КиБ/с"},
		{"Data path", "Путь к данным"},
		{"Hidden content. Press on text to see.", "Скрытый контент. Нажмите на текст чтобы отобразить."},
		{"Router Ident", "Идентификатор роутера"},
		{"Router Family", "Семейство роутера"},
		{"Router Caps", "Флаги роутера"},
		{"Version", "Версия"},
		{"Our external address", "Наш внешний адрес"},
		{"supported", "поддерживается"},
		{"Routers", "Роутеры"},
		{"Floodfills", "Флудфилы"},
		{"LeaseSets", "Лизсеты"},
		{"Client Tunnels", "Клиентские туннели"},
		{"Transit Tunnels", "Транзитные туннели"},
		{"Services", "Сервисы"},
		// ShowLocalDestinations
		{"Local Destinations", "Локальные назначения"},
		// ShowLeaseSetDestination
		{"Encrypted B33 address", "Шифрованные B33 адреса"},
		{"Address registration line", "Строка регистрации адреса"},
		{"Domain", "Домен"},
		{"Generate", "Сгенерировать"},
		{"Note: result string can be used only for registering 2LD domains (example.i2p). For registering subdomains please use i2pd-tools.",
			"Примечание: полученная строка может быть использована только для регистрации доменов второго уровня. Для регистрации поддоменов используйте i2pd-tools."},
		{"Address", "Адрес"},
		{"Type", "Тип"},
		{"EncType", "ТипШифр"},
		{"Inbound tunnels", "Входящие туннели"},
		{"Outbound tunnels", "Исходящие туннели"},
		{"ms", "мс"}, // milliseconds
		{"Tags", "Теги"},
		{"Incoming", "Входящие"},
		{"Outgoing", "Исходящие"},
		{"Destination", "Назначение"},
		{"Amount", "Количество"},
		{"Incoming Tags", "Входящие Теги"},
		{"Tags sessions", "Сессии Тегов"},
		{"Status", "Статус"},
		// ShowLocalDestination
		{"Local Destination", "Локальное назначение"},
		{"Streams", "Стримы"},
		{"Close stream", "Закрыть стрим"},
		// ShowI2CPLocalDestination
		{"I2CP session not found", "I2CP сессия не найдена"},
		{"I2CP is not enabled", "I2CP не включен"},
		// ShowLeasesSets
		{"Invalid", "Некорректный"},
		{"Store type", "Тип хранилища"},
		{"Expires", "Истекает"},
		{"Non Expired Leases", "Не истекшие Lease-ы"},
		{"Gateway", "Шлюз"},
		{"TunnelID", "ID туннеля"},
		{"EndDate", "Заканчивается"},
		{"not floodfill", "не флудфил"},
		// ShowTunnels
		{"Queue size", "Размер очереди"},
		// ShowCommands
		{"Run peer test", "Запустить тестирование"},
		{"Decline transit tunnels", "Отклонять транзитные туннели"},
		{"Accept transit tunnels", "Принимать транзитные туннели"},
		{"Cancel graceful shutdown", "Отменить плавную остановку"},
		{"Start graceful shutdown", "Запустить плавную остановку"},
		{"Force shutdown", "Принудительная остановка"},
		{"Note: any action done here are not persistent and not changes your config files.",
			"Примечание: любое действие произведенное здесь не является постоянным и не изменяет ваши конфигурационные файлы."},
		{"Logging level", "Уровень логирования"},
		{"Transit tunnels limit", "Лимит транзитных туннелей"},
		{"Change", "Изменить"},
		// ShowTransitTunnels
		{"no transit tunnels currently built", "нет построенных транзитных туннелей"},
		// ShowSAMSessions/ShowSAMSession
		{"SAM disabled", "SAM выключен"},
		{"SAM session not found", "SAM сессия не найдена"},
		{"no sessions currently running", "нет запущенных сессий"},
		{"SAM Session", "SAM сессия"},
		// ShowI2PTunnels
		{"Server Tunnels", "Серверные туннели"},
		{"Client Forwards", "Клиентские перенаправления"},
		{"Server Forwards", "Серверные перенаправления"},
		// HandlePage
		{"Unknown page", "Неизвестная страница"},
		// HandleCommand, ShowError
		{"Invalid token", "Неверный токен"},
		{"SUCCESS", "УСПЕШНО"},
		{"ERROR", "ОШИБКА"},
		{"Unknown command", "Неизвестная команда"},
		{"Command accepted", "Команда принята"},
		{"Back to commands list", "Вернуться к списку команд"},
		{"You will be redirected in 5 seconds", "Вы будете переадресованы через 5 секунд"},
		// HTTP_COMMAND_KILLSTREAM
		{"Stream closed", "Стрим закрыт"},
		{"Stream not found or already was closed", "Стрим не найден или уже закрыт"},
		{"Destination not found", "Точка назначения не найдена"},
		{"StreamID can't be null", "StreamID не может быть пустым"},
		{"Return to destination page", "Вернуться на страницу точки назначения"},
		{"You will be redirected back in 5 seconds", "Вы будете переадресованы назад через 5 секунд"},
		// HTTP_COMMAND_LIMITTRANSIT
		{"Transit tunnels count must not exceed 65535", "Число транзитных туннелей не должно превышать 65535"},
		// HTTP_COMMAND_GET_REG_STRING
		{"Register at reg.i2p", "Зарегистрировать на reg.i2p"},
		{"Description", "Описание"},
		{"A bit information about service on domain", "Немного информации о сервисе на домене"},
		{"Submit", "Отправить"},
		{"Domain can't end with .b32.i2p", "Домен не может заканчиваться на .b32.i2p"},
		{"Domain must end with .i2p", "Домен должен заканчиваться на .i2p"},
		{"Such destination is not found", "Такая точка назначения не найдена"},
		{"", ""},
	};

	static std::map<std::string, std::vector<std::string>> plurals
	{
		// ShowUptime
		{"days",    {"день", "дня", "дней"}},
		{"hours",   {"час", "часа", "часов"}},
		{"minutes", {"минуту", "минуты", "минут"}},
		{"seconds", {"секунду", "секунды", "секунд"}},
		{"", {"", "", ""}},
	};

	std::shared_ptr<const i2p::i18n::Locale> GetLocale()
	{
		return std::make_shared<i2p::i18n::Locale>(strings, plurals, [] (int n)->int { return plural(n); });
	}

} // language
} // i18n
} // i2p
<commit_msg>Correct transaltion for "Firewalled"<commit_after>/*
* Copyright (c) 2021, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
* See full license text in LICENSE file at top of project tree
*/

#include <map>
#include <vector>
#include <string>
#include <memory>
#include "I18N.h"

// Russian localization file

namespace i2p
{
namespace i18n
{
namespace russian // language
{
	// See for language plural forms here:
	// https://localization-guide.readthedocs.io/en/latest/l10n/pluralforms.html
	static int plural (int n) {
		return n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;
	}

	static std::map<std::string, std::string> strings
	{
		// HTTP Proxy
		{"Proxy error", "Ошибка прокси"},
		{"Proxy info", "Информация прокси"},
		{"Proxy error: Host not found", "Ошибка прокси: Адрес не найден"},
		{"Remote host not found in router's addressbook", "Запрошенный адрес не найден в адресной книге роутера"},
		{"You may try to find this host on jump services below", "Вы можете попробовать найти адрес на джамп сервисах ниже"},
		{"Invalid request", "Некорректный запрос"},
		{"Proxy unable to parse your request", "Прокси не может разобрать ваш запрос"},
		{"addresshelper is not supported", "addresshelper не поддерживается"},
		{"Host", "Адрес"},
		{"added to router's addressbook from helper", "добавлен в адресную книгу роутера через хелпер"},
		{"already in router's addressbook", "уже в адресной книге роутера"},
		{"Click", "Нажмите"},
		{"here", "здесь"},
		{"to proceed", "чтобы продолжить"},
		{"to update record", "чтобы обновить запись"},
		{"Addresshelper found", "Найден addresshelper"},
		{"invalid request uri", "некорректный URI запроса"},
		{"Can't detect destination host from request", "Не удалось определить адрес назначения из запроса"},
		{"Outproxy failure", "Ошибка внешнего прокси"},
		{"bad outproxy settings", "некорректные настройки внешнего прокси"},
		{"not inside I2P network, but outproxy is not enabled", "не в I2P сети, но внешний прокси не включен"},
		{"unknown outproxy url", "неизвестный URL внешнего прокси"},
		{"cannot resolve upstream proxy", "не удается определить вышестоящий прокси"},
		{"hostname too long", "имя хоста слишком длинное"},
		{"cannot connect to upstream socks proxy", "не удается подключиться к вышестоящему SOCKS прокси"},
		{"Cannot negotiate with socks proxy", "Не удается договориться с вышестоящим SOCKS прокси"},
		{"CONNECT error", "Ошибка CONNECT запроса"},
		{"Failed to Connect", "Не удалось подключиться"},
		{"socks proxy error", "ошибка SOCKS прокси"},
		{"failed to send request to upstream", "не удалось отправить запрос вышестоящему прокси"},
		{"No Reply From socks proxy", "Нет ответа от SOCKS прокси сервера"},
		{"cannot connect", "не удалось подключиться"},
		{"http out proxy not implemented", "поддержка внешнего HTTP прокси сервера не реализована"},
		{"cannot connect to upstream http proxy", "не удалось подключиться к вышестоящему HTTP прокси серверу"},
		{"Host is down", "Адрес недоступен"},
		{"Can't create connection to requested host, it may be down. Please try again later.",
			"Не удалось установить соединение к запрошенному адресу, возможно он не в сети. Попробуйте повторить запрос позже."},

		// Webconsole //
		// cssStyles
		{"Disabled", "Выключено"},
		{"Enabled", "Включено"},
		// ShowTraffic
		{"KiB", "КиБ"},
		{"MiB", "МиБ"},
		{"GiB", "ГиБ"},
		// ShowTunnelDetails
		{"building", "строится"},
		{"failed", "неудачный"},
		{"expiring", "истекает"},
		{"established", "работает"},
		{"exploratory", "исследовательский"},
		{"unknown", "неизвестно"},
		{"i2pd webconsole", "Веб-консоль i2pd"},
		// ShowPageHead
		{"Main page", "Главная"},
		{"Router commands", "Команды роутера"},
		{"Local destinations", "Локальные назнач."},
		{"LeaseSets", "Лизсеты"},
		{"Tunnels", "Туннели"},
		{"Transit tunnels", "Транзит. туннели"},
		{"Transports", "Транспорты"},
		{"I2P tunnels", "I2P туннели"},
		{"SAM sessions", "SAM сессии"},
		// Network Status
		{"OK", "OK"},
		{"Testing", "Тестирование"},
		{"Firewalled", "Заблокировано извне"},
		{"Unknown", "Неизвестно"},
		{"Proxy", "Прокси"},
		{"Mesh", "MESH-сеть"},
		{"Error", "Ошибка"},
		{"Clock skew", "Не точное время"},
		{"Offline", "Оффлайн"},
		{"Symmetric NAT", "Симметричный NAT"},
		// Status
		{"Uptime", "В сети"},
		{"Network status", "Сетевой статус"},
		{"Network status v6", "Сетевой статус v6"},
		{"Stopping in", "Остановка через"},
		{"Family", "Семейство"},
		{"Tunnel creation success rate", "Успешно построенных туннелей"},
		{"Received", "Получено"},
		{"Sent", "Отправлено"},
		{"Transit", "Транзит"},
		{"KiB/s", "КиБ/с"},
		{"Data path", "Путь к данным"},
		{"Hidden content. Press on text to see.", "Скрытый контент. Нажмите на текст чтобы отобразить."},
		{"Router Ident", "Идентификатор роутера"},
		{"Router Family", "Семейство роутера"},
		{"Router Caps", "Флаги роутера"},
		{"Version", "Версия"},
		{"Our external address", "Наш внешний адрес"},
		{"supported", "поддерживается"},
		{"Routers", "Роутеры"},
		{"Floodfills", "Флудфилы"},
		{"LeaseSets", "Лизсеты"},
		{"Client Tunnels", "Клиентские туннели"},
		{"Transit Tunnels", "Транзитные туннели"},
		{"Services", "Сервисы"},
		// ShowLocalDestinations
		{"Local Destinations", "Локальные назначения"},
		// ShowLeaseSetDestination
		{"Encrypted B33 address", "Шифрованные B33 адреса"},
		{"Address registration line", "Строка регистрации адреса"},
		{"Domain", "Домен"},
		{"Generate", "Сгенерировать"},
		{"Note: result string can be used only for registering 2LD domains (example.i2p). For registering subdomains please use i2pd-tools.",
			"Примечание: полученная строка может быть использована только для регистрации доменов второго уровня. Для регистрации поддоменов используйте i2pd-tools."},
		{"Address", "Адрес"},
		{"Type", "Тип"},
		{"EncType", "ТипШифр"},
		{"Inbound tunnels", "Входящие туннели"},
		{"Outbound tunnels", "Исходящие туннели"},
		{"ms", "мс"}, // milliseconds
		{"Tags", "Теги"},
		{"Incoming", "Входящие"},
		{"Outgoing", "Исходящие"},
		{"Destination", "Назначение"},
		{"Amount", "Количество"},
		{"Incoming Tags", "Входящие Теги"},
		{"Tags sessions", "Сессии Тегов"},
		{"Status", "Статус"},
		// ShowLocalDestination
		{"Local Destination", "Локальное назначение"},
		{"Streams", "Стримы"},
		{"Close stream", "Закрыть стрим"},
		// ShowI2CPLocalDestination
		{"I2CP session not found", "I2CP сессия не найдена"},
		{"I2CP is not enabled", "I2CP не включен"},
		// ShowLeasesSets
		{"Invalid", "Некорректный"},
		{"Store type", "Тип хранилища"},
		{"Expires", "Истекает"},
		{"Non Expired Leases", "Не истекшие Lease-ы"},
		{"Gateway", "Шлюз"},
		{"TunnelID", "ID туннеля"},
		{"EndDate", "Заканчивается"},
		{"not floodfill", "не флудфил"},
		// ShowTunnels
		{"Queue size", "Размер очереди"},
		// ShowCommands
		{"Run peer test", "Запустить тестирование"},
		{"Decline transit tunnels", "Отклонять транзитные туннели"},
		{"Accept transit tunnels", "Принимать транзитные туннели"},
		{"Cancel graceful shutdown", "Отменить плавную остановку"},
		{"Start graceful shutdown", "Запустить плавную остановку"},
		{"Force shutdown", "Принудительная остановка"},
		{"Note: any action done here are not persistent and not changes your config files.",
			"Примечание: любое действие произведенное здесь не является постоянным и не изменяет ваши конфигурационные файлы."},
		{"Logging level", "Уровень логирования"},
		{"Transit tunnels limit", "Лимит транзитных туннелей"},
		{"Change", "Изменить"},
		// ShowTransitTunnels
		{"no transit tunnels currently built", "нет построенных транзитных туннелей"},
		// ShowSAMSessions/ShowSAMSession
		{"SAM disabled", "SAM выключен"},
		{"SAM session not found", "SAM сессия не найдена"},
		{"no sessions currently running", "нет запущенных сессий"},
		{"SAM Session", "SAM сессия"},
		// ShowI2PTunnels
		{"Server Tunnels", "Серверные туннели"},
		{"Client Forwards", "Клиентские перенаправления"},
		{"Server Forwards", "Серверные перенаправления"},
		// HandlePage
		{"Unknown page", "Неизвестная страница"},
		// HandleCommand, ShowError
		{"Invalid token", "Неверный токен"},
		{"SUCCESS", "УСПЕШНО"},
		{"ERROR", "ОШИБКА"},
		{"Unknown command", "Неизвестная команда"},
		{"Command accepted", "Команда принята"},
		{"Back to commands list", "Вернуться к списку команд"},
		{"You will be redirected in 5 seconds", "Вы будете переадресованы через 5 секунд"},
		// HTTP_COMMAND_KILLSTREAM
		{"Stream closed", "Стрим закрыт"},
		{"Stream not found or already was closed", "Стрим не найден или уже закрыт"},
		{"Destination not found", "Точка назначения не найдена"},
		{"StreamID can't be null", "StreamID не может быть пустым"},
		{"Return to destination page", "Вернуться на страницу точки назначения"},
		{"You will be redirected back in 5 seconds", "Вы будете переадресованы назад через 5 секунд"},
		// HTTP_COMMAND_LIMITTRANSIT
		{"Transit tunnels count must not exceed 65535", "Число транзитных туннелей не должно превышать 65535"},
		// HTTP_COMMAND_GET_REG_STRING
		{"Register at reg.i2p", "Зарегистрировать на reg.i2p"},
		{"Description", "Описание"},
		{"A bit information about service on domain", "Немного информации о сервисе на домене"},
		{"Submit", "Отправить"},
		{"Domain can't end with .b32.i2p", "Домен не может заканчиваться на .b32.i2p"},
		{"Domain must end with .i2p", "Домен должен заканчиваться на .i2p"},
		{"Such destination is not found", "Такая точка назначения не найдена"},
		{"", ""},
	};

	static std::map<std::string, std::vector<std::string>> plurals
	{
		// ShowUptime
		{"days",    {"день", "дня", "дней"}},
		{"hours",   {"час", "часа", "часов"}},
		{"minutes", {"минуту", "минуты", "минут"}},
		{"seconds", {"секунду", "секунды", "секунд"}},
		{"", {"", "", ""}},
	};

	std::shared_ptr<const i2p::i18n::Locale> GetLocale()
	{
		return std::make_shared<i2p::i18n::Locale>(strings, plurals, [] (int n)->int { return plural(n); });
	}

} // language
} // i18n
} // i2p
<|endoftext|>