1328: Slightly change vec, h_vec, mat to ease handling x2x transforms.

https://svn.lrde.epita.fr/svn/oln/trunk/milena Index: ChangeLog from Thierry Geraud <thierry.geraud@lrde.epita.fr> Slightly change vec, h_vec, mat to ease handling x2x transforms. * mln/core/h_vec.hh (h_vec): New ctor overload for vec<d+1>. (operator=): New overload for vec<d+1>. * mln/metal/mat.hh (trait): New def for mat * vec. (operator*): Strengthen scalar version to disambiguate. * mln/metal/vec.hh (to_h_vec): New method decl. * mln/fun/x2x/translation.hh: Deactivate code in ctor w/o arg. * mln/fun/x2x/rotation.hh: Likewise. * mln/fun/internal/x2x_impl.hh (operator()): Update. * tests/mat.cc: Augment. * tests/h_vec.cc: Augment. * tests/vec.cc: Update. mln/core/h_vec.hh | 42 ++++++++++++++++++++++------ mln/fun/internal/x2x_impl.hh | 4 +- mln/fun/x2x/rotation.hh | 6 ++-- mln/fun/x2x/translation.hh | 8 +++-- mln/metal/mat.hh | 63 ++++++++++++++++++++++++++++++++++++------- mln/metal/vec.hh | 9 +++++- tests/h_vec.cc | 11 +++++++ tests/mat.cc | 7 ++++ tests/vec.cc | 5 ++- 9 files changed, 126 insertions(+), 29 deletions(-) Index: tests/mat.cc --- tests/mat.cc (revision 1327) +++ tests/mat.cc (working copy) @@ -57,4 +57,11 @@ std::cout << "hm1 = " << hm1 << ";" << std::endl; std::cout << "hm2 = " << hm2 << ";" << std::endl; std::cout << "hm3 = " << hm3 << ";" << std::endl; + + { + h_mat<2,float> m, m2; + m = m2; + // FIXME: Test *many* => runs ok... + } + } Index: tests/vec.cc --- tests/vec.cc (revision 1327) +++ tests/vec.cc (working copy) @@ -46,12 +46,13 @@ metal::vec<2,float> v2 = make::vec(6., 2.8); h_vec<1,float> hv1; - h_vec<2,float> hv2(v2); + h_vec<2,float> hv2 = v2.to_h_vec(); // Immersion into homogeneous. + h_vec<3,float> hv3(all(1.5)); hv3 += make::vec(0., 0., 0., 0.5); - metal::vec<3,float> v3 = hv3; + metal::vec<3,float> v3 = hv3.to_vec(); // Back from homogeneous. metal::vec<4,float> v4 = hv3; std::cout << "v1 = " << v1 << ";" << std::endl; Index: tests/h_vec.cc --- tests/h_vec.cc (revision 1327) +++ tests/h_vec.cc (working copy) @@ -45,6 +45,11 @@ } +void foo(const mln::h_vec<3,float>&) +{ +} + + int main() { @@ -59,4 +64,10 @@ run_in_3d(k); run_in_3d_h(k); + { + metal::vec<3,float> v; + h_vec<3,float> w(v); + w = v; + foo(v); + } } Index: mln/core/h_vec.hh --- mln/core/h_vec.hh (revision 1327) +++ mln/core/h_vec.hh (working copy) @@ -50,11 +50,11 @@ /// Constructor without argument. h_vec(); - /// Constructor from a metal::vec. - h_vec(const metal::vec<d,C>& x); + h_vec(const metal::vec<d+1, C>& other); + h_vec& operator=(const metal::vec<d+1, C>& rhs); - /// Conversion to a metal::vec. - operator metal::vec<d,C>() const; + /// Back to the natural (non-homogeneous) space. + metal::vec<d,C> to_vec() const; }; @@ -67,15 +67,39 @@ } template <unsigned d, typename C> - h_vec<d,C>::h_vec(const metal::vec<d,C>& x) + h_vec<d,C>::h_vec(const metal::vec<d+1, C>& other) + : metal::vec<d+1, C>(other) { - for (unsigned i = 0; i < d; ++i) - this->data_[i] = x[i]; - this->data_[d] = 1; // FIXME: literal::one } template <unsigned d, typename C> - h_vec<d,C>::operator metal::vec<d,C>() const + h_vec<d,C>& h_vec<d,C>::operator=(const metal::vec<d+1, C>& rhs) + { + if (& rhs = this) + return *this; + this->metal::vec<d+1, C>::operator=(rhs); + return *this; + } + + namespace metal + { + + // Immersion of a vector in its homogeneous space. + template <unsigned n, typename T> + h_vec<n, T> vec<n,T>::to_h_vec() const + { + h_vec<n, T> tmp; + for (unsigned i = 0; i < n; ++i) + tmp[i] = this->data_[i]; + tmp[n] = 1; // FIXME: literal::one + return tmp; + } + + } // end of namespace mln::metal + + + template <unsigned d, typename C> + metal::vec<d,C> h_vec<d,C>::to_vec() const { const C w = this->data_[d]; mln_assertion(w != 0); Index: mln/metal/mat.hh --- mln/metal/mat.hh (revision 1327) +++ mln/metal/mat.hh (working copy) @@ -36,6 +36,7 @@ # include <mln/trait/all.hh> # include <mln/value/props.hh> # include <mln/value/concept/all.hh> +# include <mln/metal/vec.hh> // FIXME: Document. @@ -140,6 +141,16 @@ typedef metal::mat< n, m, mln_trait_op_times(T,U) > ret; }; + // mat * vec + + template <unsigned n, unsigned m, typename T, + 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; + }; + // mat * s template <unsigned n, unsigned m, typename T, @@ -214,10 +225,38 @@ 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 + + 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 + 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; + } // * @@ -270,7 +309,7 @@ { for (unsigned i = 0; i < n; ++i) for (unsigned j = 0; j < m; ++j) - id_.data_[i][j] = (i = j); + id_(i, j) = (i = j); flower = false; } return id_; @@ -451,12 +490,18 @@ return tmp; } - 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> + 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) { - mat<n,m, mln_trait_op_times(T,S)> tmp; + mat<n,m, T> tmp; for (unsigned i = 0; i < n; ++i) for (unsigned j = 0; j < m; ++j) tmp(i, j) = lhs(i, j) * s; Index: mln/metal/vec.hh --- mln/metal/vec.hh (revision 1327) +++ mln/metal/vec.hh (working copy) @@ -44,8 +44,10 @@ namespace mln { - // Fwd decl. + // Fwd decls. namespace literal { struct zero_t; } + template <unsigned d, typename C> struct h_vec; + namespace metal @@ -152,6 +154,11 @@ template <typename U> vec& operator=(const vec<n, U>& rhs); + + // Immersion of the vector into its homogeneous space. + h_vec<n, T> to_h_vec() const; + + const T& operator[](unsigned i) const; T& operator[](unsigned i); Index: mln/fun/x2x/translation.hh --- mln/fun/x2x/translation.hh (revision 1327) +++ mln/fun/x2x/translation.hh (working copy) @@ -52,8 +52,10 @@ template <unsigned n, typename C> struct translation + : internal::x2x_impl_< metal::vec<n,C>, translation<n,C> > - , public Bijection_x2x< translation<n,C> > + , + public Bijection_x2x< translation<n,C> > { typedef fun::internal::x2x_impl_< metal::vec<n,C>, translation<n,C> > super_; @@ -80,8 +82,8 @@ template <unsigned n, typename C> translation<n,C>::translation() { - t_ = make::vec<n,C>(fun::i2v::all<C>(0)); - this->m_ = h_mat<n,C>::Id; +// t_ = make::vec<n,C>(fun::i2v::all<C>(0)); +// this->m_ = h_mat<n,C>::Id; } template <unsigned n, typename C> Index: mln/fun/x2x/rotation.hh --- mln/fun/x2x/rotation.hh (revision 1327) +++ mln/fun/x2x/rotation.hh (working copy) @@ -82,9 +82,9 @@ template <unsigned n, typename C> rotation<n,C>::rotation() { - alpha_ = 0; - dir_ = 2; - this->m_ = h_mat<n,C>::Id; +// alpha_ = 0; +// dir_ = 2; +// this->m_ = h_mat<n,C>::Id; } template <unsigned n, typename C> Index: mln/fun/internal/x2x_impl.hh --- mln/fun/internal/x2x_impl.hh (revision 1327) +++ mln/fun/internal/x2x_impl.hh (working copy) @@ -56,9 +56,9 @@ typedef typename V::coord coord; typedef h_mat<dim, coord> matrix; - h_vec<dim, coord> operator()(const h_vec<dim, coord>& x) const + V operator()(const V& x) const { - return m_ * x; + return (m_ * x.to_h_vec()).to_vec(); } const matrix& mat() const;
participants (1)
-
Thierry Geraud