https://svn.lrde.epita.fr/svn/oln/trunk/milena
Index: ChangeLog
from Thierry Geraud <thierry.geraud(a)lrde.epita.fr>
Fix missing definitions and bugs in algebra vec and mat.
* mln/literal/identity.hh: New.
* mln/accu/stat/variance.hh: Copy to...
* mln/accu/stat/var.hh: ...this new file.
Update to compute the variance matrix.
* mln/value/ops.hh: Layout.
* mln/algebra/mat.hh (mat): New overloaded ctor for identity.
(_1, set_id_): New methods.
(make): New couple of procedures.
(trait): Fix missing definitions.
(set_precise_binary_): Duplicate explicitly for op::times
and op::div.
(operator==): Fix missing const in signature.
(tr): Fix return type.
Use literal instead of 0.
(det): New procedures.
(internal::inverse): New.
* mln/algebra/vec.hh (trait): Fix missing definitions.
(set_precise_binary_): Duplicate explicitly for op::times
and op::div.
(operator-): New unary operator.
* tests/algebra/mat.cc: Copy to...
* tests/algebra/h_mat.cc: ...this new file.
* tests/algebra/mat.cc: Revamp so that there is no h_mat.
* tests/algebra/Makefile.am: Update.
mln/accu/stat/var.hh | 192 ++++++++++++---------------
mln/algebra/mat.hh | 320 ++++++++++++++++++++++++++++++++++++++--------
mln/algebra/vec.hh | 115 +++++++++++++---
mln/literal/identity.hh | 63 +++++++++
mln/value/ops.hh | 6
tests/algebra/Makefile.am | 2
tests/algebra/h_mat.cc | 17 +-
tests/algebra/mat.cc | 49 +++----
8 files changed, 553 insertions(+), 211 deletions(-)
Index: mln/literal/identity.hh
--- mln/literal/identity.hh (revision 0)
+++ mln/literal/identity.hh (revision 0)
@@ -0,0 +1,63 @@
+// Copyright (C) 2009 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_LITERAL_IDENTITY_HH
+# define MLN_LITERAL_IDENTITY_HH
+
+/// \file mln/literal/identity.hh
+///
+/// Definition of the literal of mln::identity.
+
+# include <mln/core/concept/literal.hh>
+
+
+namespace mln
+{
+
+ namespace literal
+ {
+
+ /// Type of literal identity.
+ struct identity_t : public Literal<identity_t>
+ {
+ };
+
+ /// Literal identity.
+ extern const identity_t& identity;
+
+# ifndef MLN_INCLUDE_ONLY
+
+ const identity_t& identity = identity_t();
+
+# endif
+
+ } // end of namespace mln::literal
+
+} // end of namespace mln
+
+
+#endif // ! MLN_LITERAL_IDENTITY_HH
Index: mln/accu/stat/var.hh
--- mln/accu/stat/var.hh (revision 3733)
+++ mln/accu/stat/var.hh (working copy)
@@ -25,18 +25,21 @@
// reasons why the executable file might be covered by the GNU General
// Public License.
-#ifndef MLN_ACCU_STAT_VARIANCE_HH
-# define MLN_ACCU_STAT_VARIANCE_HH
+#ifndef MLN_ACCU_STAT_VAR_HH
+# define MLN_ACCU_STAT_VAR_HH
-/// \file mln/accu/stat/variance.hh
+/// \file mln/accu/stat/var.hh
///
-/// Define an accumulator that computes the variance of a set of values.
+/// Define an accumulator that computes the variance matrix of a set
+/// of vectors.
# include <cmath>
# include <mln/accu/internal/base.hh>
+# include <mln/algebra/vec.hh>
+# include <mln/algebra/mat.hh>
+# include <mln/fun/i2v/all_to.hh>
# include <mln/util/pix.hh>
-
namespace mln
{
@@ -46,189 +49,164 @@
namespace stat
{
- /// \brief Variance accumulator class.
- /*!
- * Parameter \c T is the type of values that we sum. Parameter
- * \c S is the type to store the value sum and the sum of value
- * * value; the default type of \c S is the summation type
- * (property) of \c T. Parameter \c R is the type of the mean
- * and variance values; the default type of \c R is \c S.
- *
- * \ingroup modaccuvalues
- *
- */
- template <typename T,
- typename S = mln_sum(T),
- typename R = S>
- struct variance : public mln::accu::internal::base< R , variance<T,S,R>
>
+ /// \brief Var accumulator class.
+ ///
+ /// Parameter \c T is the type of vectors
+ ///
+ /// \ingroup modaccuvalues
+ //
+ template <typename T>
+ struct var : public mln::accu::internal::base< algebra::mat< T::dim, T::dim,
float >,
+ var<T> >
{
+ enum { dim = T::dim };
typedef T argument;
- typedef R result;
+ typedef algebra::mat<dim,dim,float> result;
- variance();
+ var();
/// Manipulators.
/// \{
void init();
- void take_as_init(const argument& t);
- void take(const argument& t);
- void take(const variance<T,S,R>& other);
+ void take(const argument& v);
+ void take(const var<T>& other);
- void take(unsigned n_times, const argument& t); // Extra.
+ void take_as_init_(const argument& v);
+ void take_n_times_(unsigned n_times, const argument& v);
/// \}
- /// Get the accumulator result (the variance value).
- R to_result() const;
-
- /// Get the variance value.
- R var() const;
+ /// Get the accumulator result (the var value).
+ result to_result() const;
- /// Get the standard deviation value.
- R standard_deviation() const;
-
- /// Get the mean value.
- R mean() const;
-
- /// Get the sum value.
- S sum() const;
+ /// Get the variance matrix.
+ result variance() const;
/// Get the number of items.
unsigned n_items() const;
- /// Check whether this accu is able to return a result.
- /// Always true here.
+ /// Get the mean vector.
+ algebra::vec<dim,float> mean() const;
+
+ /// Check whether this accu returns a valid result.
bool is_valid() const;
protected:
unsigned n_;
- S sum_, sum2_;
+ algebra::vec<dim,float> sum_;
+ algebra::mat<dim,dim,float> cov_;
};
- template <typename I, typename S, typename R>
- struct variance< util::pix<I>, S,R >;
-
-
-
# ifndef MLN_INCLUDE_ONLY
- template <typename T, typename S, typename R>
+ template <typename T>
inline
- variance<T,S,R>::variance()
+ var<T>::var()
{
init();
}
- template <typename T, typename S, typename R>
+ template <typename T>
inline
void
- variance<T,S,R>::init()
+ var<T>::init()
{
n_ = 0;
- sum_ = sum2_ = 0;
+ sum_.set_all(0);
+ cov_ .set_all(0);
}
- template <typename T, typename S, typename R>
+ template <typename T>
inline
void
- variance<T,S,R>::take(const argument& t)
+ var<T>::take(const argument& v)
{
++n_;
- sum_ += t;
- sum2_ += t * t;
+ sum_ += v;
+ cov_ += v * v.t();
}
- template <typename T, typename S, typename R>
+ template <typename T>
inline
void
- variance<T,S,R>::take(unsigned n_times, const argument& t)
+ var<T>::take(const var<T>& other)
{
- if (n_times == 0u)
- return;
- n_ += n_times;
- sum_ += n_times * t;
- sum2_ += n_times * t * t;
+ n_ += other.n_;
+ cov_ += other.cov_;
}
- template <typename T, typename S, typename R>
+ template <typename T>
inline
void
- variance<T,S,R>::take_as_init(const argument& t)
+ var<T>::take_as_init_(const argument& v)
{
n_ = 1;
- sum_ = t;
- sum2_ = t * t;
+ sum_ = v;
+ cov_ = v * v.t();
}
- template <typename T, typename S, typename R>
+ template <typename T>
inline
void
- variance<T,S,R>::take(const variance<T,S,R>& other)
+ var<T>::take_n_times_(unsigned n_times, const argument& v)
{
- n_ += other.n_;
- sum_ += other.sum_;
- sum2_ += other.sum2_;
+ n_ += n_times;
+ sum_ += n_times * v;
+ cov_ += n_times * v * v.t();
}
- template <typename T, typename S, typename R>
- inline
- R
- variance<T,S,R>::to_result() const
- {
- if (n_ == 0u)
- return 0; // Safety.
- S m_ = sum_ / n_;
- return sum2_ / n_ - m_ * m_;
- }
- template <typename T, typename S, typename R>
+ template <typename T>
inline
- R
- variance<T,S,R>::mean() const
+ mln_result(var<T>)
+ var<T>::to_result() const
{
+ static result null_(fun::i2v::all_to(0));
+
if (n_ == 0u)
- return 0; // Safety.
- return sum_ / n_;
+ return null_; // Safety.
+
+ return (cov_ - sum_ * sum_.t() / n_) / n_;
+ // Shorter than:
+ // mean_ = sum_ / n_
+ // var_ = cov_ / n_ - mean_ * mean_.t()
}
- template <typename T, typename S, typename R>
+ template <typename T>
inline
- S
- variance<T,S,R>::sum() const
+ mln_result(var<T>)
+ var<T>::variance() const
{
- return sum_;
+ return to_result();
}
- template <typename T, typename S, typename R>
+ template <typename T>
inline
unsigned
- variance<T,S,R>::n_items() const
+ var<T>::n_items() const
{
return n_;
}
- template <typename T, typename S, typename R>
+ template <typename T>
inline
- R
- variance<T,S,R>::var() const
+ algebra::vec<dim,float>
+ var<T>::mean() const
{
- return to_result();
- }
+ static algebra::vec<dim,float> null_(fun::i2v::all_to(0));
- template <typename T, typename S, typename R>
- inline
- R
- variance<T,S,R>::standard_deviation() const
- {
- return std::sqrt(to_result());
+ if (n_ == 0u)
+ return null_; // Safety.
+
+ return sum_ / n_;
}
- template <typename T, typename S, typename R>
+ template <typename T>
inline
bool
- variance<T,S,R>::is_valid() const
+ var<T>::is_valid() const
{
return n_ != 0;
}
@@ -242,4 +220,4 @@
} // end of namespace mln
-#endif // ! MLN_ACCU_STAT_VARIANCE_HH
+#endif // ! MLN_ACCU_STAT_VAR_HH
Index: mln/value/ops.hh
--- mln/value/ops.hh (revision 3734)
+++ mln/value/ops.hh (working copy)
@@ -1,5 +1,5 @@
-// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory
-// (LRDE)
+// Copyright (C) 2007, 2008, 2009 EPITA Research and Development
+// Laboratory (LRDE)
//
// This file is part of the Olena Library. This library is free
// software; you can redistribute it and/or modify it under the terms
@@ -43,10 +43,12 @@
# include <mln/literal/ops.hh>
# include <mln/metal/ret.hh>
+
/// Type trait for value sum.
# define mln_trait_value_sum_product(T, U) \
typename mln::trait::value_< mln_trait_op_times(T,U) >::sum
+
/// Shortcut for type trait for value sum.
# define mln_sum_product(T, U) mln_trait_value_sum_product(T, U)
Index: mln/algebra/mat.hh
--- mln/algebra/mat.hh (revision 3734)
+++ mln/algebra/mat.hh (working copy)
@@ -1,5 +1,5 @@
-// Copyright (C) 2006, 2008 EPITA Research and Development Laboratory
-// (LRDE)
+// Copyright (C) 2006, 2008, 2009 EPITA Research and Development
+// Laboratory (LRDE)
//
// This file is part of the Olena Library. This library is free
// software; you can redistribute it and/or modify it under the terms
@@ -41,6 +41,7 @@
# include <mln/trait/all.hh>
# include <mln/trait/value_.hh>
# include <mln/algebra/vec.hh>
+# include <mln/literal/identity.hh>
// FIXME: Document.
@@ -51,7 +52,7 @@
{
- // Fwd decl.
+ // Forward declaration.
namespace algebra {
template <unsigned n, unsigned m, typename T> class mat;
}
@@ -98,6 +99,8 @@
mat();
mat(const literal::zero_t&);
+ mat(const literal::one_t&);
+ mat(const literal::identity_t&);
template <typename U>
mat(const mat<n,m,U>& rhs);
@@ -122,76 +125,138 @@
/// Return the transpose of the matrix.
mat<m,n,T> t() const;
+ /// Return the inverse of the matrix.
+ /// Only compile on square matrix.
+ mat<n,m,T> _1() const;
+
private:
+
T data_[n][m];
+
+ void set_id_();
};
- }
+
+ template <typename T>
+ mat<2,2,T>
+ make(const T& t00, const T& t01,
+ const T& t10, const T& t11);
+
+ template <typename T>
+ mat<3,3,T>
+ make(const T& t00, const T& t01, const T& t02,
+ const T& t10, const T& t11, const T& t12,
+ const T& t20, const T& t21, const T& t22);
+
+
+ } // end of namespace algebra
+
namespace trait
{
- // Unarys.
+ // - mat
- template < template<class> class Name,
- unsigned n, unsigned m, typename T >
- struct set_precise_unary_< Name, algebra::mat<n,m,T> >
+ template < unsigned n, unsigned m, typename T >
+ struct set_precise_unary_< op::uminus,
+ algebra::mat<n,m,T> >
+ {
+ typedef algebra::mat<n, m, mln_trait_op_uminus(T)> ret;
+ };
+
+ // mat + mat
+
+ template < unsigned n, unsigned m, typename T, typename U >
+ struct set_precise_binary_< op::plus,
+ algebra::mat<n,m,T>, algebra::mat<n,m,U> >
{
- typedef algebra::mat<n, m, mln_trait_unary(Name, T)> ret;
+ typedef algebra::mat<n, m, mln_trait_op_plus(T, U)> ret;
};
- // Default for binarys; works for (+), (-), comparisons, and promote.
+ // mat - mat
- template < template<class, class> class Name,
- unsigned n, unsigned m, typename T, typename U>
- struct set_precise_binary_< Name, algebra::mat<n,m,T>,
algebra::mat<n,m,U> >
+ template < unsigned n, unsigned m, typename T, typename U >
+ struct set_precise_binary_< op::minus,
+ algebra::mat<n,m,T>, algebra::mat<n,m,U> >
{
- typedef algebra::mat<n, m, mln_trait_binary(Name, T, U)> ret;
+ typedef algebra::mat<n, m, mln_trait_op_minus(T, U)> ret;
};
// mat * mat
template < unsigned n, unsigned o, typename T,
unsigned m, typename U >
- struct set_precise_binary_< op::times, algebra::mat<n,o,T>,
algebra::mat<o,m,U> >
+ struct set_precise_binary_< op::times,
+ algebra::mat<n,o,T>, algebra::mat<o,m,U> >
{
typedef algebra::mat<n, m, mln_sum_product(T, U)> ret;
};
- template < unsigned n, typename T, typename U >
- struct set_precise_binary_< op::times, algebra::mat<n,n,T>,
algebra::mat<n,n,U> >
- { // Disambiguate between both previous defs.
- typedef algebra::mat<n, n, mln_sum_product(T, U)> ret;
+ template < unsigned o, typename T,
+ typename U >
+ struct set_precise_binary_< op::times,
+ algebra::mat<1,o,T>, algebra::mat<o,1,U> >
+ {
+ typedef mln_sum_product(T, U) ret;
};
// mat * vec
template < unsigned n, unsigned m, typename T,
typename U >
- struct set_precise_binary_< op::times, algebra::mat<n,m,T>,
algebra::vec<m,U> >
+ struct set_precise_binary_< op::times,
+ algebra::mat<n,m,T>, algebra::vec<m,U> >
{
typedef algebra::vec<n, mln_sum_product(T, U)> ret;
};
+ template < unsigned m, typename T,
+ typename U >
+ struct set_precise_binary_< op::times,
+ algebra::mat<1,m,T>, algebra::vec<m,U> >
+ {
+ typedef mln_sum_product(T, U) ret; // a scalar
+ };
+
+ // vec * mat
+
+ template < unsigned m, typename T,
+ typename U >
+ struct set_precise_binary_< op::times,
+ algebra::vec<m,T>, algebra::mat<1,m,U> >
+ {
+ typedef algebra::mat<m, m, mln_trait_op_times(T, U)> ret;
+ };
+
// mat * s
- template < template<class, class> class Name,
- unsigned n, unsigned m, typename T,
+ template < unsigned n, unsigned m, typename T,
typename S >
- struct set_precise_binary_< Name, algebra::mat<n,m,T>,
mln::value::scalar_<S> >
+ struct set_precise_binary_< op::times,
+ algebra::mat<n,m,T>, mln::value::scalar_<S> >
{
- typedef algebra::mat<n, m, mln_trait_binary(Name, T, S)> ret;
+ typedef algebra::mat<n, m, mln_trait_op_times(T, S)> ret;
};
- template < template<class, class> class Name,
- unsigned n, unsigned m, typename T,
+// template < template<class, class> class Name,
+// unsigned n, unsigned m, typename T,
+// typename S >
+// struct set_binary_< Name,
+// mln::Object, algebra::mat<n,m,T>,
+// mln::value::Scalar, S >
+// {
+// typedef algebra::mat<n, m, mln_trait_binary(Name, T, S)> ret;
+// };
+
+ // mat / s
+
+ template < unsigned n, unsigned m, typename T,
typename S >
- struct set_binary_< Name,
- mln::Object, algebra::mat<n,m,T>,
- mln::value::Scalar, S >
+ struct set_precise_binary_< op::div,
+ algebra::mat<n,m,T>, mln::value::scalar_<S> >
{
- typedef algebra::mat<n, m, mln_trait_binary(Name, T, S)> ret;
+ typedef algebra::mat<n, m, mln_trait_op_div(T, S)> ret;
};
} // end of namespace mln::trait
@@ -205,27 +270,26 @@
template <unsigned n, unsigned m, typename T, typename U>
bool
- operator==(mat<n,m,T>& lhs, const mat<n,m,U>& rhs);
+ operator==(const mat<n,m,T>& lhs, const mat<n,m,U>& rhs);
- // +
+ // - mat
+
+ template <unsigned n, unsigned m, typename T>
+ mat<n, m, mln_trait_op_uminus(T)>
+ operator-(const mat<n,m,T>& lhs);
+
+ // mat + mat
template <unsigned n, unsigned m, typename T, typename U>
- inline
mat<n, m, mln_trait_op_plus(T,U)>
operator+(const mat<n,m,T>& lhs, const mat<n,m,U>& rhs);
- // -
+ // mat - mat
template <unsigned n, unsigned m, typename T, typename U>
mat<n, m, mln_trait_op_minus(T,U)>
operator-(const mat<n,m,T>& lhs, const mat<n,m,U>& rhs);
- // - (unary)
-
- template <unsigned n, unsigned m, typename T>
- mat<n, m, mln_trait_op_uminus(T)>
- operator-(const mat<n,m,T>& lhs);
-
// mat * mat
template <unsigned n, unsigned o, typename T,
@@ -276,10 +340,23 @@
operator<<(std::ostream& ostr, const mat<n,m,T>& v);
- // trace
- template<unsigned n, typename T> inline
- float tr(const mat<n,n,T>& m);
+ // Trace.
+
+ template<unsigned n, typename T>
+ mln_sum(T)
+ tr(const mat<n,n,T>& m);
+
+
+ // Determinant.
+
+ template<typename T>
+ mln_sum_product(T,T)
+ det(const mat<2,2,T>& m);
+
+ template<typename T>
+ mln_sum_product(T,T)
+ det(const mat<3,3,T>& m);
@@ -364,6 +441,33 @@
}
template <unsigned n, unsigned m, typename T>
+ inline
+ void
+ mat<n,m,T>::set_id_()
+ {
+ for (unsigned i = 0; i < n; ++i)
+ for (unsigned j = 0; j < m; ++j)
+ if (i == j)
+ data_[i][j] = literal::one;
+ else
+ data_[i][j] = literal::zero;
+ }
+
+ template <unsigned n, unsigned m, typename T>
+ inline
+ mat<n,m,T>::mat(const literal::one_t&)
+ {
+ this->set_id_();
+ }
+
+ template <unsigned n, unsigned m, typename T>
+ inline
+ mat<n,m,T>::mat(const literal::identity_t&)
+ {
+ this->set_id_();
+ }
+
+ template <unsigned n, unsigned m, typename T>
template <typename U>
inline
mat<n,m,T>::mat(const mat<n,m,U>& rhs)
@@ -443,9 +547,100 @@
return tmp;
}
+ namespace internal
+ {
- // Operators.
+ template <typename T>
+ inline
+ mat<2,2,T>
+ inverse(const mat<2,2,T>& m)
+ {
+ T d = det(m);
+ mln_precondition(d != 0);
+ return make<T>( + m(1,1) / d, - m(0,1) / d,
+ - m(1,0) / d, + m(0,0) / d );
+ }
+ template <typename T>
+ inline
+ mat<3,3,T>
+ inverse(const mat<3,3,T>& m)
+ {
+ T d = det(m);
+ mln_precondition(d != 0);
+ return make<T>( det(make(m(1,1), m(1,2),
+ m(2,1), m(2,2))),
+
+ det(make(m(0,2), m(0,1),
+ m(2,2), m(2,1))),
+
+ det(make(m(0,1), m(0,2),
+ m(1,1), m(1,2))),
+
+
+ det(make(m(1,2), m(1,0),
+ m(2,2), m(2,0))),
+
+ det(make(m(0,0), m(0,2),
+ m(2,0), m(2,2))),
+
+ det(make(m(0,2), m(0,0),
+ m(1,2), m(1,0))),
+
+ det(make(m(1,0), m(1,1),
+ m(2,0), m(2,1))),
+
+ det(make(m(0,1), m(0,0),
+ m(2,1), m(2,0))),
+
+ det(make(m(0,0), m(0,1),
+ m(1,0), m(1,1)))
+ ) / d;
+ }
+
+ } // end of namespace algebra::inverse
+
+ template <unsigned n, unsigned m, typename T>
+ inline
+ mat<n,m,T>
+ mat<n,m,T>::_1() const
+ {
+ mlc_bool(m == n)::check();
+ return internal::inverse(*this);
+ }
+
+
+ // "Make" routines.
+
+ template <typename T>
+ inline
+ mat<2,2,T>
+ make(const T& t00, const T& t01,
+ const T& t10, const T& t11)
+ {
+ mat<2,2,T> tmp;
+ tmp(0, 0) = t00; tmp(0, 1) = t01;
+ tmp(1, 0) = t10; tmp(1, 1) = t11;
+ return tmp;
+ }
+
+ template <typename T>
+ inline
+ mat<3,3,T>
+ make(const T& t00, const T& t01, const T& t02,
+ const T& t10, const T& t11, const T& t12,
+ const T& t20, const T& t21, const T& t22)
+ {
+ mat<3,3,T> tmp;
+ tmp(0, 0) = t00; tmp(0, 1) = t01; tmp(0, 2) = t02;
+ tmp(1, 0) = t10; tmp(1, 1) = t11; tmp(1, 2) = t12;
+ tmp(2, 0) = t20; tmp(2, 1) = t21; tmp(2, 2) = t22;
+ return tmp;
+ }
+
+
+
+ // Operators.
template <unsigned n, unsigned m, typename T, typename U>
inline
@@ -620,13 +815,40 @@
// Trace.
- template<unsigned n, typename T> inline
- float tr(const mat<n,n,T>& m)
+ template<unsigned n, typename T>
+ inline
+ mln_sum(T)
+ tr(const mat<n,n,T>& m)
{
- float f = 0.f;
+ mln_sum(T) tr_ = literal::zero;
for (unsigned i = 0; i < n; ++i)
- f += m(i,i);
- return f;
+ tr_ += m(i,i);
+ return tr_;
+ }
+
+
+ // Determinant.
+
+ template<typename T>
+ inline
+ mln_sum_product(T,T)
+ det(const mat<2,2,T>& m)
+ {
+ return m(0,0) * m(1,1) - m(0,1) * m(1,0);
+ }
+
+ template<typename T>
+ inline
+ mln_sum_product(T,T)
+ det(const mat<3,3,T>& m)
+ {
+ return
+ + m(0,0) * m(1,1) * m(2,2)
+ - m(0,0) * m(1,2) * m(2,1)
+ - m(0,1) * m(1,0) * m(2,2)
+ + m(0,1) * m(1,2) * m(2,0)
+ + m(0,2) * m(1,0) * m(2,1)
+ - m(0,2) * m(1,1) * m(2,0);
}
Index: mln/algebra/vec.hh
--- mln/algebra/vec.hh (revision 3734)
+++ mln/algebra/vec.hh (working copy)
@@ -266,11 +266,13 @@
} // end of namespace mln::algebra
+
namespace trait
{
// For unary traits.
+
template < template <class> class Name,
unsigned n, typename T >
struct set_precise_unary_< Name, algebra::vec<n, T> >
@@ -279,18 +281,44 @@
typedef algebra::vec<n, V> ret;
};
+
// For binary traits.
- template < template <class, class> class Name,
- unsigned n, typename T,
+
+ // vec + vec
+
+ template < unsigned n, typename T,
+ typename U >
+ struct set_precise_binary_< op::plus,
+ algebra::vec<n, T>, algebra::vec<n, U> >
+ {
+ typedef mln_trait_op_plus(T, U) V;
+ typedef algebra::vec<n, V> ret;
+ };
+
+ // - vec
+
+ template < unsigned n, typename T >
+ struct set_precise_unary_< op::uminus,
+ algebra::vec<n, T> >
+ {
+ typedef mln_trait_op_uminus(T) V;
+ typedef algebra::vec<n, V> ret;
+ };
+
+ // vec - vec
+
+ template < unsigned n, typename T,
typename U >
- struct set_precise_binary_< Name,
+ struct set_precise_binary_< op::minus,
algebra::vec<n, T>, algebra::vec<n, U> >
{
- typedef mln_trait_binary(Name, T, U) V;
+ typedef mln_trait_op_minus(T, U) V;
typedef algebra::vec<n, V> ret;
};
+ // vec * vec
+
template < unsigned n, typename T,
typename U >
struct set_precise_binary_< op::times,
@@ -299,27 +327,39 @@
typedef mln_sum_product(T,U) ret;
};
- template < template <class, class> class Name,
- unsigned n, typename T,
+ // vec * s
+
+ template < unsigned n, typename T,
typename S >
- struct set_precise_binary_< Name,
+ struct set_precise_binary_< op::times,
algebra::vec<n, T>, mln::value::scalar_<S> >
{
- typedef mln_trait_binary(Name, T, S) V;
+ typedef mln_trait_op_times(T, S) V;
typedef algebra::vec<n, V> ret;
};
- template < template<class, class> class Name,
- unsigned n, typename T,
+ // vec / s
+
+ template < unsigned n, typename T,
typename S >
- struct set_binary_< Name,
- mln::Object, algebra::vec<n, T>,
- mln::value::Scalar, S >
+ struct set_precise_binary_< op::div,
+ algebra::vec<n, T>, mln::value::scalar_<S> >
{
- typedef mln_trait_binary(Name, T, S) V;
+ typedef mln_trait_op_div(T, S) V;
typedef algebra::vec<n, V> ret;
};
+// template < template<class, class> class Name,
+// unsigned n, typename T,
+// typename S >
+// struct set_binary_< Name,
+// mln::Object, algebra::vec<n, T>,
+// mln::value::Scalar, S >
+// {
+// typedef mln_trait_binary(Name, T, S) V;
+// typedef algebra::vec<n, V> ret;
+// };
+
} // end of namespace mln::trait
@@ -327,18 +367,25 @@
namespace algebra
{
- // eq
+ // vec == vec
template <unsigned n, typename T, typename U>
- bool operator==(const vec<n,T>& lhs, const vec<n,U>& rhs);
+ bool
+ operator==(const vec<n,T>& lhs, const vec<n,U>& rhs);
- // +
+ // vec + vec
template <unsigned n, typename T, typename U>
vec<n, mln_trait_op_plus(T,U)>
operator+(const vec<n,T>& lhs, const vec<n,U>& rhs);
- // -
+ // - vec
+
+ template <unsigned n, typename T>
+ vec<n, mln_trait_op_uminus(T)>
+ operator-(const vec<n,T>& rhs);
+
+ // vec - vec
template <unsigned n, typename T, typename U>
vec<n, mln_trait_op_minus(T,U)>
@@ -522,9 +569,12 @@
const vec<n, T> vec<n, T>::origin = all_to(0);
+
// Operators.
+ // vec == vec
+
template <unsigned n, typename T, typename U>
inline
bool operator==(const vec<n,T>& lhs, const vec<n,U>& rhs)
@@ -535,6 +585,7 @@
return true;
}
+ // vec + vec
template <unsigned n, typename T, typename U>
inline
@@ -548,6 +599,22 @@
return tmp;
}
+ // - vec
+
+ template <unsigned n, typename T>
+ inline
+ vec<n, mln_trait_op_uminus(T)>
+ operator-(const vec<n,T>& rhs)
+ {
+ typedef mln_trait_op_uminus(T) R;
+ vec<n, R> tmp;
+ for (unsigned i = 0; i < n; ++i)
+ tmp[i] = - rhs[i];
+ return tmp;
+ }
+
+ // vec - vec
+
template <unsigned n, typename T, typename U>
inline
vec<n, mln_trait_op_minus(T,U)>
@@ -560,6 +627,8 @@
return tmp;
}
+ // vec * vec
+
template <unsigned n, typename T, typename U>
inline
mln_sum_product(T,U)
@@ -572,6 +641,8 @@
return tmp;
}
+ // vec * s
+
template <unsigned n, typename T, typename S>
inline
vec<n, mln_trait_op_times(T, S)>
@@ -594,6 +665,8 @@
return tmp;
}
+ // vec / s
+
template <unsigned n, typename T, typename S>
inline
vec<n, mln_trait_op_div(T, S)>
@@ -608,6 +681,8 @@
}
+ // << v
+
template <unsigned n, typename T>
inline
std::ostream&
@@ -619,6 +694,9 @@
return ostr;
}
+
+ // >> v
+
template <unsigned n, typename T>
inline
std::istream&
@@ -629,6 +707,7 @@
return istr;
}
+
// vprod
template <typename T, typename U>
Index: tests/algebra/mat.cc
--- tests/algebra/mat.cc (revision 3734)
+++ tests/algebra/mat.cc (working copy)
@@ -1,4 +1,5 @@
-// Copyright (C) 2007 EPITA Research and Development Laboratory
+// Copyright (C) 2007, 2009 EPITA Research and Development Laboratory
+// (LRDE)
//
// This file is part of the Olena Library. This library is free
// software; you can redistribute it and/or modify it under the terms
@@ -25,16 +26,12 @@
// reasons why the executable file might be covered by the GNU General
// Public License.
-/*! \file tests/algebra/mat.cc
- *
- * \brief Tests on mln::algebra::mat.
- */
+/// \file tests/algebra/mat.cc
+///
+/// Tests on mln::algebra::mat.
-
-#include <iostream>
#include <mln/fun/i2v/all_to.hh>
#include <mln/algebra/mat.hh>
-#include <mln/algebra/h_mat.hh>
@@ -42,26 +39,26 @@
{
using namespace mln;
- algebra::mat<1,3,float> m1(all_to(4.));
- algebra::mat<2,2,float> m2 = algebra::mat<2,2,float>::Id;
-
- algebra::h_mat<1,float> hm1(m2);
- algebra::h_mat<2,float> hm2;
- algebra::h_mat<3,float> hm3(all_to(1.5));
-
- algebra::mat<4,4,float> m4 = hm3;
-
- std::cout << "m1 = " << m1 << ";" <<
std::endl;
- std::cout << "m2 = " << m2 << ";" <<
std::endl;
- std::cout << "m4 = " << m4 << ";" <<
std::endl;
- std::cout << "hm1 = " << hm1 << ";" <<
std::endl;
- std::cout << "hm2 = " << hm2 << ";" <<
std::endl;
- std::cout << "hm3 = " << hm3 << ";" <<
std::endl;
+ {
+ using namespace algebra;
+ mat<3,3,int>
+ m = algebra::make(1, 2, 3,
+ 0, 1, 4,
+ 5, 6, 0),
+ m_1 = algebra::make(-24, +18, +05,
+ +20, -15, -04,
+ -05, +04, +01);
+ mln_assertion(m._1() == m_1);
+ mln_assertion(m * m._1() == literal::identity);
+ }
{
- algebra::h_mat<2,float> m, m2;
- m = m2;
- // FIXME: Test *many* => runs ok...
+ using namespace algebra;
+ mat<2,2,int> m = algebra::make(1, 0,
+ 0, 1);
+ mln_assertion(tr(m) == 2);
+ mln_assertion(det(m) == 1);
+ mln_assertion(m._1() == m);
}
}
Index: tests/algebra/Makefile.am
--- tests/algebra/Makefile.am (revision 3734)
+++ tests/algebra/Makefile.am (working copy)
@@ -3,6 +3,7 @@
include $(top_srcdir)/milena/tests/tests.mk
check_PROGRAMS = \
+ h_mat \
h_vec \
mat \
mat2 \
@@ -10,6 +11,7 @@
vec \
vec2
+h_mat_SOURCES = h_mat.cc
h_vec_SOURCES = h_vec.cc
mat_SOURCES = mat.cc
mat2_SOURCES = mat2.cc
Index: tests/algebra/h_mat.cc
--- tests/algebra/h_mat.cc (revision 3733)
+++ tests/algebra/h_mat.cc (working copy)
@@ -1,4 +1,5 @@
-// Copyright (C) 2007 EPITA Research and Development Laboratory
+// Copyright (C) 2007, 2009 EPITA Research and Development Laboratory
+// (LRDE)
//
// This file is part of the Olena Library. This library is free
// software; you can redistribute it and/or modify it under the terms
@@ -25,13 +26,10 @@
// reasons why the executable file might be covered by the GNU General
// Public License.
-/*! \file tests/algebra/mat.cc
- *
- * \brief Tests on mln::algebra::mat.
- */
+/// \file tests/algebra/h_mat.cc
+///
+/// Tests on mln::algebra::h_mat.
-
-#include <iostream>
#include <mln/fun/i2v/all_to.hh>
#include <mln/algebra/mat.hh>
#include <mln/algebra/h_mat.hh>
@@ -42,8 +40,9 @@
{
using namespace mln;
- algebra::mat<1,3,float> m1(all_to(4.));
- algebra::mat<2,2,float> m2 = algebra::mat<2,2,float>::Id;
+ algebra::mat<1,3,float> m1;
+ m1.set_all(4);
+ algebra::mat<2,2,float> m2 = literal::identity;
algebra::h_mat<1,float> hm1(m2);
algebra::h_mat<2,float> hm2;
Property changes on: tests/algebra/h_mat.cc
___________________________________________________________________
Added: svn:mergeinfo