27 #ifndef MLN_ALGEBRA_VEC_HH
28 # define MLN_ALGEBRA_VEC_HH
37 # include <mln/core/concept/object.hh>
39 # include <mln/literal/zero.hh>
40 # include <mln/literal/origin.hh>
41 # include <mln/norm/l2.hh>
42 # include <mln/trait/all.hh>
43 # include <mln/trait/value_.hh>
44 # include <mln/fun/i2v/all_to.hh>
45 # include <mln/debug/format.hh>
47 # include <mln/value/ops.hh>
58 template <
unsigned n,
typename T>
class vec;
59 template <
unsigned d,
typename C>
class h_vec;
60 template <
unsigned n,
unsigned m,
typename T>
class mat;
68 template <
unsigned n,
typename C>
73 template <
unsigned n>
struct rgb;
76 template <
typename G,
typename C>
struct point;
77 template <
typename E>
struct Gpoint;
84 template <
unsigned n,
typename T>
85 struct value_< mln::algebra::vec<n,T> >
87 typedef trait::value::nature::vectorial nature;
88 typedef trait::value::kind::data kind;
92 nbits = n * mln_nbits(
T),
93 card = n * mln_card(
T)
96 typedef mln_value_quant_from_(card) quant;
97 typedef algebra::vec<n, mln_sum(
T)>
sum;
100 template <
unsigned n, typename
T>
101 struct set_precise_unary_< op::ord, mln::algebra::vec<n,
T> >
116 template <
unsigned n,
typename T>
123 template <
typename T>
127 void set(
const T& val0)
135 template <
typename T>
139 void set(
const T& val0,
const T& val1)
148 template <
typename T>
152 void set(
const T& val0,
const T& val1,
const T& val2)
162 template <
typename T>
166 void set(
const T& val0,
const T& val1,
const T& val2,
const T& val3)
184 template <
unsigned n,
typename T>
214 template <
typename U>
217 template <
typename U>
225 const T& operator[](
unsigned i)
const;
227 T& operator[](
unsigned i);
229 void set_all(
const T& val);
231 unsigned size()
const;
251 template <
typename F>
262 template <
typename U>
266 template <
typename U>
270 template <
typename U>
276 template <
typename T,
unsigned m>
280 template <
typename C1,
typename G,
typename C2>
286 template <
unsigned n,
typename C1,
typename G,
typename C2>
291 template <
typename C1,
typename G>
297 template <
unsigned n,
typename C1,
typename G>
302 template <
unsigned n,
typename T,
typename P>
316 template <
template <
class>
class Name,
317 unsigned n,
typename T >
318 struct set_precise_unary_< Name, algebra::vec<n, T> >
320 typedef mln_trait_unary(Name,
T) V;
321 typedef algebra::vec<n, V>
ret;
330 template <
unsigned n, typename
T,
332 struct set_precise_binary_< op::
plus,
333 algebra::vec<n, T>, algebra::vec<n, U> >
335 typedef mln_trait_op_plus(T, U) V;
336 typedef algebra::vec<n, V> ret;
341 template <
unsigned n, typename T >
342 struct set_precise_unary_< op::uminus,
345 typedef mln_trait_op_uminus(T) V;
346 typedef algebra::vec<n, V> ret;
351 template <
unsigned n, typename T,
353 struct set_precise_binary_< op::
minus,
354 algebra::vec<n, T>, algebra::vec<n, U> >
356 typedef mln_trait_op_minus(T, U) V;
357 typedef algebra::vec<n, V> ret;
362 template <
unsigned n, typename T,
364 struct set_precise_binary_< op::times,
365 algebra::vec<n, T>, algebra::vec<n, U> >
367 typedef mln_sum_product(T,U) ret;
372 template <
unsigned n, typename T,
374 struct set_precise_binary_< op::times,
377 typedef mln_trait_op_times(T, S) V;
378 typedef algebra::vec<n, V> ret;
383 template <
unsigned n, typename T,
385 struct set_precise_binary_< op::div,
388 typedef mln_trait_op_div(T, S) V;
389 typedef algebra::vec<n, V> ret;
412 template <
unsigned n,
typename T,
typename U>
418 template <
unsigned n,
typename T,
typename U>
419 vec<n, mln_trait_op_plus(T,U)>
424 template <
unsigned n,
typename T>
425 vec<n, mln_trait_op_uminus(T)>
430 template <
unsigned n,
typename T,
typename U>
431 vec<n, mln_trait_op_minus(T,U)>
437 template <
unsigned n,
typename T,
typename U>
439 operator*(const vec<n,T>& lhs, const vec<n,U>&
rhs);
443 template <
unsigned n, typename T, typename S>
444 vec<n, mln_trait_op_times(T, S)>
445 operator*(const vec<n,T>& lhs, const mln::
value::
scalar_<S>& s);
449 template <
unsigned n, typename T, typename S>
450 vec<n, mln_trait_op_div(T, S)>
451 operator/(const vec<n,T>& lhs, const mln::
value::
scalar_<S>& s);
455 template <
unsigned n, typename T>
457 operator<<(std::ostream& ostr, const vec<n,T>& v);
461 template <
unsigned n, typename T>
463 operator>>(std::istream& istr, vec<n,T>& v);
468 template <typename T, typename U>
469 vec<3, mln_trait_op_times(T,U)>
470 vprod(const vec<3, T>& lhs, const vec<3, U>& rhs);
477 # ifndef MLN_INCLUDE_ONLY
482 template <
typename C,
typename C2>
485 convert_data_(metal::bool_<false>,
const C2& v)
487 return static_cast<C
>(v);
490 template <
typename C,
typename C2>
493 convert_data_(metal::bool_<true>,
const C2& v)
495 return static_cast<C
>(
round(v));
498 template <
typename C,
typename C2>
501 convert_data(
const C2& v)
507 return convert_data_<C>(
509 mlc_and(mlc_is_not(C,
float),
510 mlc_is_not(C,
double)),
511 mlc_or(mlc_is(C2,
float),
512 mlc_is(C2,
double)))::
eval(), v);
522 template <
unsigned n,
typename T>
528 template <
unsigned n,
typename T>
530 vec<n,T>::vec(
const literal::zero_t&)
535 template <
unsigned n,
typename T>
538 vec<n,T>::operator=(
const literal::zero_t&)
544 template <
unsigned n,
typename T>
546 vec<n,T>::vec(
const literal::origin_t&)
551 template <
unsigned n,
typename T>
554 vec<n,T>::operator=(
const literal::origin_t&)
560 template <
unsigned n,
typename T>
562 vec<n,T>::vec(
const vec<n,T>& rhs)
565 for (
unsigned i = 0; i < n; ++i)
569 template <
unsigned n,
typename T>
570 template <
typename U>
572 vec<n,T>::vec(
const vec<n, U>& rhs)
575 mlc_converts_to(U, T)::check();
576 for (
unsigned i = 0; i < n; ++i)
577 data_[i] = static_cast<T>(rhs[i]);
580 template <
unsigned n,
typename T>
581 template <
typename U>
583 vec<n,T>& vec<n,T>::operator=(
const vec<n, U>& rhs)
585 mlc_converts_to(U, T)::check();
586 for (
unsigned i = 0; i < n; ++i)
587 data_[i] = static_cast<T>(rhs[i]);
591 template <
unsigned n,
typename T>
593 const T& vec<n,T>::operator[](
unsigned i)
const
595 mln_precondition(i < dim);
599 template <
unsigned n,
typename T>
601 T& vec<n,T>::operator[](
unsigned i)
603 mln_precondition(i < dim);
607 template <
unsigned n,
typename T>
609 void vec<n,T>::set_all(
const T& val)
611 for (
unsigned i = 0; i < n; ++i)
615 template <
unsigned n,
typename T>
617 unsigned vec<n,T>::size()
const
622 template <
unsigned n,
typename T>
624 const vec<n, T>& vec<n, T>::normalize()
626 mln_sum_product(T,T) l2_norm = norm::
l2(*this);
627 mln_assertion(l2_norm > mln_sum_product(T,T)(0));
628 for (
unsigned i = 0; i < n; ++i)
629 data_[i] = static_cast<T>(data_[i] / l2_norm);
633 template <
unsigned n, typename T>
634 template <typename F>
636 vec<n, T>::vec(const Function_v2v<F>& f_)
638 mlc_converts_to(mln_result(F), T)::check();
639 const F& f =
exact(f_);
640 for (
unsigned i = 0; i < n; ++i)
641 data_[i] = static_cast<T>(f(i));
645 template <
unsigned n,
typename T>
646 const vec<n, T> vec<n, T>::zero =
all_to(0);
648 template <
unsigned n,
typename T>
649 const vec<n, T> vec<n, T>::origin =
all_to(0);
658 template <
unsigned n,
typename T,
typename U>
660 bool operator==(
const vec<n,T>& lhs,
const vec<n,U>& rhs)
662 for (
unsigned i = 0; i < n; ++i)
663 if (lhs[i] != rhs[i])
670 template <
unsigned n,
typename T,
typename U>
672 vec<n, mln_trait_op_plus(T,U)>
673 operator+(
const vec<n,T>& lhs,
const vec<n,U>& rhs)
675 typedef mln_trait_op_plus(T,U) R;
677 for (
unsigned i = 0; i < n; ++i)
678 tmp[i] = lhs[i] + rhs[i];
684 template <
unsigned n, typename T>
686 vec<n, mln_trait_op_uminus(T)>
687 operator-(const vec<n,T>& rhs)
689 typedef mln_trait_op_uminus(T) R;
691 for (
unsigned i = 0; i < n; ++i)
698 template <
unsigned n, typename T, typename U>
700 vec<n, mln_trait_op_minus(T,U)>
701 operator-(const vec<n,T>& lhs, const vec<n,U>& rhs)
703 typedef mln_trait_op_minus(T,U) R;
705 for (
unsigned i = 0; i < n; ++i)
706 tmp[i] = lhs[i] - rhs[i];
712 template <
unsigned n, typename T, typename U>
715 operator*(const vec<n,T>& lhs, const vec<n,U>& rhs)
717 typedef mln_sum_product(T,U) R;
718 mln_sum_product(T,U) tmp(literal::zero);
719 for (
unsigned i = 0; i < n; ++i)
720 tmp += lhs[i] * rhs[i];
726 template <
unsigned n, typename T, typename S>
728 vec<n, mln_trait_op_times(T, S)>
729 operator*(const vec<n,T>& lhs, const mln::
value::scalar_<S>& s)
741 typedef mln_trait_op_times(T, S) R;
743 for (
unsigned i = 0; i < n; ++i)
744 tmp[i] = lhs[i] * s.to_equiv();
750 template <
unsigned n, typename T, typename S>
752 vec<n, mln_trait_op_div(T, S)>
753 operator/(const vec<n,T>& lhs, const mln::
value::scalar_<S>& s)
755 mln_precondition(value::equiv(s) != (S)(literal::zero));
756 typedef mln_trait_op_div(T, S) R;
758 for (
unsigned i = 0; i < n; ++i)
759 tmp[i] = lhs[i] / s.to_equiv();
766 template <
unsigned n, typename T>
769 operator<<(std::ostream& ostr, const vec<n,T>& v)
772 for (
unsigned i = 0; i < n; ++i)
780 template <
unsigned n,
typename T>
785 for (
unsigned i = 0; i < n; ++i)
793 template <
typename T,
typename U>
795 vec<3, mln_trait_op_times(T,U)>
796 vprod(
const vec<3, T>& lhs,
const vec<3, U>& rhs)
798 vec<3, mln_trait_op_times(T,U)> tmp;
799 tmp[0] = lhs[1] * rhs[2] - lhs[2] * rhs[1];
800 tmp[1] = lhs[2] * rhs[0] - lhs[0] * rhs[2];
801 tmp[2] = lhs[0] * rhs[1] - lhs[1] * rhs[0];
806 template <
typename P>
809 to_point(
const vec<P::dim,float>& v)
812 for (
unsigned i = 0; i < P::dim; ++i)
813 tmp[i] =
round(v[i]);
821 template <
typename T,
unsigned m>
824 from_to_(
const vec<3,T>& from, value::rgb<m>& to)
826 algebra::vec<3, unsigned> tmp;
827 for (
unsigned i = 0; i < 3; ++i)
828 tmp[i] = static_cast<unsigned>(from[i]);
830 to = value::rgb<m>(tmp);
833 template <
unsigned n,
typename C1,
typename G,
typename C2>
838 mlc_converts_to(C1, C2)::check();
839 enum { dim = G::dim };
840 mlc_bool(G::dim == n)::check();
843 for (
unsigned i = dim - 2; i < dim; ++i)
844 to[i] = mln::internal::convert_data<C2>(from[j++]);
845 for (
unsigned i = 2; i < dim; ++i, ++j)
846 to[i-j] = mln::internal::convert_data<C2>(from[j]);
849 template <
typename C1,
typename G,
typename C2>
854 mlc_converts_to(C1, C2)::check();
855 enum { dim = G::dim };
856 mlc_bool(G::dim == 1)::check();
858 to[0] = mln::internal::convert_data<C2>(from[0]);
861 template <
unsigned n,
typename C1,
typename G>
866 enum { dim = G::dim };
867 mlc_bool(G::dim == n)::check();
870 for (
unsigned i = dim - 2; i < dim; ++i)
872 for (
unsigned i = 2; i < dim; ++i, ++j)
876 template <
typename C1,
typename G>
881 enum { dim = G::dim };
882 mlc_bool(G::dim == 1)::check();
887 template <
unsigned n,
typename T,
typename P>
890 from_to_(
const vec<n,T>& from, Gpoint<P>& to_)
892 mlc_bool(P::dim == n)::check();
894 for (
unsigned i = 0; i < n; ++i)
895 to[i] = static_cast< typename P::coord >(from[i]);
902 # endif // MLN_INCLUDE_ONLY
907 # include <mln/make/vec.hh>
908 # include <mln/algebra/mat.hh>
911 #endif // ! MLN_ALGEBRA_VEC_HH