milena r1141: Add matrix handling and rewrite of vectors

URL: https://svn.lrde.epita.fr/svn/oln/trunk/milena ChangeLog: 2007-09-19 Simon Nivault <simon.nivault@lrde.epita.fr> Add matrix handling and rewrite of vectors * mln/make/mat.hh, * mln/metal/mat.hh: Matrix handling. * mln/make/vec.hh, * mln/metal/vec.hh: Rewrite. * tests/metal_mat.cc: New. --- mln/make/mat.hh | 72 +++++++++++ mln/make/vec.hh | 24 +-- mln/metal/mat.hh | 321 +++++++++++++++++++++++++++++++++++++++++++++++++++++ mln/metal/vec.hh | 50 ++++++-- tests/metal_mat.cc | 53 ++++++++ 5 files changed, 498 insertions(+), 22 deletions(-) Index: trunk/milena/tests/metal_mat.cc =================================================================== --- trunk/milena/tests/metal_mat.cc (revision 0) +++ trunk/milena/tests/metal_mat.cc (revision 1141) @@ -0,0 +1,53 @@ +// Copyright (C) 2007 EPITA Research and Development Laboratory +// +// This file is part of the Olena Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License version 2 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 +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 51 Franklin Street, Fifth Floor, +// Boston, MA 02111-1307, USA. +// +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +/*! \file tests/level_median.cc + * + * \brief Test on mln::median::median_dir. + */ + +#include <mln/metal/mat.hh> + +int main() +{ + using namespace mln; + + const int + tab1[18] = {3, 6, 5, 2, 4, 8, + 5, 7, 4, 6, 9, 2, + 2, 7, 1, 1, 5, 3}, + tab2[6] = {2, 5, 1, 0, 7, 2}, + tab3[6] = {3, 1, 6, 2, 1, 0}; + + metal::mat<3,6,int> mat36 = make::mat<3,6,18>(tab1); + metal::mat<2,3,int> mat23_1 = make::mat<2,3,6>(tab2); + metal::mat<2,3,int> mat23_2 = make::mat<2,3,6>(tab3); + + metal::mat<2,3,float> mat23_3 = mat23_1 - mat23_2; + + std::cout << mat23_3 << std::endl << mat23_3 * mat36 << std::endl; +} Index: trunk/milena/mln/metal/mat.hh =================================================================== --- trunk/milena/mln/metal/mat.hh (revision 0) +++ trunk/milena/mln/metal/mat.hh (revision 1141) @@ -0,0 +1,321 @@ +// Copyright (C) 2006 EPITA Research and Development Laboratory +// +// This file is part of the Olena Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License version 2 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 +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 51 Franklin Street, Fifth Floor, +// Boston, MA 02111-1307, USA. +// +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +#ifndef MLN_METAL_MAT_HH +# define MLN_METAL_MAT_HH + +# include <iostream> + +# include <mln/core/contract.hh> +# include <mln/metal/binary_arith_trait.hh> + +// FIXME: Document. + +namespace mln +{ + + namespace metal + { + + template <unsigned n, unsigned m, typename T> + class mat + { + public: + + typedef T value_type; + enum {N = n, M = m}; + + mat() + { + } + + template <typename U> + mat(const mat<n,m,U>& rhs); + + template <typename U> + mat& operator=(const mat<n,m,U>& rhs); + + const T& operator()(unsigned i, unsigned j) const; + + T& operator()(unsigned i, unsigned j); + + void set_all(const T& val); + + unsigned size() const; + + private: + T data_[n][m]; + }; + +# ifndef MLN_INCLUDE_ONLY + + template <unsigned n, unsigned m, typename T> + template <typename U> + mat<n,m,T>::mat(const mat<n,m,U>& rhs) + { + for (unsigned i = 0; i < n; ++i) + for (unsigned j = 0; j < m; ++j) + data_[i][j] = rhs(i, j); + } + + template <unsigned n, unsigned m, typename T> + template <typename U> + mat<n,m,T>& + mat<n,m,T>::operator=(const mat<n,m,U>& rhs) + { + for (unsigned i = 0; i < n; ++i) + for (unsigned j = 0; j < m; ++j) + data_[i][j] = rhs(i, j); + return *this; + } + + template <unsigned n, unsigned m, typename T> + const T& + mat<n,m,T>::operator()(unsigned i, unsigned j) const + { + mln_precondition(i < n && j < m); + return data_[i][j]; + } + + template <unsigned n, unsigned m, typename T> + T& + mat<n,m,T>::operator()(unsigned i, unsigned j) + { + mln_precondition(i < n && j < m); + return data_[i][j]; + } + + template <unsigned n, unsigned m, typename T> + void mat<n,m,T>::set_all(const T& val) + { + for (unsigned i = 0; i < n; ++i) + for (unsigned j = 0; j < m; ++j) + data_[i][j] = val; + } + + template <unsigned n, unsigned m, typename T> + unsigned mat<n,m,T>::size() const + { + return n * m; + } + + // eq + + template <unsigned n, unsigned m, typename T, typename U> + bool + operator==(const mat<n,m,T>& lhs, const mat<n,m,U>& rhs) + { + for (unsigned i = 0; i < n; ++i) + for (unsigned j = 0; j < m; ++j) + if (lhs(i, j) != rhs(i, j)) + return false; + return true; + } + + template <unsigned n, unsigned m, typename T, typename U> + bool + operator!=(const mat<n,m,T>& lhs, const mat<n,m,U>& rhs) + { + return not (lhs == rhs); + } + + // + + + template <unsigned n, unsigned m, typename T, typename U> + mat<n,m,T>& + operator+=(mat<n,m,T>& lhs, const mat<n,m,U>& rhs) + { + for (unsigned i = 0; i < n; ++i) + for (unsigned j = 0; j < m; ++j) + lhs(i, j) += rhs(i, j); + return lhs; + } + template <unsigned n, unsigned m, typename T, typename U> + mat<n,m,typename binary_arith_trait<T,U>::ret> + operator+(mat<n,m,T>& lhs, const mat<n,m,U>& rhs) + { + mat<n,m,typename binary_arith_trait<T,U>::ret> tmp; + for (unsigned i = 0; i < n; ++i) + for (unsigned j = 0; j < m; ++j) + tmp[i][j] = lhs(i, j) + rhs(i, j); + return tmp; + } + + // - + + template <unsigned n, unsigned m, typename T, typename U> + mat<n,m,T>& + operator-=(mat<n,m,T>& lhs, const mat<n,m,U>& rhs) + { + for (unsigned i = 0; i < n; ++i) + for (unsigned j = 0; j < m; ++j) + lhs(i, j) -= rhs(i, j); + return lhs; + } + template <unsigned n, unsigned m, typename T, typename U> + mat<n,m,typename binary_arith_trait<T,U>::ret> + operator-(mat<n,m,T>& lhs, const mat<n,m,U>& rhs) + { + mat<n,m,typename binary_arith_trait<T,U>::ret> tmp; + for (unsigned i = 0; i < n; ++i) + for (unsigned j = 0; j < m; ++j) + tmp(i, j) = lhs(i, j) - rhs(i, j); + return tmp; + } + + template <unsigned n, unsigned m, typename T> + mat<n,m,T> + operator-(const mat<n,m,T>& lhs) + { + mat<n,m,T> tmp; + for (unsigned i = 0; i < n; ++i) + for (unsigned j = 0; i < m; ++i) + tmp(i, j) = - lhs(i, j); + return tmp; + } + + // * + + template <unsigned n, unsigned m, typename T, typename U> + mat<n,m,T>& + operator*=(mat<n,m,T>& lhs, const U& scalar) + { + for (unsigned i = 0; i < n; ++i) + for (unsigned j = 0; j < m; ++j) + lhs(i, j) *= scalar; + return lhs; + } + template <unsigned n, unsigned m, typename T, typename U> + mat<n,m,typename binary_arith_trait<T,U>::ret> + operator*(mat<n,m,T>& lhs, const U& scalar) + { + mat<n,m,typename binary_arith_trait<T,U>::ret> tmp; + for (unsigned i = 0; i < n; ++i) + for (unsigned j = 0; j < m; ++j) + tmp[i][j] = lhs(i, j) * scalar; + return tmp; + } + + template <unsigned n, unsigned m, unsigned o, typename T, typename U> + mat<n,m,T>& + operator*=(mat<n,o,T>& lhs, mat<o,m,U>& rhs) + { + lhs = lhs * rhs; + return lhs; + } + template <unsigned n, unsigned m, unsigned o, typename T, typename U> + mat<n,m,typename binary_arith_trait<T,U>::ret> + operator*(mat<n,o,T>& lhs, mat<o,m,U>& rhs) + { + mat<n,m,typename binary_arith_trait<T,U>::ret> tmp; + for (unsigned i = 0; i < n; ++i) + for (unsigned j = 0; j < m; ++j) + { + tmp(i, j) = 0; + for (unsigned k = 0; k < o; ++k) + tmp(i, j) += lhs(i, k) * rhs(k, j); + } + return tmp; + } + + // / + + template <unsigned n, unsigned m, typename T, typename U> + mat<n,m,T> + operator/=(mat<n,m,T>& lhs, const U& scalar) + { + for (unsigned i = 0; i < n; ++i) + for (unsigned j = 0; j < m; ++j) + lhs(i, j) /= scalar; + return lhs; + } + template <unsigned n, unsigned m, typename T, typename U> + mat<n,m,typename binary_arith_trait<T,U>::ret> + operator/(mat<n,m,T>& lhs, const U& scalar) + { + mat<n,m,typename binary_arith_trait<T,U>::ret> tmp; + for (unsigned i = 0; i < n; ++i) + for (unsigned j = 0; j < m; ++j) + tmp[i][j] = lhs(i, j) / scalar; + return tmp; + } + + // << + + template <unsigned n, unsigned m, typename T> + std::ostream& + operator<<(std::ostream& ostr, const mat<n,m,T>& v) + { + for (unsigned i = 0; i < n; ++i) + { + ostr << '('; + for (unsigned j = 0; j < m; ++j) + ostr << v(i, j) << (j == m - 1 ? ")" : ", "); + ostr << std::endl; + } + return ostr; + } + + template <unsigned n, unsigned m> + std::ostream& + operator<<(std::ostream& ostr, const mat<n,m,unsigned char>& v) + { + for (unsigned i = 0; i < n; ++i) + { + ostr << '('; + for (unsigned j = 0; j < m; ++j) + ostr << (unsigned int)(v[i][j]) << (j == m - 1 ? ")" : ", "); + ostr << std::endl; + } + return ostr; + } + + template <unsigned n, unsigned m> + std::ostream& + operator<<(std::ostream& ostr, const mat<n,m,signed char>& v) + { + for (unsigned i = 0; i < n; ++i) + { + ostr << '('; + for (unsigned j = 0; j < m; ++j) + ostr << (signed int)(v[i][j]) << (j == m - 1 ? ")" : ", "); + ostr << std::endl; + } + return ostr; + } + + + +# endif // ! MLN_INCLUDE_ONLY + + } // end of namespace mln::metal + +} // end of namespace mln + +# include <mln/make/mat.hh> + +#endif // ! MLN_METAL_MAT_HH Index: trunk/milena/mln/metal/vec.hh =================================================================== --- trunk/milena/mln/metal/vec.hh (revision 1140) +++ trunk/milena/mln/metal/vec.hh (revision 1141) @@ -126,48 +126,78 @@ { } + vec(const vec<n, T>& rhs); + + template <typename U> + vec(const vec<n, U>& rhs); + + template <typename U> + vec& operator=(const vec<n, U>& rhs); + + const T& operator[](unsigned i) const; + + T& operator[](unsigned i); + + void set_all(const T& val); + + unsigned size() const; + + }; + + +# ifndef MLN_INCLUDE_ONLY + + template <unsigned n, typename T> + vec<n,T>::vec(const vec<n,T>& rhs) + { + for (unsigned i = 0; i < n; ++i) + data_[i] = rhs[i]; + } + + template <unsigned n, typename T> template <typename U> - vec(const vec<n, U>& rhs) + vec<n,T>::vec(const vec<n, U>& rhs) { for (unsigned i = 0; i < n; ++i) data_[i] = rhs[i]; } + template <unsigned n, typename T> template <typename U> - vec& operator=(const vec<n, U>& rhs) + vec<n,T>& vec<n,T>::operator=(const vec<n, U>& rhs) { for (unsigned i = 0; i < n; ++i) data_[i] = rhs[i]; return *this; } - const T& operator[](unsigned i) const + template <unsigned n, typename T> + const T& vec<n,T>::operator[](unsigned i) const { mln_precondition(i < dim); return data_[i]; } - T& operator[](unsigned i) + template <unsigned n, typename T> + T& vec<n,T>::operator[](unsigned i) { mln_precondition(i < dim); return data_[i]; } - void set_all(const T& val) + template <unsigned n, typename T> + void vec<n,T>::set_all(const T& val) { for (unsigned i = 0; i < n; ++i) data_[i] = val; } - unsigned size() const + template <unsigned n, typename T> + unsigned vec<n,T>::size() const { return n; } - }; - - -# ifndef MLN_INCLUDE_ONLY // eq Index: trunk/milena/mln/make/mat.hh =================================================================== --- trunk/milena/mln/make/mat.hh (revision 0) +++ trunk/milena/mln/make/mat.hh (revision 1141) @@ -0,0 +1,72 @@ +// Copyright (C) 2006 EPITA Research and Development Laboratory +// +// This file is part of the Olena Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License version 2 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 +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 51 Franklin Street, Fifth Floor, +// Boston, MA 02111-1307, USA. +// +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +#ifndef MLN_MAKE_MAT_HH +# define MLN_MAKE_MAT_HH + +/*! \file mln/make/mat.hh + * + * \brief Routine to construct an mln::metal::mat. + */ + +# include <mln/metal/mat.hh> + +namespace mln +{ + + namespace make + { + /*! \brief Create an mln::metal::mat<n,m,T>. + * + * \param[in] tab Tab of value. + * + * \pre The dimension table N is such as N = n * m + * with n and m, the dimensions oh the matrix. + */ + template <unsigned n, unsigned m, unsigned N, typename T> + metal::mat<n,m,T> mat(const T tab[N]); + +# ifndef MLN_INCLUDE_ONLY + + template <unsigned n, unsigned m, unsigned N, typename T> + metal::mat<n,m,T> mat(const T tab[N]) + { + mln_precondition(n * m == N); + metal::mat<n,m,T> tmp; + for (unsigned i = 0; i < N; ++i) + tmp(i / m, i % m) = tab[i]; + return tmp; + } + + +# endif // ! MLN_INCLUDE_ONLY + + } // end of namespace mln::make + +} // end of namespace mln + +#endif // ! MLN_MAKE_MAT_HH Index: trunk/milena/mln/make/vec.hh =================================================================== --- trunk/milena/mln/make/vec.hh (revision 1140) +++ trunk/milena/mln/make/vec.hh (revision 1141) @@ -48,7 +48,7 @@ * \return A 1D vector. */ template <typename T> - mln::metal::vec<1, T> vec(const T& v_0); + metal::vec<1, T> vec(const T& v_0); /*! \brief Create an mln::metal::vec<2,T>. * @@ -58,7 +58,7 @@ * \return A 2D vector. */ template <typename T> - mln::metal::vec<2, T> vec(const T& v_0, const T& v_1); + metal::vec<2, T> vec(const T& v_0, const T& v_1); /*! \brief Create an mln::metal::vec<3,T>. * @@ -69,7 +69,7 @@ * \return A 3D vector. */ template <typename T> - mln::metal::vec<3, T> vec(const T& v_0, const T& v_1, const T& v_2); + metal::vec<3, T> vec(const T& v_0, const T& v_1, const T& v_2); /*! \brief Create an mln::metal::vec<4,T>. * @@ -81,32 +81,32 @@ * \return A 4D vector. */ template <typename T> - mln::metal::vec<4, T> vec(const T& v_0, const T& v_1, const T& v_2, const T& v_3); + metal::vec<4, T> vec(const T& v_0, const T& v_1, const T& v_2, const T& v_3); # ifndef MLN_INCLUDE_ONLY template <typename T> - mln::metal::vec<1, T> vec(const T& v_0) + metal::vec<1, T> vec(const T& v_0) { - mln::metal::vec<1, T> tmp; + metal::vec<1, T> tmp; tmp[0] = v_0; return tmp; } template <typename T> - mln::metal::vec<2, T> vec(const T& v_0, const T& v_1) + metal::vec<2, T> vec(const T& v_0, const T& v_1) { - mln::metal::vec<2, T> tmp; + metal::vec<2, T> tmp; tmp[0] = v_0; tmp[1] = v_1; return tmp; } template <typename T> - mln::metal::vec<3, T> vec(const T& v_0, const T& v_1, const T& v_2) + metal::vec<3, T> vec(const T& v_0, const T& v_1, const T& v_2) { - mln::metal::vec<3, T> tmp; + metal::vec<3, T> tmp; tmp[0] = v_0; tmp[1] = v_1; tmp[2] = v_2; @@ -114,9 +114,9 @@ } template <typename T> - mln::metal::vec<4, T> vec(const T& v_0, const T& v_1, const T& v_2, const T& v_3) + metal::vec<4, T> vec(const T& v_0, const T& v_1, const T& v_2, const T& v_3) { - mln::metal::vec<4, T> tmp; + metal::vec<4, T> tmp; tmp[0] = v_0; tmp[1] = v_1; tmp[2] = v_2;
participants (1)
-
Simon Nivault