<commit_before>/*
 * This is part of the FL library, a C++ Bayesian filtering library
 * (https://github.com/filtering-library)
 *
 * Copyright (c) 2014 Jan Issac (jan.issac@gmail.com)
 * Copyright (c) 2014 Manuel Wuthrich (manuel.wuthrich@gmail.com)
 *
 * Max-Planck Institute for Intelligent Systems, AMD Lab
 * University of Southern California, CLMC Lab
 *
 * This Source Code Form is subject to the terms of the MIT License (MIT).
 * A copy of the license can be found in the LICENSE file distributed with this
 * source code.
 */

/**
 * \file point_set.hpp
 * \date October 2014
 * \author Jan Issac (jan.issac@gmail.com)
 */

#ifndef FL__FILTER__GAUSSIAN__POINT_SET_HPP
#define FL__FILTER__GAUSSIAN__POINT_SET_HPP

#include <map>
#include <cmath>
#include <type_traits>

#include <Eigen/Dense>

#include <fl/util/meta.hpp>
#include <fl/util/traits.hpp>

#include <fl/distribution/gaussian.hpp>
#include <fl/exception/exception.hpp>
#include <fl/filter/filter_interface.hpp>

/** \cond internal */
/**
 * Checks dimensions
 */
#define INLINE_CHECK_POINT_SET_DIMENSIONS() \
    assert(points_.cols() == int(weights_.size())); \
    if (points_.rows() == 0) \
    { \
        fl_throw(ZeroDimensionException("PointSet")); \
    } \
    if (points_.cols() == 0)  \
    { \
        fl_throw(Exception("PointSet contains no points.")); \
    }

/**
 * Checks for index out of bounds and valid dimensions
 */
#define INLINE_CHECK_POINT_SET_BOUNDS(i) \
    if (i >= int(weights_.size())) \
    { \
        fl_throw(OutOfBoundsException(i, weights_.size())); \
    } \
    INLINE_CHECK_POINT_SET_DIMENSIONS();
/** \endcond */

namespace fl
{

// Forward declaration
template <typename Point, int Points_> class PointSet;

/**
 * Trait struct of a PointSet
 */
template <typename Point_, int Points_>
struct Traits<PointSet<Point_, Points_>>
{
    /**
     * \brief Point type
     */
    typedef Point_ Point;

    /**
     * \brief Number of points for fixed-size set
     */
    enum
    {
        /**
         * \brief Number of points which provided by the PointSet.
         *
         * If the number of points is unknown and there for dynamic, then
         * NumberOfPoints is set to Eigen::Dynamic
         */
        NumberOfPoints = IsFixed<Points_>() ? Points_ : Eigen::Dynamic
    };

    /**
     * \brief Weight harbors the weights of a point. For each of the first two
     * moments there is a separate weight.
     *
     *
     * Generally a single weight suffices. However, some transforms utilize
     * different weights for each moment to select a set of points representing
     * the underlying moments.
     */
    struct Weight
    {
        /**
         * First moment (mean) point weight
         */
        double w_mean;

        /**
         * Second centered moment (covariance) point weight
         */
        double w_cov;
    };

    /**
     * \brief Point container type
     *
     * \details
     * The point container type has a fixed-size dimension of a point
     * and the number of the points is statically known.
     */
    typedef Eigen::Matrix<
                typename Point::Scalar,
                Point::RowsAtCompileTime,
                Points_
            > PointMatrix;

    /**
     * \brief WeightVector
     */
    typedef Eigen::Matrix<
                typename Point::Scalar,
                Points_,
                1
            > WeightVector;

    /**
     * \brief Weight list of all points
     */
    typedef Eigen::Array<Weight, Points_, 1> Weights;
};

/**
 * \class PointSet
 *
 * \ingroup nonlinear_gaussian_filter
 *
 * PointSet represents a container of fixed-size or dynamic-size points each
 * paired with a set of weights. PointSet has two degree-of-freedoms. The first
 * is the dimension of the points. The second is the number of points within the
 * set. Each of the parameter can either be fixed at compile time or left
 * unspecified. That is, the parameter is set to Eigen::Dynamic.
 *
 * \tparam Point    Gaussian variable type
 * \tparam Points_  Number of points representing the gaussian
 */
template <typename Point_, int Points_ = -1>
class PointSet
{
private:
    /** Typdef of \c This for #from_traits(TypeName) helper */
    typedef PointSet<Point_, Points_> This;

public:
    typedef from_traits(Point);
    typedef from_traits(PointMatrix);
    typedef from_traits(Weight);
    typedef from_traits(Weights);
    typedef from_traits(WeightVector);

public:
    /**
     * Creates a PointSet
     *
     * \param points_count   Number of points representing the Gaussian
     * \param dimension      Sample space dimension
     */
    PointSet(int dimension,
             int points_count = ToDimension<Points_>())
        : points_(dimension, points_count),
          weights_(points_count, 1)
    {
        assert(points_count >= 0);
        static_assert(Points_ >= Eigen::Dynamic, "Invalid point count");

        points_.setZero();

        double weight = (points_count > 0) ? 1./double(points_count) : 0;
        weights_.fill(Weight{weight, weight});
    }

    /**
     * Creates a PointSet
     */
    PointSet()
    {
        points_.setZero();

        double weight = (weights_.size() > 0) ? 1./double(weights_.size()) : 0;
        weights_.fill(Weight{weight, weight});
    }

    /**
     * \brief Overridable default destructor
     */
    virtual ~PointSet() { }

    /**
     * Resizes a dynamic-size PointSet
     *
     * \param Points_   Number of points
     *
     * \throws ResizingFixedSizeEntityException
     */
    void resize(int points_count)
    {
        if (int(weights_.size()) == points_count &&
            int(points_.cols()) == points_count) return;

        if (IsFixed<Points_>())
        {
            fl_throw(
                fl::ResizingFixedSizeEntityException(weights_.size(),
                                                     points_count,
                                                     "poit set Gaussian"));
        }

        points_.setZero(points_.rows(), points_count);

        weights_.resize(points_count, 1);
        const double weight = (points_count > 0)? 1. / double(points_count) : 0;
        for (int i = 0; i < points_count; ++i)
        {
            weights_(i).w_mean = weight;
            weights_(i).w_cov = weight;
        }

        // std::fill(weights_.begin(), weights_.end(), Weight{weight, weight});
    }

    /**
     * Resizes a dynamic-size PointSet
     *
     * \param Points_   Number of points
     *
     * \throws ResizingFixedSizeEntityException
     */
    void resize(int dim, int points_count)
    {
        if (dim == dimension() && points_count == count_points()) return;

        points_.setZero(dim, points_count);

        weights_.resize(points_count, 1);
        const double weight = (points_count > 0)? 1. / double(points_count) : 0;
        for (int i = 0; i < points_count; ++i)
        {
            weights_(i).w_mean = weight;
            weights_(i).w_cov = weight;
        }
    }

    /**
     * Sets the new dimension for dynamic-size points (not to confuse
     * with the number of points)
     *
     * \param dim  Dimension of each point
     */
    void dimension(int dim)
    {
        points_.resize(dim, count_points());
    }

    /**
     * \return Dimension of containing points
     */
    int dimension() const
    {
        return points_.rows();
    }

    /**
     * \return The number of points
     */
    int count_points() const
    {
        return points_.cols();
    }

    /**
     * \return read only access on i-th point
     *
     * \param i Index of requested point
     *
     * \throws OutOfBoundsException
     * \throws ZeroDimensionException
     */
    Point point(int i) const
    {
        INLINE_CHECK_POINT_SET_BOUNDS(i);

        return points_.col(i);
    }

    auto operator[](int i) -> decltype(PointMatrix().col(i))
    {
        return points_.col(i);
    }

    /**
     * \return weight of i-th point assuming both weights are the same
     *
     * \param i Index of requested point
     *
     * \throws OutOfBoundsException
     * \throws ZeroDimensionException
     */
    double weight(int i)
    {
        INLINE_CHECK_POINT_SET_BOUNDS(i);

        return weights_(i).w_mean;
    }

    /**
     * \return weights of i-th point
     *
     * \param i Index of requested point
     *
     * \throws OutOfBoundsException
     * \throws ZeroDimensionException
     */
    const Weight& weights(int i) const
    {
        INLINE_CHECK_POINT_SET_BOUNDS(i);

        return weights_(i);
    }

    /**
     * \return Point matrix (read only)
     */
    const PointMatrix& points() const noexcept
    {
        return points_;
    }

    /**
     * \return Point matrix
     */
    PointMatrix& points()
    {
        return points_;
    }

    /**
     * \return point weights vector
     */
    const Weights& weights() const noexcept
    {
        return weights_;
    }

    /**
     * \return Returns the weights for the mean of the points as a vector
     */
    WeightVector mean_weights_vector() const noexcept
    {
        const int point_count = count_points();

        WeightVector weight_vec(point_count);

        for (int i = 0; i < point_count; ++i)
        {
            weight_vec(i) = weights_(i).w_mean;
        }

        return weight_vec;
    }

    /**
     * \return Returns the weights for the covariance of the points as a vector
     */
    WeightVector covariance_weights_vector() const noexcept
    {
        const int point_count = count_points();

        WeightVector weight_vec(point_count);

        for (int i = 0; i < point_count; ++i)
        {
            weight_vec(i) = weights_(i).w_cov;
        }

        return weight_vec;
    }

    /**
     * Sets the given point matrix
     */
    void points(const PointMatrix& point_matrix)
    {
        points_ = point_matrix;
    }

    /**
     * Sets a given point at position i
     *
     * \param i         Index of point
     * \param p         The new point
     *
     * \throws OutOfBoundsException
     * \throws ZeroDimensionException
     */
    void point(int i, Point p)
    {
        INLINE_CHECK_POINT_SET_BOUNDS(i);

        points_.col(i) = p;
    }

    /**
     * Sets a given point at position i along with its weights
     *
     * \param i         Index of point
     * \param p         The new point
     * \param w         Point weights. The weights determinaing the first two
     *                  moments are the same
     *
     * \throws OutOfBoundsException
     * \throws ZeroDimensionException
     */
    void point(int i, Point p, double w)
    {
        point(i, p, Weight{w, w});
    }

    /**
     * Sets a given point at position i along with its weights
     *
     * \param i         Index of point
     * \param p         The new point
     * \param w_mean    point weight used to compute the first moment
     * \param w_cov     point weight used to compute the second centered moment
     *
     * \throws OutOfBoundsException
     * \throws ZeroDimensionException
     */
    void point(int i, Point p, double w_mean , double w_cov)
    {
        point(i, p, Weight{w_mean, w_cov});
    }

    /**
     * Sets a given point at given position i along with its weights
     *
     * \param i         Index of point
     * \param p         The new point
     * \param weights   point weights
     *
     * \throws OutOfBoundsException
     * \throws ZeroDimensionException
     */
    void point(int i, Point p, Weight weights)
    {
        INLINE_CHECK_POINT_SET_BOUNDS(i);

        points_.col(i) = p;
        weights_(i) = weights;
    }

    /**
     * Sets a given weight of a point at position i
     *
     * \param i         Index of point
     * \param w         Point weights. The weights determinaing the first two
     *                  moments are the same
     *
     * \throws OutOfBoundsException
     * \throws ZeroDimensionException
     */
    void weight(int i, double w)
    {
        weight(i, Weight{w, w});
    }

    /**
     * Sets given weights of a point at position i
     *
     * \param i         Index of point
     * \param w_mean    point weight used to compute the first moment
     * \param w_cov     point weight used to compute the second centered moment
     *
     * \throws OutOfBoundsException
     * \throws ZeroDimensionException
     */
    void weight(int i, double w_mean , double w_cov)
    {
        weight(i, Weight{w_mean, w_cov});
    }

    /**
     * Sets given weights of a point at position i
     *
     * \param i         Index of point
     * \param weights   point weights
     *
     * \throws OutOfBoundsException
     * \throws ZeroDimensionException
     */
    void weight(int i, Weight weights)
    {
        INLINE_CHECK_POINT_SET_BOUNDS(i);

        weights_(i) = weights;
    }

    /**
     * \return Centered points matrix.
     *
     * Creates a PointMatrix populated with zero mean points
     *
     * \throws ZeroDimensionException
     * \throws Exception
     */
    PointMatrix centered_points() const
    {
        INLINE_CHECK_POINT_SET_DIMENSIONS();

        PointMatrix centered(points_.rows(), points_.cols());

        const Point weighted_mean = mean();
        const int point_count = points_.cols();
        for (int i = 0; i < point_count; ++i)
        {
            centered.col(i) = points_.col(i) - weighted_mean;
        }

        return centered;
    }

    Point center()
    {
        const Point weighted_mean = mean();
        const int point_count = points_.cols();
        for (int i = 0; i < point_count; ++i)
        {
            points_.col(i) -= weighted_mean;
        }

        return weighted_mean;
    }

    /**
     * \return The weighted mean of all points
     *
     * \throws ZeroDimensionException
     * \throws Exception
     */
    Point mean() const
    {
        INLINE_CHECK_POINT_SET_DIMENSIONS();

        Point weighted_mean;
        weighted_mean.setZero(points_.rows());

        const int point_count = points_.cols();
        for (int i = 0; i < point_count; ++i)
        {
            weighted_mean += weights_(i).w_mean * points_.col(i);
        }

        return weighted_mean;
    }

protected:
    /**
     * \brief point container
     */
    PointMatrix points_;

    /**
     * \brief weight container
     */
    Weights weights_;
};

}

#endif
<commit_msg>Doc updates<commit_after>/*
 * This is part of the FL library, a C++ Bayesian filtering library
 * (https://github.com/filtering-library)
 *
 * Copyright (c) 2014 Jan Issac (jan.issac@gmail.com)
 * Copyright (c) 2014 Manuel Wuthrich (manuel.wuthrich@gmail.com)
 *
 * Max-Planck Institute for Intelligent Systems, AMD Lab
 * University of Southern California, CLMC Lab
 *
 * This Source Code Form is subject to the terms of the MIT License (MIT).
 * A copy of the license can be found in the LICENSE file distributed with this
 * source code.
 */

/**
 * \file point_set.hpp
 * \date October 2014
 * \author Jan Issac (jan.issac@gmail.com)
 */

#ifndef FL__FILTER__GAUSSIAN__POINT_SET_HPP
#define FL__FILTER__GAUSSIAN__POINT_SET_HPP

#include <map>
#include <cmath>
#include <type_traits>

#include <Eigen/Dense>

#include <fl/util/meta.hpp>
#include <fl/util/traits.hpp>

#include <fl/distribution/gaussian.hpp>
#include <fl/exception/exception.hpp>
#include <fl/filter/filter_interface.hpp>

/** \cond internal */
/**
 * Checks dimensions
 */
#define INLINE_CHECK_POINT_SET_DIMENSIONS() \
    assert(points_.cols() == int(weights_.size())); \
    if (points_.rows() == 0) \
    { \
        fl_throw(ZeroDimensionException("PointSet")); \
    } \
    if (points_.cols() == 0)  \
    { \
        fl_throw(Exception("PointSet contains no points.")); \
    }

/**
 * Checks for index out of bounds and valid dimensions
 */
#define INLINE_CHECK_POINT_SET_BOUNDS(i) \
    if (i >= int(weights_.size())) \
    { \
        fl_throw(OutOfBoundsException(i, weights_.size())); \
    } \
    INLINE_CHECK_POINT_SET_DIMENSIONS();
/** \endcond */

namespace fl
{

// Forward declaration
template <typename Point, int Points_> class PointSet;

/**
 * Trait struct of a PointSet
 */
template <typename Point_, int Points_>
struct Traits<PointSet<Point_, Points_>>
{
    /**
     * \brief Point type
     */
    typedef Point_ Point;

    /**
     * \brief Number of points for fixed-size set
     */
    enum
    {
        /**
         * \brief Number of points which provided by the PointSet.
         *
         * If the number of points is unknown and there for dynamic, then
         * NumberOfPoints is set to Eigen::Dynamic
         */
        NumberOfPoints = IsFixed<Points_>() ? Points_ : Eigen::Dynamic
    };

    /**
     * \brief Weight harbors the weights of a point. For each of the first two
     * moments there is a separate weight.
     *
     *
     * Generally a single weight suffices. However, some transforms utilize
     * different weights for each moment to select a set of points representing
     * the underlying moments.
     */
    struct Weight
    {
        /**
         * First moment (mean) point weight
         */
        double w_mean;

        /**
         * Second centered moment (covariance) point weight
         */
        double w_cov;
    };

    /**
     * \brief Point container type
     *
     * \details
     * The point container type has a fixed-size dimension of a point
     * and the number of the points is statically known.
     */
    typedef Eigen::Matrix<
                typename Point::Scalar,
                Point::RowsAtCompileTime,
                Points_
            > PointMatrix;

    /**
     * \brief WeightVector
     */
    typedef Eigen::Matrix<
                typename Point::Scalar,
                Points_,
                1
            > WeightVector;

    /**
     * \brief Weight list of all points
     */
    typedef Eigen::Array<Weight, Points_, 1> Weights;
};

/**
 * \ingroup nonlinear_gaussian_filter
 *
 * \brief PointSet represents a container of fixed-size or dynamic-size points each
 *        paired with a set of weights.
 *
 * PointSet has two degree-of-freedoms. The first
 * is the dimension of the points. The second is the number of points within the
 * set. Each of the parameter can either be fixed at compile time or left
 * unspecified. That is, the parameter is set to Eigen::Dynamic.
 *
 * \tparam Point    Gaussian variable type
 * \tparam Points_  Number of points representing the gaussian
 */
template <typename Point_, int Points_ = -1>
class PointSet
{
private:
    /** \brief Typdef of \c This for #from_traits(TypeName) helper */
    typedef PointSet<Point_, Points_> This;

public:
    typedef from_traits(Point);
    typedef from_traits(PointMatrix);
    typedef from_traits(Weight);
    typedef from_traits(Weights);
    typedef from_traits(WeightVector);

public:
    /**
     * \brief Creates a PointSet
     *
     * \param points_count   Number of points representing the Gaussian
     * \param dimension      Sample space dimension
     */
    PointSet(int dimension,
             int points_count = ToDimension<Points_>())
        : points_(dimension, points_count),
          weights_(points_count, 1)
    {
        assert(points_count >= 0);
        static_assert(Points_ >= Eigen::Dynamic, "Invalid point count");

        points_.setZero();

        double weight = (points_count > 0) ? 1./double(points_count) : 0;
        weights_.fill(Weight{weight, weight});
    }

    /**
     * \brief Creates a PointSet
     */
    PointSet()
    {
        points_.setZero();

        double weight = (weights_.size() > 0) ? 1./double(weights_.size()) : 0;
        weights_.fill(Weight{weight, weight});
    }

    /**
     * \brief Overridable default destructor
     */
    virtual ~PointSet() { }

    /**
     * \brief Resizes a dynamic-size PointSet
     *
     * \param Points_   Number of points
     *
     * \throws ResizingFixedSizeEntityException
     */
    void resize(int points_count)
    {
        if (int(weights_.size()) == points_count &&
            int(points_.cols()) == points_count) return;

        if (IsFixed<Points_>())
        {
            fl_throw(
                fl::ResizingFixedSizeEntityException(weights_.size(),
                                                     points_count,
                                                     "poit set Gaussian"));
        }

        points_.setZero(points_.rows(), points_count);

        weights_.resize(points_count, 1);
        const double weight = (points_count > 0)? 1. / double(points_count) : 0;
        for (int i = 0; i < points_count; ++i)
        {
            weights_(i).w_mean = weight;
            weights_(i).w_cov = weight;
        }

        // std::fill(weights_.begin(), weights_.end(), Weight{weight, weight});
    }

    /**
     * \brief Resizes a dynamic-size PointSet
     *
     * \param Points_   Number of points
     *
     * \throws ResizingFixedSizeEntityException
     */
    void resize(int dim, int points_count)
    {
        if (dim == dimension() && points_count == count_points()) return;

        points_.setZero(dim, points_count);

        weights_.resize(points_count, 1);
        const double weight = (points_count > 0)? 1. / double(points_count) : 0;
        for (int i = 0; i < points_count; ++i)
        {
            weights_(i).w_mean = weight;
            weights_(i).w_cov = weight;
        }
    }

    /**
     * \brief Sets the new dimension for dynamic-size points (not to confuse
     * with the number of points)
     *
     * \param dim  Dimension of each point
     */
    void dimension(int dim)
    {
        points_.resize(dim, count_points());
    }

    /**
     * \return Dimension of containing points
     */
    int dimension() const
    {
        return points_.rows();
    }

    /**
     * \brief  The number of points
     */
    int count_points() const
    {
        return points_.cols();
    }

    /**
     * \brief  Read only access on i-th point
     *
     * \param i Index of requested point
     *
     * \throws OutOfBoundsException
     * \throws ZeroDimensionException
     */
    Point point(int i) const
    {
        INLINE_CHECK_POINT_SET_BOUNDS(i);

        return points_.col(i);
    }

    auto operator[](int i) -> decltype(PointMatrix().col(i))
    {
        return points_.col(i);
    }

    /**
     * \brief  weight of i-th point assuming both weights are the same
     *
     * \param i Index of requested point
     *
     * \throws OutOfBoundsException
     * \throws ZeroDimensionException
     */
    double weight(int i)
    {
        INLINE_CHECK_POINT_SET_BOUNDS(i);

        return weights_(i).w_mean;
    }

    /**
     * \brief  weights of i-th point
     *
     * \param i Index of requested point
     *
     * \throws OutOfBoundsException
     * \throws ZeroDimensionException
     */
    const Weight& weights(int i) const
    {
        INLINE_CHECK_POINT_SET_BOUNDS(i);

        return weights_(i);
    }

    /**
     * \brief  Point matrix (read only)
     */
    const PointMatrix& points() const noexcept
    {
        return points_;
    }

    /**
     * \brief  Point matrix
     */
    PointMatrix& points()
    {
        return points_;
    }

    /**
     * \brief  point weights vector
     */
    const Weights& weights() const noexcept
    {
        return weights_;
    }

    /**
     * \brief  Returns the weights for the mean of the points as a vector
     */
    WeightVector mean_weights_vector() const noexcept
    {
        const int point_count = count_points();

        WeightVector weight_vec(point_count);

        for (int i = 0; i < point_count; ++i)
        {
            weight_vec(i) = weights_(i).w_mean;
        }

        return weight_vec;
    }

    /**
     * \brief  Returns the weights for the covariance of the points as a vector
     */
    WeightVector covariance_weights_vector() const noexcept
    {
        const int point_count = count_points();

        WeightVector weight_vec(point_count);

        for (int i = 0; i < point_count; ++i)
        {
            weight_vec(i) = weights_(i).w_cov;
        }

        return weight_vec;
    }

    /**
     * \brief Sets the given point matrix
     */
    void points(const PointMatrix& point_matrix)
    {
        points_ = point_matrix;
    }

    /**
     * \brief Sets a given point at position i
     *
     * \param i         Index of point
     * \param p         The new point
     *
     * \throws OutOfBoundsException
     * \throws ZeroDimensionException
     */
    void point(int i, Point p)
    {
        INLINE_CHECK_POINT_SET_BOUNDS(i);

        points_.col(i) = p;
    }

    /**
     * \brief Sets a given point at position i along with its weights
     *
     * \param i         Index of point
     * \param p         The new point
     * \param w         Point weights. The weights determinaing the first two
     *                  moments are the same
     *
     * \throws OutOfBoundsException
     * \throws ZeroDimensionException
     */
    void point(int i, Point p, double w)
    {
        point(i, p, Weight{w, w});
    }

    /**
     * \brief Sets a given point at position i along with its weights
     *
     * \param i         Index of point
     * \param p         The new point
     * \param w_mean    point weight used to compute the first moment
     * \param w_cov     point weight used to compute the second centered moment
     *
     * \throws OutOfBoundsException
     * \throws ZeroDimensionException
     */
    void point(int i, Point p, double w_mean , double w_cov)
    {
        point(i, p, Weight{w_mean, w_cov});
    }

    /**
     * \brief Sets a given point at given position i along with its weights
     *
     * \param i         Index of point
     * \param p         The new point
     * \param weights   point weights
     *
     * \throws OutOfBoundsException
     * \throws ZeroDimensionException
     */
    void point(int i, Point p, Weight weights)
    {
        INLINE_CHECK_POINT_SET_BOUNDS(i);

        points_.col(i) = p;
        weights_(i) = weights;
    }

    /**
     * \brief Sets a given weight of a point at position i
     *
     * \param i         Index of point
     * \param w         Point weights. The weights determinaing the first two
     *                  moments are the same
     *
     * \throws OutOfBoundsException
     * \throws ZeroDimensionException
     */
    void weight(int i, double w)
    {
        weight(i, Weight{w, w});
    }

    /**
     * \brief Sets given weights of a point at position i
     *
     * \param i         Index of point
     * \param w_mean    point weight used to compute the first moment
     * \param w_cov     point weight used to compute the second centered moment
     *
     * \throws OutOfBoundsException
     * \throws ZeroDimensionException
     */
    void weight(int i, double w_mean , double w_cov)
    {
        weight(i, Weight{w_mean, w_cov});
    }

    /**
     * Sets given weights of a point at position i
     *
     * \param i         Index of point
     * \param weights   point weights
     *
     * \throws OutOfBoundsException
     * \throws ZeroDimensionException
     */
    void weight(int i, Weight weights)
    {
        INLINE_CHECK_POINT_SET_BOUNDS(i);

        weights_(i) = weights;
    }

    /**
     * \brief Creates a PointMatrix populated with zero mean points
     *
     * \return Centered points matrix.
     *
     * \throws ZeroDimensionException
     * \throws Exception
     */
    PointMatrix centered_points() const
    {
        INLINE_CHECK_POINT_SET_DIMENSIONS();

        PointMatrix centered(points_.rows(), points_.cols());

        const Point weighted_mean = mean();
        const int point_count = points_.cols();
        for (int i = 0; i < point_count; ++i)
        {
            centered.col(i) = points_.col(i) - weighted_mean;
        }

        return centered;
    }

    /**
     * \brief Centers all points and returns the mean over all points.
     *
     * Computes the weighted mean of all points and subtracts the mean from all
     * points. Finally returns the weighted mean
     *
     * \return Weighted mean
     */
    Point center()
    {
        const Point weighted_mean = mean();
        const int point_count = points_.cols();
        for (int i = 0; i < point_count; ++i)
        {
            points_.col(i) -= weighted_mean;
        }

        return weighted_mean;
    }

    /**
     * \brief Returns the weighted mean of all points
     *
     * \throws ZeroDimensionException
     * \throws Exception
     */
    Point mean() const
    {
        INLINE_CHECK_POINT_SET_DIMENSIONS();

        Point weighted_mean;
        weighted_mean.setZero(points_.rows());

        const int point_count = points_.cols();
        for (int i = 0; i < point_count; ++i)
        {
            weighted_mean += weights_(i).w_mean * points_.col(i);
        }

        return weighted_mean;
    }

protected:
    /**
     * \brief point container
     */
    PointMatrix points_;

    /**
     * \brief weight container
     */
    Weights weights_;
};

}

#endif
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: except.cxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: mh $ $Date: 2002-10-02 11:41:21 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#include <stdio.h>
#include <dlfcn.h>
#include <cxxabi.h>
#include <hash_map>

#include <rtl/strbuf.hxx>
#include <rtl/ustrbuf.hxx>
#include <osl/diagnose.h>
#include <osl/mutex.hxx>

#include <bridges/cpp_uno/bridge.hxx>
#include <typelib/typedescription.hxx>
#include <uno/any2.h>

#include "share.hxx"

using namespace ::std;
using namespace ::osl;
using namespace ::rtl;
using namespace ::com::sun::star::uno;
using namespace ::__cxxabiv1;

namespace CPPU_CURRENT_NAMESPACE
{

void dummy_can_throw_anything( char const * )
{
}

//==================================================================================================
static OUString toUNOname( char const * p ) SAL_THROW( () )
{
#ifdef DEBUG
    char const * start = p;
#endif

    // example: N3com3sun4star4lang24IllegalArgumentExceptionE

    OUStringBuffer buf( 64 );
    OSL_ASSERT( 'N' == *p );
    ++p; // skip N

    while ('E' != *p)
    {
        // read chars count
        long n = (*p++ - '0');
        while ('0' <= *p && '9' >= *p)
        {
            n *= 10;
            n += (*p++ - '0');
        }
        buf.appendAscii( p, n );
        p += n;
        if ('E' != *p)
            buf.append( (sal_Unicode)'.' );
    }

#ifdef DEBUG
    OUString ret( buf.makeStringAndClear() );
    OString c_ret( OUStringToOString( ret, RTL_TEXTENCODING_ASCII_US ) );
    fprintf( stderr, "> toUNOname(): %s => %s\n", start, c_ret.getStr() );
    return ret;
#else
    return buf.makeStringAndClear();
#endif
}

//==================================================================================================
class RTTI
{
    typedef hash_map< OUString, type_info *, OUStringHash > t_rtti_map;

    Mutex m_mutex;
    t_rtti_map m_rttis;
    t_rtti_map m_generatedRttis;

    void * m_hApp;

public:
    RTTI() SAL_THROW( () );
    ~RTTI() SAL_THROW( () );

    type_info * getRTTI( typelib_CompoundTypeDescription * ) SAL_THROW( () );
};
//__________________________________________________________________________________________________
RTTI::RTTI() SAL_THROW( () )
    : m_hApp( dlopen( 0, RTLD_LAZY ) )
{
}
//__________________________________________________________________________________________________
RTTI::~RTTI() SAL_THROW( () )
{
    dlclose( m_hApp );
}

//__________________________________________________________________________________________________
type_info * RTTI::getRTTI( typelib_CompoundTypeDescription *pTypeDescr ) SAL_THROW( () )
{
    type_info * rtti;

    OUString const & unoName = *(OUString const *)&pTypeDescr->aBase.pTypeName;

    MutexGuard guard( m_mutex );
    t_rtti_map::const_iterator iFind( m_rttis.find( unoName ) );
    if (iFind == m_rttis.end())
    {
        // RTTI symbol
        OStringBuffer buf( 64 );
        buf.append( RTL_CONSTASCII_STRINGPARAM("_ZTIN") );
        sal_Int32 index = 0;
        do
        {
            OUString token( unoName.getToken( 0, '.', index ) );
            buf.append( token.getLength() );
            OString c_token( OUStringToOString( token, RTL_TEXTENCODING_ASCII_US ) );
            buf.append( c_token );
        }
        while (index >= 0);
        buf.append( 'E' );

        OString symName( buf.makeStringAndClear() );
        rtti = (type_info *)dlsym( m_hApp, symName.getStr() );

        if (rtti)
        {
            pair< t_rtti_map::iterator, bool > insertion(
                m_rttis.insert( t_rtti_map::value_type( unoName, rtti ) ) );
            OSL_ENSURE( insertion.second, "### inserting new rtti failed?!" );
        }
        else
        {
            // try to lookup the symbol in the generated rtti map
            t_rtti_map::const_iterator iFind( m_generatedRttis.find( unoName ) );
            if (iFind == m_generatedRttis.end())
            {
                // we must generate it !
                // symbol and rtti-name is nearly identical,
                // the symbol is prefixed with _ZTI
                char const * rttiName = symName.getStr() +4;
#ifdef DEBUG
                fprintf( stderr,"generated rtti for %s\n", rttiName );
#endif
                if (pTypeDescr->pBaseTypeDescription)
                {
                    // ensure availability of base
                    type_info * base_rtti = getRTTI(
                        (typelib_CompoundTypeDescription *)pTypeDescr->pBaseTypeDescription );
                    rtti = new __si_class_type_info(
                        strdup( rttiName ), (__class_type_info *)base_rtti );
                }
                else
                {
                    // this class has no base class
                    rtti = new __class_type_info( strdup( rttiName ) );
                }

                pair< t_rtti_map::iterator, bool > insertion(
                    m_generatedRttis.insert( t_rtti_map::value_type( unoName, rtti ) ) );
                OSL_ENSURE( insertion.second, "### inserting new generated rtti failed?!" );
            }
            else // taking already generated rtti
            {
                rtti = iFind->second;
            }
        }
    }
    else
    {
        rtti = iFind->second;
    }

    return rtti;
}

//--------------------------------------------------------------------------------------------------
static void deleteException( void * pExc )
{
    __cxa_exception const * header = ((__cxa_exception const *)pExc - 1);
    typelib_TypeDescription * pTD = 0;
    OUString unoName( toUNOname( header->exceptionType->name() ) );
    ::typelib_typedescription_getByName( &pTD, unoName.pData );
    OSL_ENSURE( pTD, "### unknown exception type! leaving out destruction => leaking!!!" );
    if (pTD)
    {
        ::uno_destructData( pExc, pTD, cpp_release );
        ::typelib_typedescription_release( pTD );
    }
}

//==================================================================================================
void raiseException( uno_Any * pUnoExc, uno_Mapping * pUno2Cpp )
{
    void * pCppExc;
    type_info * rtti;

    {
    // construct cpp exception object
    typelib_TypeDescription * pTypeDescr = 0;
    TYPELIB_DANGER_GET( &pTypeDescr, pUnoExc->pType );
    OSL_ASSERT( pTypeDescr );
    if (! pTypeDescr)
        terminate();

    pCppExc = __cxa_allocate_exception( pTypeDescr->nSize );
    ::uno_copyAndConvertData( pCppExc, pUnoExc->pData, pTypeDescr, pUno2Cpp );

    // destruct uno exception
    ::uno_any_destruct( pUnoExc, 0 );
    // avoiding locked counts
    static RTTI * s_rtti = 0;
    if (! s_rtti)
    {
        MutexGuard guard( Mutex::getGlobalMutex() );
        if (! s_rtti)
        {
#ifdef LEAK_STATIC_DATA
            s_rtti = new RTTI();
#else
            static RTTI rtti_data;
            s_rtti = &rtti_data;
#endif
        }
    }
    rtti = (type_info *)s_rtti->getRTTI( (typelib_CompoundTypeDescription *) pTypeDescr );
    TYPELIB_DANGER_RELEASE( pTypeDescr );
    OSL_ENSURE( rtti, "### no rtti for throwing exception!" );
    if (! rtti)
        terminate();
    }

    __cxa_throw( pCppExc, rtti, deleteException );
}

//==================================================================================================
void fillUnoException( __cxa_exception * header, uno_Any * pExc, uno_Mapping * pCpp2Uno )
{
    OSL_ENSURE( header, "### no exception header!!!" );
    if (! header)
        terminate();

    typelib_TypeDescription * pExcTypeDescr = 0;
    OUString unoName( toUNOname( header->exceptionType->name() ) );
    ::typelib_typedescription_getByName( &pExcTypeDescr, unoName.pData );
    OSL_ENSURE( pExcTypeDescr, "### can not get type description for exception!!!" );
    if (! pExcTypeDescr)
        terminate();

    // construct uno exception any
    ::uno_any_constructAndConvert( pExc, header->adjustedPtr, pExcTypeDescr, pCpp2Uno );
    ::typelib_typedescription_release( pExcTypeDescr );
}

}

<commit_msg>INTEGRATION: CWS dbgmacros1 (1.3.36); FILE MERGED 2003/04/09 10:15:35 kso 1.3.36.1: #108413# - debug macro unification.<commit_after>/*************************************************************************
 *
 *  $RCSfile: except.cxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: vg $ $Date: 2003-04-15 16:26:17 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#include <stdio.h>
#include <dlfcn.h>
#include <cxxabi.h>
#include <hash_map>

#include <rtl/strbuf.hxx>
#include <rtl/ustrbuf.hxx>
#include <osl/diagnose.h>
#include <osl/mutex.hxx>

#include <bridges/cpp_uno/bridge.hxx>
#include <typelib/typedescription.hxx>
#include <uno/any2.h>

#include "share.hxx"

using namespace ::std;
using namespace ::osl;
using namespace ::rtl;
using namespace ::com::sun::star::uno;
using namespace ::__cxxabiv1;

namespace CPPU_CURRENT_NAMESPACE
{

void dummy_can_throw_anything( char const * )
{
}

//==================================================================================================
static OUString toUNOname( char const * p ) SAL_THROW( () )
{
#if OSL_DEBUG_LEVEL > 1
    char const * start = p;
#endif

    // example: N3com3sun4star4lang24IllegalArgumentExceptionE

    OUStringBuffer buf( 64 );
    OSL_ASSERT( 'N' == *p );
    ++p; // skip N

    while ('E' != *p)
    {
        // read chars count
        long n = (*p++ - '0');
        while ('0' <= *p && '9' >= *p)
        {
            n *= 10;
            n += (*p++ - '0');
        }
        buf.appendAscii( p, n );
        p += n;
        if ('E' != *p)
            buf.append( (sal_Unicode)'.' );
    }

#if OSL_DEBUG_LEVEL > 1
    OUString ret( buf.makeStringAndClear() );
    OString c_ret( OUStringToOString( ret, RTL_TEXTENCODING_ASCII_US ) );
    fprintf( stderr, "> toUNOname(): %s => %s\n", start, c_ret.getStr() );
    return ret;
#else
    return buf.makeStringAndClear();
#endif
}

//==================================================================================================
class RTTI
{
    typedef hash_map< OUString, type_info *, OUStringHash > t_rtti_map;

    Mutex m_mutex;
    t_rtti_map m_rttis;
    t_rtti_map m_generatedRttis;

    void * m_hApp;

public:
    RTTI() SAL_THROW( () );
    ~RTTI() SAL_THROW( () );

    type_info * getRTTI( typelib_CompoundTypeDescription * ) SAL_THROW( () );
};
//__________________________________________________________________________________________________
RTTI::RTTI() SAL_THROW( () )
    : m_hApp( dlopen( 0, RTLD_LAZY ) )
{
}
//__________________________________________________________________________________________________
RTTI::~RTTI() SAL_THROW( () )
{
    dlclose( m_hApp );
}

//__________________________________________________________________________________________________
type_info * RTTI::getRTTI( typelib_CompoundTypeDescription *pTypeDescr ) SAL_THROW( () )
{
    type_info * rtti;

    OUString const & unoName = *(OUString const *)&pTypeDescr->aBase.pTypeName;

    MutexGuard guard( m_mutex );
    t_rtti_map::const_iterator iFind( m_rttis.find( unoName ) );
    if (iFind == m_rttis.end())
    {
        // RTTI symbol
        OStringBuffer buf( 64 );
        buf.append( RTL_CONSTASCII_STRINGPARAM("_ZTIN") );
        sal_Int32 index = 0;
        do
        {
            OUString token( unoName.getToken( 0, '.', index ) );
            buf.append( token.getLength() );
            OString c_token( OUStringToOString( token, RTL_TEXTENCODING_ASCII_US ) );
            buf.append( c_token );
        }
        while (index >= 0);
        buf.append( 'E' );

        OString symName( buf.makeStringAndClear() );
        rtti = (type_info *)dlsym( m_hApp, symName.getStr() );

        if (rtti)
        {
            pair< t_rtti_map::iterator, bool > insertion(
                m_rttis.insert( t_rtti_map::value_type( unoName, rtti ) ) );
            OSL_ENSURE( insertion.second, "### inserting new rtti failed?!" );
        }
        else
        {
            // try to lookup the symbol in the generated rtti map
            t_rtti_map::const_iterator iFind( m_generatedRttis.find( unoName ) );
            if (iFind == m_generatedRttis.end())
            {
                // we must generate it !
                // symbol and rtti-name is nearly identical,
                // the symbol is prefixed with _ZTI
                char const * rttiName = symName.getStr() +4;
#if OSL_DEBUG_LEVEL > 1
                fprintf( stderr,"generated rtti for %s\n", rttiName );
#endif
                if (pTypeDescr->pBaseTypeDescription)
                {
                    // ensure availability of base
                    type_info * base_rtti = getRTTI(
                        (typelib_CompoundTypeDescription *)pTypeDescr->pBaseTypeDescription );
                    rtti = new __si_class_type_info(
                        strdup( rttiName ), (__class_type_info *)base_rtti );
                }
                else
                {
                    // this class has no base class
                    rtti = new __class_type_info( strdup( rttiName ) );
                }

                pair< t_rtti_map::iterator, bool > insertion(
                    m_generatedRttis.insert( t_rtti_map::value_type( unoName, rtti ) ) );
                OSL_ENSURE( insertion.second, "### inserting new generated rtti failed?!" );
            }
            else // taking already generated rtti
            {
                rtti = iFind->second;
            }
        }
    }
    else
    {
        rtti = iFind->second;
    }

    return rtti;
}

//--------------------------------------------------------------------------------------------------
static void deleteException( void * pExc )
{
    __cxa_exception const * header = ((__cxa_exception const *)pExc - 1);
    typelib_TypeDescription * pTD = 0;
    OUString unoName( toUNOname( header->exceptionType->name() ) );
    ::typelib_typedescription_getByName( &pTD, unoName.pData );
    OSL_ENSURE( pTD, "### unknown exception type! leaving out destruction => leaking!!!" );
    if (pTD)
    {
        ::uno_destructData( pExc, pTD, cpp_release );
        ::typelib_typedescription_release( pTD );
    }
}

//==================================================================================================
void raiseException( uno_Any * pUnoExc, uno_Mapping * pUno2Cpp )
{
    void * pCppExc;
    type_info * rtti;

    {
    // construct cpp exception object
    typelib_TypeDescription * pTypeDescr = 0;
    TYPELIB_DANGER_GET( &pTypeDescr, pUnoExc->pType );
    OSL_ASSERT( pTypeDescr );
    if (! pTypeDescr)
        terminate();

    pCppExc = __cxa_allocate_exception( pTypeDescr->nSize );
    ::uno_copyAndConvertData( pCppExc, pUnoExc->pData, pTypeDescr, pUno2Cpp );

    // destruct uno exception
    ::uno_any_destruct( pUnoExc, 0 );
    // avoiding locked counts
    static RTTI * s_rtti = 0;
    if (! s_rtti)
    {
        MutexGuard guard( Mutex::getGlobalMutex() );
        if (! s_rtti)
        {
#ifdef LEAK_STATIC_DATA
            s_rtti = new RTTI();
#else
            static RTTI rtti_data;
            s_rtti = &rtti_data;
#endif
        }
    }
    rtti = (type_info *)s_rtti->getRTTI( (typelib_CompoundTypeDescription *) pTypeDescr );
    TYPELIB_DANGER_RELEASE( pTypeDescr );
    OSL_ENSURE( rtti, "### no rtti for throwing exception!" );
    if (! rtti)
        terminate();
    }

    __cxa_throw( pCppExc, rtti, deleteException );
}

//==================================================================================================
void fillUnoException( __cxa_exception * header, uno_Any * pExc, uno_Mapping * pCpp2Uno )
{
    OSL_ENSURE( header, "### no exception header!!!" );
    if (! header)
        terminate();

    typelib_TypeDescription * pExcTypeDescr = 0;
    OUString unoName( toUNOname( header->exceptionType->name() ) );
    ::typelib_typedescription_getByName( &pExcTypeDescr, unoName.pData );
    OSL_ENSURE( pExcTypeDescr, "### can not get type description for exception!!!" );
    if (! pExcTypeDescr)
        terminate();

    // construct uno exception any
    ::uno_any_constructAndConvert( pExc, header->adjustedPtr, pExcTypeDescr, pCpp2Uno );
    ::typelib_typedescription_release( pExcTypeDescr );
}

}

<|endoftext|>


<commit_before>// An Homage to Vera Molnar's "An Homange to Durer"
SquareSize = [[Square Size]]
gridHeight = [[Grid Height]]
gridWidth = [[Grid Width]]

columnCounter = [[shiftCounter]]
rowCounter = [[rowCounter]]

if(columnCounter < [[gridWidth]]) {
  drawVeraLines([[columnCounter]], [[rowCounter]])
  columnCounter++;
} else if ([[rowCounter]] < [[gridHeight]]) {
  columnCounter = 0;
  rowCounter++;
} else {
  rowCounter = 0;
  columnCounter = 0;
}<commit_msg>Fix typo in pseudocode comment<commit_after>// An homage to Vera Molnar's "Hommage a Durer"
SquareSize = [[Square Size]]
gridHeight = [[Grid Height]]
gridWidth = [[Grid Width]]

columnCounter = [[shiftCounter]]
rowCounter = [[rowCounter]]

if(columnCounter < [[gridWidth]]) {
  drawVeraLines([[columnCounter]], [[rowCounter]])
  columnCounter++;
} else if ([[rowCounter]] < [[gridHeight]]) {
  columnCounter = 0;
  rowCounter++;
} else {
  rowCounter = 0;
  columnCounter = 0;
}<|endoftext|>


<commit_before>#ifndef DUNE_STUFF_FUNCTION_EXPRESSION_HH
#define DUNE_STUFF_FUNCTION_EXPRESSION_HH

#ifdef HAVE_CMAKE_CONFIG
  #include "cmake_config.h"
#else
  #include "config.h"
#endif // ifdef HAVE_CMAKE_CONFIG

#include <sstream>
#include <vector>

#ifdef HAVE_EIGEN
  #include <Eigen/Core>
#endif // HAVE_EIGEN

#include <dune/common/fvector.hh>
#include <dune/common/dynvector.hh>
#include <dune/common/exceptions.hh>

#ifdef HAVE_DUNE_FEM
  #include <dune/fem/function/common/function.hh>
  #include <dune/fem/space/common/functionspace.hh>
#endif // HAVE_DUNE_FEM

#include <dune/stuff/common/parameter/tree.hh>
#include <dune/stuff/common/string.hh>

#include "expression/mathexpr.hh"
#include "interface.hh"

namespace Dune {
namespace Stuff {
namespace Function {

/**
  \brief  Provides a function which evaluates a given mathematical expression at runtime.

          Given a mathematical expression as a string, a domain \f$ K_d^{m \geq 1} \f$ and a range \f$ K_r^{n \geq 1}
          \f$ this function represents the map
          \f{eqnarray}
            f:K_d^m \to K_r^n\\
            x = (x_1, \dots, x_m)' \mapsto (f_1(x), \dots f_n(x))',
          \f}
          where \f$ K_d \f$ is the DomainType and \f$ K_r \f$ is the RangeType, usually a power of \f$ \mathcal{R} \f$.
          The name of the variable as well as the \f$ n \f$ expressions of \f$f_1, \dots, f_n\f$ have to be given in a
          Dune::ParameterTree in the following form:
\code variable: x
expression.0: 2*x[0]
expression.1: sin(x[1])*x[0]\endcode
          There have to exist at least \f$n\f$ expressions; the entries of the variable are indexed by \f$[i]\f$ for
          \f$ 0 \leq i \leq m - 1 \f$.
 **/
template< class DomainFieldImp, int maxDimDomain, class RangeFieldImp, int maxDimRange >
class Expression
  : public Interface< DomainFieldImp, maxDimDomain, RangeFieldImp, maxDimRange >
{
public:
  typedef DomainFieldImp DomainFieldType;

  typedef RangeFieldImp RangeFieldType;

  typedef Interface< DomainFieldImp, maxDimDomain, RangeFieldImp, maxDimRange > BaseType;

  typedef Expression< DomainFieldImp, maxDimDomain, RangeFieldImp, maxDimRange > ThisType;

//  static const std::string id()
//  {
//    return BaseType::id() + ".expression";
//  }

  Expression(const std::string _variable, const std::string _expression)
  {
    const std::vector< std::string > expressions(1, _expression);
    setup(_variable, expressions);
  } // Expression(const std::string variable, const std::string expression)

  Expression(const std::string _variable, const std::vector< std::string > _expressions)
  {
    setup(_variable, _expressions);
  } // Expression(const std::string variable, const std::vector< std::string >& expressions)

  Expression(const ThisType& other)
  {
    setup(other.variable(), other.expression());
  } // Expression(const ThisType& other)

  static ThisType createFromParamTree(const Dune::ParameterTree& paramTree)
  {
    const Dune::Stuff::Common::ExtendedParameterTree extendedParamtree(paramTree);
    // get variable
    if (!extendedParamtree.hasKey("variable"))
      DUNE_THROW(Dune::RangeError, "\nError: missing key 'variable'!");
    const std::string variable = extendedParamtree.get("variable", "not_meaningful_default_value");
    // get expressions
    if (!extendedParamtree.hasKey("expression"))
      DUNE_THROW(Dune::RangeError, "\nError: missing key or vector 'expression'!");
    const std::vector< std::string > expressions
        = extendedParamtree.getVector< std::string >("expression", "not_meaningful_default_value");
    // create and return
    return ThisType(variable, expressions);
  } // static ThisType createFromParamTree(const Stuff::Common::ExtendedParameterTree& paramTree)

  ThisType& operator=(const ThisType& other)
  {
    if (this != &other) {
      cleanup();
      setup(other.variable(), other.expression());
    }
    return this;
  } // ThisType& operator=(const ThisType& other)

  ~Expression()
  {
    cleanup();
  } // ~Expression()

  std::string variable() const
  {
    return variable_;
  }

  const std::vector< std::string > expression() const
  {
    return expressions_;
  }

  unsigned int dimRange() const
  {
    return actualDimRange_;
  }

  //! needed for Interface
  virtual void evaluate(const Dune::FieldVector< DomainFieldImp, maxDimDomain >& arg, Dune::FieldVector< RangeFieldImp, maxDimRange >& ret) const
  {
    // ensure right dimensions
    assert(arg.size() <= maxDimDomain);
    assert(ret.size() <= dimRange());
    // arg
    for (typename Dune::FieldVector< DomainFieldImp, maxDimDomain >::size_type i = 0; i < arg.size(); ++i) {
      *(arg_[i]) = arg[i];
    }
    // ret
    for (typename Dune::FieldVector< RangeFieldImp, maxDimRange >::size_type i = 0; i < ret.size(); ++i) {
      ret[i] = op_[i]->Val();
    }
  }

  template< class DomainVectorType, class RangeVectorType >
  void evaluate(const Dune::DenseVector< DomainVectorType >& arg, Dune::DenseVector< RangeVectorType >& ret) const
  {
    // ensure right dimensions
    assert(arg.size() <= maxDimDomain);
    assert(ret.size() <= dimRange());
    // arg
    for (typename Dune::DenseVector< DomainVectorType >::size_type i = 0; i < arg.size(); ++i) {
      *(arg_[i]) = arg[i];
    }
    // ret
    for (typename Dune::DenseVector< RangeVectorType >::size_type i = 0; i < ret.size(); ++i) {
      ret[i] = op_[i]->Val();
    }
  }

#ifdef HAVE_EIGEN
  void evaluate(const Eigen::VectorXd& arg, Eigen::VectorXd& ret) const
  {
    // ensure right dimensions
    assert(arg.size() <= maxDimDomain);
    assert(ret.size() <= dimRange());
    // arg
    for (int i = 0; i < arg.size(); ++ i) {
      *(arg_[i]) = arg(i);
    }
    // ret
    for (int i = 0; i < ret.size(); ++ i) {
      ret(i) = op_[i]->Val();
    }
  }
#endif // HAVE_EIGEN

private:
  void setup(const std::string& _variable, const std::vector< std::string >& _expressions)
  {
    assert(maxDimDomain > 0);
    assert(maxDimRange > 0);
    // set expressions
    if (_expressions.size() < 1)
      DUNE_THROW(Dune::InvalidStateException,"\nError: Given 'expressions'-vector is empty!");
    actualDimRange_ = _expressions.size();
    expressions_ = _expressions;
    // set variable (i.e. "x")
    variable_ = _variable;
    // fill variables (i.e. "x[0]", "x[1]", ...)
    for (int i = 0; i < maxDimDomain; ++i) {
      std::stringstream variableStream;
      variableStream << variable_ << "[" << i << "]";
      variables_.push_back(variableStream.str());
    }
    // create epressions
    for (unsigned int i = 0; i < maxDimDomain; ++i) {
      arg_[i] = new DomainFieldType(0.0);
      var_arg_[i] = new RVar(variables_[i].c_str(), arg_[i]);
      vararray_[i] = var_arg_[i];
    }
    for (unsigned int i = 0; i < dimRange(); ++ i) {
      op_[i] = new ROperation(expressions_[i].c_str(), maxDimDomain, vararray_);
    }
  } // void setup(const std::string& variable, const std::vector< std::string >& expressions)

  void cleanup()
  {
    for (unsigned int i = 0; i < dimRange(); ++i) {
      delete op_[i];
    }
    for (unsigned int i = 0; i < maxDimDomain; ++i) {
      delete var_arg_[i];
      delete arg_[i];
    }
  } // void cleanup()

  std::string                variable_;
  std::vector< std::string > variables_;
  std::vector< std::string > expressions_;
  unsigned int actualDimRange_;
  mutable DomainFieldType* arg_[maxDimDomain];
  RVar* var_arg_[maxDimDomain];
  RVar* vararray_[maxDimDomain];
  ROperation* op_[maxDimRange];
}; // class Expression

} // namespace Function
} // namespace Stuff
} // namespace Dune

#endif // DUNE_STUFF_FUNCTION_EXPRESSION_HH
<commit_msg>[function.expression] removed id(), added report()<commit_after>#ifndef DUNE_STUFF_FUNCTION_EXPRESSION_HH
#define DUNE_STUFF_FUNCTION_EXPRESSION_HH

#ifdef HAVE_CMAKE_CONFIG
  #include "cmake_config.h"
#else
  #include "config.h"
#endif // ifdef HAVE_CMAKE_CONFIG

#include <sstream>
#include <vector>

#ifdef HAVE_EIGEN
  #include <Eigen/Core>
#endif // HAVE_EIGEN

#include <dune/common/fvector.hh>
#include <dune/common/dynvector.hh>
#include <dune/common/exceptions.hh>

#ifdef HAVE_DUNE_FEM
  #include <dune/fem/function/common/function.hh>
  #include <dune/fem/space/common/functionspace.hh>
#endif // HAVE_DUNE_FEM

#include <dune/stuff/common/parameter/tree.hh>
#include <dune/stuff/common/string.hh>

#include "expression/mathexpr.hh"
#include "interface.hh"

namespace Dune {
namespace Stuff {
namespace Function {

/**
  \brief  Provides a function which evaluates a given mathematical expression at runtime.

          Given a mathematical expression as a string, a domain \f$ K_d^{m \geq 1} \f$ and a range \f$ K_r^{n \geq 1}
          \f$ this function represents the map
          \f{eqnarray}
            f:K_d^m \to K_r^n\\
            x = (x_1, \dots, x_m)' \mapsto (f_1(x), \dots f_n(x))',
          \f}
          where \f$ K_d \f$ is the DomainType and \f$ K_r \f$ is the RangeType, usually a power of \f$ \mathcal{R} \f$.
          The name of the variable as well as the \f$ n \f$ expressions of \f$f_1, \dots, f_n\f$ have to be given in a
          Dune::ParameterTree in the following form:
\code variable: x
expression.0: 2*x[0]
expression.1: sin(x[1])*x[0]\endcode
          There have to exist at least \f$n\f$ expressions; the entries of the variable are indexed by \f$[i]\f$ for
          \f$ 0 \leq i \leq m - 1 \f$.
 **/
template< class DomainFieldImp, int maxDimDomain, class RangeFieldImp, int maxDimRange >
class Expression
  : public Interface< DomainFieldImp, maxDimDomain, RangeFieldImp, maxDimRange >
{
public:
  typedef DomainFieldImp DomainFieldType;

  typedef RangeFieldImp RangeFieldType;

  typedef Interface< DomainFieldImp, maxDimDomain, RangeFieldImp, maxDimRange > BaseType;

  typedef Expression< DomainFieldImp, maxDimDomain, RangeFieldImp, maxDimRange > ThisType;

  Expression(const std::string _variable, const std::string _expression)
  {
    const std::vector< std::string > expressions(1, _expression);
    setup(_variable, expressions);
  } // Expression(const std::string variable, const std::string expression)

  Expression(const std::string _variable, const std::vector< std::string > _expressions)
  {
    setup(_variable, _expressions);
  } // Expression(const std::string variable, const std::vector< std::string >& expressions)

  Expression(const ThisType& other)
  {
    setup(other.variable(), other.expression());
  } // Expression(const ThisType& other)

  static ThisType createFromParamTree(const Dune::ParameterTree& paramTree)
  {
    const Dune::Stuff::Common::ExtendedParameterTree extendedParamtree(paramTree);
    // get variable
    if (!extendedParamtree.hasKey("variable"))
      DUNE_THROW(Dune::RangeError, "\nError: missing key 'variable'!");
    const std::string variable = extendedParamtree.get("variable", "not_meaningful_default_value");
    // get expressions
    if (!extendedParamtree.hasKey("expression"))
      DUNE_THROW(Dune::RangeError, "\nError: missing key or vector 'expression'!");
    const std::vector< std::string > expressions
        = extendedParamtree.getVector< std::string >("expression", "not_meaningful_default_value");
    // create and return
    return ThisType(variable, expressions);
  } // static ThisType createFromParamTree(const Stuff::Common::ExtendedParameterTree& paramTree)

  ThisType& operator=(const ThisType& other)
  {
    if (this != &other) {
      cleanup();
      setup(other.variable(), other.expression());
    }
    return this;
  } // ThisType& operator=(const ThisType& other)

  ~Expression()
  {
    cleanup();
  } // ~Expression()

  void report(const std::string name = "stuff.function.expression",
              std::ostream& stream = std::cout,
              const std::string& prefix = "") const
  {
    const std::string tmp = name + "(" + variable() + ") = ";
    stream << prefix << tmp;
    if (expression().size() == 1)
        stream << expression()[0] << std::endl;
    else {
      stream << "[ " << expression()[0] << ";" << std::endl;
      const std::string whitespace = Dune::Stuff::Common::whitespaceify(tmp + "[ ");
      for (unsigned int i = 1; i < expression().size() - 1; ++i)
        stream << prefix << whitespace << expression()[i] << ";" << std::endl;
      stream << prefix << whitespace << expression()[expression().size() -1] << " ]" << std::endl;
    }
  } // void report(const std::string, std::ostream&, const std::string&) const

  std::string variable() const
  {
    return variable_;
  }

  const std::vector< std::string > expression() const
  {
    return expressions_;
  }

  unsigned int dimRange() const
  {
    return actualDimRange_;
  }

  //! needed for Interface
  virtual void evaluate(const Dune::FieldVector< DomainFieldImp, maxDimDomain >& arg, Dune::FieldVector< RangeFieldImp, maxDimRange >& ret) const
  {
    // ensure right dimensions
    assert(arg.size() <= maxDimDomain);
    assert(ret.size() <= dimRange());
    // arg
    for (typename Dune::FieldVector< DomainFieldImp, maxDimDomain >::size_type i = 0; i < arg.size(); ++i) {
      *(arg_[i]) = arg[i];
    }
    // ret
    for (typename Dune::FieldVector< RangeFieldImp, maxDimRange >::size_type i = 0; i < ret.size(); ++i) {
      ret[i] = op_[i]->Val();
    }
  }

  template< class DomainVectorType, class RangeVectorType >
  void evaluate(const Dune::DenseVector< DomainVectorType >& arg, Dune::DenseVector< RangeVectorType >& ret) const
  {
    // ensure right dimensions
    assert(arg.size() <= maxDimDomain);
    assert(ret.size() <= dimRange());
    // arg
    for (typename Dune::DenseVector< DomainVectorType >::size_type i = 0; i < arg.size(); ++i) {
      *(arg_[i]) = arg[i];
    }
    // ret
    for (typename Dune::DenseVector< RangeVectorType >::size_type i = 0; i < ret.size(); ++i) {
      ret[i] = op_[i]->Val();
    }
  }

#ifdef HAVE_EIGEN
  /**
   * \attention ret is resized to size dimRange()!
   */
  void evaluate(const Eigen::VectorXd& arg, Eigen::VectorXd& ret) const
  {
    // ensure right dimensions
    assert(arg.size() <= maxDimDomain);
    ret.resize(dimRange());
    // arg
    for (int i = 0; i < arg.size(); ++ i) {
      *(arg_[i]) = arg(i);
    }
    // ret
    for (int i = 0; i < ret.size(); ++ i) {
      ret(i) = op_[i]->Val();
    }
  } // void evaluate(const Eigen::VectorXd& arg, Eigen::VectorXd& ret) const
#endif // HAVE_EIGEN

private:
  void setup(const std::string& _variable, const std::vector< std::string >& _expressions)
  {
    assert(maxDimDomain > 0);
    assert(maxDimRange > 0);
    // set expressions
    if (_expressions.size() < 1)
      DUNE_THROW(Dune::InvalidStateException,"\nError: Given 'expressions'-vector is empty!");
    actualDimRange_ = _expressions.size();
    expressions_ = _expressions;
    // set variable (i.e. "x")
    variable_ = _variable;
    // fill variables (i.e. "x[0]", "x[1]", ...)
    for (int i = 0; i < maxDimDomain; ++i) {
      std::stringstream variableStream;
      variableStream << variable_ << "[" << i << "]";
      variables_.push_back(variableStream.str());
    }
    // create epressions
    for (unsigned int i = 0; i < maxDimDomain; ++i) {
      arg_[i] = new DomainFieldType(0.0);
      var_arg_[i] = new RVar(variables_[i].c_str(), arg_[i]);
      vararray_[i] = var_arg_[i];
    }
    for (unsigned int i = 0; i < dimRange(); ++ i) {
      op_[i] = new ROperation(expressions_[i].c_str(), maxDimDomain, vararray_);
    }
  } // void setup(const std::string& variable, const std::vector< std::string >& expressions)

  void cleanup()
  {
    for (unsigned int i = 0; i < dimRange(); ++i) {
      delete op_[i];
    }
    for (unsigned int i = 0; i < maxDimDomain; ++i) {
      delete var_arg_[i];
      delete arg_[i];
    }
  } // void cleanup()

  std::string                variable_;
  std::vector< std::string > variables_;
  std::vector< std::string > expressions_;
  unsigned int actualDimRange_;
  mutable DomainFieldType* arg_[maxDimDomain];
  RVar* var_arg_[maxDimDomain];
  RVar* vararray_[maxDimDomain];
  ROperation* op_[maxDimRange];
}; // class Expression

} // namespace Function
} // namespace Stuff
} // namespace Dune

#endif // DUNE_STUFF_FUNCTION_EXPRESSION_HH
<|endoftext|>


<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_GRID_WALKER_WRAPPER_HH
#define DUNE_STUFF_GRID_WALKER_WRAPPER_HH

#include "functors.hh"

namespace Dune {
namespace Stuff {
namespace Grid {
namespace internal {

template <class GridViewType>
class Codim0Object
  : public Functor::Codim0< GridViewType >
{
  typedef typename GridViewType::template Codim<0>::Entity EntityType;
public:
  ~Codim0Object() {}
  virtual bool apply_on(const GridViewType& grid_view, const EntityType& entity) const = 0;
};

template<class GridViewType, class Codim0FunctorType>
class Codim0FunctorWrapper
  : public Codim0Object<GridViewType>
{
  typedef typename GridViewType::template Codim<0>::Entity EntityType;
public:
  Codim0FunctorWrapper(Codim0FunctorType& wrapped_functor,
                       const ApplyOn::WhichEntity< GridViewType >* where)
    : wrapped_functor_(wrapped_functor)
    , where_(where)
  {}

  virtual ~Codim0FunctorWrapper() {}

  virtual void prepare() DS_OVERRIDE DS_FINAL
  {
    wrapped_functor_.prepare();
  }

  virtual bool apply_on(const GridViewType& grid_view, const EntityType& entity) const DS_OVERRIDE DS_FINAL
  {
    return where_->apply_on(grid_view, entity);
  }

  virtual void apply_local(const EntityType& entity) DS_OVERRIDE DS_FINAL
  {
    wrapped_functor_.apply_local(entity);
  }

  virtual void finalize() DS_OVERRIDE DS_FINAL
  {
    wrapped_functor_.finalize();
  }

private:
  Codim0FunctorType& wrapped_functor_;
  std::unique_ptr< const ApplyOn::WhichEntity< GridViewType > > where_;
}; // class Codim0FunctorWrapper

template <class GridViewType>
class Codim1Object
  : public Functor::Codim1< GridViewType >
{
  typedef typename GridViewType::Intersection IntersectionType;
  typedef typename GridViewType::template Codim<0>::Entity EntityType;
public:
  ~Codim1Object() {}
  virtual bool apply_on(const GridViewType& grid_view, const IntersectionType& intersection) const = 0;
};

template<class GridViewType, class Codim1FunctorType>
class Codim1FunctorWrapper
  : public Codim1Object<GridViewType>
{
  typedef typename GridViewType::Intersection IntersectionType;
  typedef typename GridViewType::template Codim<0>::Entity EntityType;
public:
  Codim1FunctorWrapper(Codim1FunctorType& wrapped_functor,
                       const ApplyOn::WhichIntersection< GridViewType >* where)
    : wrapped_functor_(wrapped_functor)
    , where_(where)
  {}

  virtual void prepare() DS_OVERRIDE DS_FINAL
  {
    wrapped_functor_.prepare();
  }

  virtual bool apply_on(const GridViewType& grid_view, const IntersectionType& intersection) const DS_OVERRIDE DS_FINAL
  {
    return where_->apply_on(grid_view, intersection);
  }

  virtual void apply_local(const IntersectionType& intersection,
                           const EntityType& inside_entity,
                           const EntityType& outside_entity) DS_OVERRIDE DS_FINAL
  {
    wrapped_functor_.apply_local(intersection, inside_entity, outside_entity);
  }

  virtual void finalize() DS_OVERRIDE DS_FINAL
  {
    wrapped_functor_.finalize();
  }

private:
  Codim1FunctorType& wrapped_functor_;
  std::unique_ptr< const ApplyOn::WhichIntersection< GridViewType > > where_;
}; // class Codim1FunctorWrapper

template<class GridViewType, class WalkerType>
class WalkerWrapper
  : public Codim0Object<GridViewType>
  , public Codim1Object<GridViewType>
{
  typedef typename GridViewType::template Codim<0>::Entity EntityType;
  typedef typename GridViewType::Intersection IntersectionType;
public:
  WalkerWrapper(WalkerType& grid_walker,
                const ApplyOn::WhichEntity< GridViewType >* which_entities)
    : grid_walker_(grid_walker)
    , which_entities_(which_entities)
    , which_intersections_(new ApplyOn::AllIntersections< GridViewType >())
  {}

  WalkerWrapper(WalkerType& grid_walker,
                const ApplyOn::WhichIntersection< GridViewType >* which_intersections)
    : grid_walker_(grid_walker)
    , which_entities_(new ApplyOn::AllEntities< GridViewType >())
    , which_intersections_(which_intersections)
  {}

  virtual ~WalkerWrapper() {}

  virtual void prepare() DS_OVERRIDE DS_FINAL
  {
    grid_walker_.prepare();
  }

  virtual bool apply_on(const GridViewType& grid_view, const EntityType& entity) const DS_OVERRIDE DS_FINAL
  {
    return which_entities_->apply_on(grid_view, entity) && grid_walker_.apply_on(entity);
  }

  virtual bool apply_on(const GridViewType& grid_view, const IntersectionType& intersection) const DS_OVERRIDE DS_FINAL
  {
    return which_intersections_->apply_on(grid_view, intersection) && grid_walker_.apply_on(intersection);
  }

  virtual void apply_local(const EntityType& entity) DS_OVERRIDE DS_FINAL
  {
    grid_walker_.apply_local(entity);
  }

  virtual void apply_local(const IntersectionType& intersection,
                           const EntityType& inside_entity,
                           const EntityType& outside_entity) DS_OVERRIDE DS_FINAL
  {
    grid_walker_.apply_local(intersection, inside_entity, outside_entity);
  }

  virtual void finalize() DS_OVERRIDE DS_FINAL
  {
    grid_walker_.finalize();
  }

private:
  WalkerType& grid_walker_;
  std::unique_ptr< const ApplyOn::WhichEntity< GridViewType > > which_entities_;
  std::unique_ptr< const ApplyOn::WhichIntersection< GridViewType > > which_intersections_;
}; // class WalkerWrapper

template<class GridViewType >
class Codim0LambdaWrapper
  : public Codim0Object< GridViewType >
{
  typedef Codim0Object< GridViewType > BaseType;
public:
  typedef typename BaseType::EntityType            EntityType;
  typedef std::function< void(const EntityType&) > LambdaType;

  Codim0LambdaWrapper(LambdaType lambda, const ApplyOn::WhichEntity< GridViewType >* where)
    : lambda_(lambda)
    , where_(where)
  {}

  virtual ~Codim0LambdaWrapper() {}

  virtual bool apply_on(const GridViewType& grid_view, const EntityType& entity) const DS_OVERRIDE DS_FINAL
  {
    return where_->apply_on(grid_view, entity);
  }

  virtual void apply_local(const EntityType& entity) DS_OVERRIDE DS_FINAL
  {
    lambda_(entity);
  }

private:
  LambdaType lambda_;
  std::unique_ptr< const ApplyOn::WhichEntity< GridViewType > > where_;
}; // class Codim0LambdaWrapper

} // namespace internal
} // namespace Grid
} // namespace Stuff
} // namespace Dune

#endif // DUNE_STUFF_GRID_WALKER_WRAPPER_HH
<commit_msg>[grid.walker.wrapper] use correct type<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_GRID_WALKER_WRAPPER_HH
#define DUNE_STUFF_GRID_WALKER_WRAPPER_HH

#include "functors.hh"

namespace Dune {
namespace Stuff {
namespace Grid {
namespace internal {

template <class GridViewType>
class Codim0Object
  : public Functor::Codim0< GridViewType >
{
  typedef Functor::Codim0< GridViewType > BaseType;
public:
  typedef typename BaseType::EntityType EntityType;

  ~Codim0Object() {}

  virtual bool apply_on(const GridViewType& grid_view, const EntityType& entity) const = 0;
};

template<class GridViewType, class Codim0FunctorType>
class Codim0FunctorWrapper
  : public Codim0Object<GridViewType>
{
  typedef typename GridViewType::template Codim<0>::Entity EntityType;
public:
  Codim0FunctorWrapper(Codim0FunctorType& wrapped_functor,
                       const ApplyOn::WhichEntity< GridViewType >* where)
    : wrapped_functor_(wrapped_functor)
    , where_(where)
  {}

  virtual ~Codim0FunctorWrapper() {}

  virtual void prepare() DS_OVERRIDE DS_FINAL
  {
    wrapped_functor_.prepare();
  }

  virtual bool apply_on(const GridViewType& grid_view, const EntityType& entity) const DS_OVERRIDE DS_FINAL
  {
    return where_->apply_on(grid_view, entity);
  }

  virtual void apply_local(const EntityType& entity) DS_OVERRIDE DS_FINAL
  {
    wrapped_functor_.apply_local(entity);
  }

  virtual void finalize() DS_OVERRIDE DS_FINAL
  {
    wrapped_functor_.finalize();
  }

private:
  Codim0FunctorType& wrapped_functor_;
  std::unique_ptr< const ApplyOn::WhichEntity< GridViewType > > where_;
}; // class Codim0FunctorWrapper

template <class GridViewType>
class Codim1Object
  : public Functor::Codim1< GridViewType >
{
  typedef typename GridViewType::Intersection IntersectionType;
  typedef typename GridViewType::template Codim<0>::Entity EntityType;
public:
  ~Codim1Object() {}
  virtual bool apply_on(const GridViewType& grid_view, const IntersectionType& intersection) const = 0;
};

template<class GridViewType, class Codim1FunctorType>
class Codim1FunctorWrapper
  : public Codim1Object<GridViewType>
{
  typedef typename GridViewType::Intersection IntersectionType;
  typedef typename GridViewType::template Codim<0>::Entity EntityType;
public:
  Codim1FunctorWrapper(Codim1FunctorType& wrapped_functor,
                       const ApplyOn::WhichIntersection< GridViewType >* where)
    : wrapped_functor_(wrapped_functor)
    , where_(where)
  {}

  virtual void prepare() DS_OVERRIDE DS_FINAL
  {
    wrapped_functor_.prepare();
  }

  virtual bool apply_on(const GridViewType& grid_view, const IntersectionType& intersection) const DS_OVERRIDE DS_FINAL
  {
    return where_->apply_on(grid_view, intersection);
  }

  virtual void apply_local(const IntersectionType& intersection,
                           const EntityType& inside_entity,
                           const EntityType& outside_entity) DS_OVERRIDE DS_FINAL
  {
    wrapped_functor_.apply_local(intersection, inside_entity, outside_entity);
  }

  virtual void finalize() DS_OVERRIDE DS_FINAL
  {
    wrapped_functor_.finalize();
  }

private:
  Codim1FunctorType& wrapped_functor_;
  std::unique_ptr< const ApplyOn::WhichIntersection< GridViewType > > where_;
}; // class Codim1FunctorWrapper

template<class GridViewType, class WalkerType>
class WalkerWrapper
  : public Codim0Object<GridViewType>
  , public Codim1Object<GridViewType>
{
  typedef typename GridViewType::template Codim<0>::Entity EntityType;
  typedef typename GridViewType::Intersection IntersectionType;
public:
  WalkerWrapper(WalkerType& grid_walker,
                const ApplyOn::WhichEntity< GridViewType >* which_entities)
    : grid_walker_(grid_walker)
    , which_entities_(which_entities)
    , which_intersections_(new ApplyOn::AllIntersections< GridViewType >())
  {}

  WalkerWrapper(WalkerType& grid_walker,
                const ApplyOn::WhichIntersection< GridViewType >* which_intersections)
    : grid_walker_(grid_walker)
    , which_entities_(new ApplyOn::AllEntities< GridViewType >())
    , which_intersections_(which_intersections)
  {}

  virtual ~WalkerWrapper() {}

  virtual void prepare() DS_OVERRIDE DS_FINAL
  {
    grid_walker_.prepare();
  }

  virtual bool apply_on(const GridViewType& grid_view, const EntityType& entity) const DS_OVERRIDE DS_FINAL
  {
    return which_entities_->apply_on(grid_view, entity) && grid_walker_.apply_on(entity);
  }

  virtual bool apply_on(const GridViewType& grid_view, const IntersectionType& intersection) const DS_OVERRIDE DS_FINAL
  {
    return which_intersections_->apply_on(grid_view, intersection) && grid_walker_.apply_on(intersection);
  }

  virtual void apply_local(const EntityType& entity) DS_OVERRIDE DS_FINAL
  {
    grid_walker_.apply_local(entity);
  }

  virtual void apply_local(const IntersectionType& intersection,
                           const EntityType& inside_entity,
                           const EntityType& outside_entity) DS_OVERRIDE DS_FINAL
  {
    grid_walker_.apply_local(intersection, inside_entity, outside_entity);
  }

  virtual void finalize() DS_OVERRIDE DS_FINAL
  {
    grid_walker_.finalize();
  }

private:
  WalkerType& grid_walker_;
  std::unique_ptr< const ApplyOn::WhichEntity< GridViewType > > which_entities_;
  std::unique_ptr< const ApplyOn::WhichIntersection< GridViewType > > which_intersections_;
}; // class WalkerWrapper

template<class GridViewType >
class Codim0LambdaWrapper
  : public Codim0Object< GridViewType >
{
  typedef Codim0Object< GridViewType > BaseType;
public:
  typedef typename BaseType::EntityType            EntityType;
  typedef std::function< void(const EntityType&) > LambdaType;

  Codim0LambdaWrapper(LambdaType lambda, const ApplyOn::WhichEntity< GridViewType >* where)
    : lambda_(lambda)
    , where_(where)
  {}

  virtual ~Codim0LambdaWrapper() {}

  virtual bool apply_on(const GridViewType& grid_view, const EntityType& entity) const DS_OVERRIDE DS_FINAL
  {
    return where_->apply_on(grid_view, entity);
  }

  virtual void apply_local(const EntityType& entity) DS_OVERRIDE DS_FINAL
  {
    lambda_(entity);
  }

private:
  LambdaType lambda_;
  std::unique_ptr< const ApplyOn::WhichEntity< GridViewType > > where_;
}; // class Codim0LambdaWrapper

} // namespace internal
} // namespace Grid
} // namespace Stuff
} // namespace Dune

#endif // DUNE_STUFF_GRID_WALKER_WRAPPER_HH
<|endoftext|>


<commit_before><commit_msg>Add a CHECK() around the SharedMemory ftruncate() call to finger it as a crash culprit.<commit_after><|endoftext|>


<commit_before>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2000, 2010 Oracle and/or its affiliates.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_basic.hxx"

#include "app.hxx"
#include "basic.hrc"
#include "appwin.hxx"
#include "status.hxx"

#include <vcl/decoview.hxx>

StatusLine::StatusLine( BasicFrame* p )
: TaskBar( p )
, pFrame( p )
{
    // initialize TaskToolBox
    TaskToolBox*    pTempTaskToolBox = GetTaskToolBox();
    pTempTaskToolBox->SetActivateTaskHdl( LINK( this, StatusLine, ActivateTask ) );

    // initialize TaskStatusBar
    TaskStatusBar*  pTempStatusBar = GetStatusBar();
    long nCharWidth = GetTextWidth( '0' );  // We state: All numbers has the same width
    pTempStatusBar->InsertItem( ST_MESSAGE, GetTextWidth( 'X' ) * 20, SIB_LEFT | SIB_IN | SIB_AUTOSIZE );
    pTempStatusBar->InsertItem( ST_LINE, 5*nCharWidth );
    pTempStatusBar->InsertItem( ST_PROF, GetTextWidth( 'X' ) * 10 );
    pTempStatusBar->InsertStatusField();

    Show();
}

void StatusLine::Message( const String& s )
{
    GetStatusBar()->SetItemText( ST_MESSAGE, s );
}

void StatusLine::Pos( const String& s )
{
    GetStatusBar()->SetItemText( ST_LINE, s );
}

void StatusLine::SetProfileName( const String& s )
{
    GetStatusBar()->SetItemText( ST_PROF, s );
}

IMPL_LINK( StatusLine, ActivateTask, TaskToolBox*, pTTB )
{
    sal_uInt16 nFirstWinPos=0;
    MenuBar* pMenu = pFrame->GetMenuBar();
    PopupMenu* pWinMenu = pMenu->GetPopupMenu( RID_APPWINDOW );

    while ( pWinMenu->GetItemId( nFirstWinPos ) < RID_WIN_FILE1 && nFirstWinPos < pWinMenu->GetItemCount() )
        nFirstWinPos++;

    nFirstWinPos += pTTB->GetItemPos( pTTB->GetCurItemId() ) / 2;

    sal_uInt16 x;
    x = pTTB->GetItemPos( pTTB->GetCurItemId() );
    x = pWinMenu->GetItemId( nFirstWinPos );
    x = pWinMenu->GetItemCount();
    AppWin* pWin = pFrame->FindWin( pWinMenu->GetItemText( pWinMenu->GetItemId( nFirstWinPos ) ).EraseAllChars( L'~' ) );
    if ( pWin )
    {
        pWin->Minimize( sal_False );
        pWin->ToTop();
    }
    return 0;
}

void StatusLine::LoadTaskToolBox()
{
    sal_uInt16 nFirstWinPos=0;
    MenuBar* pMenu = pFrame->GetMenuBar();
    PopupMenu* pWinMenu = pMenu->GetPopupMenu( RID_APPWINDOW );

    while ( pWinMenu->GetItemId( nFirstWinPos ) < RID_WIN_FILE1 && nFirstWinPos < pWinMenu->GetItemCount() )
        nFirstWinPos++;

    TaskToolBox* pTaskToolBox = GetTaskToolBox();

    pTaskToolBox->StartUpdateTask();

    while ( nFirstWinPos < pWinMenu->GetItemCount() )
    {   // There are windows
        Window* pWin = pFrame->FindWin( pWinMenu->GetItemId( nFirstWinPos ) );

        if ( pWin )
            pTaskToolBox->UpdateTask( Image(), pWin->GetText(), pWin == pFrame->pList->back() && !( pFrame->pList->back()->GetWinState() & TT_WIN_STATE_HIDE ) );

        nFirstWinPos++;
    }

    pTaskToolBox->EndUpdateTask();
    Resize();
    Invalidate();
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<commit_msg>these statements have no effect, looks like debugging code<commit_after>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2000, 2010 Oracle and/or its affiliates.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_basic.hxx"

#include "app.hxx"
#include "basic.hrc"
#include "appwin.hxx"
#include "status.hxx"

#include <vcl/decoview.hxx>

StatusLine::StatusLine( BasicFrame* p )
: TaskBar( p )
, pFrame( p )
{
    // initialize TaskToolBox
    TaskToolBox*    pTempTaskToolBox = GetTaskToolBox();
    pTempTaskToolBox->SetActivateTaskHdl( LINK( this, StatusLine, ActivateTask ) );

    // initialize TaskStatusBar
    TaskStatusBar*  pTempStatusBar = GetStatusBar();
    long nCharWidth = GetTextWidth( '0' );  // We state: All numbers has the same width
    pTempStatusBar->InsertItem( ST_MESSAGE, GetTextWidth( 'X' ) * 20, SIB_LEFT | SIB_IN | SIB_AUTOSIZE );
    pTempStatusBar->InsertItem( ST_LINE, 5*nCharWidth );
    pTempStatusBar->InsertItem( ST_PROF, GetTextWidth( 'X' ) * 10 );
    pTempStatusBar->InsertStatusField();

    Show();
}

void StatusLine::Message( const String& s )
{
    GetStatusBar()->SetItemText( ST_MESSAGE, s );
}

void StatusLine::Pos( const String& s )
{
    GetStatusBar()->SetItemText( ST_LINE, s );
}

void StatusLine::SetProfileName( const String& s )
{
    GetStatusBar()->SetItemText( ST_PROF, s );
}

IMPL_LINK( StatusLine, ActivateTask, TaskToolBox*, pTTB )
{
    sal_uInt16 nFirstWinPos=0;
    MenuBar* pMenu = pFrame->GetMenuBar();
    PopupMenu* pWinMenu = pMenu->GetPopupMenu( RID_APPWINDOW );

    while ( pWinMenu->GetItemId( nFirstWinPos ) < RID_WIN_FILE1 && nFirstWinPos < pWinMenu->GetItemCount() )
        nFirstWinPos++;

    nFirstWinPos += pTTB->GetItemPos( pTTB->GetCurItemId() ) / 2;

    AppWin* pWin = pFrame->FindWin( pWinMenu->GetItemText( pWinMenu->GetItemId( nFirstWinPos ) ).EraseAllChars( L'~' ) );
    if ( pWin )
    {
        pWin->Minimize( sal_False );
        pWin->ToTop();
    }
    return 0;
}

void StatusLine::LoadTaskToolBox()
{
    sal_uInt16 nFirstWinPos=0;
    MenuBar* pMenu = pFrame->GetMenuBar();
    PopupMenu* pWinMenu = pMenu->GetPopupMenu( RID_APPWINDOW );

    while ( pWinMenu->GetItemId( nFirstWinPos ) < RID_WIN_FILE1 && nFirstWinPos < pWinMenu->GetItemCount() )
        nFirstWinPos++;

    TaskToolBox* pTaskToolBox = GetTaskToolBox();

    pTaskToolBox->StartUpdateTask();

    while ( nFirstWinPos < pWinMenu->GetItemCount() )
    {   // There are windows
        Window* pWin = pFrame->FindWin( pWinMenu->GetItemId( nFirstWinPos ) );

        if ( pWin )
            pTaskToolBox->UpdateTask( Image(), pWin->GetText(), pWin == pFrame->pList->back() && !( pFrame->pList->back()->GetWinState() & TT_WIN_STATE_HIDE ) );

        nFirstWinPos++;
    }

    pTaskToolBox->EndUpdateTask();
    Resize();
    Invalidate();
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<|endoftext|>


<commit_before>#define BOOST_TEST_MODULE ftEdgeTest
#include <boost/test/unit_test.hpp>

#include <fstream>
#include "GoTools/utils/Point.h"
#include "GoTools/geometry/Utils.h"
#include "GoTools/geometry/ObjectHeader.h"
#include "GoTools/geometry/Circle.h"
#include "GoTools/compositemodel/Vertex.h"
#include "GoTools/compositemodel/ftEdge.h"

using namespace std;
using namespace Go;

BOOST_AUTO_TEST_CASE(ConstructFromCircle)
{
    ifstream in("data/ftEdge.dat");
    BOOST_CHECK_MESSAGE(!in.bad(), "Input file not found or file corrupt");

    ObjectHeader header;
    shared_ptr<Circle> circle(new Circle);
    Point pt1(3);
    Point pt2(3);

    int index = 0;
    while (!in.eof()) {

	cout << "index: " << index << endl;

	// Circle
	header.read(in);
	circle->read(in);

	// Vertices
	pt1.read(in);
	shared_ptr<Vertex> v1(new Vertex(pt1));
	pt2.read(in);
	shared_ptr<Vertex> v2(new Vertex(pt2));

	// ftEdge
	ftEdge edge(circle, v1, v2);

	// Test vertices
	shared_ptr<Vertex> va, vb;
	edge.getVertices(va, vb);
	double eps = 1.0e-6;
	double dist1 = (v1->getVertexPoint() - va->getVertexPoint()).length();
	double dist2 = (v2->getVertexPoint() - vb->getVertexPoint()).length();
	bool verticesOK = (dist1 < eps) && (dist2 < eps);
        BOOST_CHECK(verticesOK);

	// Test if not reversed
	bool isNotReversed = !edge.isReversed();
	BOOST_CHECK(isNotReversed);

	// Test parameter interval
	double parlen = edge.tMax() - edge.tMin();
	bool lessthan2pi = (parlen <= 2.0 * M_PI);
	BOOST_CHECK(lessthan2pi);

	Utils::eatwhite(in);

	++index;
    }

}

<commit_msg>Test tweaks.<commit_after>#define BOOST_TEST_MODULE ftEdgeTest
#include <boost/test/unit_test.hpp>

#include <fstream>
#include "GoTools/utils/Point.h"
#include "GoTools/geometry/Utils.h"
#include "GoTools/geometry/ObjectHeader.h"
#include "GoTools/geometry/Circle.h"
#include "GoTools/compositemodel/Vertex.h"
#include "GoTools/compositemodel/ftEdge.h"

using namespace std;
using namespace Go;

BOOST_AUTO_TEST_CASE(ConstructFromCircle)
{
    ifstream in("data/ftEdge.dat");
    BOOST_CHECK_MESSAGE(!in.bad(), "Input file not found or file corrupt");

    ObjectHeader header;
    shared_ptr<Circle> circle(new Circle);
    Point pt1(3);
    Point pt2(3);

    int index = 0;
    while (!in.eof()) {

	cout << "index: " << index << endl;

	// Circle
	header.read(in);
	circle->read(in);

	// Vertices
	pt1.read(in);
	shared_ptr<Vertex> v1(new Vertex(pt1));
	pt2.read(in);
	shared_ptr<Vertex> v2(new Vertex(pt2));

	// ftEdge
	ftEdge edge(circle, v1, v2);

	// Test vertices
	shared_ptr<Vertex> va, vb;
	edge.getVertices(va, vb);
	double eps = 1.0e-6;
	double dist1 = (v1->getVertexPoint() - va->getVertexPoint()).length();
	double dist2 = (v2->getVertexPoint() - vb->getVertexPoint()).length();
	bool verticesOK = (dist1 < eps) && (dist2 < eps);
        BOOST_CHECK(verticesOK);

	// Test if not reversed
	bool isNotReversed = !edge.isReversed();
	BOOST_CHECK(isNotReversed);

	// Test parameter interval
	double parlen = edge.tMax() - edge.tMin();
	bool lessthan2pi = (parlen <= 2.0 * M_PI);
	BOOST_CHECK(lessthan2pi);

	Utils::eatwhite(in);

	++index;
    }

}

<|endoftext|>