<commit_before>// This file is part of the dune-stuff project:
//   https://github.com/wwu-numerik/dune-stuff/
// Copyright holders: Rene Milk, Felix Schindler
// License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)

#ifndef DUNE_STUFF_LA_CONTAINER_EIGEN_SPARSE_HH
#define DUNE_STUFF_LA_CONTAINER_EIGEN_SPARSE_HH

#include <memory>
#include <type_traits>
#include <vector>
#include <complex>

#include <boost/numeric/conversion/cast.hpp>

#include <dune/stuff/common/disable_warnings.hh>
# if HAVE_EIGEN
#   include <Eigen/SparseCore>
# endif
#include <dune/stuff/common/reenable_warnings.hh>

#include <dune/common/typetraits.hh>
#include <dune/common/ftraits.hh>

#include <dune/stuff/aliases.hh>
#include <dune/stuff/common/exceptions.hh>
#include <dune/stuff/common/crtp.hh>
#include <dune/stuff/common/float_cmp.hh>

#include "dune/stuff/la/container/interfaces.hh"
#include "dune/stuff/la/container/pattern.hh"

#include "dense.hh"

namespace Dune {
namespace Stuff {
namespace LA {

// forwards
template< class ScalarType >
class EigenRowMajorSparseMatrix;

class EigenMatrixInterfaceDynamic {};

#if HAVE_EIGEN

namespace internal {

/**
 * \brief Traits for EigenRowMajorSparseMatrix.
 */
template< class ScalarImp = double >
class EigenRowMajorSparseMatrixTraits
{
public:
  typedef typename Dune::FieldTraits< ScalarImp >::field_type             ScalarType;
  typedef typename Dune::FieldTraits< ScalarImp >::real_type              RealType;
  typedef EigenRowMajorSparseMatrix< ScalarType >                         derived_type;
  typedef typename ::Eigen::SparseMatrix< ScalarType, ::Eigen::RowMajor > BackendType;
}; // class RowMajorSparseMatrixTraits

} // namespace internal

/**
 * \brief A sparse matrix implementation of the MatrixInterface with row major memory layout.
 */
template< class ScalarImp = double >
class EigenRowMajorSparseMatrix
  : public MatrixInterface< internal::EigenRowMajorSparseMatrixTraits< ScalarImp >, ScalarImp >
  , public ProvidesBackend< internal::EigenRowMajorSparseMatrixTraits< ScalarImp > >
{
  typedef EigenRowMajorSparseMatrix< ScalarImp >                                              ThisType;
  typedef MatrixInterface< internal::EigenRowMajorSparseMatrixTraits< ScalarImp >,ScalarImp > MatrixInterfaceType;
  static_assert(!std::is_same< DUNE_STUFF_SSIZE_T, int >::value,
                "You have to manually disable the constructor below which uses DUNE_STUFF_SSIZE_T!");
public:
  typedef internal::EigenRowMajorSparseMatrixTraits< ScalarImp > Traits;
  typedef typename Traits::BackendType                           BackendType;
  typedef typename Traits::ScalarType                            ScalarType;
  typedef typename Traits::RealType                              RealType;

private:
  typedef typename BackendType::Index EIGEN_size_t;

public:
  /**
   * \brief This is the constructor of interest which creates a sparse matrix.
   */
  EigenRowMajorSparseMatrix(const size_t rr, const size_t cc, const SparsityPatternDefault& pattern)
  {
    backend_ = std::make_shared< BackendType >(internal::boost_numeric_cast< EIGEN_size_t >(rr),
                                               internal::boost_numeric_cast< EIGEN_size_t >(cc));
    if (rr > 0 && cc > 0) {
      if (size_t(pattern.size()) != rr)
        DUNE_THROW(Exceptions::shapes_do_not_match,
                   "The size of the pattern (" << pattern.size()
                   << ") does not match the number of rows of this (" << rr << ")!");
      for (size_t row = 0; row < size_t(pattern.size()); ++row) {
        backend_->startVec(internal::boost_numeric_cast< EIGEN_size_t >(row));
        const auto& columns = pattern.inner(row);
        for (auto& column : columns) {
#ifndef NDEBUG
          if (column >= cc)
            DUNE_THROW(Exceptions::shapes_do_not_match,
                       "The size of row " << row << " of the pattern does not match the number of columns of this ("
                       << cc << ")!");
#endif // NDEBUG
          backend_->insertBackByOuterInner(internal::boost_numeric_cast< EIGEN_size_t >(row),
                                           internal::boost_numeric_cast< EIGEN_size_t >(column));
        }
        // create entry (insertBackByOuterInner() can not handle empty rows)
        if (columns.size() == 0)
          backend_->insertBackByOuterInner(internal::boost_numeric_cast< EIGEN_size_t >(row), 0);
      }
      backend_->finalize();
      backend_->makeCompressed();
    }
  } // EigenRowMajorSparseMatrix(...)

  explicit EigenRowMajorSparseMatrix(const size_t rr = 0, const size_t cc = 0)
  {
    backend_ = std::make_shared<BackendType>(rr, cc);
  }

  /// This constructor is needed for the python bindings.
  explicit EigenRowMajorSparseMatrix(const DUNE_STUFF_SSIZE_T rr, const DUNE_STUFF_SSIZE_T cc = 0)
    : backend_(new BackendType(internal::boost_numeric_cast< EIGEN_size_t >(rr),
                               internal::boost_numeric_cast< EIGEN_size_t >(cc)))
  {}

  explicit EigenRowMajorSparseMatrix(const int rr, const int cc = 0)
    : backend_(new BackendType(internal::boost_numeric_cast< EIGEN_size_t >(rr),
                               internal::boost_numeric_cast< EIGEN_size_t >(cc)))
  {}

  EigenRowMajorSparseMatrix(const ThisType& other)
    : backend_(other.backend_)
  {}

  explicit EigenRowMajorSparseMatrix(const BackendType& other)
    : backend_(new BackendType(other))
  {}

  /**
   *  \note Takes ownership of backend_ptr in the sense that you must not delete it afterwards!
   */
  explicit EigenRowMajorSparseMatrix(BackendType* backend_ptr)
    : backend_(backend_ptr)
  {}

  explicit EigenRowMajorSparseMatrix(std::shared_ptr< BackendType > backend_ptr)
    : backend_(backend_ptr)
  {}

  ThisType& operator=(const ThisType& other)
  {
    backend_ = other.backend_;
    return *this;
  }

  /**
   *  \note Does a deep copy.
   */
  ThisType& operator=(const BackendType& other)
  {
    backend_ = std::make_shared< BackendType >(other);
    return *this;
  }

  /// \name Required by the ProvidesBackend interface.
  /// \{

  BackendType& backend()
  {
    ensure_uniqueness();
    return *backend_;
  }

  const BackendType& backend() const
  {
    ensure_uniqueness();
    return *backend_;
  }

  /// \}
  /// \name Required by ContainerInterface.
  /// \{

  ThisType copy() const
  {
    return ThisType(*backend_);
  }

  void scal(const ScalarType& alpha)
  {
    backend() *= alpha;
  } // ... scal(...)

  void axpy(const ScalarType& alpha, const ThisType& xx)
  {
    if (!has_equal_shape(xx))
      DUNE_THROW(Exceptions::shapes_do_not_match,
                 "The shape of xx (" << xx.rows() << "x" << xx.cols()
                 << ") does not match the shape of this (" << rows() << "x" << cols() << ")!");
    const auto& xx_ref= *(xx.backend_);
    backend() += alpha * xx_ref;
  } // ... axpy(...)

  bool has_equal_shape(const ThisType& other) const
  {
    return (rows() == other.rows()) && (cols() == other.cols());
  }

  /// \}
  /// \name Required by MatrixInterface.
  /// \{

  inline size_t rows() const
  {
    return backend_->rows();
  }

  inline size_t cols() const
  {
    return backend_->cols();
  }

  template< class T1, class T2 >
  inline void mv(const EigenBaseVector< T1, ScalarType >& xx, EigenBaseVector< T2, ScalarType >& yy) const
  {
    yy.backend().transpose() = backend_->operator*(*xx.backend_);
  }

  void add_to_entry(const size_t ii, const size_t jj, const ScalarType& value)
  {
    assert(these_are_valid_indices(ii, jj));
    backend().coeffRef(internal::boost_numeric_cast< EIGEN_size_t >(ii),
                       internal::boost_numeric_cast< EIGEN_size_t >(jj)) += value;
  }

  void set_entry(const size_t ii, const size_t jj, const ScalarType& value)
  {
    assert(these_are_valid_indices(ii, jj));
    backend().coeffRef(internal::boost_numeric_cast< EIGEN_size_t >(ii),
                       internal::boost_numeric_cast< EIGEN_size_t >(jj)) = value;
  }

  ScalarType get_entry(const size_t ii, const size_t jj) const
  {
    assert(ii < rows());
    assert(jj < cols());
    return backend_->coeff(internal::boost_numeric_cast< EIGEN_size_t >(ii),
                           internal::boost_numeric_cast< EIGEN_size_t >(jj));
  }

  void clear_row(const size_t ii)
  {
    if (ii >= rows())
      DUNE_THROW(Exceptions::index_out_of_range,
                 "Given ii (" << ii << ") is larger than the rows of this (" << rows() << ")!");
    backend().row(internal::boost_numeric_cast< EIGEN_size_t >(ii)) *= ScalarType(0);
  }

  void clear_col(const size_t jj)
  {
    if (jj >= cols())
      DUNE_THROW(Exceptions::index_out_of_range,
                 "Given jj (" << jj << ") is larger than the cols of this (" << cols() << ")!");
    ensure_uniqueness();
    for (size_t row = 0; internal::boost_numeric_cast< EIGEN_size_t >(row) < backend_->outerSize(); ++row) {
      for (typename BackendType::InnerIterator row_it(*backend_, internal::boost_numeric_cast< EIGEN_size_t >(row));
           row_it; ++row_it) {
        const size_t col = row_it.col();
        if (col == jj) {
          backend_->coeffRef(internal::boost_numeric_cast< EIGEN_size_t >(row),
                             internal::boost_numeric_cast< EIGEN_size_t >(jj)) = ScalarType(0);
          break;
        } else if (col > jj)
          break;
      }
    }
  } // ... clear_col(...)

  void unit_row(const size_t ii)
  {
    if (ii >= cols())
      DUNE_THROW(Exceptions::index_out_of_range,
                 "Given ii (" << ii << ") is larger than the cols of this (" << cols() << ")!");
    if (ii >= rows())
      DUNE_THROW(Exceptions::index_out_of_range,
                 "Given ii (" << ii << ") is larger than the rows of this (" << rows() << ")!");
    if (!these_are_valid_indices(ii, ii))
      DUNE_THROW(Exceptions::index_out_of_range,
                 "Diagonal entry (" << ii << ", " << ii << ") is not contained in the sparsity pattern!");
    backend().row(internal::boost_numeric_cast< EIGEN_size_t >(ii)) *= ScalarType(0);
    set_entry(ii, ii, ScalarType(1));
  } // ... unit_row(...)

  void unit_col(const size_t jj)
  {
    if (jj >= cols())
      DUNE_THROW(Exceptions::index_out_of_range,
                 "Given jj (" << jj << ") is larger than the cols of this (" << cols() << ")!");
    if (jj >= rows())
      DUNE_THROW(Exceptions::index_out_of_range,
                 "Given jj (" << jj << ") is larger than the rows of this (" << rows() << ")!");
    ensure_uniqueness();
    for (size_t row = 0; internal::boost_numeric_cast< EIGEN_size_t >(row) < backend_->outerSize(); ++row) {
      for (typename BackendType::InnerIterator row_it(*backend_, internal::boost_numeric_cast< EIGEN_size_t >(row));
           row_it; ++row_it) {
        const size_t col = row_it.col();
        if (col == jj) {
          if (col == row)
            backend_->coeffRef(internal::boost_numeric_cast< EIGEN_size_t >(row),
                               internal::boost_numeric_cast< EIGEN_size_t >(col)) = ScalarType(1);
          else
            backend_->coeffRef(internal::boost_numeric_cast< EIGEN_size_t >(row),
                               internal::boost_numeric_cast< EIGEN_size_t >(jj))  = ScalarType(0);
          break;
        } else if (col > jj)
          break;
      }
    }
  } // ... unit_col(...)

  bool valid() const
  {
    // serialize matrix (no copy done here)
    auto& non_const_ref = const_cast< BackendType& >(*backend_);
    return EigenMappedDenseVector< ScalarType >(non_const_ref.valuePtr(), non_const_ref.nonZeros()).valid();
  }

  /// \}

private:
  typedef typename BackendType::Index   IndexType;

  bool these_are_valid_indices(const size_t ii, const size_t jj) const
  {
    if (ii >= rows())
      return false;
    if (jj >= cols())
      return false;
    for (size_t row = ii; internal::boost_numeric_cast< EIGEN_size_t >(row) < backend_->outerSize(); ++row) {
      for (typename BackendType::InnerIterator row_it(*backend_, internal::boost_numeric_cast< EIGEN_size_t >(row));
           row_it; ++row_it) {
        const size_t col = row_it.col();
        if ((ii == row) && (jj == col))
          return true;
        else if ((row > ii) && (col > jj))
          return false;
      }
    }
    return false;
  } // ... these_are_valid_indices(...)

  inline void ensure_uniqueness() const
  {
    if (!backend_.unique())
      backend_ = std::make_shared< BackendType >(*backend_);
  } // ... ensure_uniqueness(...)

  mutable std::shared_ptr< BackendType > backend_;
}; // class EigenRowMajorSparseMatrix

#else // HAVE_EIGEN

template< class ScalarImp >
class EigenRowMajorSparseMatrix
{
  static_assert(AlwaysFalse< ScalarImp >::value, "You are missing Eigen!");
};

#endif // HAVE_EIGEN

} // namespace LA
namespace Common {

#if HAVE_EIGEN

template< class T >
struct MatrixAbstraction< LA::EigenRowMajorSparseMatrix< T > >
  : public LA::internal::MatrixAbstractionBase< LA::EigenRowMajorSparseMatrix< T > >
{};

#endif // HAVE_EIGEN

} // namespace Common
} // namespace Stuff
} // namespace Dune

#endif // DUNE_STUFF_LA_CONTAINER_EIGEN_SPARSE_HH
<commit_msg>[container.eigen.sparse] enable use of valid() for non-double data by iterating over non-zero entries, refs #52<commit_after>// This file is part of the dune-stuff project:
//   https://github.com/wwu-numerik/dune-stuff/
// Copyright holders: Rene Milk, Felix Schindler
// License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)

#ifndef DUNE_STUFF_LA_CONTAINER_EIGEN_SPARSE_HH
#define DUNE_STUFF_LA_CONTAINER_EIGEN_SPARSE_HH

#include <memory>
#include <type_traits>
#include <vector>
#include <complex>

#include <boost/numeric/conversion/cast.hpp>

#include <dune/stuff/common/disable_warnings.hh>
# if HAVE_EIGEN
#   include <Eigen/SparseCore>
# endif
#include <dune/stuff/common/reenable_warnings.hh>

#include <dune/common/typetraits.hh>
#include <dune/common/ftraits.hh>

#include <dune/stuff/aliases.hh>
#include <dune/stuff/common/exceptions.hh>
#include <dune/stuff/common/crtp.hh>
#include <dune/stuff/common/float_cmp.hh>

#include "dune/stuff/la/container/interfaces.hh"
#include "dune/stuff/la/container/pattern.hh"

#include "dense.hh"

namespace Dune {
namespace Stuff {
namespace LA {

// forwards
template< class ScalarType >
class EigenRowMajorSparseMatrix;

class EigenMatrixInterfaceDynamic {};

#if HAVE_EIGEN

namespace internal {

/**
 * \brief Traits for EigenRowMajorSparseMatrix.
 */
template< class ScalarImp = double >
class EigenRowMajorSparseMatrixTraits
{
public:
  typedef typename Dune::FieldTraits< ScalarImp >::field_type             ScalarType;
  typedef typename Dune::FieldTraits< ScalarImp >::real_type              RealType;
  typedef EigenRowMajorSparseMatrix< ScalarType >                         derived_type;
  typedef typename ::Eigen::SparseMatrix< ScalarType, ::Eigen::RowMajor > BackendType;
}; // class RowMajorSparseMatrixTraits

} // namespace internal

/**
 * \brief A sparse matrix implementation of the MatrixInterface with row major memory layout.
 */
template< class ScalarImp = double >
class EigenRowMajorSparseMatrix
  : public MatrixInterface< internal::EigenRowMajorSparseMatrixTraits< ScalarImp >, ScalarImp >
  , public ProvidesBackend< internal::EigenRowMajorSparseMatrixTraits< ScalarImp > >
{
  typedef EigenRowMajorSparseMatrix< ScalarImp >                                              ThisType;
  typedef MatrixInterface< internal::EigenRowMajorSparseMatrixTraits< ScalarImp >,ScalarImp > MatrixInterfaceType;
  static_assert(!std::is_same< DUNE_STUFF_SSIZE_T, int >::value,
                "You have to manually disable the constructor below which uses DUNE_STUFF_SSIZE_T!");
public:
  typedef internal::EigenRowMajorSparseMatrixTraits< ScalarImp > Traits;
  typedef typename Traits::BackendType                           BackendType;
  typedef typename Traits::ScalarType                            ScalarType;
  typedef typename Traits::RealType                              RealType;

private:
  typedef typename BackendType::Index EIGEN_size_t;

public:
  /**
   * \brief This is the constructor of interest which creates a sparse matrix.
   */
  EigenRowMajorSparseMatrix(const size_t rr, const size_t cc, const SparsityPatternDefault& pattern)
  {
    backend_ = std::make_shared< BackendType >(internal::boost_numeric_cast< EIGEN_size_t >(rr),
                                               internal::boost_numeric_cast< EIGEN_size_t >(cc));
    if (rr > 0 && cc > 0) {
      if (size_t(pattern.size()) != rr)
        DUNE_THROW(Exceptions::shapes_do_not_match,
                   "The size of the pattern (" << pattern.size()
                   << ") does not match the number of rows of this (" << rr << ")!");
      for (size_t row = 0; row < size_t(pattern.size()); ++row) {
        backend_->startVec(internal::boost_numeric_cast< EIGEN_size_t >(row));
        const auto& columns = pattern.inner(row);
        for (auto& column : columns) {
#ifndef NDEBUG
          if (column >= cc)
            DUNE_THROW(Exceptions::shapes_do_not_match,
                       "The size of row " << row << " of the pattern does not match the number of columns of this ("
                       << cc << ")!");
#endif // NDEBUG
          backend_->insertBackByOuterInner(internal::boost_numeric_cast< EIGEN_size_t >(row),
                                           internal::boost_numeric_cast< EIGEN_size_t >(column));
        }
        // create entry (insertBackByOuterInner() can not handle empty rows)
        if (columns.size() == 0)
          backend_->insertBackByOuterInner(internal::boost_numeric_cast< EIGEN_size_t >(row), 0);
      }
      backend_->finalize();
      backend_->makeCompressed();
    }
  } // EigenRowMajorSparseMatrix(...)

  explicit EigenRowMajorSparseMatrix(const size_t rr = 0, const size_t cc = 0)
  {
    backend_ = std::make_shared<BackendType>(rr, cc);
  }

  /// This constructor is needed for the python bindings.
  explicit EigenRowMajorSparseMatrix(const DUNE_STUFF_SSIZE_T rr, const DUNE_STUFF_SSIZE_T cc = 0)
    : backend_(new BackendType(internal::boost_numeric_cast< EIGEN_size_t >(rr),
                               internal::boost_numeric_cast< EIGEN_size_t >(cc)))
  {}

  explicit EigenRowMajorSparseMatrix(const int rr, const int cc = 0)
    : backend_(new BackendType(internal::boost_numeric_cast< EIGEN_size_t >(rr),
                               internal::boost_numeric_cast< EIGEN_size_t >(cc)))
  {}

  EigenRowMajorSparseMatrix(const ThisType& other)
    : backend_(other.backend_)
  {}

  explicit EigenRowMajorSparseMatrix(const BackendType& other)
    : backend_(new BackendType(other))
  {}

  /**
   *  \note Takes ownership of backend_ptr in the sense that you must not delete it afterwards!
   */
  explicit EigenRowMajorSparseMatrix(BackendType* backend_ptr)
    : backend_(backend_ptr)
  {}

  explicit EigenRowMajorSparseMatrix(std::shared_ptr< BackendType > backend_ptr)
    : backend_(backend_ptr)
  {}

  ThisType& operator=(const ThisType& other)
  {
    backend_ = other.backend_;
    return *this;
  }

  /**
   *  \note Does a deep copy.
   */
  ThisType& operator=(const BackendType& other)
  {
    backend_ = std::make_shared< BackendType >(other);
    return *this;
  }

  /// \name Required by the ProvidesBackend interface.
  /// \{

  BackendType& backend()
  {
    ensure_uniqueness();
    return *backend_;
  }

  const BackendType& backend() const
  {
    ensure_uniqueness();
    return *backend_;
  }

  /// \}
  /// \name Required by ContainerInterface.
  /// \{

  ThisType copy() const
  {
    return ThisType(*backend_);
  }

  void scal(const ScalarType& alpha)
  {
    backend() *= alpha;
  } // ... scal(...)

  void axpy(const ScalarType& alpha, const ThisType& xx)
  {
    if (!has_equal_shape(xx))
      DUNE_THROW(Exceptions::shapes_do_not_match,
                 "The shape of xx (" << xx.rows() << "x" << xx.cols()
                 << ") does not match the shape of this (" << rows() << "x" << cols() << ")!");
    const auto& xx_ref= *(xx.backend_);
    backend() += alpha * xx_ref;
  } // ... axpy(...)

  bool has_equal_shape(const ThisType& other) const
  {
    return (rows() == other.rows()) && (cols() == other.cols());
  }

  /// \}
  /// \name Required by MatrixInterface.
  /// \{

  inline size_t rows() const
  {
    return backend_->rows();
  }

  inline size_t cols() const
  {
    return backend_->cols();
  }

  template< class T1, class T2 >
  inline void mv(const EigenBaseVector< T1, ScalarType >& xx, EigenBaseVector< T2, ScalarType >& yy) const
  {
    yy.backend().transpose() = backend_->operator*(*xx.backend_);
  }

  void add_to_entry(const size_t ii, const size_t jj, const ScalarType& value)
  {
    assert(these_are_valid_indices(ii, jj));
    backend().coeffRef(internal::boost_numeric_cast< EIGEN_size_t >(ii),
                       internal::boost_numeric_cast< EIGEN_size_t >(jj)) += value;
  }

  void set_entry(const size_t ii, const size_t jj, const ScalarType& value)
  {
    assert(these_are_valid_indices(ii, jj));
    backend().coeffRef(internal::boost_numeric_cast< EIGEN_size_t >(ii),
                       internal::boost_numeric_cast< EIGEN_size_t >(jj)) = value;
  }

  ScalarType get_entry(const size_t ii, const size_t jj) const
  {
    assert(ii < rows());
    assert(jj < cols());
    return backend_->coeff(internal::boost_numeric_cast< EIGEN_size_t >(ii),
                           internal::boost_numeric_cast< EIGEN_size_t >(jj));
  }

  void clear_row(const size_t ii)
  {
    if (ii >= rows())
      DUNE_THROW(Exceptions::index_out_of_range,
                 "Given ii (" << ii << ") is larger than the rows of this (" << rows() << ")!");
    backend().row(internal::boost_numeric_cast< EIGEN_size_t >(ii)) *= ScalarType(0);
  }

  void clear_col(const size_t jj)
  {
    if (jj >= cols())
      DUNE_THROW(Exceptions::index_out_of_range,
                 "Given jj (" << jj << ") is larger than the cols of this (" << cols() << ")!");
    ensure_uniqueness();
    for (size_t row = 0; internal::boost_numeric_cast< EIGEN_size_t >(row) < backend_->outerSize(); ++row) {
      for (typename BackendType::InnerIterator row_it(*backend_, internal::boost_numeric_cast< EIGEN_size_t >(row));
           row_it; ++row_it) {
        const size_t col = row_it.col();
        if (col == jj) {
          backend_->coeffRef(internal::boost_numeric_cast< EIGEN_size_t >(row),
                             internal::boost_numeric_cast< EIGEN_size_t >(jj)) = ScalarType(0);
          break;
        } else if (col > jj)
          break;
      }
    }
  } // ... clear_col(...)

  void unit_row(const size_t ii)
  {
    if (ii >= cols())
      DUNE_THROW(Exceptions::index_out_of_range,
                 "Given ii (" << ii << ") is larger than the cols of this (" << cols() << ")!");
    if (ii >= rows())
      DUNE_THROW(Exceptions::index_out_of_range,
                 "Given ii (" << ii << ") is larger than the rows of this (" << rows() << ")!");
    if (!these_are_valid_indices(ii, ii))
      DUNE_THROW(Exceptions::index_out_of_range,
                 "Diagonal entry (" << ii << ", " << ii << ") is not contained in the sparsity pattern!");
    backend().row(internal::boost_numeric_cast< EIGEN_size_t >(ii)) *= ScalarType(0);
    set_entry(ii, ii, ScalarType(1));
  } // ... unit_row(...)

  void unit_col(const size_t jj)
  {
    if (jj >= cols())
      DUNE_THROW(Exceptions::index_out_of_range,
                 "Given jj (" << jj << ") is larger than the cols of this (" << cols() << ")!");
    if (jj >= rows())
      DUNE_THROW(Exceptions::index_out_of_range,
                 "Given jj (" << jj << ") is larger than the rows of this (" << rows() << ")!");
    ensure_uniqueness();
    for (size_t row = 0; internal::boost_numeric_cast< EIGEN_size_t >(row) < backend_->outerSize(); ++row) {
      for (typename BackendType::InnerIterator row_it(*backend_, internal::boost_numeric_cast< EIGEN_size_t >(row));
           row_it; ++row_it) {
        const size_t col = row_it.col();
        if (col == jj) {
          if (col == row)
            backend_->coeffRef(internal::boost_numeric_cast< EIGEN_size_t >(row),
                               internal::boost_numeric_cast< EIGEN_size_t >(col)) = ScalarType(1);
          else
            backend_->coeffRef(internal::boost_numeric_cast< EIGEN_size_t >(row),
                               internal::boost_numeric_cast< EIGEN_size_t >(jj))  = ScalarType(0);
          break;
        } else if (col > jj)
          break;
      }
    }
  } // ... unit_col(...)

  bool valid() const
  {
    // iterate over non-zero entries
    typedef typename BackendType::InnerIterator InnerIterator;
    for (EIGEN_size_t ii = 0; ii < backend_->outerSize(); ++ii) {
      for (InnerIterator it(*backend_, ii); it; ++it) {
        if (std::isnan(std::real(it.value())) || std::isnan(std::imag(it.value())) || std::isinf(std::abs(it.value())))
          return false;
      }
    }
    return true;
  }

  /// \}

private:
  typedef typename BackendType::Index   IndexType;

  bool these_are_valid_indices(const size_t ii, const size_t jj) const
  {
    if (ii >= rows())
      return false;
    if (jj >= cols())
      return false;
    for (size_t row = ii; internal::boost_numeric_cast< EIGEN_size_t >(row) < backend_->outerSize(); ++row) {
      for (typename BackendType::InnerIterator row_it(*backend_, internal::boost_numeric_cast< EIGEN_size_t >(row));
           row_it; ++row_it) {
        const size_t col = row_it.col();
        if ((ii == row) && (jj == col))
          return true;
        else if ((row > ii) && (col > jj))
          return false;
      }
    }
    return false;
  } // ... these_are_valid_indices(...)

  inline void ensure_uniqueness() const
  {
    if (!backend_.unique())
      backend_ = std::make_shared< BackendType >(*backend_);
  } // ... ensure_uniqueness(...)

  mutable std::shared_ptr< BackendType > backend_;
}; // class EigenRowMajorSparseMatrix

#else // HAVE_EIGEN

template< class ScalarImp >
class EigenRowMajorSparseMatrix
{
  static_assert(AlwaysFalse< ScalarImp >::value, "You are missing Eigen!");
};

#endif // HAVE_EIGEN

} // namespace LA
namespace Common {

#if HAVE_EIGEN

template< class T >
struct MatrixAbstraction< LA::EigenRowMajorSparseMatrix< T > >
  : public LA::internal::MatrixAbstractionBase< LA::EigenRowMajorSparseMatrix< T > >
{};

#endif // HAVE_EIGEN

} // namespace Common
} // namespace Stuff
} // namespace Dune

#endif // DUNE_STUFF_LA_CONTAINER_EIGEN_SPARSE_HH
<|endoftext|>


<commit_before>/***********************************************************************************************************************
 * LoopStatement.cpp
 *
 *  Created on: Jan 31, 2011
 *      Author: Dimitar Asenov
 **********************************************************************************************************************/

#include "statements/LoopStatement.h"

namespace OOModel {

EXTENDABLENODE_DEFINE_EMPTY_CONSTRUCTORS(LoopStatement, Statement)
EXTENDABLENODE_DEFINE_TYPE_REGISTRATION_METHODS(LoopStatement, Statement)

REGISTER_ATTRIBUTE(LoopStatement, condition, Expression, false, false, true)
REGISTER_ATTRIBUTE(LoopStatement, initStep, Statement, false, true, true)
REGISTER_ATTRIBUTE(LoopStatement, updateStep, Statement, false, true, true)
REGISTER_ATTRIBUTE(LoopStatement, body, Statement, false, false, true)

}
<commit_msg>CHANGED: A loop's condition is now optional<commit_after>/***********************************************************************************************************************
 * LoopStatement.cpp
 *
 *  Created on: Jan 31, 2011
 *      Author: Dimitar Asenov
 **********************************************************************************************************************/

#include "statements/LoopStatement.h"

namespace OOModel {

EXTENDABLENODE_DEFINE_EMPTY_CONSTRUCTORS(LoopStatement, Statement)
EXTENDABLENODE_DEFINE_TYPE_REGISTRATION_METHODS(LoopStatement, Statement)

REGISTER_ATTRIBUTE(LoopStatement, condition, Expression, false, true, true)
REGISTER_ATTRIBUTE(LoopStatement, initStep, Statement, false, true, true)
REGISTER_ATTRIBUTE(LoopStatement, updateStep, Statement, false, true, true)
REGISTER_ATTRIBUTE(LoopStatement, body, Statement, false, false, true)

}
<|endoftext|>


<commit_before>#include "store-api.hh"
#include "globals.hh"
#include "util.hh"

namespace nix {

bool isInStore(const Path & path)
{
    return isInDir(path, settings.nixStore);
}

bool isStorePath(const Path & path)
{
    return isInStore(path)
        && path.find('/', settings.nixStore.size() + 1) == Path::npos;
}

void assertStorePath(const Path & path)
{
    if (!isStorePath(path))
        throw Error(format("path ‘%1%’ is not in the Nix store") % path);
}

Path toStorePath(const Path & path)
{
    if (!isInStore(path))
        throw Error(format("path ‘%1%’ is not in the Nix store") % path);
    Path::size_type slash = path.find('/', settings.nixStore.size() + 1);
    if (slash == Path::npos)
        return path;
    else
        return Path(path, 0, slash);
}

Path followLinksToStore(const Path & _path)
{
    Path path = absPath(_path);
    while (!isInStore(path)) {
        if (!isLink(path)) break;
        string target = readLink(path);
        path = absPath(target, dirOf(path));
    }
    if (!isInStore(path))
        throw Error(format("path ‘%1%’ is not in the Nix store") % path);
    return path;
}

Path followLinksToStorePath(const Path & path)
{
    return toStorePath(followLinksToStore(path));
}

string storePathToName(const Path & path)
{
    assertStorePath(path);
    return string(path, settings.nixStore.size() + storePathHashLen + 2);
}

string storePathToHash(const Path & path)
{
    assertStorePath(path);
    return string(path, settings.nixStore.size() + 1, storePathHashLen);
}

void checkStoreName(const string & name)
{
    string validChars = "+-._?=";
    /* Disallow names starting with a dot for possible security
       reasons (e.g., "." and ".."). */
    if (string(name, 0, 1) == ".")
        throw Error(format("illegal name: ‘%1%’") % name);
    for (auto & i : name)
        if (!((i >= 'A' && i <= 'Z') ||
              (i >= 'a' && i <= 'z') ||
              (i >= '0' && i <= '9') ||
              validChars.find(i) != string::npos))
        {
            throw Error(format("invalid character ‘%1%’ in name ‘%2%’")
                % i % name);
        }
}

/* Store paths have the following form:

   <store>/<h>-<name>

   where

   <store> = the location of the Nix store, usually /nix/store

   <name> = a human readable name for the path, typically obtained
     from the name attribute of the derivation, or the name of the
     source file from which the store path is created.  For derivation
     outputs other than the default "out" output, the string "-<id>"
     is suffixed to <name>.

   <h> = base-32 representation of the first 160 bits of a SHA-256
     hash of <s>; the hash part of the store name

   <s> = the string "<type>:sha256:<h2>:<store>:<name>";
     note that it includes the location of the store as well as the
     name to make sure that changes to either of those are reflected
     in the hash (e.g. you won't get /nix/store/<h>-name1 and
     /nix/store/<h>-name2 with equal hash parts).

   <type> = one of:
     "text:<r1>:<r2>:...<rN>"
       for plain text files written to the store using
       addTextToStore(); <r1> ... <rN> are the references of the
       path.
     "source"
       for paths copied to the store using addToStore() when recursive
       = true and hashAlgo = "sha256"
     "output:<id>"
       for either the outputs created by derivations, OR paths copied
       to the store using addToStore() with recursive != true or
       hashAlgo != "sha256" (in that case "source" is used; it's
       silly, but it's done that way for compatibility).  <id> is the
       name of the output (usually, "out").

   <h2> = base-16 representation of a SHA-256 hash of:
     if <type> = "text:...":
       the string written to the resulting store path
     if <type> = "source":
       the serialisation of the path from which this store path is
       copied, as returned by hashPath()
     if <type> = "output:out":
       for non-fixed derivation outputs:
         the derivation (see hashDerivationModulo() in
         primops.cc)
       for paths copied by addToStore() or produced by fixed-output
       derivations:
         the string "fixed:out:<rec><algo>:<hash>:", where
           <rec> = "r:" for recursive (path) hashes, or "" or flat
             (file) hashes
           <algo> = "md5", "sha1" or "sha256"
           <hash> = base-16 representation of the path or flat hash of
             the contents of the path (or expected contents of the
             path for fixed-output derivations)

   It would have been nicer to handle fixed-output derivations under
   "source", e.g. have something like "source:<rec><algo>", but we're
   stuck with this for now...

   The main reason for this way of computing names is to prevent name
   collisions (for security).  For instance, it shouldn't be feasible
   to come up with a derivation whose output path collides with the
   path for a copied source.  The former would have a <s> starting with
   "output:out:", while the latter would have a <2> starting with
   "source:".
*/

Path makeStorePath(const string & type,
    const Hash & hash, const string & name)
{
    /* e.g., "source:sha256:1abc...:/nix/store:foo.tar.gz" */
    string s = type + ":sha256:" + printHash(hash) + ":"
        + settings.nixStore + ":" + name;

    checkStoreName(name);

    return settings.nixStore + "/"
        + printHash32(compressHash(hashString(htSHA256, s), 20))
        + "-" + name;
}

Path makeOutputPath(const string & id,
    const Hash & hash, const string & name)
{
    return makeStorePath("output:" + id, hash,
        name + (id == "out" ? "" : "-" + id));
}

Path makeFixedOutputPath(bool recursive,
    HashType hashAlgo, Hash hash, string name)
{
    return hashAlgo == htSHA256 && recursive
        ? makeStorePath("source", hash, name)
        : makeStorePath("output:out", hashString(htSHA256,
                "fixed:out:" + (recursive ? (string) "r:" : "") +
                printHashType(hashAlgo) + ":" + printHash(hash) + ":"),
            name);
}

std::pair<Path, Hash> computeStorePathForPath(const Path & srcPath,
    bool recursive, HashType hashAlgo, PathFilter & filter)
{
    HashType ht(hashAlgo);
    Hash h = recursive ? hashPath(ht, srcPath, filter).first : hashFile(ht, srcPath);
    string name = baseNameOf(srcPath);
    Path dstPath = makeFixedOutputPath(recursive, hashAlgo, h, name);
    return std::pair<Path, Hash>(dstPath, h);
}

Path computeStorePathForText(const string & name, const string & s,
    const PathSet & references)
{
    Hash hash = hashString(htSHA256, s);
    /* Stuff the references (if any) into the type.  This is a bit
       hacky, but we can't put them in `s' since that would be
       ambiguous. */
    string type = "text";
    for (auto & i : references) {
        type += ":";
        type += i;
    }
    return makeStorePath(type, hash, name);
}

void Store::queryReferences(const Path & path, PathSet & references)
{
    ValidPathInfo info = queryPathInfo(path);
    references.insert(info.references.begin(), info.references.end());
}

/* Return a string accepted by decodeValidPathInfo() that
   registers the specified paths as valid.  Note: it's the
   responsibility of the caller to provide a closure. */
string Store::makeValidityRegistration(const PathSet & paths,
    bool showDerivers, bool showHash)
{
    string s = "";

    for (auto & i : paths) {
        s += i + "\n";

        ValidPathInfo info = queryPathInfo(i);

        if (showHash) {
            s += printHash(info.narHash) + "\n";
            s += (format("%1%\n") % info.narSize).str();
        }

        Path deriver = showDerivers ? info.deriver : "";
        s += deriver + "\n";

        s += (format("%1%\n") % info.references.size()).str();

        for (auto & j : info.references)
            s += j + "\n";
    }

    return s;
}

ValidPathInfo decodeValidPathInfo(std::istream & str, bool hashGiven)
{
    ValidPathInfo info;
    getline(str, info.path);
    if (str.eof()) { info.path = ""; return info; }
    if (hashGiven) {
        string s;
        getline(str, s);
        info.narHash = parseHash(htSHA256, s);
        getline(str, s);
        if (!string2Int(s, info.narSize)) throw Error("number expected");
    }
    getline(str, info.deriver);
    string s; int n;
    getline(str, s);
    if (!string2Int(s, n)) throw Error("number expected");
    while (n--) {
        getline(str, s);
        info.references.insert(s);
    }
    if (!str || str.eof()) throw Error("missing input");
    return info;
}

string showPaths(const PathSet & paths)
{
    string s;
    for (auto & i : paths) {
        if (s.size() != 0) s += ", ";
        s += "‘" + i + "’";
    }
    return s;
}

void Store::exportPaths(const Paths & paths,
    bool sign, Sink & sink)
{
    for (auto & i : paths) {
        sink << 1;
        exportPath(i, sign, sink);
    }
    sink << 0;
}

}

#include "local-store.hh"
#include "remote-store.hh"
#include "local-binary-cache-store.hh"

namespace nix {

ref<Store> openStoreAt(const std::string & uri, bool reserveSpace)
{
    if (std::string(uri, 0, 7) == "file://") {
        return make_ref<LocalBinaryCacheStore>(std::shared_ptr<Store>(0),
            "", "", // FIXME: allow the signing key to be set
            std::string(uri, 7));
    }

    enum { mDaemon, mLocal, mAuto } mode;

    mode = uri == "daemon" ? mDaemon : mAuto;

    if (mode == mAuto) {
        if (LocalStore::haveWriteAccess())
            mode = mLocal;
        else if (pathExists(settings.nixDaemonSocketFile))
            mode = mDaemon;
        else
            mode = mLocal;
    }

    return mode == mDaemon
        ? (ref<Store>) make_ref<RemoteStore>()
        : (ref<Store>) make_ref<LocalStore>(reserveSpace);
}

ref<Store> openStore(bool reserveSpace)
{
    return openStoreAt(getEnv("NIX_REMOTE"), reserveSpace);
}

}
<commit_msg>openStoreAt(): Initialise the binary cache<commit_after>#include "store-api.hh"
#include "globals.hh"
#include "util.hh"

namespace nix {

bool isInStore(const Path & path)
{
    return isInDir(path, settings.nixStore);
}

bool isStorePath(const Path & path)
{
    return isInStore(path)
        && path.find('/', settings.nixStore.size() + 1) == Path::npos;
}

void assertStorePath(const Path & path)
{
    if (!isStorePath(path))
        throw Error(format("path ‘%1%’ is not in the Nix store") % path);
}

Path toStorePath(const Path & path)
{
    if (!isInStore(path))
        throw Error(format("path ‘%1%’ is not in the Nix store") % path);
    Path::size_type slash = path.find('/', settings.nixStore.size() + 1);
    if (slash == Path::npos)
        return path;
    else
        return Path(path, 0, slash);
}

Path followLinksToStore(const Path & _path)
{
    Path path = absPath(_path);
    while (!isInStore(path)) {
        if (!isLink(path)) break;
        string target = readLink(path);
        path = absPath(target, dirOf(path));
    }
    if (!isInStore(path))
        throw Error(format("path ‘%1%’ is not in the Nix store") % path);
    return path;
}

Path followLinksToStorePath(const Path & path)
{
    return toStorePath(followLinksToStore(path));
}

string storePathToName(const Path & path)
{
    assertStorePath(path);
    return string(path, settings.nixStore.size() + storePathHashLen + 2);
}

string storePathToHash(const Path & path)
{
    assertStorePath(path);
    return string(path, settings.nixStore.size() + 1, storePathHashLen);
}

void checkStoreName(const string & name)
{
    string validChars = "+-._?=";
    /* Disallow names starting with a dot for possible security
       reasons (e.g., "." and ".."). */
    if (string(name, 0, 1) == ".")
        throw Error(format("illegal name: ‘%1%’") % name);
    for (auto & i : name)
        if (!((i >= 'A' && i <= 'Z') ||
              (i >= 'a' && i <= 'z') ||
              (i >= '0' && i <= '9') ||
              validChars.find(i) != string::npos))
        {
            throw Error(format("invalid character ‘%1%’ in name ‘%2%’")
                % i % name);
        }
}

/* Store paths have the following form:

   <store>/<h>-<name>

   where

   <store> = the location of the Nix store, usually /nix/store

   <name> = a human readable name for the path, typically obtained
     from the name attribute of the derivation, or the name of the
     source file from which the store path is created.  For derivation
     outputs other than the default "out" output, the string "-<id>"
     is suffixed to <name>.

   <h> = base-32 representation of the first 160 bits of a SHA-256
     hash of <s>; the hash part of the store name

   <s> = the string "<type>:sha256:<h2>:<store>:<name>";
     note that it includes the location of the store as well as the
     name to make sure that changes to either of those are reflected
     in the hash (e.g. you won't get /nix/store/<h>-name1 and
     /nix/store/<h>-name2 with equal hash parts).

   <type> = one of:
     "text:<r1>:<r2>:...<rN>"
       for plain text files written to the store using
       addTextToStore(); <r1> ... <rN> are the references of the
       path.
     "source"
       for paths copied to the store using addToStore() when recursive
       = true and hashAlgo = "sha256"
     "output:<id>"
       for either the outputs created by derivations, OR paths copied
       to the store using addToStore() with recursive != true or
       hashAlgo != "sha256" (in that case "source" is used; it's
       silly, but it's done that way for compatibility).  <id> is the
       name of the output (usually, "out").

   <h2> = base-16 representation of a SHA-256 hash of:
     if <type> = "text:...":
       the string written to the resulting store path
     if <type> = "source":
       the serialisation of the path from which this store path is
       copied, as returned by hashPath()
     if <type> = "output:out":
       for non-fixed derivation outputs:
         the derivation (see hashDerivationModulo() in
         primops.cc)
       for paths copied by addToStore() or produced by fixed-output
       derivations:
         the string "fixed:out:<rec><algo>:<hash>:", where
           <rec> = "r:" for recursive (path) hashes, or "" or flat
             (file) hashes
           <algo> = "md5", "sha1" or "sha256"
           <hash> = base-16 representation of the path or flat hash of
             the contents of the path (or expected contents of the
             path for fixed-output derivations)

   It would have been nicer to handle fixed-output derivations under
   "source", e.g. have something like "source:<rec><algo>", but we're
   stuck with this for now...

   The main reason for this way of computing names is to prevent name
   collisions (for security).  For instance, it shouldn't be feasible
   to come up with a derivation whose output path collides with the
   path for a copied source.  The former would have a <s> starting with
   "output:out:", while the latter would have a <2> starting with
   "source:".
*/

Path makeStorePath(const string & type,
    const Hash & hash, const string & name)
{
    /* e.g., "source:sha256:1abc...:/nix/store:foo.tar.gz" */
    string s = type + ":sha256:" + printHash(hash) + ":"
        + settings.nixStore + ":" + name;

    checkStoreName(name);

    return settings.nixStore + "/"
        + printHash32(compressHash(hashString(htSHA256, s), 20))
        + "-" + name;
}

Path makeOutputPath(const string & id,
    const Hash & hash, const string & name)
{
    return makeStorePath("output:" + id, hash,
        name + (id == "out" ? "" : "-" + id));
}

Path makeFixedOutputPath(bool recursive,
    HashType hashAlgo, Hash hash, string name)
{
    return hashAlgo == htSHA256 && recursive
        ? makeStorePath("source", hash, name)
        : makeStorePath("output:out", hashString(htSHA256,
                "fixed:out:" + (recursive ? (string) "r:" : "") +
                printHashType(hashAlgo) + ":" + printHash(hash) + ":"),
            name);
}

std::pair<Path, Hash> computeStorePathForPath(const Path & srcPath,
    bool recursive, HashType hashAlgo, PathFilter & filter)
{
    HashType ht(hashAlgo);
    Hash h = recursive ? hashPath(ht, srcPath, filter).first : hashFile(ht, srcPath);
    string name = baseNameOf(srcPath);
    Path dstPath = makeFixedOutputPath(recursive, hashAlgo, h, name);
    return std::pair<Path, Hash>(dstPath, h);
}

Path computeStorePathForText(const string & name, const string & s,
    const PathSet & references)
{
    Hash hash = hashString(htSHA256, s);
    /* Stuff the references (if any) into the type.  This is a bit
       hacky, but we can't put them in `s' since that would be
       ambiguous. */
    string type = "text";
    for (auto & i : references) {
        type += ":";
        type += i;
    }
    return makeStorePath(type, hash, name);
}

void Store::queryReferences(const Path & path, PathSet & references)
{
    ValidPathInfo info = queryPathInfo(path);
    references.insert(info.references.begin(), info.references.end());
}

/* Return a string accepted by decodeValidPathInfo() that
   registers the specified paths as valid.  Note: it's the
   responsibility of the caller to provide a closure. */
string Store::makeValidityRegistration(const PathSet & paths,
    bool showDerivers, bool showHash)
{
    string s = "";

    for (auto & i : paths) {
        s += i + "\n";

        ValidPathInfo info = queryPathInfo(i);

        if (showHash) {
            s += printHash(info.narHash) + "\n";
            s += (format("%1%\n") % info.narSize).str();
        }

        Path deriver = showDerivers ? info.deriver : "";
        s += deriver + "\n";

        s += (format("%1%\n") % info.references.size()).str();

        for (auto & j : info.references)
            s += j + "\n";
    }

    return s;
}

ValidPathInfo decodeValidPathInfo(std::istream & str, bool hashGiven)
{
    ValidPathInfo info;
    getline(str, info.path);
    if (str.eof()) { info.path = ""; return info; }
    if (hashGiven) {
        string s;
        getline(str, s);
        info.narHash = parseHash(htSHA256, s);
        getline(str, s);
        if (!string2Int(s, info.narSize)) throw Error("number expected");
    }
    getline(str, info.deriver);
    string s; int n;
    getline(str, s);
    if (!string2Int(s, n)) throw Error("number expected");
    while (n--) {
        getline(str, s);
        info.references.insert(s);
    }
    if (!str || str.eof()) throw Error("missing input");
    return info;
}

string showPaths(const PathSet & paths)
{
    string s;
    for (auto & i : paths) {
        if (s.size() != 0) s += ", ";
        s += "‘" + i + "’";
    }
    return s;
}

void Store::exportPaths(const Paths & paths,
    bool sign, Sink & sink)
{
    for (auto & i : paths) {
        sink << 1;
        exportPath(i, sign, sink);
    }
    sink << 0;
}

}

#include "local-store.hh"
#include "remote-store.hh"
#include "local-binary-cache-store.hh"

namespace nix {

ref<Store> openStoreAt(const std::string & uri, bool reserveSpace)
{
    if (std::string(uri, 0, 7) == "file://") {
        auto store = make_ref<LocalBinaryCacheStore>(std::shared_ptr<Store>(0),
            "", "", // FIXME: allow the signing key to be set
            std::string(uri, 7));
        store->init();
        return store;
    }

    enum { mDaemon, mLocal, mAuto } mode;

    mode = uri == "daemon" ? mDaemon : mAuto;

    if (mode == mAuto) {
        if (LocalStore::haveWriteAccess())
            mode = mLocal;
        else if (pathExists(settings.nixDaemonSocketFile))
            mode = mDaemon;
        else
            mode = mLocal;
    }

    return mode == mDaemon
        ? (ref<Store>) make_ref<RemoteStore>()
        : (ref<Store>) make_ref<LocalStore>(reserveSpace);
}

ref<Store> openStore(bool reserveSpace)
{
    return openStoreAt(getEnv("NIX_REMOTE"), reserveSpace);
}

}
<|endoftext|>


<commit_before>/*
-----------------------------------------------------------------------------
This source file is part of OGRE
    (Object-oriented Graphics Rendering Engine)
For the latest info, see http://www.ogre3d.org/

Copyright (c) 2000-2009 Torus Knot Software Ltd
Also see acknowledgements in Readme.html

This program is free software you can redistribute it and/or modify it under
the terms of the GNU Lesser General Public License as published by the Free Software
Foundation either version 2 of the License, or (at your option) any later
version.

This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License along with
this program if not, write to the Free Software Foundation, Inc., 59 Temple
Place - Suite 330, Boston, MA 02111-1307, USA, or go to
http://www.gnu.org/copyleft/lesser.txt.

You may alternatively use this source under the terms of a specific version of
the OGRE Unrestricted License provided you have obtained such a license from
Torus Knot Software Ltd.
-----------------------------------------------------------------------------
*/
#include "OgreStableHeaders.h"
#include "OgreHighLevelGpuProgram.h"
#include "OgreException.h"
#include "OgreGpuProgramManager.h"
#include "OgreLogManager.h"

namespace Ogre
{
    //---------------------------------------------------------------------------
    HighLevelGpuProgram::HighLevelGpuProgram(ResourceManager* creator,
        const String& name, ResourceHandle handle, const String& group,
        bool isManual, ManualResourceLoader* loader)
        : GpuProgram(creator, name, handle, group, isManual, loader),
        mHighLevelLoaded(false), mAssemblerProgram(0), mConstantDefsBuilt(false)
    {
    }
    //---------------------------------------------------------------------------
    void HighLevelGpuProgram::loadImpl()
    {
		if (isSupported())
		{
			// load self
			loadHighLevel();

			// create low-level implementation
			createLowLevelImpl();
			// load constructed assembler program (if it exists)
			if (!mAssemblerProgram.isNull())
			{
				mAssemblerProgram->load();
			}

		}
    }
    //---------------------------------------------------------------------------
    void HighLevelGpuProgram::unloadImpl()
    {
        if (!mAssemblerProgram.isNull())
        {
            mAssemblerProgram->getCreator()->remove(mAssemblerProgram->getHandle());
            mAssemblerProgram.setNull();
        }

        unloadHighLevel();
		resetCompileError();
    }
    //---------------------------------------------------------------------------
    HighLevelGpuProgram::~HighLevelGpuProgram()
    {
        // superclasses will trigger unload
    }
    //---------------------------------------------------------------------------
    GpuProgramParametersSharedPtr HighLevelGpuProgram::createParameters(void)
    {
		// Lock mutex before allowing this since this is a top-level method
		// called outside of the load()
		OGRE_LOCK_AUTO_MUTEX

        // Make sure param defs are loaded
        GpuProgramParametersSharedPtr params = GpuProgramManager::getSingleton().createParameters();
		// Only populate named parameters if we can support this program
		if (this->isSupported())
		{
			loadHighLevel();
			// Errors during load may have prevented compile
			if (this->isSupported())
			{
				populateParameterNames(params);
			}
		}
		// Copy in default parameters if present
		if (!mDefaultParams.isNull())
			params->copyConstantsFrom(*(mDefaultParams.get()));
        return params;
    }
    //---------------------------------------------------------------------------
    void HighLevelGpuProgram::loadHighLevel(void)
    {
        if (!mHighLevelLoaded)
        {
			try
			{
				loadHighLevelImpl();
				mHighLevelLoaded = true;
				if (!mDefaultParams.isNull())
				{
					// Keep a reference to old ones to copy
					GpuProgramParametersSharedPtr savedParams = mDefaultParams;
					// reset params to stop them being referenced in the next create
					mDefaultParams.setNull();

					// Create new params
					mDefaultParams = createParameters();

					// Copy old (matching) values across
					// Don't use copyConstantsFrom since program may be different
					mDefaultParams->copyMatchingNamedConstantsFrom(*savedParams.get());

				}

			}
			catch (const Exception& e)
			{
				// will already have been logged
				LogManager::getSingleton().stream()
					<< "High-level program " << mName << " encountered an error "
					<< "during loading and is thus not supported.\n"
					<< e.getFullDescription();

				mCompileError = true;
			}
        }
    }
    //---------------------------------------------------------------------------
    void HighLevelGpuProgram::unloadHighLevel(void)
    {
        if (mHighLevelLoaded)
        {
            unloadHighLevelImpl();
			// Clear saved constant defs
			mConstantDefsBuilt = false;
			createParameterMappingStructures(true);

            mHighLevelLoaded = false;
        }
    }
    //---------------------------------------------------------------------------
    void HighLevelGpuProgram::loadHighLevelImpl(void)
    {
        if (mLoadFromFile)
        {
            // find & load source code
            DataStreamPtr stream =
                ResourceGroupManager::getSingleton().openResource(
                    mFilename, mGroup, true, this);

            mSource = stream->getAsString();
        }

        loadFromSource();

    }
	//---------------------------------------------------------------------
	const GpuNamedConstants& HighLevelGpuProgram::getConstantDefinitions() const
	{
		if (!mConstantDefsBuilt)
		{
			buildConstantDefinitions();
			mConstantDefsBuilt = true;
		}
		return *mConstantDefs.get();

	}
	//---------------------------------------------------------------------
	void HighLevelGpuProgram::populateParameterNames(GpuProgramParametersSharedPtr params)
	{
		getConstantDefinitions();
		params->_setNamedConstants(mConstantDefs);
		// also set logical / physical maps for programs which use this
		params->_setLogicalIndexes(mFloatLogicalToPhysical, mIntLogicalToPhysical);
	}
	//-----------------------------------------------------------------------
	//-----------------------------------------------------------------------
	HighLevelGpuProgramPtr& HighLevelGpuProgramPtr::operator=(const GpuProgramPtr& r)
	{
		// Can assign direct
		if (pRep == static_cast<HighLevelGpuProgram*>(r.getPointer()))
			return *this;
		release();
		// lock & copy other mutex pointer
        OGRE_MUTEX_CONDITIONAL(r.OGRE_AUTO_MUTEX_NAME)
        {
		    OGRE_LOCK_MUTEX(*r.OGRE_AUTO_MUTEX_NAME)
		    OGRE_COPY_AUTO_SHARED_MUTEX(r.OGRE_AUTO_MUTEX_NAME)
		    pRep = static_cast<HighLevelGpuProgram*>(r.getPointer());
		    pUseCount = r.useCountPointer();
		    if (pUseCount)
		    {
			    ++(*pUseCount);
		    }
        }
		else
		{
			// RHS must be a null pointer
			assert(r.isNull() && "RHS must be null if it has no mutex!");
			setNull();
		}
		return *this;
	}

}
<commit_msg>OgreHighLevelGpuProgram - Added a check in HighLevelGpuProgram::loadImpl() so if mAssemblerProgram is the same as OgreHighLevelGpuProgram - it won't load twice. I found the issue while working on the d3d11 render system. Without this fix - there is an endless loop when calling loadImpl.<commit_after>/*
-----------------------------------------------------------------------------
This source file is part of OGRE
    (Object-oriented Graphics Rendering Engine)
For the latest info, see http://www.ogre3d.org/

Copyright (c) 2000-2009 Torus Knot Software Ltd
Also see acknowledgements in Readme.html

This program is free software you can redistribute it and/or modify it under
the terms of the GNU Lesser General Public License as published by the Free Software
Foundation either version 2 of the License, or (at your option) any later
version.

This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License along with
this program if not, write to the Free Software Foundation, Inc., 59 Temple
Place - Suite 330, Boston, MA 02111-1307, USA, or go to
http://www.gnu.org/copyleft/lesser.txt.

You may alternatively use this source under the terms of a specific version of
the OGRE Unrestricted License provided you have obtained such a license from
Torus Knot Software Ltd.
-----------------------------------------------------------------------------
*/
#include "OgreStableHeaders.h"
#include "OgreHighLevelGpuProgram.h"
#include "OgreException.h"
#include "OgreGpuProgramManager.h"
#include "OgreLogManager.h"

namespace Ogre
{
    //---------------------------------------------------------------------------
    HighLevelGpuProgram::HighLevelGpuProgram(ResourceManager* creator,
        const String& name, ResourceHandle handle, const String& group,
        bool isManual, ManualResourceLoader* loader)
        : GpuProgram(creator, name, handle, group, isManual, loader),
        mHighLevelLoaded(false), mAssemblerProgram(0), mConstantDefsBuilt(false)
    {
    }
    //---------------------------------------------------------------------------
    void HighLevelGpuProgram::loadImpl()
    {
		if (isSupported())
		{
			// load self
			loadHighLevel();

			// create low-level implementation
			createLowLevelImpl();
			// load constructed assembler program (if it exists)
			if (!mAssemblerProgram.isNull() && mAssemblerProgram.getPointer() != this)
			{
				mAssemblerProgram->load();
			}

		}
    }
    //---------------------------------------------------------------------------
    void HighLevelGpuProgram::unloadImpl()
    {
        if (!mAssemblerProgram.isNull())
        {
            mAssemblerProgram->getCreator()->remove(mAssemblerProgram->getHandle());
            mAssemblerProgram.setNull();
        }

        unloadHighLevel();
		resetCompileError();
    }
    //---------------------------------------------------------------------------
    HighLevelGpuProgram::~HighLevelGpuProgram()
    {
        // superclasses will trigger unload
    }
    //---------------------------------------------------------------------------
    GpuProgramParametersSharedPtr HighLevelGpuProgram::createParameters(void)
    {
		// Lock mutex before allowing this since this is a top-level method
		// called outside of the load()
		OGRE_LOCK_AUTO_MUTEX

        // Make sure param defs are loaded
        GpuProgramParametersSharedPtr params = GpuProgramManager::getSingleton().createParameters();
		// Only populate named parameters if we can support this program
		if (this->isSupported())
		{
			loadHighLevel();
			// Errors during load may have prevented compile
			if (this->isSupported())
			{
				populateParameterNames(params);
			}
		}
		// Copy in default parameters if present
		if (!mDefaultParams.isNull())
			params->copyConstantsFrom(*(mDefaultParams.get()));
        return params;
    }
    //---------------------------------------------------------------------------
    void HighLevelGpuProgram::loadHighLevel(void)
    {
        if (!mHighLevelLoaded)
        {
			try
			{
				loadHighLevelImpl();
				mHighLevelLoaded = true;
				if (!mDefaultParams.isNull())
				{
					// Keep a reference to old ones to copy
					GpuProgramParametersSharedPtr savedParams = mDefaultParams;
					// reset params to stop them being referenced in the next create
					mDefaultParams.setNull();

					// Create new params
					mDefaultParams = createParameters();

					// Copy old (matching) values across
					// Don't use copyConstantsFrom since program may be different
					mDefaultParams->copyMatchingNamedConstantsFrom(*savedParams.get());

				}

			}
			catch (const Exception& e)
			{
				// will already have been logged
				LogManager::getSingleton().stream()
					<< "High-level program " << mName << " encountered an error "
					<< "during loading and is thus not supported.\n"
					<< e.getFullDescription();

				mCompileError = true;
			}
        }
    }
    //---------------------------------------------------------------------------
    void HighLevelGpuProgram::unloadHighLevel(void)
    {
        if (mHighLevelLoaded)
        {
            unloadHighLevelImpl();
			// Clear saved constant defs
			mConstantDefsBuilt = false;
			createParameterMappingStructures(true);

            mHighLevelLoaded = false;
        }
    }
    //---------------------------------------------------------------------------
    void HighLevelGpuProgram::loadHighLevelImpl(void)
    {
        if (mLoadFromFile)
        {
            // find & load source code
            DataStreamPtr stream =
                ResourceGroupManager::getSingleton().openResource(
                    mFilename, mGroup, true, this);

            mSource = stream->getAsString();
        }

        loadFromSource();

    }
	//---------------------------------------------------------------------
	const GpuNamedConstants& HighLevelGpuProgram::getConstantDefinitions() const
	{
		if (!mConstantDefsBuilt)
		{
			buildConstantDefinitions();
			mConstantDefsBuilt = true;
		}
		return *mConstantDefs.get();

	}
	//---------------------------------------------------------------------
	void HighLevelGpuProgram::populateParameterNames(GpuProgramParametersSharedPtr params)
	{
		getConstantDefinitions();
		params->_setNamedConstants(mConstantDefs);
		// also set logical / physical maps for programs which use this
		params->_setLogicalIndexes(mFloatLogicalToPhysical, mIntLogicalToPhysical);
	}
	//-----------------------------------------------------------------------
	//-----------------------------------------------------------------------
	HighLevelGpuProgramPtr& HighLevelGpuProgramPtr::operator=(const GpuProgramPtr& r)
	{
		// Can assign direct
		if (pRep == static_cast<HighLevelGpuProgram*>(r.getPointer()))
			return *this;
		release();
		// lock & copy other mutex pointer
        OGRE_MUTEX_CONDITIONAL(r.OGRE_AUTO_MUTEX_NAME)
        {
		    OGRE_LOCK_MUTEX(*r.OGRE_AUTO_MUTEX_NAME)
		    OGRE_COPY_AUTO_SHARED_MUTEX(r.OGRE_AUTO_MUTEX_NAME)
		    pRep = static_cast<HighLevelGpuProgram*>(r.getPointer());
		    pUseCount = r.useCountPointer();
		    if (pUseCount)
		    {
			    ++(*pUseCount);
		    }
        }
		else
		{
			// RHS must be a null pointer
			assert(r.isNull() && "RHS must be null if it has no mutex!");
			setNull();
		}
		return *this;
	}

}
<|endoftext|>


<commit_before>//
//  fusion.cpp
//  Submarine
//
//  Created by Jean Caillé on 11/11/2013.
//  Copyright (c) 2013 Florian Denis. All rights reserved.
//

#include "fusion.h"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"

#pragma mark - GAUSSIAN PYRAMID

std::vector<cv::Mat> gaussianPyramid(const cv::Mat input, int levels){
    // Called on mask
    std::vector<cv::Mat> pyramid = std::vector<cv::Mat>();
    cv::Size pyrSize = input.size();
    pyramid.push_back(input);
    for(int i = 0 ; i < levels ; i++){
        cv::Mat newLevel ;
        pyrSize = cv::Size(MAX(1, pyrSize.width / 2), MAX(1, pyrSize.height / 2)); // Make sure size is valid
        cv::pyrDown(pyramid.back(), newLevel, pyrSize);
        pyramid.push_back(newLevel);
    }
    return pyramid;
}

#pragma mark - LAPLACIAN PYRAMID

std::vector<cv::Mat> laplacianPyramid(cv::Mat input, int levels){
    std::vector<cv::Mat> pyramid = std::vector<cv::Mat>();
    cv::Mat currentImg = input;
    for (int i = 0; i < levels; i ++) {
        cv::Mat down, up;
        cv::pyrDown(currentImg, down);
        cv::pyrUp(down, up, currentImg.size());
        cv::Mat newLevel = currentImg - up;
        pyramid.push_back(newLevel);
        currentImg = down;
    }
    return pyramid;
}

#pragma mark - FUSION

void naiveFusion(cv::Mat a, cv::Mat b, cv::Mat dst){

}<commit_msg>Fuuuuuuuuu --- siooooon<commit_after>//
//  fusion.cpp
//  Submarine
//
//  Created by Jean Caillé on 11/11/2013.
//  Copyright (c) 2013 Florian Denis. All rights reserved.
//

#include "fusion.h"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"

#pragma mark - GAUSSIAN PYRAMID

std::vector<cv::Mat> gaussianPyramid(const cv::Mat input, int levels){
    // Called on mask
    std::vector<cv::Mat> pyramid = std::vector<cv::Mat>();
    cv::Size pyrSize = input.size();
    pyramid.push_back(input);
    for(int i = 0 ; i < levels - 1 ; i++){
        cv::Mat newLevel ;
        pyrSize = cv::Size(MAX(1, pyrSize.width / 2), MAX(1, pyrSize.height / 2)); // Make sure size is valid
        cv::pyrDown(pyramid.back(), newLevel, pyrSize);
        pyramid.push_back(newLevel);
    }
    std::cout << "There are " << pyramid.size() << " images in the gaussian pyramid" << std::endl;
    return pyramid;
}

#pragma mark - LAPLACIAN PYRAMID

std::vector<cv::Mat> laplacianPyramid(cv::Mat input, int levels){
    std::vector<cv::Mat> pyramid = std::vector<cv::Mat>();
    cv::Mat currentImg = input;
    cv::imshow("input", input);
    for (int i = 0; i < levels; i ++) {
        cv::Mat down, up;
        cv::pyrDown(currentImg, down);
        cv::pyrUp(down, up, currentImg.size());
        cv::Mat newLevel;
        cv::absdiff(currentImg, up, newLevel);
        pyramid.push_back(newLevel);
        currentImg = down;
        cv::waitKey();
    }
    std::cout << "There are " << pyramid.size() << " images in the laplacian pyramid" << std::endl;
    return pyramid;
}

#pragma mark - FUSION

void fuseInputs(std::vector<cv::Mat> inputs, std::vector<cv::Mat> weights, cv::Mat dst){
    int levels = 5;
    //Compute laplacian pyramid
    std::vector<cv::Mat> firstInputPyramid = laplacianPyramid(inputs[0], levels);
    std::vector<cv::Mat> secondInputPyramid = laplacianPyramid(inputs[1], levels);

    //Compute gaussian pyramid of weights
    std::vector<cv::Mat> firstWeightPyramid = gaussianPyramid(weights[0], levels);
    std::vector<cv::Mat> secondWeightPyramid = gaussianPyramid(weights[1], levels);

    //Fuse inputs according to formula
    for(int i = 0 ; i < firstInputPyramid.size(); i++){
        cv::Mat A, B;
        cv::multiply(firstInputPyramid[i], firstWeightPyramid[i], A);
        cv::multiply(secondInputPyramid[i], secondWeightPyramid[i], B);
        dst += A+B;
    }
}

void naiveFusion(std::vector<cv::Mat> inputs, std::vector<cv::Mat> weights, cv::Mat dst){
    for(int i = 0 ; i < inputs.size(); i++){
        cv::Mat A;
        cv::multiply(inputs[i], weights[i], A);
        dst += A;
    }
}<|endoftext|>


<commit_before><commit_msg>[SofaKernel] remove framework_test/io/ImagePNG_test.cpp that poped-up because of failed merged.<commit_after><|endoftext|>


<commit_before>/**
 * \file
 * \brief SemaphoreFunctor class header
 *
 * \author Copyright (C) 2014-2015 Kamil Szczygiel http://www.distortec.com http://www.freddiechopin.info
 *
 * \par License
 * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not
 * distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * \date 2015-01-12
 */

#ifndef INCLUDE_DISTORTOS_SYNCHRONIZATION_SEMAPHOREFUNCTOR_HPP_
#define INCLUDE_DISTORTOS_SYNCHRONIZATION_SEMAPHOREFUNCTOR_HPP_

#include "distortos/estd/TypeErasedFunctor.hpp"

namespace distortos
{

class Semaphore;

namespace synchronization
{

/**
 * \brief SemaphoreFunctor is a type-erased interface for functors which execute some action on semaphore (wait(),
 * tryWait(), tryWaitFor(), tryWaitUntil(), ...).
 *
 * The functor will be called with one argument - \a semaphore - which is a reference to Semaphore object on which the
 * action will be executed. Functor's operator should return zero if the action was executed successfully, error code
 * otherwise.
 */

using SemaphoreFunctor = estd::TypeErasedFunctor<int(Semaphore&)>;

}	// namespace synchronization

}	// namespace distortos

#endif	// INCLUDE_DISTORTOS_SYNCHRONIZATION_SEMAPHOREFUNCTOR_HPP_
<commit_msg>SemaphoreFunctor: implement it as proper class instead of type alias<commit_after>/**
 * \file
 * \brief SemaphoreFunctor class header
 *
 * \author Copyright (C) 2014-2015 Kamil Szczygiel http://www.distortec.com http://www.freddiechopin.info
 *
 * \par License
 * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not
 * distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * \date 2015-07-09
 */

#ifndef INCLUDE_DISTORTOS_SYNCHRONIZATION_SEMAPHOREFUNCTOR_HPP_
#define INCLUDE_DISTORTOS_SYNCHRONIZATION_SEMAPHOREFUNCTOR_HPP_

#include "distortos/estd/TypeErasedFunctor.hpp"

namespace distortos
{

class Semaphore;

namespace synchronization
{

/**
 * \brief SemaphoreFunctor is a type-erased interface for functors which execute some action on semaphore (wait(),
 * tryWait(), tryWaitFor(), tryWaitUntil(), ...).
 *
 * The functor will be called with one argument - \a semaphore - which is a reference to Semaphore object on which the
 * action will be executed. Functor's operator should return zero if the action was executed successfully, error code
 * otherwise.
 */

class SemaphoreFunctor : public estd::TypeErasedFunctor<int(Semaphore&)>
{

};

}	// namespace synchronization

}	// namespace distortos

#endif	// INCLUDE_DISTORTOS_SYNCHRONIZATION_SEMAPHOREFUNCTOR_HPP_
<|endoftext|>


<commit_before>#include "MainCamera.h"
#include "Utility.hpp"
#include "Matrix.h"
#include "LightCullingUtility.h"
#include "CameraManager.h"
#include "ObjectManager.h"

using namespace Utility;
using namespace Device;
using namespace Core;
using namespace Rendering;
using namespace Rendering::Buffer;
using namespace Rendering::Shader;
using namespace Rendering::Camera;
using namespace Device;
using namespace Math;
using namespace Rendering::Manager;
using namespace Rendering::Geometry;

void MainCamera::Initialize(DirectX& dx, ShaderManager& shaderMgr, const Rect<uint>& rect)
{
	// setting desc
	{
		auto size = rect.size.Cast<float>();
		_desc.aspect = size.w / size.h;
		_desc.renderRect = rect;
	}

	_camCB.Initialize(dx);
}

bool MainCamera::UpdateCB(Device::DirectX & dx, const Core::Transform& dirtyTransform)
{
	assert(dirtyTransform.GetObjectID() == _objID);

	bool changedTF = dirtyTransform.GetDirty() | _dirty;
	if (changedTF)
		_camCBChangeState = TransformCB::ChangeState::HasChanged;

	if ((_camCBChangeState != TransformCB::ChangeState::No) == false)
		return false;

	const Matrix& worldMat = dirtyTransform.GetWorldMatrix();

	{
		_camCBData.viewMat = Matrix::ComputeViewMatrix(worldMat);
		Matrix& viewMat = _camCBData.viewMat;

		_projMat = ComputePerspectiveMatrix(true);
		_viewProjMat = viewMat * _projMat;

		_camCBData.viewProjMat = _viewProjMat;

		_camCBData.worldPos = Vector3(worldMat._41, worldMat._42, worldMat._43);
		_camCBData.prevViewProjMat = _prevViewProjMat;
		_camCBData.packedCamNearFar = (Half(_desc.near).GetValue() << 16) | Half(_desc.far).GetValue();
	}

	// Make Frustum
	if (changedTF)
	{
		Matrix notInvProj = ComputePerspectiveMatrix(false);
		_frustum.Make(_camCBData.viewMat * notInvProj);
	}

	_camCBData.viewMat				= Matrix::Transpose(_camCBData.viewMat);
	_camCBData.viewProjMat			= Matrix::Transpose(_camCBData.viewProjMat);
	_camCBData.prevViewProjMat		= Matrix::Transpose(_camCBData.prevViewProjMat);

	_camCB.UpdateSubResource(dx, _camCBData);

	_camCBChangeState = TransformCB::ChangeState((static_cast<uint>(_camCBChangeState) + 1) % static_cast<uint>(TransformCB::ChangeState::MAX));
	_prevViewProjMat = _viewProjMat;

	_dirty = false;
	return true;
}

Math::Matrix MainCamera::ComputePerspectiveMatrix(bool isInverted) const
{
	float fovRadian = DEG_2_RAD(_desc.fieldOfViewDegree);

	float near = _desc.near;
	float far = _desc.far;

	if (isInverted)
		std::swap(near, far);

	return Matrix::PerspectiveFovLH(_desc.aspect, fovRadian, near, far);
}

Math::Matrix Rendering::Camera::MainCamera::ComputeOrthogonalMatrix(bool isInverted) const
{
	float near = _desc.near;
	float far = _desc.far;

	if (isInverted)
		std::swap(near, far);

	auto size = _desc.renderRect.size.Cast<float>();
	return Matrix::OrthoLH(size.w, size.h, near, far);
}
<commit_msg>MainCamera - ClassifyTransparentMesh 추가<commit_after>#include "MainCamera.h"
#include "Utility.hpp"
#include "Matrix.h"
#include "LightCullingUtility.h"
#include "CameraManager.h"
#include "ObjectManager.h"

using namespace Utility;
using namespace Device;
using namespace Core;
using namespace Rendering;
using namespace Rendering::Buffer;
using namespace Rendering::Shader;
using namespace Rendering::Camera;
using namespace Device;
using namespace Math;
using namespace Rendering::Manager;
using namespace Rendering::Geometry;

void MainCamera::Initialize(DirectX& dx, ShaderManager& shaderMgr, const Rect<uint>& rect)
{
	// setting desc
	{
		auto size = rect.size.Cast<float>();
		_desc.aspect = size.w / size.h;
		_desc.renderRect = rect;
	}

	_camCB.Initialize(dx);
}

bool MainCamera::UpdateCB(Device::DirectX & dx, const Core::Transform& dirtyTransform)
{
	assert(dirtyTransform.GetObjectID() == _objID);

	bool changedTF = dirtyTransform.GetDirty() | _dirty;
	if (changedTF)
		_camCBChangeState = TransformCB::ChangeState::HasChanged;

	if ((_camCBChangeState != TransformCB::ChangeState::No) == false)
		return false;

	const Matrix& worldMat = dirtyTransform.GetWorldMatrix();

	{
		_camCBData.viewMat = Matrix::ComputeViewMatrix(worldMat);
		Matrix& viewMat = _camCBData.viewMat;

		_projMat = ComputePerspectiveMatrix(true);
		_viewProjMat = viewMat * _projMat;

		_camCBData.viewProjMat = _viewProjMat;

		_camCBData.worldPos = Vector3(worldMat._41, worldMat._42, worldMat._43);
		_camCBData.prevViewProjMat = _prevViewProjMat;
		_camCBData.packedCamNearFar = (Half(_desc.near).GetValue() << 16) | Half(_desc.far).GetValue();
	}

	// Make Frustum
	if (changedTF)
	{
		Matrix notInvProj = ComputePerspectiveMatrix(false);
		_frustum.Make(_camCBData.viewMat * notInvProj);
	}

	_camCBData.viewMat				= Matrix::Transpose(_camCBData.viewMat);
	_camCBData.viewProjMat			= Matrix::Transpose(_camCBData.viewProjMat);
	_camCBData.prevViewProjMat		= Matrix::Transpose(_camCBData.prevViewProjMat);

	_camCB.UpdateSubResource(dx, _camCBData);

	_camCBChangeState = TransformCB::ChangeState((static_cast<uint>(_camCBChangeState) + 1) % static_cast<uint>(TransformCB::ChangeState::MAX));
	_prevViewProjMat = _viewProjMat;

	_dirty = false;
	return true;
}

Math::Matrix MainCamera::ComputePerspectiveMatrix(bool isInverted) const
{
	float fovRadian = DEG_2_RAD(_desc.fieldOfViewDegree);

	float near = _desc.near;
	float far = _desc.far;

	if (isInverted)
		std::swap(near, far);

	return Matrix::PerspectiveFovLH(_desc.aspect, fovRadian, near, far);
}

Math::Matrix MainCamera::ComputeOrthogonalMatrix(bool isInverted) const
{
	float near = _desc.near;
	float far = _desc.far;

	if (isInverted)
		std::swap(near, far);

	auto size = _desc.renderRect.size.Cast<float>();
	return Matrix::OrthoLH(size.w, size.h, near, far);
}

void MainCamera::ClassifyTransparentMesh(const TransparentMeshPool& pool,
										 const ObjectManager& objMgr,
										 const TransformPool& transformPool)
{
	MainCamera* thisCam = this;
	ClassifyTransparentMesh(_transparentMeshes, pool, objMgr, transformPool,
			[thisCam](const Mesh& mesh, const Transform& tarnsform)
			{
				Vector3 worldPos = transform.GetWorldPosition();
				return thisCam->_frustum.In(worldPos, mesh.GetRadius());
			}
		);
}
<|endoftext|>


<commit_before>/*
**  Copyright (C) 2012 Aldebaran Robotics
**  See COPYING for the license
*/
#include <qi/future.hpp>
#include <boost/thread.hpp>

namespace qi {

  namespace detail {

    class FutureBasePrivate {
    public:
      FutureBasePrivate();
      boost::condition_variable _cond;
      boost::mutex              _mutex;
      std::string               _error;
      bool                      _isReady;
      bool                      _hasError;
    };

    FutureBasePrivate::FutureBasePrivate()
      : _cond(),
        _mutex(),
        _error(),
        _isReady(false),
        _hasError(false)
    {
    }

    FutureBase::FutureBase()
      : _p(new FutureBasePrivate())
    {
    }

    FutureBase::~FutureBase()
    {
      delete _p;
    };

    bool FutureBase::wait(int msecs) const {
      boost::mutex::scoped_lock lock(_p->_mutex);
      if (_p->_isReady || _p->_hasError)
        return true;
      if (msecs > 0)
        _p->_cond.timed_wait(lock, boost::posix_time::milliseconds(msecs));
      else
        _p->_cond.wait(lock);
      return _p->_isReady || _p->_hasError;
    }

    void FutureBase::reportReady() {
      boost::mutex::scoped_lock lock(_p->_mutex);
      _p->_isReady = true;
    }

    void FutureBase::notifyReady() {
      _p->_cond.notify_all();
    }

    void FutureBase::reportError(const std::string &message) {
      boost::mutex::scoped_lock lock(_p->_mutex);
      _p->_hasError = true;
      _p->_isReady = true;
      _p->_error = message;
    }

    bool FutureBase::isReady() const {
      return _p->_isReady;
    }

    bool FutureBase::hasError(int msecs) const {
      wait(msecs);
      return _p->_hasError;
    }

    const std::string &FutureBase::error() const {
      wait();
      return _p->_error;
    }

    void FutureBase::reset() {
      boost::mutex::scoped_lock lock(_p->_mutex);
      _p->_isReady = false;
      _p->_error = std::string();
      _p->_hasError = false;
    }

    boost::mutex& FutureBase::mutex()
    {
      return _p->_mutex;
    }
  }

}

<commit_msg>Future: Env variable to warn about wait from network thread.<commit_after>/*
**  Copyright (C) 2012 Aldebaran Robotics
**  See COPYING for the license
*/
#include <qi/future.hpp>
#include <qi/log.hpp>
#include <qi/os.hpp>
#include <qi/eventloop.hpp>

#include <boost/thread.hpp>

namespace qi {

  namespace detail {

    class FutureBasePrivate {
    public:
      FutureBasePrivate();
      boost::condition_variable _cond;
      boost::mutex              _mutex;
      std::string               _error;
      bool                      _isReady;
      bool                      _hasError;
    };

    FutureBasePrivate::FutureBasePrivate()
      : _cond(),
        _mutex(),
        _error(),
        _isReady(false),
        _hasError(false)
    {
    }

    FutureBase::FutureBase()
      : _p(new FutureBasePrivate())
    {
    }

    FutureBase::~FutureBase()
    {
      delete _p;
    };

    bool FutureBase::wait(int msecs) const {
      static bool detectEventLoopWait = !os::getenv("QI_DETECT_FUTURE_WAIT_FROM_NETWORK_EVENTLOOP").empty();
      if (detectEventLoopWait && getDefaultNetworkEventLoop()->isInEventLoopThread())
        qiLogWarning("qi.future") << "Future wait in network thread.";
      boost::mutex::scoped_lock lock(_p->_mutex);
      if (_p->_isReady || _p->_hasError)
        return true;
      if (msecs > 0)
        _p->_cond.timed_wait(lock, boost::posix_time::milliseconds(msecs));
      else
        _p->_cond.wait(lock);
      return _p->_isReady || _p->_hasError;
    }

    void FutureBase::reportReady() {
      boost::mutex::scoped_lock lock(_p->_mutex);
      _p->_isReady = true;
    }

    void FutureBase::notifyReady() {
      _p->_cond.notify_all();
    }

    void FutureBase::reportError(const std::string &message) {
      boost::mutex::scoped_lock lock(_p->_mutex);
      _p->_hasError = true;
      _p->_isReady = true;
      _p->_error = message;
    }

    bool FutureBase::isReady() const {
      return _p->_isReady;
    }

    bool FutureBase::hasError(int msecs) const {
      wait(msecs);
      return _p->_hasError;
    }

    const std::string &FutureBase::error() const {
      wait();
      return _p->_error;
    }

    void FutureBase::reset() {
      boost::mutex::scoped_lock lock(_p->_mutex);
      _p->_isReady = false;
      _p->_error = std::string();
      _p->_hasError = false;
    }

    boost::mutex& FutureBase::mutex()
    {
      return _p->_mutex;
    }
  }

}

<|endoftext|>


<commit_before>#include "CreateMeshCMPT.h"
#include "CreateMeshOP.h"
#include "StagePanel.h"
#include "FileIO.h"
#include "ShapeFactory.h"
#include "Shape.h"

namespace emesh
{

CreateMeshCMPT::CreateMeshCMPT(wxWindow* parent, const wxString& name,
					   StagePanel* stage)
	: d2d::AbstractEditCMPT(parent, name, stage)
	, m_stage(stage)
{
	m_editOP = new CreateMeshOP(stage);
}

wxSizer* CreateMeshCMPT::initLayout()
{
	wxSizer* sizer = new wxBoxSizer(wxVERTICAL);
	sizer->AddSpacer(15);
	{
		wxArrayString choices;
		choices.Add(wxT("mesh"));
		choices.Add(wxT("strip"));
		wxRadioBox* typeChoice = new wxRadioBox(this, wxID_ANY, wxT("Type"),
			wxDefaultPosition, wxDefaultSize, choices, 2, wxRA_SPECIFY_COLS);
// 		typeChoice->SetSelection(1);
// 		ShapeFactory::Instance()->SetShapeType(ST_STRIP);
		typeChoice->SetSelection(0);
		ShapeFactory::Instance()->SetShapeType(ST_MESH);
 		Connect(typeChoice->GetId(), wxEVT_COMMAND_RADIOBOX_SELECTED,
 			wxCommandEventHandler(CreateMeshCMPT::onChangeType));
		sizer->Add(typeChoice);

		sizer->AddSpacer(5);

		wxCheckBox* regionSet = new wxCheckBox(this, wxID_ANY, wxT("ʹñ߽"),
			wxDefaultPosition, wxDefaultSize, wxCHK_2STATE);
		bool use_region = ShapeFactory::Instance()->IsUseRegion();
		regionSet->SetValue(use_region);
		Connect(regionSet->GetId(), wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(CreateMeshCMPT::onChangeUseRegion));
		sizer->Add(regionSet);
	}
	sizer->AddSpacer(15);
	{
		wxButton* btn = new wxButton(this, wxID_ANY, wxT("Copy..."));
		Connect(btn->GetId(), wxEVT_COMMAND_BUTTON_CLICKED,
			wxCommandEventHandler(CreateMeshCMPT::onCopy));
		sizer->Add(btn);
	}
	sizer->AddSpacer(10);
	{
		wxButton* btn = new wxButton(this, wxID_ANY, wxT("Clear"));
		Connect(btn->GetId(), wxEVT_COMMAND_BUTTON_CLICKED,
			wxCommandEventHandler(CreateMeshCMPT::onClear));
		sizer->Add(btn);
	}
	return sizer;
}

void CreateMeshCMPT::onChangeType(wxCommandEvent& event)
{
	int idx = event.GetSelection();
	switch (idx)
	{
	case 0:
		ShapeFactory::Instance()->SetShapeType(ST_MESH);
		break;
	case 1:
		ShapeFactory::Instance()->SetShapeType(ST_STRIP);
		break;
	}
}

void CreateMeshCMPT::onChangeUseRegion(wxCommandEvent& event)
{
	ShapeFactory::Instance()->SetUseRegion(event.IsChecked());
}

void CreateMeshCMPT::onCopy(wxCommandEvent& event)
{
// 	std::string tag = d2d::FileNameParser::getFileTag(d2d::FileNameParser::e_mesh);
// 	wxFileDialog dlg(this, wxT("Open"), wxEmptyString, wxEmptyString,
// 		wxT("*_") + tag + wxT(".json"), wxFD_OPEN);
// 	if (dlg.ShowModal() == wxID_OK)
// 	{
// 		FileIO::loadStruct(dlg.GetPath(), *m_stage->getMesh());
// 		m_editPanel->Refresh();
// 	}
}

void CreateMeshCMPT::onClear(wxCommandEvent& event)
{
	m_stage->getShape()->Clear();
	m_editPanel->Refresh();
	m_editOP->clear();
}

}<commit_msg>[FIXED] CreateMeshCMPT clear<commit_after>#include "CreateMeshCMPT.h"
#include "CreateMeshOP.h"
#include "StagePanel.h"
#include "FileIO.h"
#include "ShapeFactory.h"
#include "Shape.h"

namespace emesh
{

CreateMeshCMPT::CreateMeshCMPT(wxWindow* parent, const wxString& name,
					   StagePanel* stage)
	: d2d::AbstractEditCMPT(parent, name, stage)
	, m_stage(stage)
{
	m_editOP = new CreateMeshOP(stage);
}

wxSizer* CreateMeshCMPT::initLayout()
{
	wxSizer* sizer = new wxBoxSizer(wxVERTICAL);
	sizer->AddSpacer(15);
	{
		wxArrayString choices;
		choices.Add(wxT("mesh"));
		choices.Add(wxT("strip"));
		wxRadioBox* typeChoice = new wxRadioBox(this, wxID_ANY, wxT("Type"),
			wxDefaultPosition, wxDefaultSize, choices, 2, wxRA_SPECIFY_COLS);
// 		typeChoice->SetSelection(1);
// 		ShapeFactory::Instance()->SetShapeType(ST_STRIP);
		typeChoice->SetSelection(0);
		ShapeFactory::Instance()->SetShapeType(ST_MESH);
 		Connect(typeChoice->GetId(), wxEVT_COMMAND_RADIOBOX_SELECTED,
 			wxCommandEventHandler(CreateMeshCMPT::onChangeType));
		sizer->Add(typeChoice);

		sizer->AddSpacer(5);

		wxCheckBox* regionSet = new wxCheckBox(this, wxID_ANY, wxT("ʹñ߽"),
			wxDefaultPosition, wxDefaultSize, wxCHK_2STATE);
		bool use_region = ShapeFactory::Instance()->IsUseRegion();
		regionSet->SetValue(use_region);
		Connect(regionSet->GetId(), wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(CreateMeshCMPT::onChangeUseRegion));
		sizer->Add(regionSet);
	}
	sizer->AddSpacer(15);
	{
		wxButton* btn = new wxButton(this, wxID_ANY, wxT("Copy..."));
		Connect(btn->GetId(), wxEVT_COMMAND_BUTTON_CLICKED,
			wxCommandEventHandler(CreateMeshCMPT::onCopy));
		sizer->Add(btn);
	}
	sizer->AddSpacer(10);
	{
		wxButton* btn = new wxButton(this, wxID_ANY, wxT("Clear"));
		Connect(btn->GetId(), wxEVT_COMMAND_BUTTON_CLICKED,
			wxCommandEventHandler(CreateMeshCMPT::onClear));
		sizer->Add(btn);
	}
	return sizer;
}

void CreateMeshCMPT::onChangeType(wxCommandEvent& event)
{
	int idx = event.GetSelection();
	switch (idx)
	{
	case 0:
		ShapeFactory::Instance()->SetShapeType(ST_MESH);
		break;
	case 1:
		ShapeFactory::Instance()->SetShapeType(ST_STRIP);
		break;
	}
}

void CreateMeshCMPT::onChangeUseRegion(wxCommandEvent& event)
{
	ShapeFactory::Instance()->SetUseRegion(event.IsChecked());
}

void CreateMeshCMPT::onCopy(wxCommandEvent& event)
{
// 	std::string tag = d2d::FileNameParser::getFileTag(d2d::FileNameParser::e_mesh);
// 	wxFileDialog dlg(this, wxT("Open"), wxEmptyString, wxEmptyString,
// 		wxT("*_") + tag + wxT(".json"), wxFD_OPEN);
// 	if (dlg.ShowModal() == wxID_OK)
// 	{
// 		FileIO::loadStruct(dlg.GetPath(), *m_stage->getMesh());
// 		m_editPanel->Refresh();
// 	}
}

void CreateMeshCMPT::onClear(wxCommandEvent& event)
{
	Shape* shape = m_stage->getShape();
	if (shape) {
		shape->Clear();
	}
	m_stage->clearShapes();

	m_editPanel->Refresh();
	m_editOP->clear();
}

}<|endoftext|>


<commit_before>/* ---------------------------------------------------------------------
 * Numenta Platform for Intelligent Computing (NuPIC)
 * Copyright (C) 2013, Numenta, Inc.  Unless you have an agreement
 * with Numenta, Inc., for a separate license for this software code, the
 * following terms and conditions apply:
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 3 as
 * published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see http://www.gnu.org/licenses.
 *
 * http://numenta.org/licenses/
 * ---------------------------------------------------------------------
 */

/* @file NuPIC init/shutdown operations */

#include <set>

/** @namespace nta
 * Contains the primary NuPIC API.
 */
namespace nta
{
  class Network;

  /**
   * Contains initialization and shutdown operations
   */
  class NuPIC
  {
  public:
    /** TODO: document */
    static void init();
    /** TODO: document */
    static void shutdown();
    /** TODO: document */
    static bool isInitialized();
  private:
    /**
     * As a safety measure, don't allow NuPIC to be shut down
     * if there are any networks still around. Networks
     * register/unregister themselves at creation and
     * destruction time.
     *
     * TBD: license checking will be done in NuPIC::init()
     */
    friend class Network;
    static void registerNetwork(Network* net);
    static void unregisterNetwork(Network* net);
    static std::set<Network*> networks_;
    static bool initialized_;
  };
} // namespace nta

<commit_msg>Document NuPIC.hpp<commit_after>/* ---------------------------------------------------------------------
 * Numenta Platform for Intelligent Computing (NuPIC)
 * Copyright (C) 2013, Numenta, Inc.  Unless you have an agreement
 * with Numenta, Inc., for a separate license for this software code, the
 * following terms and conditions apply:
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 3 as
 * published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see http://www.gnu.org/licenses.
 *
 * http://numenta.org/licenses/
 * ---------------------------------------------------------------------
 */

/* @file NuPIC init/shutdown operations */

#include <set>

/** @namespace nta
 *
 * Contains the primary NuPIC API.
 */
namespace nta
{
  class Network;

  /**
   * Contains initialization and shutdown operations
   */
  class NuPIC
  {
  public:
    /**
     * Initialize NuPIC.
     *
     * @note Creating a Network will auto-initialize NuPIC.
     */
    static void init();

    /**
     * Shutdown NuPIC.
     *
     * @note Shutting down NuPIC with any Network still registered to it will fail.
     */
    static void shutdown();

    /**
     *
     * @return Whether NuPIC is initialized successfully.
     */
    static bool isInitialized();
  private:
    /*
     * As a safety measure, don't allow NuPIC to be shut down
     * if there are any networks still around. Networks
     * register/unregister themselves at creation and
     * destruction time.
     *
     * TBD: license checking will be done in NuPIC::init()
     */

    friend class Network;
    static void registerNetwork(Network* net);
    static void unregisterNetwork(Network* net);
    static std::set<Network*> networks_;
    static bool initialized_;
  };
} // namespace nta

<|endoftext|>


<commit_before>#include <image_cloud/common/small_helpers.hpp>
#include <image_cloud/common/type.hpp>
#include <image_cloud/common/calibration/multi_score.hpp>
#include <image_cloud/common/calibration/structs.hpp>

#include <opencv2/core/core.hpp>
#include <math.h>

#ifndef SEARCH_GRID_6_DH_
#define SEARCH_GRID_6D_H_

namespace search
{

struct Value{
	float min;
	float max;
	int step_count;
	float step_width;

	Value( float value, float range, int step_count = 3){
		init_min_max(value - range/2, value + range/2, step_count);
	}

	void init_range( float value, float range, int step_count = 3){
		init_min_max(value - range/2, value + range/2, step_count);
	}

	void init_min_max(float min, float max, int step_count = 3){
		assert(min < max);
		assert(step_count > 1);
		this->min = min;
		this->max = max;
		this->step_count = step_count;
		step_width = (max - min)/step_count;
	}

	float at(int step){
		assert(step < step_count);
		return min + (step_width*step);
	}
};

struct Search_setup{
	Value x;
	Value y;
	Value z;
	Value roll;
	Value pitch;
	Value yaw;
};

struct Search_value{
	Search_value(){
		init(0, 0, 0, 0, 0, 0, 0);
	}

	Search_value( float x, float y, float z, float roll, float pitch, float yaw, long unsigned int result = 0){
		init(x, y, z, roll, pitch, yaw, result);
	}

	void init(float x, float y, float z, float roll, float pitch, float yaw, long unsigned int result = 0)
	{
		this->x = x;
		this->y = y;
		this->z = z;
		this->roll = roll;
		this->pitch = pitch;
		this->yaw = yaw;
		this->result = result;
	}

	std::string to_string(){
		std::stringstream ss;
		ss << "x: " << x << " y: " << y <<" z: " << z;
		ss << " roll: " << roll << " pitch: " << pitch << " yaw: " << yaw;
		ss << "result: " << result << "\n";
		return ss.str();
	}

	float x;
	float y;
	float z;
	float roll;
	float pitch;
	float yaw;
	long unsigned int result;
};

	void grid_setup(Search_setup setup, std::vector<Search_value>& results){
		for(int x=0; x < setup.x.step_count; ++x)
		{
			for(int y=0; y < setup.y.step_count; ++x)
			{
				for(int z=0; z < setup.z.step_count; ++x)
				{
					for(int roll=0; roll < setup.roll.step_count; ++x)
					{
						for(int pitch=0; pitch < setup.pitch.step_count; ++x)
						{
							for(int yaw=0; yaw < setup.yaw.step_count; ++x)
							{
								results.push_back(Search_value(setup.x.at(x), setup.x.at(y), setup.x.at(z), setup.x.at(roll), setup.x.at(pitch), setup.x.at(yaw)));
							}
						}
					}
				}
			}
		}
	}

	template <typename PointT, typename ImageT>
	void grid_calculate(const image_geometry::PinholeCameraModel &camera_model, const std::vector<pcl::PointCloud<PointT> > &pointclouds, const std::vector<cv::Mat> &edge_images, std::vector<Search_value>& results){
		for(int i=0; i < results; ++i){
			multi_score<PointT, ImageT>(camera_model, pointclouds, edge_images, results.at(i));
		}
	}
}
<commit_msg>fixed copy paste errors, refactored structs to own file<commit_after>#include <image_cloud/common/small_helpers.hpp>
#include <image_cloud/common/type.hpp>
#include <image_cloud/common/calibration/multi_score.hpp>
#include <image_cloud/common/calibration/structs.hpp>

#include <opencv2/core/core.hpp>
#include <math.h>

#ifndef SEARCH_GRID_6D_H_
#define SEARCH_GRID_6D_H_

namespace search
{
	void grid_setup(Search_setup setup, std::vector<Search_value>& results){
		for(int x=0; x < setup.x.steps_max; ++x)
		{
			for(int y=0; y < setup.y.steps_max; ++y)
			{
				for(int z=0; z < setup.z.steps_max; ++z)
				{
					for(int roll=0; roll < setup.roll.steps_max; ++roll)
					{
						for(int pitch=0; pitch < setup.pitch.steps_max; ++pitch)
						{
							for(int yaw=0; yaw < setup.yaw.steps_max; ++yaw)
							{
								results.push_back(Search_value(setup.x.at(x), setup.y.at(y), setup.z.at(z), setup.roll.at(roll), setup.pitch.at(pitch), setup.yaw.at(yaw)));
							}
						}
					}
				}
			}
		}
	}

	template <typename PointT, typename ImageT>
	inline void calculate(const image_geometry::PinholeCameraModel &camera_model, const std::vector<pcl::PointCloud<PointT> > &pointclouds, const std::vector<cv::Mat> &edge_images, std::vector<Search_value>& results){
		for(int i=0; i < results.size(); ++i){
			score::multi_score<PointT, ImageT>(camera_model, pointclouds, edge_images, results.at(i));
		}
	}
}

#endif
<|endoftext|>


<commit_before><commit_msg>PCC QA task: changed binning and include check for fMCWeights object<commit_after><|endoftext|>