https://svn.lrde.epita.fr/svn/oln/trunk/milena
Index: ChangeLog
from Thierry Geraud <thierry.geraud(a)lrde.epita.fr>
Make metal vec and mat work with traits and scalars.
* tests/metal_mat.cc: Inactivate "non" tests.
Augment.
* tests/metal_vec.cc: Augment.
* tests/value_int_u8.cc: Conform to style.
* mln/trait/op/eq.hh: Remove dead code.
* mln/core/category.hh: Add const version.
* mln/core/h_vec.hh: Add traits.
* mln/core/ops.hh: Handle const types in traits.
* mln/literal/ops.hh: Add traits.
* mln/metal/mat.hh: Fix.
* mln/metal/vec.hh (sprod): Replace by...
(operator*): ...this new operator.
* mln/arith/plus.hh (plus_cst): Simplify.
* mln/value/ops.hh: Add traits for scalar_.
* mln/value/quat.hh: Update.
* mln/value/int_u.hh (uminus): New trait.
* mln/value/int_u_sat.hh: Fix ctor.
* mln/value/builtin/ops.hh: Enhance FIXME txt.
* mln/morpho/includes.hh: Update.
mln/arith/plus.hh | 5
mln/core/category.hh | 5
mln/core/h_vec.hh | 43 ++++++
mln/core/ops.hh | 32 +++++
mln/literal/ops.hh | 39 +++++-
mln/metal/mat.hh | 292 ++++++++++++-----------------------------------
mln/metal/vec.hh | 64 +++++-----
mln/morpho/includes.hh | 2
mln/trait/op/eq.hh | 8 -
mln/value/builtin/ops.hh | 3
mln/value/int_u.hh | 6
mln/value/int_u_sat.hh | 12 +
mln/value/ops.hh | 125 +++++++++++++++++++-
mln/value/quat.hh | 4
tests/metal_mat.cc | 64 ++++++++--
tests/metal_vec.cc | 14 +-
tests/value_int_u8.cc | 1
17 files changed, 434 insertions(+), 285 deletions(-)
Index: tests/metal_mat.cc
--- tests/metal_mat.cc (revision 1383)
+++ tests/metal_mat.cc (working copy)
@@ -31,23 +31,63 @@
*/
#include <mln/metal/mat.hh>
+#include <mln/value/int_u8.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);
+ // FIXME: A test should not print!
+
+ // 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;
+
+ using metal::vec;
+ vec<2,int> v = make::vec(5,1);
+
+ using metal::mat;
+ mat<2,2, vec<2,int> > mv;
+ mv.set_all(v);
+ // std::cout << mv << std::endl;
- metal::mat<2,3,float> mat23_3 = mat23_1 - mat23_2;
+ {
+ mat<2,2,float> tmp = mv * mv;
+ // std::cout << tmp << std::endl;
+ tmp(0,0) = 0;
+ }
+ {
+ vec<2, vec<2,float> > tmp = mv * v;
+ // std::cout << (mv * v) << std::endl;
+ tmp[0] = v;
+ }
+ {
+ mat<2,2,float> tmp = value::scalar(v) * mv;
+ // std::cout << (value::scalar(v) * mv) << std::endl;
+ tmp(0,0) = 0;
+ }
+ {
+ vec<2, mat<2,2, vec<2,float> > > tmp = v * value::scalar(mv);
+ // std::cout << (v * value::scalar(mv)) << std::endl;
+ tmp[0](0,0) = v;
+ }
+ {
+ value::int_u8 i = 0;
+ mat<2,2, vec<2,int> > tmp = mv * i;
+ // std::cout << mv * i << std::endl;
+ tmp(0,0) = v;
+ }
- std::cout << mat23_3 << std::endl << mat23_3 * mat36 <<
std::endl;
}
Index: tests/metal_vec.cc
--- tests/metal_vec.cc (revision 1383)
+++ tests/metal_vec.cc (working copy)
@@ -34,6 +34,8 @@
#include <mln/value/int_u8.hh>
+struct nu {};
+
int main()
{
using namespace mln;
@@ -41,13 +43,11 @@
metal::vec<3,int> v_int = make::vec(3,6,7);
metal::vec<3,float> v_f = make::vec(2.6, 1.9, 5.2);
- std::cout << v_int + v_f << std::endl;
- std::cout << v_f / 3 << std::endl;
+ mln_assertion((v_int + v_f) = ((v_f + v_int)));
+ mln_assertion((v_f / 3) = ((3 * v_f) / 9));
- {
-// value::int_u8 i = 3;
-// std::cout << value::scalar(i) * v_f << std::endl;
- // FIXME: Read FIXME in metal::vec::operator* and set up a test!
- }
+ value::int_u8 i = 3;
+ mln_assertion((i * v_f) = (value::scalar(i) * v_f));
+ mln_assertion((literal::zero + v_f) = v_f);
}
Index: tests/value_int_u8.cc
--- tests/value_int_u8.cc (revision 1383)
+++ tests/value_int_u8.cc (working copy)
@@ -33,6 +33,7 @@
#include <mln/value/int_u8.hh>
#include <tests/value_macros.hh>
+
int main()
{
using namespace mln;
Index: mln/trait/op/eq.hh
--- mln/trait/op/eq.hh (revision 1383)
+++ mln/trait/op/eq.hh (working copy)
@@ -52,14 +52,6 @@
} // end of namespace mln::trait::op
-
-// /// Default definition of op::eq is 'bool'.
-// template <typename L, typename R>
-// struct set_binary_< op::eq, Object, L, Object, R >
-// {
-// typedef bool ret;
-// };
-
} // end of namespace mln::trait
} // end of namespace mln
Index: mln/core/category.hh
--- mln/core/category.hh (revision 1383)
+++ mln/core/category.hh (working copy)
@@ -64,6 +64,11 @@
typedef typename T::category ret; // FIXME: if found or Unknown<void> =>
write a meta-program...
};
+ template <typename T>
+ struct category< const T >
+ {
+ typedef typename category<T>::ret ret;
+ };
} // end of namespace mln
Index: mln/core/h_vec.hh
--- mln/core/h_vec.hh (revision 1383)
+++ mln/core/h_vec.hh (working copy)
@@ -39,6 +39,49 @@
namespace mln
{
+ // Fwd decl.
+ template <unsigned d, typename C> struct h_vec;
+
+
+
+ namespace trait
+ {
+
+ // For unary traits.
+
+ template < template <class> class Name,
+ unsigned d, typename C >
+ struct set_precise_unary_< Name, h_vec<d, C> >
+ {
+ typedef mln_trait_unary(Name, C) V;
+ typedef h_vec<d, V> ret;
+ };
+
+ // For binary traits.
+
+ template < template <class, class> class Name,
+ unsigned d, typename C,
+ typename Q >
+ struct set_precise_binary_< Name,
+ h_vec<d, C>, h_vec<d, Q> >
+ {
+ typedef mln_trait_binary(Name, C, Q) V;
+ typedef h_vec<d, V> ret;
+ };
+
+ template < template <class, class> class Name,
+ unsigned d, typename C,
+ typename S >
+ struct set_precise_binary_< Name,
+ h_vec<d, C>, mln::value::scalar_<S> >
+ {
+ typedef mln_trait_binary(Name, C, S) V;
+ typedef h_vec<d, V> ret;
+ };
+
+ } // end of namespace mln::trait
+
+
template <unsigned d, typename C>
struct h_vec : public metal::vec<d + 1, C>
Index: mln/core/ops.hh
--- mln/core/ops.hh (revision 1383)
+++ mln/core/ops.hh (working copy)
@@ -91,6 +91,38 @@
// FIXME: Same for the other definitions below...
+
+ // Case of "const" in types.
+
+ template< template <class> class Name,
+ typename O >
+ struct set_precise_unary_< Name, const O >
+ {
+ typedef mln_trait_unary(Name, O) ret;
+ };
+
+ template< template <class,class> class Name,
+ typename O1, typename O2 >
+ struct set_precise_binary_< Name, O1, const O2 >
+ {
+ typedef mln_trait_binary(Name, O1, O2) ret;
+ };
+
+ template< template <class,class> class Name,
+ typename O1, typename O2 >
+ struct set_precise_binary_< Name, const O1, O2 >
+ {
+ typedef mln_trait_binary(Name, O1, O2) ret;
+ };
+
+ template< template <class,class> class Name,
+ typename O1, typename O2 >
+ struct set_precise_binary_< Name, const O1, const O2 >
+ {
+ typedef mln_trait_binary(Name, O1, O2) ret;
+ };
+
+
} // end of mln::trait
Index: mln/literal/ops.hh
--- mln/literal/ops.hh (revision 1383)
+++ mln/literal/ops.hh (working copy)
@@ -29,7 +29,9 @@
# define MLN_LITERAL_OPS_HH
/*! \file mln/literal/ops.hh
- * \brief Definitions of some operators.
+ *
+ * \brief Definitions of some operators where at least one literal is
+ * involved.
*/
# include <mln/core/concept/literal.hh>
@@ -42,6 +44,39 @@
namespace mln
{
+
+ namespace trait
+ {
+
+ template < template <class, class> class Name,
+ typename L, typename O >
+ struct set_binary_< Name, mln::Literal, L, mln::Object, O >
+ {
+ typedef mln_trait_binary(Name, O, O) ret;
+ };
+
+ template < template <class, class> class Name,
+ typename O, typename L >
+ struct set_binary_< Name, mln::Object, O, mln::Literal, L >
+ {
+ typedef mln_trait_binary(Name, O, O) ret;
+ };
+
+ template < typename L1, typename L2 >
+ struct set_binary_< op::eq, mln::Literal, L1, mln::Literal, L2 >
+ {
+ typedef bool ret;
+ };
+
+ template < typename L1, typename L2 >
+ struct set_binary_< op::neq, mln::Literal, L1, mln::Literal, L2 >
+ {
+ typedef bool ret;
+ };
+
+ } // end of namespace mln::trait
+
+
// Arithmetical operators.
template <typename O, typename L>
@@ -214,7 +249,7 @@
operator=(const Literal<L>& lhs, const Object<O>& rhs)
{
// mlc_converts_to(L, O)::check();
- return rhs = lhs;
+ return O(exact(lhs)) = exact(rhs);
}
template <typename L1, typename L2>
Index: mln/metal/mat.hh
--- mln/metal/mat.hh (revision 1383)
+++ mln/metal/mat.hh (working copy)
@@ -100,41 +100,22 @@
namespace trait
{
- // promote
+ // Unarys.
- template <unsigned n, unsigned m, typename T, typename U>
- struct set_precise_binary_<promote, metal::mat<n,m, T>, metal::mat<n,m,
U> >
+ template < template<class> class Name,
+ unsigned n, unsigned m, typename T >
+ struct set_precise_unary_< Name, metal::mat<n,m,T> >
{
- typedef metal::mat<n,m, mln_trait_promote(T, U)> ret;
+ typedef metal::mat<n, m, mln_trait_unary(Name, T)> ret;
};
+ // Default for binarys; works for (+), (-), comparisons, and promote.
- // mat + mat
-
- template <unsigned n, unsigned m, typename T,
- typename U>
- struct set_precise_binary_<op::plus, metal::mat<n, m, T>, metal::mat<n,
m, U> >
+ template < template<class, class> class Name,
+ unsigned n, unsigned m, typename T, typename U>
+ struct set_precise_binary_< Name, metal::mat<n,m,T>, metal::mat<n,m,U>
>
{
- typedef metal::mat<n, m, mln_trait_op_plus(T, U)> ret;
- };
-
- // FIXME: + mat
-
- // mat - mat
-
- template <unsigned n, unsigned m, typename T,
- typename U>
- struct set_precise_binary_<op::minus, metal::mat<n, m, T>, metal::mat<n,
m, U> >
- {
- typedef metal::mat<n, m, mln_trait_op_minus(T, U)> ret;
- };
-
- // - mat
-
- template <unsigned n, unsigned m, typename T>
- struct set_precise_unary_<op::uminus, metal::mat<n, m, T> >
- {
- typedef metal::mat<n, m, mln_trait_op_uminus(T)> ret;
+ typedef metal::mat<n, m, mln_trait_binary(Name, T, U)> ret;
};
// mat * mat
@@ -143,7 +124,13 @@
unsigned m, typename U>
struct set_precise_binary_<op::times, metal::mat<n,o,T>,
metal::mat<o,m,U> >
{
- typedef metal::mat< n, m, mln_trait_op_times(T,U) > ret;
+ typedef metal::mat<n, m, mln_sum_x(T, U)> ret;
+ };
+
+ template < unsigned n, typename T, typename U >
+ struct set_precise_binary_< op::times, metal::mat<n,n,T>,
metal::mat<n,n,U> >
+ { // Disambiguate between both previous defs.
+ typedef metal::mat<n, n, mln_sum_x(T, U)> ret;
};
// mat * vec
@@ -152,17 +139,27 @@
typename U>
struct set_precise_binary_<op::times, metal::mat<n,m,T>,
metal::vec<m,U> >
{
- typedef mln_trait_op_times(T,U) TxU;
- typedef metal::vec< m, mln_sum(TxU) > ret;
+ typedef metal::vec<n, mln_sum_x(T, U)> ret;
};
// mat * s
- template <unsigned n, unsigned m, typename T,
+ template < template<class, class> class Name,
+ unsigned n, unsigned m, typename T,
typename S>
- struct set_precise_binary_<op::times, metal::mat<n,m,T>, S >
+ struct set_precise_binary_< Name, metal::mat<n,m,T>,
mln::value::scalar_<S> >
{
- typedef metal::mat< n, m, mln_trait_op_times(T,S) > ret;
+ typedef metal::mat<n, m, mln_trait_binary(Name, T, S)> ret;
+ };
+
+ template < template<class, class> class Name,
+ unsigned n, unsigned m, typename T,
+ typename S >
+ struct set_binary_< Name,
+ mln::Object, metal::mat<n,m,T>,
+ mln::value::Scalar, S >
+ {
+ typedef metal::mat<n, m, mln_trait_binary(Name, T, S)> ret;
};
} // end of namespace mln::trait
@@ -187,31 +184,19 @@
namespace metal
{
- // eq
+ // =
template <unsigned n, unsigned m, typename T, typename U>
bool
- operator=(const mat<n,m,T>& lhs, const mat<n,m,U>& rhs);
+ operator=(mat<n,m,T>& lhs, const mat<n,m,U>& 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);
-
- // + (binary)
+ // +
template <unsigned n, unsigned m, typename T, typename U>
mat<n, m, mln_trait_op_plus(T,U)>
operator+(mat<n,m,T>& lhs, const mat<n,m,U>& 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);
-
- // - (binary)
+ // -
template <unsigned n, unsigned m, typename T, typename U>
mat<n, m, mln_trait_op_minus(T,U)>
@@ -223,67 +208,32 @@
mat<n, m, mln_trait_op_uminus(T)>
operator-(const mat<n,m,T>& lhs);
- // Operator *.
+ // mat * mat
template <unsigned n, unsigned o, typename T,
unsigned m, typename U>
- mat<n, m, mln_trait_op_times(T,U)>
- operator*(const mat<n,o,T>& lhs, const mat<o,m,U>& rhs); // mat *
mat
-
-
-// template <unsigned n, unsigned m, typename T,
-// typename S>
-// mat<n, m, mln_trait_op_times(T,S)>
-// operator*(const mat<n,m,T>& lhs, const S& s); // mat * s
-
-
- // FIXME: Simplification below of the general code above:
-
- template <unsigned n, unsigned m, typename T>
- mat<n, m, T>
- operator*(const mat<n,m,T>& lhs, const T& s); // mat * s
+ mat<n, m, mln_sum_x(T,U)>
+ operator*(const mat<n,o,T>& lhs, const mat<o,m,U>& rhs);
+ // mat * vec
template <unsigned n, unsigned m, typename T,
typename U>
- typename mln::trait::op::times< mat<n,m,T>, vec<m,U> >::ret
- operator*(const mat<n,m,T>& lhs, const vec<m,U>& rhs) // mat *
vec
- // FIXME: Move below...
- {
- typedef mat<n,m,T> mat_t;
- typedef vec<m,U> vec_t;
- mln_trait_op_times(mat_t, vec_t) tmp;
- for (unsigned i = 0; i < n; ++i)
- {
- mln_trait_op_times(T,U) sum = 0; // FIXME: Use literal::zero.
- for (unsigned j = 0; j < m; ++j)
- sum += lhs(i, j) * rhs[j];
- tmp[i] = sum;
- }
- return tmp;
- }
+ vec<n, mln_sum_x(T,U)>
+ operator*(const mat<n,m,T>& lhs, const vec<m,U>& rhs);
- // *-
- template <unsigned n, typename T, typename U>
- mat<n,n,T>&
- operator*=(mat<n,n,T>& lhs, const mat<n,n,U>& rhs);
-
- template <unsigned n, unsigned m, typename T, typename U>
- mat<n,m,T>&
- operator*=(mat<n,m,T>& lhs, const U& rhs);
-
- // Operator /.
+ // mat * s
- template <unsigned n, unsigned m, typename T, typename S>
- mat<n, m, mln_trait_op_times(T,S)> // FIXME: times instead of div...
- operator/(const mat<n,m,T>& lhs, const S& s);
+ template <unsigned n, unsigned m, typename T,
+ typename S>
+ mat<n, m, mln_trait_op_times(T,S)>
+ operator*(const mat<n,m,T>& lhs, const value::scalar_<S>& s);
- // /+ // mat / s
template <unsigned n, unsigned m, typename T, typename S>
- mat<n,m,T>&
- operator/=(mat<n,m,T>& lhs, const S& s);
+ mat<n, m, mln_trait_op_div(T,S)>
+ operator/(const mat<n,m,T>& lhs, const value::scalar_<S>& s);
// <<
@@ -291,13 +241,6 @@
std::ostream&
operator<<(std::ostream& ostr, const mat<n,m,T>& v);
- template <unsigned n, unsigned m>
- std::ostream&
- operator<<(std::ostream& ostr, const mat<n,m,unsigned char>& v);
-
- template <unsigned n, unsigned m>
- std::ostream&
- operator<<(std::ostream& ostr, const mat<n,m,signed char>& v);
# ifndef MLN_INCLUDE_ONLY
@@ -382,7 +325,8 @@
}
- // eq
+ // Operators.
+
template <unsigned n, unsigned m, typename T, typename U>
bool
@@ -395,20 +339,6 @@
return true;
}
- // +-
- 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;
- }
-
- // Operator +.
-
template <unsigned n, unsigned m, typename T, typename U>
mat<n, m, mln_trait_op_plus(T,U)>
operator+(const mat<n,m,T>& lhs, const mat<n,m,U>& rhs)
@@ -420,20 +350,6 @@
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;
- }
-
- // Operators -.
-
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)
@@ -456,81 +372,55 @@
return tmp;
}
- // *-
- template <unsigned n, typename T, typename U>
- mat<n,n,T>&
- operator*=(mat<n,n,T>& lhs, const mat<n,n,U>& rhs)
- {
- // FIXME: Optimize!
- lhs = lhs * rhs;
- return lhs;
- }
-
- template <unsigned n, unsigned m, typename T, typename U>
- mat<n,m,T>&
- operator*=(mat<n,m,T>& lhs, const U& s)
- {
- for (unsigned i = 0; i < n; ++i)
- for (unsigned j = 0; j < m; ++j)
- lhs(i, j) *= s;
- return lhs;
- }
-
- // Operators *.
-
template <unsigned n, unsigned o, typename T,
unsigned m, typename U>
- mat<n,m, mln_trait_op_times(T,U)>
+ mat<n, m, mln_sum_x(T,U)>
operator*(const mat<n,o,T>& lhs, const mat<o,m,U>& rhs)
{
- mat<n,m, mln_trait_op_times(T,U)> tmp;
+ mat<n,m, mln_sum_x(T,U)> tmp;
for (unsigned i = 0; i < n; ++i)
for (unsigned j = 0; j < m; ++j)
{
- tmp(i, j) = 0;
+ tmp(i, j) = literal::zero;
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>
- mat<n, m, T>
- operator*(const mat<n,m,T>& lhs, const T& s) // mat * s
-
- // FIXME: Read above.
-
-// template <unsigned n, unsigned m, typename T,
-// typename S>
-// mat<n,m, mln_trait_op_times(T,S)>
-// operator*(const mat<n,m,T>& lhs, const S& s)
+ template <unsigned n, unsigned m, typename T,
+ typename U>
+ vec<n, mln_sum_x(T,U)>
+ operator*(const mat<n,m,T>& lhs, const vec<m,U>& rhs)
{
- mat<n,m, T> tmp;
+ vec<n, mln_sum_x(T,U)> tmp;
for (unsigned i = 0; i < n; ++i)
+ {
+ mln_sum_x(T,U) sum(literal::zero);
for (unsigned j = 0; j < m; ++j)
- tmp(i, j) = lhs(i, j) * s;
+ sum += lhs(i, j) * rhs[j];
+ tmp[i] = sum;
+ }
return tmp;
}
- // /
-
template <unsigned n, unsigned m, typename T, typename S>
- mat<n,m,T>&
- operator/=(mat<n,m,T>& lhs, const S& s)
+ mat<n, m, mln_trait_op_times(T,S)>
+ operator*(const mat<n,m,T>& lhs, const value::scalar_<S>& s_)
{
+ S s = s_.to_equiv();
+ mat<n, m, mln_trait_op_times(T,S)> tmp;
for (unsigned i = 0; i < n; ++i)
for (unsigned j = 0; j < m; ++j)
- lhs(i, j) /= s;
- return lhs;
+ tmp(i, j) = lhs(i, j) * s;
+ return tmp;
}
- // Operator /.
-
template <unsigned n, unsigned m, typename T, typename S>
- mat<n,m, mln_trait_op_times(T,S)> // FIXME: Use div, not times!
- operator/(const mat<n,m,T>& lhs, const S& s)
+ mat<n,m, mln_trait_op_div(T,S)>
+ operator/(const mat<n,m,T>& lhs, const value::scalar_<S>& s_)
{
+ S s = s_.to_equiv();
mat<n,m, mln_trait_op_times(T,S)> tmp;
for (unsigned i = 0; i < n; ++i)
for (unsigned j = 0; j < m; ++j)
@@ -546,44 +436,14 @@
{
for (unsigned i = 0; i < n; ++i)
{
- ostr << '(';
+ ostr << '[';
for (unsigned j = 0; j < m; ++j)
- ostr << v(i, j) << (j = m - 1 ? ")" : ", ");
+ ostr << debug::format(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
Index: mln/metal/vec.hh
--- mln/metal/vec.hh (revision 1383)
+++ mln/metal/vec.hh (working copy)
@@ -177,8 +177,6 @@
void set_all(const T& val);
- T sprod(const vec<n, T>& rhs) const; // FIXME: Return is not T.
-
unsigned size() const;
const vec<n, T>& normalize();
@@ -222,6 +220,14 @@
typedef metal::vec<n, V> ret;
};
+ template < unsigned n, typename T,
+ typename U >
+ struct set_precise_binary_< op::times,
+ metal::vec<n, T>, metal::vec<n, U> >
+ {
+ typedef mln_sum_x(T,U) ret;
+ };
+
template < template <class, class> class Name,
unsigned n, typename T,
typename S >
@@ -232,8 +238,16 @@
typedef metal::vec<n, V> ret;
};
- // FIXME: What about scalar * vec!!!
-
+ template < template<class, class> class Name,
+ unsigned n, typename T,
+ typename S >
+ struct set_binary_< Name,
+ mln::Object, metal::vec<n, T>,
+ mln::value::Scalar, S >
+ {
+ typedef mln_trait_binary(Name, T, S) V;
+ typedef metal::vec<n, V> ret;
+ };
} // end of namespace mln::trait
@@ -274,17 +288,19 @@
vec<n, mln_trait_op_minus(T,U)>
operator-(const vec<n,T>& lhs, const vec<n,U>& rhs);
-// template <unsigned n, typename T>
-// vec<n, mln_trait_op_uminus(T)>
-// operator-(const vec<n,T>& lhs);
+ // vec * vec
- // *
+ template <unsigned n, typename T, typename U>
+ mln_sum_x(T,U)
+ operator*(const vec<n,T>& lhs, const vec<n,U>& rhs);
+
+ // vec * s
template <unsigned n, typename T, typename S>
vec<n, mln_trait_op_times(T, S)>
operator*(const vec<n,T>& lhs, const mln::value::scalar_<S>& s);
- // /
+ // vec / s
template <unsigned n, typename T, typename S>
vec<n, mln_trait_op_div(T, S)>
@@ -372,16 +388,6 @@
}
template <unsigned n, typename T>
- T vec<n,T>::sprod(const vec<n, T>& rhs) const
- {
- T tmp = 0;
-
- for (unsigned i = 0; i < n; ++i)
- tmp += data_[i] * rhs.data_[i];
- return tmp;
- }
-
- template <unsigned n, typename T>
unsigned vec<n,T>::size() const
{
return n;
@@ -417,7 +423,8 @@
const vec<n, T> vec<n, T>::origin = all_to(0);
- // eq
+ // Operators.
+
template <unsigned n, typename T, typename U>
bool operator=(const vec<n,T>& lhs, const vec<n,U>& rhs)
@@ -428,7 +435,6 @@
return true;
}
- // +
template <unsigned n, typename T, typename U>
vec<n, mln_trait_op_plus(T,U)>
@@ -440,8 +446,6 @@
return tmp;
}
- // -
-
template <unsigned n, typename T, typename U>
vec<n, mln_trait_op_minus(T,U)>
operator-(const vec<n,T>& lhs, const vec<n,U>& rhs)
@@ -452,7 +456,16 @@
return tmp;
}
- // *
+ template <unsigned n, typename T, typename U>
+ mln_sum_x(T,U)
+ operator*(const vec<n,T>& lhs, const vec<n,U>& rhs)
+ {
+ mln_sum_x(T,U) tmp(literal::zero);
+ for (unsigned i = 0; i < n; ++i)
+ tmp += lhs[i] * rhs[i];
+ return tmp;
+ }
+
template <unsigned n, typename T, typename S>
vec<n, mln_trait_op_times(T, S)>
@@ -474,8 +487,6 @@
return tmp;
}
- // /
-
template <unsigned n, typename T, typename S>
vec<n, mln_trait_op_div(T, S)>
operator/(const vec<n,T>& lhs, const mln::value::scalar_<S>& s)
@@ -487,7 +498,6 @@
return tmp;
}
- // <<
template <unsigned n, typename T>
std::ostream&
Index: mln/arith/plus.hh
--- mln/arith/plus.hh (revision 1383)
+++ mln/arith/plus.hh (working copy)
@@ -178,9 +178,8 @@
void plus_cst(const Image<I>& input, const V& val, Image<O>&
output)
{
mln_precondition(exact(output).domain() = exact(input).domain());
- impl::plus_(mln_trait_image_speed(I)(), exact(input),
- trait::image::speed::any(), pw::cst(val) | exact(input).domain(),
- mln_trait_image_speed(O)(), exact(output)); // Calls the previous version.
+ plus(input, pw::cst(val) | exact(input).domain(), output);
+ // Calls the previous version.
}
template <typename L, typename R>
Index: mln/value/ops.hh
--- mln/value/ops.hh (revision 1383)
+++ mln/value/ops.hh (working copy)
@@ -37,11 +37,16 @@
# include <mln/value/builtin/all.hh>
# include <mln/value/concept/all.hh>
# include <mln/value/equiv.hh>
+# include <mln/value/props.hh>
# include <mln/literal/zero.hh>
# include <mln/literal/one.hh>
+# include <mln/literal/ops.hh>
# include <mln/metal/ret.hh>
+# define mln_sum_x(T, U) typename mln::value::props< mln_trait_op_times(T,U)
>::sum
+
+
// FIXME: In the definitions below, is that equiv or interop?
@@ -62,7 +67,8 @@
typedef mln_trait_unary(Name, mln_value_equiv(V)) ret;
};
- // Binary traits for any Scalar type.
+
+ // Binary traits for any Scalar type...
template < template <class, class> class Name,
typename Vl, typename Vr >
@@ -71,6 +77,36 @@
typedef mln_trait_binary(Name, mln_value_equiv(Vl), mln_value_equiv(Vr)) ret;
};
+ // ...and for the special case of a couple of value::scalar_.
+
+ template < template <class, class> class Name,
+ typename Sl, typename Sr >
+ struct set_binary_< Name,
+ mln::value::Scalar, mln::value::scalar_<Sl>,
+ mln::value::Scalar, mln::value::scalar_<Sr> >
+ {
+ typedef mln_trait_binary(Name, mln_value_equiv(Sl), mln_value_equiv(Sr)) ret;
+ };
+
+
+ // Some binary traits for "scalar(s) OP obj" when OP commutes =>
"obj OP scalar(s)".
+
+ template < typename S, typename O >
+ struct set_binary_< op::plus,
+ mln::value::Scalar, mln::value::scalar_<S>,
+ mln::Object, O >
+ {
+ typedef mln_trait_op_plus(O, mln::value::scalar_<S>) ret;
+ };
+
+ template < typename S, typename O >
+ struct set_binary_< op::times,
+ mln::value::Scalar, mln::value::scalar_<S>,
+ mln::Object, O >
+ {
+ typedef mln_trait_op_times(O, mln::value::scalar_<S>) ret;
+ };
+
} // end of namespace mln::trait
@@ -97,6 +133,16 @@
operator % (const value::Scalar<Vl>& lhs, const
value::Scalar<Vr>& rhs);
+
+ template <typename S, typename O>
+ mln_trait_op_plus(O, value::scalar_<S>)
+ operator + (const value::scalar_<S>& lhs, const Object<O>& rhs);
+
+ template <typename S, typename O>
+ mln_trait_op_times(O, value::scalar_<S>)
+ operator * (const value::scalar_<S>& lhs, const Object<O>& rhs);
+
+
// Arithmetical unary operators.
template <typename S>
@@ -112,6 +158,29 @@
+ // Case of value::scalar_ OP value::scalar_.
+
+ template <typename Sl, typename Sr>
+ mln_trait_op_plus(Sl, Sr)
+ operator + (const value::scalar_<Sl>& lhs, const
value::scalar_<Sr>& rhs);
+
+ template <typename Sl, typename Sr>
+ mln_trait_op_minus(Sl, Sr)
+ operator - (const value::scalar_<Sl>& lhs, const
value::scalar_<Sr>& rhs);
+
+ template <typename Sl, typename Sr>
+ mln_trait_op_times(Sl, Sr)
+ operator * (const value::scalar_<Sl>& lhs, const
value::scalar_<Sr>& rhs);
+
+ template <typename Sl, typename Sr>
+ mln_trait_op_div(Sl, Sr)
+ operator / (const value::scalar_<Sl>& lhs, const
value::scalar_<Sr>& rhs);
+
+ template <typename Sl, typename Sr>
+ mln_trait_op_mod(Sl, Sr)
+ operator % (const value::scalar_<Sl>& lhs, const
value::scalar_<Sr>& rhs);
+
+
# ifndef MLN_INCLUDE_ONLY
@@ -157,6 +226,60 @@
return - rhs.to_equiv();
}
+ template <typename S, typename O>
+ mln_trait_op_plus(O, value::scalar_<S>)
+ operator + (const value::scalar_<S>& lhs, const Object<O>& rhs)
+ {
+ return exact(rhs) + lhs;
+ }
+
+ template <typename S, typename O>
+ mln_trait_op_times(O, value::scalar_<S>)
+ operator * (const value::scalar_<S>& lhs, const Object<O>& rhs)
+ {
+ return exact(rhs) * lhs;
+ }
+
+ // ...
+
+
+ // With scalar_ OP scalar_.
+
+ template <typename Sl, typename Sr>
+ mln_trait_op_plus(Sl, Sr)
+ operator + (const value::scalar_<Sl>& lhs, const
value::scalar_<Sr>& rhs)
+ {
+ return value::equiv(lhs) + value::equiv(rhs);
+ }
+
+ template <typename Sl, typename Sr>
+ mln_trait_op_minus(Sl, Sr)
+ operator - (const value::scalar_<Sl>& lhs, const
value::scalar_<Sr>& rhs)
+ {
+ return value::equiv(lhs) - value::equiv(rhs);
+ }
+
+ template <typename Sl, typename Sr>
+ mln_trait_op_times(Sl, Sr)
+ operator * (const value::scalar_<Sl>& lhs, const
value::scalar_<Sr>& rhs)
+ {
+ return value::equiv(lhs) * value::equiv(rhs);
+ }
+
+ template <typename Sl, typename Sr>
+ mln_trait_op_div(Sl, Sr)
+ operator / (const value::scalar_<Sl>& lhs, const
value::scalar_<Sr>& rhs)
+ {
+ return value::equiv(lhs) / value::equiv(rhs);
+ }
+
+ template <typename Sl, typename Sr>
+ mln_trait_op_mod(Sl, Sr)
+ operator % (const value::scalar_<Sl>& lhs, const
value::scalar_<Sr>& rhs)
+ {
+ return value::equiv(lhs) % value::equiv(rhs);
+ }
+
// ...
# endif // ! MLN_INCLUDE_ONLY
Index: mln/value/quat.hh
--- mln/value/quat.hh (revision 1383)
+++ mln/value/quat.hh (working copy)
@@ -335,7 +335,7 @@
float
quat::sprod(const quat& rhs) const
{
- return v_.sprod(rhs.to_vec());
+ return v_ * rhs.to_vec();
}
bool quat::is_unit() const
@@ -443,7 +443,7 @@
quat operator*(const quat& lhs, const quat& rhs)
{
- quat tmp(lhs.s() * rhs.s() - lhs.v().sprod(rhs.v()),
+ quat tmp(lhs.s() * rhs.s() - lhs.v() * rhs.v(),
metal::vprod(lhs.v(), rhs.v()) + lhs.s() * rhs.v() + rhs.s() * lhs.v());
return tmp;
}
Index: mln/value/int_u.hh
--- mln/value/int_u.hh (revision 1383)
+++ mln/value/int_u.hh (working copy)
@@ -59,6 +59,12 @@
{
template <unsigned n>
+ struct set_precise_unary_< op::uminus, mln::value::int_u<n> >
+ {
+ typedef int ret;
+ };
+
+ template <unsigned n>
struct value_< mln::value::int_u<n> > :
mln::trait::value_integer_<n>
{
};
Index: mln/value/int_u_sat.hh
--- mln/value/int_u_sat.hh (revision 1383)
+++ mln/value/int_u_sat.hh (working copy)
@@ -60,7 +60,7 @@
public internal::value_like_< int_u<n>, // Equivalent.
mln_enc(int_u<n>), // Encoding.
- int, // Interoperation.
+ unsigned, // Interoperation.
int_u_sat<n> > // Exact.
{
/// Constructor without argument.
@@ -130,10 +130,11 @@
template <unsigned n>
int_u_sat<n>::int_u_sat(int i)
{
+ static const unsigned max_ = mln_max(int_u<n>);
if (i < 0)
this->v_ = 0;
- else if (i > mln_max(int_u_sat<n>))
- this->v_ = mln_max(int_u_sat<n>);
+ else if (i > max_)
+ this->v_ = max_;
else
this->v_ = i;
}
@@ -148,10 +149,11 @@
int_u_sat<n>&
int_u_sat<n>::operator=(int i)
{
+ static const unsigned max_ = mln_max(int_u<n>);
if (i < 0)
this->v_ = 0;
- else if (i > mln_max(int_u_sat<n>))
- this->v_ = mln_max(int_u_sat<n>);
+ else if (i > max_)
+ this->v_ = max_;
else
this->v_ = i;
return *this;
Index: mln/value/builtin/ops.hh
--- mln/value/builtin/ops.hh (revision 1383)
+++ mln/value/builtin/ops.hh (working copy)
@@ -284,7 +284,7 @@
struct set_unary_< Name,
mln::value::Built_In, B >
{
- typedef B ret; // FIXME: Wrong!
+ typedef B ret; // FIXME: Wrong because some types are unsigned!
};
@@ -364,7 +364,6 @@
typedef mln_trait_op_mod(mln::value::scalar_<B>, O) ret;
};
-
} // end of namespace mln::trait
Index: mln/morpho/includes.hh
--- mln/morpho/includes.hh (revision 1383)
+++ mln/morpho/includes.hh (working copy)
@@ -38,6 +38,8 @@
# include <mln/core/concept/window.hh>
# include <mln/core/concept/neighborhood.hh>
+# include <mln/value/ops.hh>
+
# include <mln/accu/min.hh>
# include <mln/accu/max.hh>
# include <mln/accu/min_h.hh>