URL:
https://svn.lrde.epita.fr/svn/oln/trunk/milena
ChangeLog:
2007-09-19 Simon Nivault <simon.nivault(a)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;