26 #ifndef MLN_ALGEBRA_INTERNAL_MAT_BASE_HH
27 # define MLN_ALGEBRA_INTERNAL_MAT_BASE_HH
35 # include <mln/core/concept/object.hh>
36 # include <mln/core/concept/function.hh>
37 # include <mln/core/contract.hh>
38 # include <mln/trait/all.hh>
39 # include <mln/trait/value_.hh>
40 # include <mln/algebra/vec.hh>
41 # include <mln/literal/identity.hh>
57 template <
unsigned n,
unsigned m,
typename T,
typename E>
58 class mat_base :
public Object< E >
71 mat_base(
const literal::zero_t&);
72 mat_base(
const literal::one_t&);
73 mat_base(
const literal::identity_t&);
75 template <
typename U,
typename M>
76 mat_base(
const mat_base<n,m,U,M>& rhs);
80 mat_base(
const Function_v2v<F>& f);
82 template <
typename U,
typename M>
83 mat_base& operator=(
const mat_base<n,m,U,M>& rhs);
85 const T& operator()(
unsigned i,
unsigned j)
const;
87 T& operator()(
unsigned i,
unsigned j);
89 void set_all(
const T& val);
91 unsigned size()
const;
96 mat_base<m,n,T,E> t()
const;
100 mat_base<n,m,T,E> _1()
const;
120 template <
unsigned n,
unsigned m,
typename T >
121 struct set_precise_unary_< op::uminus,
122 algebra::internal::mat_base<n,m,T,E> >
124 typedef algebra::internal::mat_base<n, m, mln_trait_op_uminus(T),E> ret;
129 template <
unsigned n,
unsigned m,
typename T,
typename E1,
typename U,
typename E2 >
130 struct set_precise_binary_< op::
plus,
131 algebra::internal::mat_base<n,m,T,E1>, algebra::internal::mat_base<n,m,U,E2> >
133 typedef algebra::internal::mat_base<n, m, mln_trait_op_plus(T, U)> ret;
138 template <
unsigned n,
unsigned m,
typename T,
typename E1,
typename U,
typename E2 >
139 struct set_precise_binary_< op::
minus,
140 algebra::internal::mat_base<n,m,T,E1>, algebra::internal::mat_base<n,m,U,E2> >
142 typedef algebra::internal::mat_base<n, m, mln_trait_op_minus(T, U),> ret;
147 template <
unsigned n,
unsigned o,
typename T,
148 unsigned m,
typename U >
149 struct set_precise_binary_< op::
times,
150 algebra::internal::mat_base<n,o,T>, algebra::internal::mat_base<o,m,U> >
152 typedef algebra::internal::mat_base<n, m, mln_sum_product(T, U)> ret;
155 template <
unsigned o,
typename T,
157 struct set_precise_binary_< op::
times,
158 algebra::internal::mat_base<1,o,T>, algebra::internal::mat_base<o,1,U> >
160 typedef mln_sum_product(T, U) ret;
165 template <
unsigned n,
unsigned m, typename T,
167 struct set_precise_binary_< op::times,
168 algebra::internal::mat_base<n,m,T,E>, algebra::vec<m,U> >
170 typedef algebra::vec<n, mln_sum_product(T, U)> ret;
173 template <
unsigned m,
typename T,
175 struct set_precise_binary_< op::
times,
176 algebra::internal::mat_base<1,m,T>, algebra::vec<m,U> >
178 typedef mln_sum_product(T, U) ret;
183 template <
unsigned m, typename T,
185 struct set_precise_binary_< op::times,
186 algebra::vec<m,T>, algebra::internal::mat_base<1,m,U> >
188 typedef algebra::internal::mat_base<m, m, mln_trait_op_times(T, U)> ret;
193 template <
unsigned n,
unsigned m,
typename T,
195 struct set_precise_binary_< op::
times,
196 algebra::internal::mat_base<n,m,T,E>, mln::value::scalar_<S> >
198 typedef algebra::internal::mat_base<n, m, mln_trait_op_times(T, S)> ret;
213 template <
unsigned n,
unsigned m,
typename T,
215 struct set_precise_binary_< op::
div,
216 algebra::internal::mat_base<n,m,T,E>, mln::value::scalar_<S> >
218 typedef algebra::internal::mat_base<n, m, mln_trait_op_div(T, S)> ret;
233 template <
unsigned n,
unsigned m,
typename T,
typename U>
235 operator==(
const mat_base<n,m,T,E>& lhs,
const mat_base<n,m,U>& rhs);
239 template <
unsigned n,
unsigned m,
typename T,
typename E>
240 mat_base<n, m, mln_trait_op_uminus(T)>
241 operator-(
const mat_base<n,m,T,E>& lhs);
245 template <
unsigned n,
unsigned m,
typename T,
typename U>
246 mat_base<n, m, mln_trait_op_plus(T,U)>
247 operator+(
const mat_base<n,m,T,E>& lhs,
const mat_base<n,m,U>& rhs);
251 template <
unsigned n,
unsigned m,
typename T,
typename U>
252 mat_base<n, m, mln_trait_op_minus(T,U)>
253 operator-(
const mat_base<n,m,T,E>& lhs,
const mat_base<n,m,U>& rhs);
257 template <
unsigned n,
unsigned o,
typename T,
258 unsigned m,
typename U>
259 mat_base<n, m, mln_sum_product(T,U)>
260 operator*(
const mat_base<n,o,T>& lhs,
const mat_base<o,m,U>& rhs);
262 template <
unsigned o,
typename T,
265 operator*(const mat_base<1,o,T>& lhs, const mat_base<o,1,U>& rhs);
269 template <
unsigned n,
unsigned m, typename T,
271 vec<n, mln_sum_product(T,U)>
272 operator*(const mat_base<n,m,T,E>& lhs, const vec<m,U>& rhs);
274 template <
unsigned m, typename T,
277 operator*(const mat_base<1,m,T>& lhs, const vec<m,U>& rhs);
281 template <
unsigned m, typename T, typename U>
282 mat_base<m, m, mln_trait_op_times(T,U)>
283 operator*(const vec<m,T>& lhs, const mat_base<1,m,U>& rhs);
287 template <
unsigned n,
unsigned m, typename T,
289 mat_base<n, m, mln_trait_op_times(T,S)>
290 operator*(const mat_base<n,m,T,E>& lhs, const value::scalar_<S>& s);
294 template <
unsigned n,
unsigned m, typename T, typename S>
295 mat_base<n, m, mln_trait_op_div(T,S)>
296 operator/(const mat_base<n,m,T,E>& lhs, const value::scalar_<S>& s);
300 template <
unsigned n,
unsigned m, typename T, typename E>
302 operator<<(std::ostream& ostr, const mat_base<n,m,T,E>& v);
310 template<
unsigned n, typename T, typename E>
312 tr(const internal::mat_base<n,n,T>& m);
318 template<typename T, typename E>
320 det(const internal::mat_base<2,2,T>& m);
323 template<typename T, typename E>
325 det(const internal::mat_base<3,3,T>& m);
328 # ifndef MLN_INCLUDE_ONLY
335 template <
unsigned n,
typename T,
typename E>
336 template <
typename U>
338 vec<n,T>::operator mat_base<n,1,U>()
const
340 mlc_converts_to(T, U)::check();
342 for (
unsigned i = 0; i < n; ++i)
343 tmp(i, 0) = data_[i];
350 template <
unsigned n,
typename T,
typename E>
351 template <
typename U>
353 vec<n,T>::vec(
const mat_base<n, 1, U>& rhs)
355 mlc_converts_to(T, U)::check();
356 for (
unsigned i = 0; i < n; ++i)
357 data_[i] = rhs(i, 0);
360 template <
unsigned n,
typename T,
typename E>
361 template <
typename U>
364 vec<n,T>::operator=(
const mat_base<n, 1, U>& rhs)
366 mlc_converts_to(T, U)::check();
367 for (
unsigned i = 0; i < n; ++i)
368 data_[i] = rhs(i, 0);
376 template <
unsigned n,
unsigned m,
typename T,
typename E>
377 const mat_base<n,m,T,E>
378 mat_base<n,m,T,E>::Id = mat_base<n,m,T,E>::identity();
380 template <
unsigned n,
unsigned m,
typename T,
typename E>
383 mat_base<n,m,T,E>::identity()
385 static mat_base<n,m,T,E> id_;
386 static bool flower =
true;
389 for (
unsigned i = 0; i < n; ++i)
390 for (
unsigned j = 0; j < m; ++j)
391 id_(i, j) = (i == j);
397 template <
unsigned n,
unsigned m,
typename T,
typename E>
399 mat_base<n,m,T,E>::mat_base()
403 template <
unsigned n,
unsigned m,
typename T,
typename E>
405 mat_base<n,m,T,E>::mat_base(
const literal::zero_t&)
410 template <
unsigned n,
unsigned m,
typename T,
typename E>
413 mat_base<n,m,T,E>::set_id_()
415 for (
unsigned i = 0; i < n; ++i)
416 for (
unsigned j = 0; j < m; ++j)
423 template <
unsigned n,
unsigned m,
typename T,
typename E>
425 mat_base<n,m,T,E>::mat_base(
const literal::one_t&)
430 template <
unsigned n,
unsigned m,
typename T,
typename E>
432 mat_base<n,m,T,E>::mat_base(
const literal::identity_t&)
437 template <
unsigned n,
unsigned m,
typename T,
typename E>
438 template <
typename U>
440 mat_base<n,m,T,E>::mat_base(
const mat_base<n,m,U>& rhs)
442 for (
unsigned i = 0; i < n; ++i)
443 for (
unsigned j = 0; j < m; ++j)
444 data_[i][j] = static_cast<T>( rhs(i, j) );
447 template <
unsigned n,
unsigned m,
typename T,
typename E>
448 template <
typename F>
450 mat_base<n,m,T,E>::mat_base(
const Function_v2v<F>& f_)
452 mlc_converts_to(mln_result(F), T)::check();
453 const F& f = exact(f_);
454 for (
unsigned i = 0; i < n; ++i)
455 for (
unsigned j = 0; j < m; ++j)
456 data_[i][j] = static_cast<T>( f(i * n + j) );
459 template <
unsigned n,
unsigned m,
typename T,
typename E>
460 template <
typename U>
463 mat_base<n,m,T,E>::operator=(
const mat_base<n,m,U>& rhs)
465 for (
unsigned i = 0; i < n; ++i)
466 for (
unsigned j = 0; j < m; ++j)
467 data_[i][j] = static_cast<T>( rhs(i, j) );
471 template <
unsigned n,
unsigned m,
typename T,
typename E>
474 mat_base<n,m,T,E>::operator()(
unsigned i,
unsigned j)
const
476 mln_precondition(i < n && j < m);
480 template <
unsigned n,
unsigned m,
typename T,
typename E>
483 mat_base<n,m,T,E>::operator()(
unsigned i,
unsigned j)
485 mln_precondition(i < n && j < m);
489 template <
unsigned n,
unsigned m,
typename T,
typename E>
491 void mat_base<n,m,T,E>::set_all(
const T& val)
493 for (
unsigned i = 0; i < n; ++i)
494 for (
unsigned j = 0; j < m; ++j)
498 template <
unsigned n,
unsigned m,
typename T,
typename E>
500 unsigned mat_base<n,m,T,E>::size()
const
505 template <
unsigned n,
unsigned m,
typename T,
typename E>
508 mat_base<n,m,T,E>::t()
const
510 mat_base<m,n,T,E> tmp;
511 for (
unsigned i = 0; i < n; ++i)
512 for (
unsigned j = 0; j < m; ++j)
513 tmp(j,i) = data_[i][j];
518 template <
typename T,
typename E>
521 inverse(
const mat_base<2,2,T>& m)
524 mln_precondition(d != 0);
525 return make<float>( + m(1,1) / d, - m(0,1) / d,
526 - m(1,0) / d, + m(0,0) / d );
529 template <
typename T,
typename E>
532 inverse(
const mat_base<3,3,T>& m)
535 mln_precondition(d != 0);
536 return make<float>(
det(make(m(1,1), m(1,2),
539 det(make(m(0,2), m(0,1),
542 det(make(m(0,1), m(0,2),
546 det(make(m(1,2), m(1,0),
549 det(make(m(0,0), m(0,2),
552 det(make(m(0,2), m(0,0),
555 det(make(m(1,0), m(1,1),
558 det(make(m(0,1), m(0,0),
561 det(make(m(0,0), m(0,1),
567 template <
unsigned n,
unsigned m,
typename T,
typename E>
570 mat_base<n,m,T,E>::_1()
const
572 mlc_bool(m == n)::check();
573 return internal::inverse(*
this);
579 template <
unsigned n,
unsigned m,
typename T,
typename U>
582 operator==(
const mat_base<n,m,T,E>& lhs,
const mat_base<n,m,U>& rhs)
584 for (
unsigned i = 0; i < n; ++i)
585 for (
unsigned j = 0; j < m; ++j)
586 if (lhs(i, j) != rhs(i, j))
591 template <
unsigned n,
unsigned m,
typename T,
typename U>
593 mat_base<n, m, mln_trait_op_plus(T,U)>
594 operator+(
const mat_base<n,m,T,E>& lhs,
const mat_base<n,m,U>& rhs)
596 mat_base<n, m, mln_trait_op_plus(T,U)> tmp;
597 for (
unsigned i = 0; i < n; ++i)
598 for (
unsigned j = 0; j < m; ++j)
599 tmp(i, j) = lhs(i, j) + rhs(i, j);
603 template <
unsigned n,
unsigned m,
typename T,
typename U>
605 mat_base<n,m, mln_trait_op_minus(T,U)>
606 operator-(
const mat_base<n,m,T,E>& lhs,
const mat_base<n,m,U>& rhs)
608 mat_base<n,m, mln_trait_op_minus(T,U)> tmp;
609 for (
unsigned i = 0; i < n; ++i)
610 for (
unsigned j = 0; j < m; ++j)
611 tmp(i, j) = lhs(i, j) - rhs(i, j);
615 template <
unsigned n,
unsigned m,
typename T,
typename E>
617 mat_base<n,m, mln_trait_op_uminus(T)>
618 operator-(
const mat_base<n,m,T,E>& rhs)
620 mat_base<n,m, mln_trait_op_uminus(T)> tmp;
621 for (
unsigned i = 0; i < n; ++i)
622 for (
unsigned j = 0; i < m; ++i)
623 tmp(i, j) = - rhs(i, j);
629 template <
unsigned n,
unsigned o,
typename T,
630 unsigned m,
typename U>
632 mat_base<n, m, mln_sum_product(T,U)>
633 operator*(
const mat_base<n,o,T>& lhs,
const mat_base<o,m,U>& rhs)
635 mat_base<n,m, mln_sum_product(T,U)> tmp;
636 for (
unsigned i = 0; i < n; ++i)
637 for (
unsigned j = 0; j < m; ++j)
640 for (
unsigned k = 0; k < o; ++k)
641 tmp(i, j) += lhs(i, k) * rhs(k, j);
646 template <
unsigned o,
typename T,
650 operator*(const mat_base<1,o,T>& lhs, const mat_base<o,1,U>& rhs)
652 mln_sum_product(T,U) tmp(literal::zero);
653 for (
unsigned k = 0; k < o; ++k)
654 tmp += lhs(0, k) * rhs(k, 0);
660 template <
unsigned n,
unsigned m, typename T,
663 vec<n, mln_sum_product(T,U)>
664 operator*(const mat_base<n,m,T,E>& lhs, const vec<m,U>& rhs)
666 vec<n, mln_sum_product(T,U)> tmp;
667 for (
unsigned i = 0; i < n; ++i)
669 mln_sum_product(T,U) sum(literal::zero);
670 for (
unsigned j = 0; j < m; ++j)
671 sum += lhs(i, j) * rhs[j];
677 template <
unsigned m, typename T,
681 operator*(const mat_base<1,m,T>& lhs, const vec<m,U>& rhs)
683 mln_sum_product(T,U) tmp(literal::zero);
684 for (
unsigned j = 0; j < m; ++j)
685 tmp += lhs(0, j) * rhs[j];
691 template <
unsigned m, typename T,
694 mat_base<m, m, mln_trait_op_times(T,U)>
695 operator*(const vec<m,T>& lhs, const mat_base<1,m,U>& rhs)
697 mat_base<m, m, mln_trait_op_times(T,U)> tmp;
698 for (
unsigned i = 0; i < m; ++i)
699 for (
unsigned j = 0; j < m; ++j)
700 tmp(i, j) = lhs[i] * rhs(0, j);
706 template <
unsigned n,
unsigned m,
typename T,
typename S>
708 mat_base<n, m, mln_trait_op_times(T,S)>
709 operator*(
const mat_base<n,m,T,E>& lhs,
const value::scalar_<S>& s_)
712 mat_base<n, m, mln_trait_op_times(T,S)> tmp;
713 for (
unsigned i = 0; i < n; ++i)
714 for (
unsigned j = 0; j < m; ++j)
715 tmp(i, j) = lhs(i, j) * s;
719 template <
unsigned n,
unsigned m,
typename T,
typename S>
721 mat_base<n,m, mln_trait_op_div(T,S)>
722 operator/(
const mat_base<n,m,T,E>& lhs,
const value::scalar_<S>& s_)
725 mat_base<n,m, mln_trait_op_times(T,S)> tmp;
726 for (
unsigned i = 0; i < n; ++i)
727 for (
unsigned j = 0; j < m; ++j)
728 tmp(i,j) = lhs(i, j) / s;
734 template <
unsigned n,
unsigned m,
typename T,
typename E>
737 operator<<(std::ostream& ostr, const mat_base<n,m,T,E>& v)
739 for (
unsigned i = 0; i < n; ++i)
742 for (
unsigned j = 0; j < m; ++j)
743 ostr << debug::format_base(v(i, j)) << (j == m - 1 ?
"]" :
", ");
753 template<
unsigned n,
typename T,
typename E>
756 tr(const internal::mat_base<n,n,T>& m)
759 for (
unsigned i = 0; i < n; ++i)
767 template<
typename T,
typename E>
770 det(const internal::mat_base<2,2,T>& m)
772 return m(0,0) * m(1,1) - m(0,1) * m(1,0);
775 template<
typename T,
typename E>
778 det(const internal::mat_base<3,3,T>& m)
781 + m(0,0) * m(1,1) * m(2,2)
782 - m(0,0) * m(1,2) * m(2,1)
783 - m(0,1) * m(1,0) * m(2,2)
784 + m(0,1) * m(1,2) * m(2,0)
785 + m(0,2) * m(1,0) * m(2,1)
786 - m(0,2) * m(1,1) * m(2,0);
792 template <
unsigned n,
typename T,
typename E>
794 internal::mat_base<1,n,T>
797 internal::mat_base<1,n,T> tmp;
798 for (
unsigned i = 0; i < n; ++i)
803 # endif // ! MLN_INCLUDE_ONLY
809 #endif // ! MLN_ALGEBRA_INTERNAL_MAT_BASE_HH