Milena (Olena)  User documentation 2.0a Id
 All Classes Namespaces Functions Variables Typedefs Enumerator Groups Pages
mat_base.hh
1 // Copyright (C) 2012 EPITA Research and Development Laboratory (LRDE)
2 //
3 // This file is part of Olena.
4 //
5 // Olena is free software: you can redistribute it and/or modify it under
6 // the terms of the GNU General Public License as published by the Free
7 // Software Foundation, version 2 of the License.
8 //
9 // Olena is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with Olena. If not, see <http://www.gnu.org/licenses/>.
16 //
17 // As a special exception, you may use this file as part of a free
18 // software project without restriction. Specifically, if other files
19 // instantiate templates or use macros or inline functions from this
20 // file, or you compile this file and link it with other files to produce
21 // an executable, this file does not by itself cause the resulting
22 // executable to be covered by the GNU General Public License. This
23 // exception does not however invalidate any other reasons why the
24 // executable file might be covered by the GNU General Public License.
25 
26 #ifndef MLN_ALGEBRA_INTERNAL_MAT_BASE_HH
27 # define MLN_ALGEBRA_INTERNAL_MAT_BASE_HH
28 
32 
33 # include <iostream>
34 
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>
42 
43 
44 // FIXME: Document.
45 
46 
47 
48 namespace mln
49 {
50 
51  namespace algebra
52  {
53 
54  namespace internal
55  {
56 
57  template <unsigned n, unsigned m, typename T, typename E>
58  class mat_base : public Object< E >
59  {
60  public:
61 
62  typedef T coord;
63  enum { N = n,
64  M = m,
65  dim = n * m };
66 
67  static const E Id;
68 
69  mat_base();
70 
71  mat_base(const literal::zero_t&);
72  mat_base(const literal::one_t&);
73  mat_base(const literal::identity_t&);
74 
75  template <typename U, typename M>
76  mat_base(const mat_base<n,m,U,M>& rhs);
77 
79  template <typename F>
80  mat_base(const Function_v2v<F>& f);
81 
82  template <typename U, typename M>
83  mat_base& operator=(const mat_base<n,m,U,M>& rhs);
84 
85  const T& operator()(unsigned i, unsigned j) const;
86 
87  T& operator()(unsigned i, unsigned j);
88 
89  void set_all(const T& val);
90 
91  unsigned size() const;
92 
93  static mat_base identity();
94 
96  mat_base<m,n,T,E> t() const;
97 
100  mat_base<n,m,T,E> _1() const;
101 
102  private:
103 
104  T data_[n][m];
105 
106  void set_id_();
107  };
108 
109 
110  } // end of namespace algebra::internal
111 
112  } // end of namespace algebra
113 
114 
115  namespace trait
116  {
117 
118  // - internal::mat_base
119 
120  template < unsigned n, unsigned m, typename T >
121  struct set_precise_unary_< op::uminus,
122  algebra::internal::mat_base<n,m,T,E> >
123  {
124  typedef algebra::internal::mat_base<n, m, mln_trait_op_uminus(T),E> ret;
125  };
126 
127  // internal::mat_base + internal::mat_base
128 
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> >
132  {
133  typedef algebra::internal::mat_base<n, m, mln_trait_op_plus(T, U)> ret;
134  };
135 
136  // internal::mat_base - internal::mat_base
137 
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> >
141  {
142  typedef algebra::internal::mat_base<n, m, mln_trait_op_minus(T, U),> ret;
143  };
144 
145  // internal::mat_base * internal::mat_base
146 
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> >
151  {
152  typedef algebra::internal::mat_base<n, m, mln_sum_product(T, U)> ret;
153  };
154 
155  template < unsigned o, typename T,
156  typename U >
157  struct set_precise_binary_< op::times,
158  algebra::internal::mat_base<1,o,T>, algebra::internal::mat_base<o,1,U> >
159  {
160  typedef mln_sum_product(T, U) ret;
161  };
162 
163  // internal::mat_base * vec
164 
165  template < unsigned n, unsigned m, typename T,
166  typename U >
167  struct set_precise_binary_< op::times,
168  algebra::internal::mat_base<n,m,T,E>, algebra::vec<m,U> >
169  {
170  typedef algebra::vec<n, mln_sum_product(T, U)> ret;
171  };
172 
173  template < unsigned m, typename T,
174  typename U >
175  struct set_precise_binary_< op::times,
176  algebra::internal::mat_base<1,m,T>, algebra::vec<m,U> >
177  {
178  typedef mln_sum_product(T, U) ret; // a scalar
179  };
180 
181  // vec * internal::mat_base
182 
183  template < unsigned m, typename T,
184  typename U >
185  struct set_precise_binary_< op::times,
186  algebra::vec<m,T>, algebra::internal::mat_base<1,m,U> >
187  {
188  typedef algebra::internal::mat_base<m, m, mln_trait_op_times(T, U)> ret;
189  };
190 
191  // internal::mat_base * s
192 
193  template < unsigned n, unsigned m, typename T,
194  typename S >
195  struct set_precise_binary_< op::times,
196  algebra::internal::mat_base<n,m,T,E>, mln::value::scalar_<S> >
197  {
198  typedef algebra::internal::mat_base<n, m, mln_trait_op_times(T, S)> ret;
199  };
200 
201  // template < template<class, class> class Name,
202  // unsigned n, unsigned m, typename T,
203  // typename S >
204  // struct set_binary_< Name,
205  // mln::Object, algebra::internal::mat_base<n,m,T,E>,
206  // mln::value::Scalar, S >
207  // {
208  // typedef algebra::internal::mat_base<n, m, mln_trait_binary(Name, T, S)> ret;
209  // };
210 
211  // internal::mat_base / s
212 
213  template < unsigned n, unsigned m, typename T,
214  typename S >
215  struct set_precise_binary_< op::div,
216  algebra::internal::mat_base<n,m,T,E>, mln::value::scalar_<S> >
217  {
218  typedef algebra::internal::mat_base<n, m, mln_trait_op_div(T, S)> ret;
219  };
220 
221  } // end of namespace mln::trait
222 
223 
224 
225  namespace algebra
226  {
227 
228  namespace internal
229  {
230 
231  // ==
232 
233  template <unsigned n, unsigned m, typename T, typename U>
234  bool
235  operator==(const mat_base<n,m,T,E>& lhs, const mat_base<n,m,U>& rhs);
236 
237  // - mat_base
238 
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);
242 
243  // mat_base + mat_base
244 
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);
248 
249  // mat_base - mat_base
250 
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);
254 
255  // mat_base * mat_base
256 
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);
261 
262  template <unsigned o, typename T,
263  typename U>
264  mln_sum_product(T,U)
265  operator*(const mat_base<1,o,T>& lhs, const mat_base<o,1,U>& rhs);
266 
267  // mat_base * vec
268 
269  template <unsigned n, unsigned m, typename T,
270  typename U>
271  vec<n, mln_sum_product(T,U)>
272  operator*(const mat_base<n,m,T,E>& lhs, const vec<m,U>& rhs);
273 
274  template <unsigned m, typename T,
275  typename U>
276  mln_sum_product(T,U) // scalar
277  operator*(const mat_base<1,m,T>& lhs, const vec<m,U>& rhs);
278 
279  // vec * mat_base
280 
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);
284 
285  // mat_base * s
286 
287  template <unsigned n, unsigned m, typename T,
288  typename S>
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);
291 
292  // mat_base / s
293 
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);
297 
298  // <<
299 
300  template <unsigned n, unsigned m, typename T, typename E>
301  std::ostream&
302  operator<<(std::ostream& ostr, const mat_base<n,m,T,E>& v);
303 
304  } // end of namespace algebra::internal
305 
306 
307  // Trace.
308 
310  template<unsigned n, typename T, typename E>
311  mln_sum(T)
312  tr(const internal::mat_base<n,n,T>& m);
313 
314 
315  // Determinant.
316 
318  template<typename T, typename E>
319  mln_sum_product(T,T)
320  det(const internal::mat_base<2,2,T>& m);
321 
323  template<typename T, typename E>
324  mln_sum_product(T,T)
325  det(const internal::mat_base<3,3,T>& m);
326 
327 
328 # ifndef MLN_INCLUDE_ONLY
329 
330  namespace internal
331  {
332 
333  // vec -> mat_base
334 
335  template <unsigned n, typename T, typename E>
336  template <typename U>
337  inline
338  vec<n,T>::operator mat_base<n,1,U>() const
339  {
340  mlc_converts_to(T, U)::check();
341  mat_base<n,1,U> tmp;
342  for (unsigned i = 0; i < n; ++i)
343  tmp(i, 0) = data_[i];
344  return tmp;
345  }
346 
347 
348  // mat_base -> vec
349 
350  template <unsigned n, typename T, typename E>
351  template <typename U>
352  inline
353  vec<n,T>::vec(const mat_base<n, 1, U>& rhs)
354  {
355  mlc_converts_to(T, U)::check();
356  for (unsigned i = 0; i < n; ++i)
357  data_[i] = rhs(i, 0);
358  }
359 
360  template <unsigned n, typename T, typename E>
361  template <typename U>
362  inline
363  vec<n,T>&
364  vec<n,T>::operator=(const mat_base<n, 1, U>& rhs)
365  {
366  mlc_converts_to(T, U)::check();
367  for (unsigned i = 0; i < n; ++i)
368  data_[i] = rhs(i, 0);
369  return *this;
370  }
371 
372 
373 
374  // Id
375 
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();
379 
380  template <unsigned n, unsigned m, typename T, typename E>
381  inline
382  mat_base<n,m,T,E>
383  mat_base<n,m,T,E>::identity()
384  {
385  static mat_base<n,m,T,E> id_;
386  static bool flower = true;
387  if (flower)
388  {
389  for (unsigned i = 0; i < n; ++i)
390  for (unsigned j = 0; j < m; ++j)
391  id_(i, j) = (i == j);
392  flower = false;
393  }
394  return id_;
395  }
396 
397  template <unsigned n, unsigned m, typename T, typename E>
398  inline
399  mat_base<n,m,T,E>::mat_base()
400  {
401  }
402 
403  template <unsigned n, unsigned m, typename T, typename E>
404  inline
405  mat_base<n,m,T,E>::mat_base(const literal::zero_t&)
406  {
407  this->set_all(0);
408  }
409 
410  template <unsigned n, unsigned m, typename T, typename E>
411  inline
412  void
413  mat_base<n,m,T,E>::set_id_()
414  {
415  for (unsigned i = 0; i < n; ++i)
416  for (unsigned j = 0; j < m; ++j)
417  if (i == j)
418  data_[i][j] = literal::one;
419  else
420  data_[i][j] = literal::zero;
421  }
422 
423  template <unsigned n, unsigned m, typename T, typename E>
424  inline
425  mat_base<n,m,T,E>::mat_base(const literal::one_t&)
426  {
427  this->set_id_();
428  }
429 
430  template <unsigned n, unsigned m, typename T, typename E>
431  inline
432  mat_base<n,m,T,E>::mat_base(const literal::identity_t&)
433  {
434  this->set_id_();
435  }
436 
437  template <unsigned n, unsigned m, typename T, typename E>
438  template <typename U>
439  inline
440  mat_base<n,m,T,E>::mat_base(const mat_base<n,m,U>& rhs)
441  {
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) );
445  }
446 
447  template <unsigned n, unsigned m, typename T, typename E>
448  template <typename F>
449  inline
450  mat_base<n,m,T,E>::mat_base(const Function_v2v<F>& f_)
451  {
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) );
457  }
458 
459  template <unsigned n, unsigned m, typename T, typename E>
460  template <typename U>
461  inline
462  mat_base<n,m,T,E>&
463  mat_base<n,m,T,E>::operator=(const mat_base<n,m,U>& rhs)
464  {
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) );
468  return *this;
469  }
470 
471  template <unsigned n, unsigned m, typename T, typename E>
472  inline
473  const T&
474  mat_base<n,m,T,E>::operator()(unsigned i, unsigned j) const
475  {
476  mln_precondition(i < n && j < m);
477  return data_[i][j];
478  }
479 
480  template <unsigned n, unsigned m, typename T, typename E>
481  inline
482  T&
483  mat_base<n,m,T,E>::operator()(unsigned i, unsigned j)
484  {
485  mln_precondition(i < n && j < m);
486  return data_[i][j];
487  }
488 
489  template <unsigned n, unsigned m, typename T, typename E>
490  inline
491  void mat_base<n,m,T,E>::set_all(const T& val)
492  {
493  for (unsigned i = 0; i < n; ++i)
494  for (unsigned j = 0; j < m; ++j)
495  data_[i][j] = val;
496  }
497 
498  template <unsigned n, unsigned m, typename T, typename E>
499  inline
500  unsigned mat_base<n,m,T,E>::size() const
501  {
502  return n * m;
503  }
504 
505  template <unsigned n, unsigned m, typename T, typename E>
506  inline
507  mat_base<m,n,T,E>
508  mat_base<n,m,T,E>::t() const
509  {
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];
514  return tmp;
515  }
516 
517 
518  template <typename T, typename E>
519  inline
520  mat_base<2,2,float>
521  inverse(const mat_base<2,2,T>& m)
522  {
523  float d = det(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 );
527  }
528 
529  template <typename T, typename E>
530  inline
531  mat_base<3,3,float>
532  inverse(const mat_base<3,3,T>& m)
533  {
534  float d = det(m);
535  mln_precondition(d != 0);
536  return make<float>( det(make(m(1,1), m(1,2),
537  m(2,1), m(2,2))),
538 
539  det(make(m(0,2), m(0,1),
540  m(2,2), m(2,1))),
541 
542  det(make(m(0,1), m(0,2),
543  m(1,1), m(1,2))),
544 
545 
546  det(make(m(1,2), m(1,0),
547  m(2,2), m(2,0))),
548 
549  det(make(m(0,0), m(0,2),
550  m(2,0), m(2,2))),
551 
552  det(make(m(0,2), m(0,0),
553  m(1,2), m(1,0))),
554 
555  det(make(m(1,0), m(1,1),
556  m(2,0), m(2,1))),
557 
558  det(make(m(0,1), m(0,0),
559  m(2,1), m(2,0))),
560 
561  det(make(m(0,0), m(0,1),
562  m(1,0), m(1,1)))
563  ) / d;
564  }
565 
566 
567  template <unsigned n, unsigned m, typename T, typename E>
568  inline
569  mat_base<n,m,T,E>
570  mat_base<n,m,T,E>::_1() const
571  {
572  mlc_bool(m == n)::check();
573  return internal::inverse(*this);
574  }
575 
576 
577  // Operators.
578 
579  template <unsigned n, unsigned m, typename T, typename U>
580  inline
581  bool
582  operator==(const mat_base<n,m,T,E>& lhs, const mat_base<n,m,U>& rhs)
583  {
584  for (unsigned i = 0; i < n; ++i)
585  for (unsigned j = 0; j < m; ++j)
586  if (lhs(i, j) != rhs(i, j))
587  return false;
588  return true;
589  }
590 
591  template <unsigned n, unsigned m, typename T, typename U>
592  inline
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)
595  {
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);
600  return tmp;
601  }
602 
603  template <unsigned n, unsigned m, typename T, typename U>
604  inline
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)
607  {
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);
612  return tmp;
613  }
614 
615  template <unsigned n, unsigned m, typename T, typename E>
616  inline
617  mat_base<n,m, mln_trait_op_uminus(T)>
618  operator-(const mat_base<n,m,T,E>& rhs)
619  {
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);
624  return tmp;
625  }
626 
627  // mat_base * mat_base
628 
629  template <unsigned n, unsigned o, typename T,
630  unsigned m, typename U>
631  inline
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)
634  {
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)
638  {
639  tmp(i, j) = literal::zero;
640  for (unsigned k = 0; k < o; ++k)
641  tmp(i, j) += lhs(i, k) * rhs(k, j);
642  }
643  return tmp;
644  }
645 
646  template <unsigned o, typename T,
647  typename U>
648  inline
649  mln_sum_product(T,U)
650  operator*(const mat_base<1,o,T>& lhs, const mat_base<o,1,U>& rhs)
651  {
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);
655  return tmp;
656  }
657 
658  // mat_base * vec
659 
660  template <unsigned n, unsigned m, typename T,
661  typename U>
662  inline
663  vec<n, mln_sum_product(T,U)>
664  operator*(const mat_base<n,m,T,E>& lhs, const vec<m,U>& rhs)
665  {
666  vec<n, mln_sum_product(T,U)> tmp;
667  for (unsigned i = 0; i < n; ++i)
668  {
669  mln_sum_product(T,U) sum(literal::zero);
670  for (unsigned j = 0; j < m; ++j)
671  sum += lhs(i, j) * rhs[j];
672  tmp[i] = sum;
673  }
674  return tmp;
675  }
676 
677  template <unsigned m, typename T,
678  typename U>
679  inline
680  mln_sum_product(T,U) // scalar
681  operator*(const mat_base<1,m,T>& lhs, const vec<m,U>& rhs)
682  {
683  mln_sum_product(T,U) tmp(literal::zero);
684  for (unsigned j = 0; j < m; ++j)
685  tmp += lhs(0, j) * rhs[j];
686  return tmp;
687  }
688 
689  // vec * mat_base
690 
691  template <unsigned m, typename T,
692  typename U>
693  inline
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)
696  {
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);
701  return tmp;
702  }
703 
704  // mat_base * s
705 
706  template <unsigned n, unsigned m, typename T, typename S>
707  inline
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_)
710  {
711  S s = s_.to_equiv();
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;
716  return tmp;
717  }
718 
719  template <unsigned n, unsigned m, typename T, typename S>
720  inline
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_)
723  {
724  S s = s_.to_equiv();
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;
729  return tmp;
730  }
731 
732  // <<
733 
734  template <unsigned n, unsigned m, typename T, typename E>
735  inline
736  std::ostream&
737  operator<<(std::ostream& ostr, const mat_base<n,m,T,E>& v)
738  {
739  for (unsigned i = 0; i < n; ++i)
740  {
741  ostr << '[';
742  for (unsigned j = 0; j < m; ++j)
743  ostr << debug::format_base(v(i, j)) << (j == m - 1 ? "]" : ", ");
744  ostr << std::endl;
745  }
746  return ostr;
747  }
748 
749  } // end of namespace algebra::internal
750 
751  // Trace.
752 
753  template<unsigned n, typename T, typename E>
754  inline
755  mln_sum(T)
756  tr(const internal::mat_base<n,n,T>& m)
757  {
758  mln_sum(T) tr_ = literal::zero;
759  for (unsigned i = 0; i < n; ++i)
760  tr_ += m(i,i);
761  return tr_;
762  }
763 
764 
765  // Determinant.
766 
767  template<typename T, typename E>
768  inline
769  mln_sum_product(T,T)
770  det(const internal::mat_base<2,2,T>& m)
771  {
772  return m(0,0) * m(1,1) - m(0,1) * m(1,0);
773  }
774 
775  template<typename T, typename E>
776  inline
777  mln_sum_product(T,T)
778  det(const internal::mat_base<3,3,T>& m)
779  {
780  return
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);
787  }
788 
789 
790  // vec methods.
791 
792  template <unsigned n, typename T, typename E>
793  inline
794  internal::mat_base<1,n,T>
795  vec<n,T>::t() const
796  {
797  internal::mat_base<1,n,T> tmp;
798  for (unsigned i = 0; i < n; ++i)
799  tmp(0,i) = data_[i];
800  return tmp;
801  }
802 
803 # endif // ! MLN_INCLUDE_ONLY
804 
805  } // end of namespace mln::algebra
806 
807  } // end of namespace mln
808 
809 #endif // ! MLN_ALGEBRA_INTERNAL_MAT_BASE_HH