26 #ifndef MLN_ALGEBRA_MAT_HH
27 # define MLN_ALGEBRA_MAT_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>
54 template <
unsigned n,
unsigned m,
typename T>
class mat;
61 template <
unsigned n,
unsigned m,
typename T>
62 struct value_< algebra::
mat<n,m,T> >
64 typedef trait::value::nature::matrix nature;
65 typedef trait::value::kind::data kind;
68 nbits = n * m * mln_nbits(T),
69 card = n * m * mln_card(T)
71 typedef mln_value_quant_from_(card) quant;
73 typedef algebra::mat<n, m, mln_sum(T)> sum;
84 template <
unsigned n,
unsigned m,
typename T>
85 class mat :
public Object< mat<n,m,T> >
94 static const mat<n,m,T> Id;
98 mat(
const literal::zero_t&);
99 mat(
const literal::one_t&);
100 mat(
const literal::identity_t&);
102 template <
typename U>
103 mat(
const mat<n,m,U>& rhs);
106 template <
typename F>
107 mat(
const Function_v2v<F>& f);
109 template <
typename U>
110 mat& operator=(
const mat<n,m,U>& rhs);
112 const T& operator()(
unsigned i,
unsigned j)
const;
114 T& operator()(
unsigned i,
unsigned j);
116 void set_all(
const T& val);
118 unsigned size()
const;
123 mat<m,n,T> t()
const;
127 mat<n,m,T> _1()
const;
137 template <
typename T>
139 make(
const T& t00,
const T& t01,
140 const T& t10,
const T& t11);
142 template <
typename T>
144 make(
const T& t00,
const T& t01,
const T& t02,
145 const T& t10,
const T& t11,
const T& t12,
146 const T& t20,
const T& t21,
const T& t22);
158 template <
unsigned n,
unsigned m,
typename T >
159 struct set_precise_unary_< op::uminus,
160 algebra::mat<n,m,T> >
162 typedef algebra::mat<n, m, mln_trait_op_uminus(T)> ret;
167 template <
unsigned n,
unsigned m,
typename T,
typename U >
168 struct set_precise_binary_< op::
plus,
169 algebra::mat<n,m,T>, algebra::mat<n,m,U> >
171 typedef algebra::mat<n, m, mln_trait_op_plus(T, U)> ret;
176 template <
unsigned n,
unsigned m,
typename T,
typename U >
177 struct set_precise_binary_< op::
minus,
178 algebra::mat<n,m,T>, algebra::mat<n,m,U> >
180 typedef algebra::mat<n, m, mln_trait_op_minus(T, U)> ret;
185 template <
unsigned n,
unsigned o,
typename T,
186 unsigned m,
typename U >
187 struct set_precise_binary_< op::
times,
188 algebra::mat<n,o,T>, algebra::mat<o,m,U> >
190 typedef algebra::mat<n, m, mln_sum_product(T, U)> ret;
193 template <
unsigned o,
typename T,
195 struct set_precise_binary_< op::
times,
196 algebra::mat<1,o,T>, algebra::mat<o,1,U> >
198 typedef mln_sum_product(T, U) ret;
203 template <
unsigned n,
unsigned m, typename T,
205 struct set_precise_binary_< op::times,
206 algebra::mat<n,m,T>, algebra::vec<m,U> >
208 typedef algebra::vec<n, mln_sum_product(T, U)> ret;
211 template <
unsigned m,
typename T,
213 struct set_precise_binary_< op::
times,
214 algebra::mat<1,m,T>, algebra::vec<m,U> >
216 typedef mln_sum_product(T, U) ret;
221 template <
unsigned m, typename T,
223 struct set_precise_binary_< op::times,
224 algebra::vec<m,T>, algebra::mat<1,m,U> >
226 typedef algebra::mat<m, m, mln_trait_op_times(T, U)> ret;
231 template <
unsigned n,
unsigned m,
typename T,
233 struct set_precise_binary_< op::
times,
234 algebra::mat<n,m,T>, mln::value::scalar_<S> >
236 typedef algebra::mat<n, m, mln_trait_op_times(T, S)> ret;
251 template <
unsigned n,
unsigned m,
typename T,
253 struct set_precise_binary_< op::
div,
254 algebra::mat<n,m,T>, mln::value::scalar_<S> >
256 typedef algebra::mat<n, m, mln_trait_op_div(T, S)> ret;
268 template <
unsigned n,
unsigned m,
typename T,
typename U>
270 operator==(
const mat<n,m,T>& lhs,
const mat<n,m,U>& rhs);
274 template <
unsigned n,
unsigned m,
typename T>
275 mat<n, m, mln_trait_op_uminus(T)>
276 operator-(
const mat<n,m,T>& lhs);
280 template <
unsigned n,
unsigned m,
typename T,
typename U>
281 mat<n, m, mln_trait_op_plus(T,U)>
282 operator+(
const mat<n,m,T>& lhs,
const mat<n,m,U>& rhs);
286 template <
unsigned n,
unsigned m,
typename T,
typename U>
287 mat<n, m, mln_trait_op_minus(T,U)>
288 operator-(
const mat<n,m,T>& lhs,
const mat<n,m,U>& rhs);
292 template <
unsigned n,
unsigned o,
typename T,
293 unsigned m,
typename U>
294 mat<n, m, mln_sum_product(T,U)>
295 operator*(
const mat<n,o,T>& lhs,
const mat<o,m,U>& rhs);
297 template <
unsigned o,
typename T,
300 operator*(const mat<1,o,T>& lhs, const mat<o,1,U>& rhs);
304 template <
unsigned n,
unsigned m, typename T,
306 vec<n, mln_sum_product(T,U)>
307 operator*(const mat<n,m,T>& lhs, const vec<m,U>& rhs);
309 template <
unsigned m, typename T,
312 operator*(const mat<1,m,T>& lhs, const vec<m,U>& rhs);
316 template <
unsigned m, typename T, typename U>
317 mat<m, m, mln_trait_op_times(T,U)>
318 operator*(const vec<m,T>& lhs, const mat<1,m,U>& rhs);
322 template <
unsigned n,
unsigned m, typename T,
324 mat<n, m, mln_trait_op_times(T,S)>
325 operator*(const mat<n,m,T>& lhs, const value::scalar_<S>& s);
329 template <
unsigned n,
unsigned m, typename T, typename S>
330 mat<n, m, mln_trait_op_div(T,S)>
331 operator/(const mat<n,m,T>& lhs, const value::scalar_<S>& s);
335 template <
unsigned n,
unsigned m, typename T>
337 operator<<(std::ostream& ostr, const mat<n,m,T>& v);
343 template<
unsigned n, typename T>
345 tr(const mat<n,n,T>& m);
352 det(const mat<2,2,T>& m);
356 det(const mat<3,3,T>& m);
360 # ifndef MLN_INCLUDE_ONLY
365 template <
unsigned n,
typename T>
366 template <
typename U>
368 vec<n,T>::operator mat<n,1,U>()
const
370 mlc_converts_to(T, U)::check();
372 for (
unsigned i = 0; i < n; ++i)
373 tmp(i, 0) = data_[i];
380 template <
unsigned n,
typename T>
381 template <
typename U>
383 vec<n,T>::vec(
const mat<n, 1, U>& rhs)
385 mlc_converts_to(T, U)::check();
386 for (
unsigned i = 0; i < n; ++i)
387 data_[i] = rhs(i, 0);
390 template <
unsigned n,
typename T>
391 template <
typename U>
394 vec<n,T>::operator=(
const mat<n, 1, U>& rhs)
396 mlc_converts_to(T, U)::check();
397 for (
unsigned i = 0; i < n; ++i)
398 data_[i] = rhs(i, 0);
406 template <
unsigned n,
unsigned m,
typename T>
408 mat<n,m,T>::Id = mat<n,m,T>::identity();
410 template <
unsigned n,
unsigned m,
typename T>
413 mat<n,m,T>::identity()
415 static mat<n,m,T> id_;
416 static bool flower =
true;
419 for (
unsigned i = 0; i < n; ++i)
420 for (
unsigned j = 0; j < m; ++j)
421 id_(i, j) = (i == j);
427 template <
unsigned n,
unsigned m,
typename T>
433 template <
unsigned n,
unsigned m,
typename T>
435 mat<n,m,T>::mat(
const literal::zero_t&)
440 template <
unsigned n,
unsigned m,
typename T>
443 mat<n,m,T>::set_id_()
445 for (
unsigned i = 0; i < n; ++i)
446 for (
unsigned j = 0; j < m; ++j)
453 template <
unsigned n,
unsigned m,
typename T>
455 mat<n,m,T>::mat(
const literal::one_t&)
460 template <
unsigned n,
unsigned m,
typename T>
462 mat<n,m,T>::mat(
const literal::identity_t&)
467 template <
unsigned n,
unsigned m,
typename T>
468 template <
typename U>
470 mat<n,m,T>::mat(
const mat<n,m,U>& rhs)
472 for (
unsigned i = 0; i < n; ++i)
473 for (
unsigned j = 0; j < m; ++j)
474 data_[i][j] = static_cast<T>( rhs(i, j) );
477 template <
unsigned n,
unsigned m,
typename T>
478 template <
typename F>
480 mat<n,m,T>::mat(
const Function_v2v<F>& f_)
482 mlc_converts_to(mln_result(F), T)::check();
483 const F& f = exact(f_);
484 for (
unsigned i = 0; i < n; ++i)
485 for (
unsigned j = 0; j < m; ++j)
486 data_[i][j] = static_cast<T>( f(i * n + j) );
489 template <
unsigned n,
unsigned m,
typename T>
490 template <
typename U>
493 mat<n,m,T>::operator=(
const mat<n,m,U>& rhs)
495 for (
unsigned i = 0; i < n; ++i)
496 for (
unsigned j = 0; j < m; ++j)
497 data_[i][j] = static_cast<T>( rhs(i, j) );
501 template <
unsigned n,
unsigned m,
typename T>
504 mat<n,m,T>::operator()(
unsigned i,
unsigned j)
const
506 mln_precondition(i < n && j < m);
510 template <
unsigned n,
unsigned m,
typename T>
513 mat<n,m,T>::operator()(
unsigned i,
unsigned j)
515 mln_precondition(i < n && j < m);
519 template <
unsigned n,
unsigned m,
typename T>
521 void mat<n,m,T>::set_all(
const T& val)
523 for (
unsigned i = 0; i < n; ++i)
524 for (
unsigned j = 0; j < m; ++j)
528 template <
unsigned n,
unsigned m,
typename T>
530 unsigned mat<n,m,T>::size()
const
535 template <
unsigned n,
unsigned m,
typename T>
538 mat<n,m,T>::t()
const
541 for (
unsigned i = 0; i < n; ++i)
542 for (
unsigned j = 0; j < m; ++j)
543 tmp(j,i) = data_[i][j];
551 template <
typename T>
554 inverse(
const mat<2,2,T>& m)
557 mln_precondition(d != 0);
558 return make<float>( + m(1,1) / d, - m(0,1) / d,
559 - m(1,0) / d, + m(0,0) / d );
562 template <
typename T>
565 inverse(
const mat<3,3,T>& m)
568 mln_precondition(d != 0);
569 return make<float>(
det(make(m(1,1), m(1,2),
572 det(make(m(0,2), m(0,1),
575 det(make(m(0,1), m(0,2),
579 det(make(m(1,2), m(1,0),
582 det(make(m(0,0), m(0,2),
585 det(make(m(0,2), m(0,0),
588 det(make(m(1,0), m(1,1),
591 det(make(m(0,1), m(0,0),
594 det(make(m(0,0), m(0,1),
601 template <
unsigned n,
unsigned m,
typename T>
604 mat<n,m,T>::_1()
const
606 mlc_bool(m == n)::check();
607 return internal::inverse(*
this);
613 template <
typename T>
616 make(
const T& t00,
const T& t01,
617 const T& t10,
const T& t11)
620 tmp(0, 0) = t00; tmp(0, 1) = t01;
621 tmp(1, 0) = t10; tmp(1, 1) = t11;
625 template <
typename T>
628 make(
const T& t00,
const T& t01,
const T& t02,
629 const T& t10,
const T& t11,
const T& t12,
630 const T& t20,
const T& t21,
const T& t22)
633 tmp(0, 0) = t00; tmp(0, 1) = t01; tmp(0, 2) = t02;
634 tmp(1, 0) = t10; tmp(1, 1) = t11; tmp(1, 2) = t12;
635 tmp(2, 0) = t20; tmp(2, 1) = t21; tmp(2, 2) = t22;
643 template <
unsigned n,
unsigned m,
typename T,
typename U>
646 operator==(
const mat<n,m,T>& lhs,
const mat<n,m,U>& rhs)
648 for (
unsigned i = 0; i < n; ++i)
649 for (
unsigned j = 0; j < m; ++j)
650 if (lhs(i, j) != rhs(i, j))
655 template <
unsigned n,
unsigned m,
typename T,
typename U>
657 mat<n, m, mln_trait_op_plus(T,U)>
658 operator+(
const mat<n,m,T>& lhs,
const mat<n,m,U>& rhs)
660 mat<n, m, mln_trait_op_plus(T,U)> tmp;
661 for (
unsigned i = 0; i < n; ++i)
662 for (
unsigned j = 0; j < m; ++j)
663 tmp(i, j) = lhs(i, j) + rhs(i, j);
667 template <
unsigned n,
unsigned m,
typename T,
typename U>
669 mat<n,m, mln_trait_op_minus(T,U)>
670 operator-(
const mat<n,m,T>& lhs,
const mat<n,m,U>& rhs)
672 mat<n,m, mln_trait_op_minus(T,U)> tmp;
673 for (
unsigned i = 0; i < n; ++i)
674 for (
unsigned j = 0; j < m; ++j)
675 tmp(i, j) = lhs(i, j) - rhs(i, j);
679 template <
unsigned n,
unsigned m,
typename T>
681 mat<n,m, mln_trait_op_uminus(T)>
682 operator-(
const mat<n,m,T>& rhs)
684 mat<n,m, mln_trait_op_uminus(T)> tmp;
685 for (
unsigned i = 0; i < n; ++i)
686 for (
unsigned j = 0; i < m; ++i)
687 tmp(i, j) = - rhs(i, j);
693 template <
unsigned n,
unsigned o,
typename T,
694 unsigned m,
typename U>
696 mat<n, m, mln_sum_product(T,U)>
697 operator*(
const mat<n,o,T>& lhs,
const mat<o,m,U>& rhs)
699 mat<n,m, mln_sum_product(T,U)> tmp;
700 for (
unsigned i = 0; i < n; ++i)
701 for (
unsigned j = 0; j < m; ++j)
704 for (
unsigned k = 0; k < o; ++k)
705 tmp(i, j) += lhs(i, k) * rhs(k, j);
710 template <
unsigned o,
typename T,
714 operator*(const mat<1,o,T>& lhs, const mat<o,1,U>& rhs)
716 mln_sum_product(T,U) tmp(literal::zero);
717 for (
unsigned k = 0; k < o; ++k)
718 tmp += lhs(0, k) * rhs(k, 0);
724 template <
unsigned n,
unsigned m, typename T,
727 vec<n, mln_sum_product(T,U)>
728 operator*(const mat<n,m,T>& lhs, const vec<m,U>& rhs)
730 vec<n, mln_sum_product(T,U)> tmp;
731 for (
unsigned i = 0; i < n; ++i)
733 mln_sum_product(T,U) sum(literal::zero);
734 for (
unsigned j = 0; j < m; ++j)
735 sum += lhs(i, j) * rhs[j];
741 template <
unsigned m, typename T,
745 operator*(const mat<1,m,T>& lhs, const vec<m,U>& rhs)
747 mln_sum_product(T,U) tmp(literal::zero);
748 for (
unsigned j = 0; j < m; ++j)
749 tmp += lhs(0, j) * rhs[j];
755 template <
unsigned m, typename T,
758 mat<m, m, mln_trait_op_times(T,U)>
759 operator*(const vec<m,T>& lhs, const mat<1,m,U>& rhs)
761 mat<m, m, mln_trait_op_times(T,U)> tmp;
762 for (
unsigned i = 0; i < m; ++i)
763 for (
unsigned j = 0; j < m; ++j)
764 tmp(i, j) = lhs[i] * rhs(0, j);
770 template <
unsigned n,
unsigned m,
typename T,
typename S>
772 mat<n, m, mln_trait_op_times(T,S)>
773 operator*(
const mat<n,m,T>& lhs,
const value::scalar_<S>& s_)
776 mat<n, m, mln_trait_op_times(T,S)> tmp;
777 for (
unsigned i = 0; i < n; ++i)
778 for (
unsigned j = 0; j < m; ++j)
779 tmp(i, j) = lhs(i, j) * s;
783 template <
unsigned n,
unsigned m,
typename T,
typename S>
785 mat<n,m, mln_trait_op_div(T,S)>
786 operator/(
const mat<n,m,T>& lhs,
const value::scalar_<S>& s_)
789 mat<n,m, mln_trait_op_times(T,S)> tmp;
790 for (
unsigned i = 0; i < n; ++i)
791 for (
unsigned j = 0; j < m; ++j)
792 tmp(i,j) = lhs(i, j) / s;
798 template <
unsigned n,
unsigned m,
typename T>
801 operator<<(std::ostream& ostr, const mat<n,m,T>& v)
803 for (
unsigned i = 0; i < n; ++i)
806 for (
unsigned j = 0; j < m; ++j)
816 template<
unsigned n,
typename T>
819 tr(const mat<n,n,T>& m)
821 mln_sum(T) tr_ = literal::zero;
822 for (
unsigned i = 0; i < n; ++i)
833 det(const mat<2,2,T>& m)
835 return m(0,0) * m(1,1) - m(0,1) * m(1,0);
841 det(const mat<3,3,T>& m)
844 + m(0,0) * m(1,1) * m(2,2)
845 - m(0,0) * m(1,2) * m(2,1)
846 - m(0,1) * m(1,0) * m(2,2)
847 + m(0,1) * m(1,2) * m(2,0)
848 + m(0,2) * m(1,0) * m(2,1)
849 - m(0,2) * m(1,1) * m(2,0);
855 template <
unsigned n,
typename T>
861 for (
unsigned i = 0; i < n; ++i)
866 # endif // ! MLN_INCLUDE_ONLY
872 # include <mln/make/mat.hh>
874 #endif // ! MLN_ALGEBRA_MAT_HH