matrix_tools.hpp

Back to Matrix class

pastel/math/matrix/

#ifndef PASTELMATH_MATRIX_TOOLS_HPP
#define PASTELMATH_MATRIX_TOOLS_HPP

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

#include "pastel/sys/mytypes.h"
#include "pastel/sys/tuple/tuple_tools.h"

namespace Pastel
{

    template <typename Real>
    Real& scalar(Matrix<Real>& matrix)
    {
        return matrix(0, 0);
    }

    template <typename Real>
    const Real& scalar(const Matrix<Real>& matrix)
    {
        return matrix(0, 0);
    }

    template <typename Real, typename Expression>
    Vector<Real, Dynamic> diagonal(
        const MatrixExpression<Real, Expression>& matrix)
    {
        ENSURE_OP(matrix.width(), ==, matrix.height());

        integer n = matrix.width();

        Vector<Real, Dynamic> result(ofDimension(n));

        for (integer i = 0;i < n;++i)
        {
            result[i] = matrix(i, i);
        }

        return result;
    }

    template <typename Real, integer N>
    void setDiagonal(
        Matrix<Real>& matrix,
        const NoDeduction<Real>& value)
    {
        integer width = matrix.width();
        integer height = matrix.height();

        ENSURE_OP(width, ==, height);

        matrix.set(0);

        for (integer i = 0;i < width;++i)
        {
            matrix(i, i) = value;
        }
    }

    template <typename Real, integer N>
    void setDiagonal(
        Matrix<Real>& matrix,
        const Vector<Real, N>& values)
    {
        integer size = values.size();

        ENSURE2(matrix.width() == size, matrix.width(), size);
        ENSURE2(matrix.height() == size, matrix.height(), size);

        matrix.set(0);

        for (integer i = 0;i < size;++i)
        {
            matrix(i, i) = values[i];
        }
    }

    template <typename Real, integer Height, integer Width>
    void transponate(
        Matrix<Real>& matrix)
    {
        integer width = matrix.width();
        integer height = matrix.height();

        using std::swap;

        for (integer y = 0;y < height;++y)
        {
            for (integer x = y + 1;x < width;++x)
            {
                swap(matrix(y, x), matrix(x, y));
            }
        }
    }

    template <typename Real, integer N, typename Expression>
    MatrixDiagonal<Real, Expression> diagonalMatrix(
        integer m, integer n,

        const VectorExpression<Real, N, Expression>& diagonal)
    {
        return MatrixDiagonal<Real, Expression>(
            m, n,
            (const Expression&)diagonal);
    }

    template <typename Real, integer N, typename Expression>
    MatrixDiagonal<Real, Expression> diagonalMatrix(
        const VectorExpression<Real, N, Expression>& diagonal)
    {
        return MatrixDiagonal<Real, Expression>(
            diagonal.size(), diagonal.size(),
            (const Expression&)diagonal);
    }

    template <typename Real>
    MatrixDiagonal<Real, VectorConstant<Real, Dynamic>> identityMatrix(
        integer m, integer n)
    {
        PENSURE_OP(m, >=, 0);
        PENSURE_OP(n, >=, 0);
        return diagonalMatrix<Real>(m, n, 
            VectorConstant<Real, Dynamic>(1, std::min(m, n)));
    }

    template <typename Real>
    MatrixConstant<Real> constantMatrix(
        integer m, integer n, NoDeduction<Real> value)
    {
        PENSURE_OP(m, >=, 0);
        PENSURE_OP(n, >=, 0);
        return MatrixConstant<Real>(m, n, std::move(value));
    }

    template <typename Real, typename Expression>
    MatrixTranspose<Real, Expression> transpose(
        const MatrixExpression<Real, Expression>& that)
    {
        return MatrixTranspose<Real, Expression>(
            (const Expression&)that);
    }

    template <typename Real, typename Expression>
    MatrixSum<Real, Expression> sum(
        const MatrixExpression<Real, Expression>& that)
    {
        return MatrixSum<Real, Expression>(
            (const Expression&)that);
    }

    template <typename Real, typename Expression>
    MatrixMin<Real, Expression> min(
        const MatrixExpression<Real, Expression>& that)
    {
        return MatrixMin<Real, Expression>(
            (const Expression&)that);
    }

    template <typename Real, typename Expression>
    MatrixMax<Real, Expression> max(
        const MatrixExpression<Real, Expression>& that)
    {
        return MatrixMax<Real, Expression>(
            (const Expression&)that);
    }

    template <typename Real, typename Expression>
    MatrixAbs<Real, Expression> abs(
        const MatrixExpression<Real, Expression>& that)
    {
        return MatrixAbs<Real, Expression>(
            (const Expression&)that);
    }

    template <typename Real, typename Expression>
    MatrixRepeat<Real, Expression> repeat(
        const MatrixExpression<Real, Expression>& that,
        integer yBlocks, integer xBlocks)
    {
        return MatrixRepeat<Real, Expression>(
            (const Expression&)that, yBlocks, xBlocks);
    }

    template <typename Real, integer N>
    ArrayMatrix<Real> arrayMatrix(
        integer height, integer width,
        Real (&data)[N])
    {
        PENSURE_OP(height, >=, 0);
        PENSURE_OP(width, >=, 0);
        PENSURE_OP(height * width, ==, N);

        return ArrayMatrix<Real>(height, width, data);
    }

    template <typename Real>
    ArrayMatrix<Real> arrayMatrix(
        integer height, integer width,
        const Real* data)
    {
        PENSURE_OP(height, >=, 0);
        PENSURE_OP(width, >=, 0);

        return ArrayMatrix<Real>(height, width, data);
    }

    template <typename Real, integer M, integer N>
    ArrayMatrix<Real> arrayMatrix(
        Real (&data)[M][N])
    {
        return ArrayMatrix<Real>(M, N, data);
    }

    template <typename Real>
    Matrix<Real> matrix1x1(NoDeduction<Real> a00)
    {
        Matrix<Real> matrix(1, 1);
        matrix(0, 0) = a00;
        return matrix;
    }

    template <
        typename Real, integer N, 
        typename Expression1>
    Matrix<Real> matrix1x1(
        const VectorExpression<Real, N, Expression1>& firstColumn)
    {
        Matrix<Real> matrix(1, 1);
        matrix.column(0) = firstColumn;
        return matrix;
    }

    template <typename Real>
    Matrix<Real> matrix2x2(NoDeduction<Real> a00, NoDeduction<Real> a01,
                           NoDeduction<Real> a10, NoDeduction<Real> a11)
    {
        Matrix<Real> matrix(2, 2);
        matrix(0, 0) = a00;
        matrix(0, 1) = a01;
        matrix(1, 0) = a10;
        matrix(1, 1) = a11;
        return matrix;
    }

    template <
        typename Real, integer N, 
        typename Expression1, 
        typename Expression2>
    Matrix<Real> matrix2x2(
        const VectorExpression<Real, N, Expression1>& firstColumn,
        const VectorExpression<Real, N, Expression2>& secondColumn)
    {
        Matrix<Real> matrix(2, 2);
        matrix.column(0) = firstColumn;
        matrix.column(1) = secondColumn;
        return matrix;
    }

    template <typename Real>
    Matrix<Real> matrix3x3(NoDeduction<Real> a00, NoDeduction<Real> a01, NoDeduction<Real> a02,
                           NoDeduction<Real> a10, NoDeduction<Real> a11, NoDeduction<Real> a12,
                           NoDeduction<Real> a20, NoDeduction<Real> a21, NoDeduction<Real> a22)
    {
        Matrix<Real> matrix(3, 3);
        matrix(0, 0) = a00;
        matrix(0, 1) = a01;
        matrix(0, 2) = a02;
        matrix(1, 0) = a10;
        matrix(1, 1) = a11;
        matrix(1, 2) = a12;
        matrix(2, 0) = a20;
        matrix(2, 1) = a21;
        matrix(2, 2) = a22;
        return matrix;
    }

    template <
        typename Real, integer N, 
        typename Expression1, 
        typename Expression2,
        typename Expression3>
    Matrix<Real> matrix3x3(
        const VectorExpression<Real, N, Expression1>& firstColumn,
        const VectorExpression<Real, N, Expression2>& secondColumn,
        const VectorExpression<Real, N, Expression3>& thirdColumn)
    {
        Matrix<Real> matrix(3, 3);
        matrix.column(0) = firstColumn;
        matrix.column(1) = secondColumn;
        matrix.column(2) = thirdColumn;
        return matrix;
    }

    template <typename Real>
    Matrix<Real> matrix4x4(NoDeduction<Real> a00, NoDeduction<Real> a01, NoDeduction<Real> a02, NoDeduction<Real> a03,
                           NoDeduction<Real> a10, NoDeduction<Real> a11, NoDeduction<Real> a12, NoDeduction<Real> a13,
                           NoDeduction<Real> a20, NoDeduction<Real> a21, NoDeduction<Real> a22, NoDeduction<Real> a23,
                           NoDeduction<Real> a30, NoDeduction<Real> a31, NoDeduction<Real> a32, NoDeduction<Real> a33)
    {
        Matrix<Real> matrix(4, 4);
        matrix(0, 0) = a00;
        matrix(0, 1) = a01;
        matrix(0, 2) = a02;
        matrix(0, 3) = a03;
        matrix(1, 0) = a10;
        matrix(1, 1) = a11;
        matrix(1, 2) = a12;
        matrix(1, 3) = a13;
        matrix(2, 0) = a20;
        matrix(2, 1) = a21;
        matrix(2, 2) = a22;
        matrix(2, 3) = a23;
        matrix(3, 0) = a30;
        matrix(3, 1) = a31;
        matrix(3, 2) = a32;
        matrix(3, 3) = a33;
        return matrix;
    }

    template <
        typename Real, integer N, 
        typename Expression1, 
        typename Expression2,
        typename Expression3,
        typename Expression4>
    Matrix<Real> matrix4x4(
        const VectorExpression<Real, N, Expression1>& firstColumn,
        const VectorExpression<Real, N, Expression2>& secondColumn,
        const VectorExpression<Real, N, Expression3>& thirdColumn,
        const VectorExpression<Real, N, Expression4>& fourthColumn)
    {
        Matrix<Real> matrix(4, 4);
        matrix.column(0) = firstColumn;
        matrix.column(1) = secondColumn;
        matrix.column(2) = thirdColumn;
        matrix.column(3) = fourthColumn;
        return matrix;
    }

    template <typename Real, 
        integer Height, integer Width, 
        typename LeftExpression,
        typename RightExpression>
        OuterProduct<Real, LeftExpression, RightExpression>
        outerProduct(
        const VectorExpression<Real, Height, LeftExpression>& left,
        const VectorExpression<Real, Width, RightExpression>& right)
    {
        return OuterProduct<Real, LeftExpression, RightExpression>(
            (const LeftExpression&)left, (const RightExpression&)right);
    }

    template <typename Real, integer N, typename Expression>
        OuterProduct<Real, Expression, Expression>
        outerProduct(
        const VectorExpression<Real, N, Expression>& that)
    {
        return Pastel::outerProduct(that, that);
    }

    template <typename Real>
    void swap(Matrix<Real>& left, Matrix<Real>& right)
    {
        left.swap(right);
    }

    template <typename Real, integer N, 
    typename LeftExpression, typename RightExpression>
    const VectorMatrixMultiplication<Real, N, LeftExpression, RightExpression> operator *(
        const VectorExpression<Real, N, LeftExpression>& left,
        const MatrixExpression<Real, RightExpression>& right)
    {
        return VectorMatrixMultiplication<Real, N, LeftExpression, RightExpression>(
            (const LeftExpression&)left, 
            (const RightExpression&)right);
    }

    template <typename Real, integer N,
    typename LeftExpression, typename RightExpression>
    const MatrixVectorMultiplication<Real, N, LeftExpression, RightExpression> operator *(
        const MatrixExpression<Real, LeftExpression>& left,
        const VectorExpression<Real, N, RightExpression>& right)
    {
        return MatrixVectorMultiplication<Real, N, LeftExpression, RightExpression>(
            (const LeftExpression&)left, 
            (const RightExpression&)right);
    }

}

#include <iostream>

namespace Pastel
{

    template <typename Real, typename Expression>
    std::ostream& operator<<(
        std::ostream& stream,
        const MatrixExpression<Real, Expression>& m)
    {
        integer width = m.width();
        integer height = m.height();

        for (integer y = 0;y < height;++y)
        {
            for (integer x = 0;x < width;++x)
            {
                stream << m(y, x) << ", ";
            }
            stream << std::endl;
        }

        return stream;
    }

}

#endif