matrix_expression_more.hpp

Back to Matrix class

pastel/math/matrix/

#ifndef PASTELMATH_MATRIX_EXPRESSION_MORE_HPP
#define PASTELMATH_MATRIX_EXPRESSION_MORE_HPP

#include "pastel/math/matrix/matrix_expression_more.h"

namespace Pastel
{

    template <
        typename Real,
        typename Expression>
    class MatrixSum
        : public VectorExpression<Real, Dynamic, MatrixSum<Real, Expression> >
    {
    public:
        using StorageType = const MatrixSum&;

        explicit MatrixSum(
            const Expression& data)
            : data_(data)
        {
        }

        Real operator[](integer index) const
        {
            Real sum = 0;
            integer n = data_.height();

            for (integer i = 0;i < n;++i)
            {
                sum += data_(i, index);
            }

            return sum;
        }

        integer size() const
        {
            return data_.width();
        }

        bool involves(
            const void* memoryBegin,
            const void* memoryEnd) const
        {
            return data_.involves(memoryBegin, memoryEnd);
        }

        bool evaluateBeforeAssignment(
            const void* memoryBegin,
            const void* memoryEnd) const
        {
            // This is a non-trivial vector
            // expression.
            return data_.involves(memoryBegin, memoryEnd);
        }

    private:
        typename Expression::StorageType data_;
    };

    template <typename Real, typename Expression>
    class MatrixMin
        : public VectorExpression<Real, Dynamic, MatrixMin<Real, Expression> >
    {
    public:
        using StorageType = const MatrixMin&;

        explicit MatrixMin(
            const Expression& data)
            : data_(data)
        {
        }

        Real operator[](integer index) const
        {
            Real minValue = Infinity();
            integer n = data_.height();

            for (integer i = 0;i < n;++i)
            {
                Real value = data_(i, index);
                if (value < minValue)
                {
                    minValue = value;
                }
            }

            return minValue;
        }

        integer size() const
        {
            return data_.width();
        }

        bool involves(
            const void* memoryBegin,
            const void* memoryEnd) const
        {
            return data_.involves(memoryBegin, memoryEnd);
        }

        bool evaluateBeforeAssignment(
            const void* memoryBegin,
            const void* memoryEnd) const
        {
            // This is a non-trivial vector
            // expression.
            return data_.involves(memoryBegin, memoryEnd);
        }

    private:
        typename Expression::StorageType data_;
    };

    template <typename Real, typename Expression>
    class MatrixMax
        : public VectorExpression<Real, Dynamic, MatrixMax<Real, Expression> >
    {
    public:
        using StorageType = const MatrixMax&;

        explicit MatrixMax(
            const Expression& data)
            : data_(data)
        {
        }

        Real operator[](integer index) const
        {
            Real maxValue = -Infinity();
            integer n = data_.height();

            for (integer i = 0;i < n;++i)
            {
                Real value = data_(i, index);
                if (value > maxValue)
                {
                    maxValue = value;
                }
            }

            return maxValue;
        }

        integer size() const
        {
            return data_.width();
        }

        bool involves(
            const void* memoryBegin,
            const void* memoryEnd) const
        {
            return data_.involves(memoryBegin, memoryEnd);
        }

        bool evaluateBeforeAssignment(
            const void* memoryBegin,
            const void* memoryEnd) const
        {
            // This is a non-trivial vector
            // expression.
            return data_.involves(memoryBegin, memoryEnd);
        }

    private:
        typename Expression::StorageType data_;
    };

    template <typename Real, typename Expression>
    class MatrixAbs
        : public MatrixExpression<Real, 
        MatrixAbs<Real, Expression> >
    {
    public:
        using StorageType = const MatrixAbs&;

        explicit MatrixAbs(
            const Expression& data)
            : data_(data)
        {
        }

        Real operator()(integer y, integer x) const
        {
            return abs(data_(y, x));
        }

        integer width() const
        {
            return data_.width();
        }

        integer height() const
        {
            return data_.height();
        }

        bool involves(
            const void* memoryBegin,
            const void* memoryEnd) const
        {
            return data_.involves(memoryBegin, memoryEnd);
        }

        bool evaluateBeforeAssignment(
            const void* memoryBegin,
            const void* memoryEnd) const
        {
            return data_.evaluateBeforeAssignment(memoryBegin, memoryEnd);
        }

    private:
        typename Expression::StorageType data_;
    };

    template <typename Real, typename Expression>
    class MatrixRepeat
        : public MatrixExpression<Real, 
        MatrixRepeat<Real, Expression> >
    {
    public:
        using StorageType = const MatrixRepeat;

        explicit MatrixRepeat(
            const Expression& data,
            integer yBlocks,
            integer xBlocks)
            : data_(data)
            , dataWidth_(data.width())
            , dataHeight_(data.height())
            , width_(data.width() * xBlocks)
            , height_(data.height() * yBlocks)
        {
            PENSURE_OP(xBlocks, >=, 0);
            PENSURE_OP(yBlocks, >=, 0);
        }

        Real operator()(integer y, integer x) const
        {
            return data_(y % dataHeight_, x % dataWidth_);
        }

        integer width() const
        {
            return width_;
        }

        integer height() const
        {
            return height_;
        }

        bool involves(
            const void* memoryBegin,
            const void* memoryEnd) const
        {
            return data_.involves(memoryBegin, memoryEnd);
        }

        bool evaluateBeforeAssignment(
            const void* memoryBegin,
            const void* memoryEnd) const
        {
            return data_.evaluateBeforeAssignment(memoryBegin, memoryEnd);
        }

    private:
        typename Expression::StorageType data_;
        integer dataWidth_;
        integer dataHeight_;
        integer width_;
        integer height_;
    };

    template <
        typename Real,
        typename LeftExpression,
        typename RightExpression>
    class OuterProduct
        : public MatrixExpression<Real, 
        OuterProduct<Real, 
        LeftExpression, RightExpression> >
    {
    public:

        using StorageType = const OuterProduct&;

        OuterProduct(
            const LeftExpression& left,
            const RightExpression& right)
            : left_(left)
            , right_(right)
        {
        }

        Real operator()(integer y, integer x) const
        {
            return left_[y] * right_[x];
        }

        integer width() const
        {
            return right_.size();
        }

        integer height() const
        {
            return left_.size();
        }

        bool involves(
            const void* memoryBegin, const void* memoryEnd) const
        {
            return left_.involves(memoryBegin, memoryEnd) ||
                right_.involves(memoryBegin, memoryEnd);
        }

        bool evaluateBeforeAssignment(
            const void* memoryBegin, const void* memoryEnd) const
        {
            // This is a non-trivial combination.
            return left_.involves(memoryBegin, memoryEnd) ||
                right_.involves(memoryBegin, memoryEnd);
        }

    private:
        typename LeftExpression::StorageType left_;
        typename RightExpression::StorageType right_;
    };

}

#endif