00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #ifndef MLN_ALGEBRA_MAT_HH
00027 # define MLN_ALGEBRA_MAT_HH
00028
00032
00033 # include <iostream>
00034
00035 # include <mln/core/concept/object.hh>
00036 # include <mln/core/concept/function.hh>
00037 # include <mln/core/contract.hh>
00038 # include <mln/trait/all.hh>
00039 # include <mln/trait/value_.hh>
00040 # include <mln/algebra/vec.hh>
00041 # include <mln/literal/identity.hh>
00042
00043
00044
00045
00046
00047
00048 namespace mln
00049 {
00050
00051
00052
00053 namespace algebra {
00054 template <unsigned n, unsigned m, typename T> class mat;
00055 }
00056
00057
00058 namespace trait
00059 {
00060
00061 template <unsigned n, unsigned m, typename T>
00062 struct value_< algebra::mat<n,m,T> >
00063 {
00064 typedef trait::value::nature::matrix nature;
00065 typedef trait::value::kind::data kind;
00066
00067 enum {
00068 nbits = n * m * mln_nbits(T),
00069 card = n * m * mln_card(T)
00070 };
00071 typedef mln_value_quant_from_(card) quant;
00072
00073 typedef algebra::mat<n, m, mln_sum(T)> sum;
00074 };
00075
00076 }
00077
00078
00079
00080 namespace algebra
00081 {
00082
00083
00084 template <unsigned n, unsigned m, typename T>
00085 class mat : public Object< mat<n,m,T> >
00086 {
00087 public:
00088
00089 typedef T coord;
00090 enum { N = n,
00091 M = m,
00092 dim = n * m };
00093
00094 static const mat<n,m,T> Id;
00095
00096 mat();
00097
00098 mat(const literal::zero_t&);
00099 mat(const literal::one_t&);
00100 mat(const literal::identity_t&);
00101
00102 template <typename U>
00103 mat(const mat<n,m,U>& rhs);
00104
00106 template <typename F>
00107 mat(const Function_v2v<F>& f);
00108
00109 template <typename U>
00110 mat& operator=(const mat<n,m,U>& rhs);
00111
00112 const T& operator()(unsigned i, unsigned j) const;
00113
00114 T& operator()(unsigned i, unsigned j);
00115
00116 void set_all(const T& val);
00117
00118 unsigned size() const;
00119
00120 static mat identity();
00121
00123 mat<m,n,T> t() const;
00124
00127 mat<n,m,T> _1() const;
00128
00129 private:
00130
00131 T data_[n][m];
00132
00133 void set_id_();
00134 };
00135
00136
00137 template <typename T>
00138 mat<2,2,T>
00139 make(const T& t00, const T& t01,
00140 const T& t10, const T& t11);
00141
00142 template <typename T>
00143 mat<3,3,T>
00144 make(const T& t00, const T& t01, const T& t02,
00145 const T& t10, const T& t11, const T& t12,
00146 const T& t20, const T& t21, const T& t22);
00147
00148
00149 }
00150
00151
00152
00153 namespace trait
00154 {
00155
00156
00157
00158 template < unsigned n, unsigned m, typename T >
00159 struct set_precise_unary_< op::uminus,
00160 algebra::mat<n,m,T> >
00161 {
00162 typedef algebra::mat<n, m, mln_trait_op_uminus(T)> ret;
00163 };
00164
00165
00166
00167 template < unsigned n, unsigned m, typename T, typename U >
00168 struct set_precise_binary_< op::plus,
00169 algebra::mat<n,m,T>, algebra::mat<n,m,U> >
00170 {
00171 typedef algebra::mat<n, m, mln_trait_op_plus(T, U)> ret;
00172 };
00173
00174
00175
00176 template < unsigned n, unsigned m, typename T, typename U >
00177 struct set_precise_binary_< op::minus,
00178 algebra::mat<n,m,T>, algebra::mat<n,m,U> >
00179 {
00180 typedef algebra::mat<n, m, mln_trait_op_minus(T, U)> ret;
00181 };
00182
00183
00184
00185 template < unsigned n, unsigned o, typename T,
00186 unsigned m, typename U >
00187 struct set_precise_binary_< op::times,
00188 algebra::mat<n,o,T>, algebra::mat<o,m,U> >
00189 {
00190 typedef algebra::mat<n, m, mln_sum_product(T, U)> ret;
00191 };
00192
00193 template < unsigned o, typename T,
00194 typename U >
00195 struct set_precise_binary_< op::times,
00196 algebra::mat<1,o,T>, algebra::mat<o,1,U> >
00197 {
00198 typedef mln_sum_product(T, U) ret;
00199 };
00200
00201
00202
00203 template < unsigned n, unsigned m, typename T,
00204 typename U >
00205 struct set_precise_binary_< op::times,
00206 algebra::mat<n,m,T>, algebra::vec<m,U> >
00207 {
00208 typedef algebra::vec<n, mln_sum_product(T, U)> ret;
00209 };
00210
00211 template < unsigned m, typename T,
00212 typename U >
00213 struct set_precise_binary_< op::times,
00214 algebra::mat<1,m,T>, algebra::vec<m,U> >
00215 {
00216 typedef mln_sum_product(T, U) ret;
00217 };
00218
00219
00220
00221 template < unsigned m, typename T,
00222 typename U >
00223 struct set_precise_binary_< op::times,
00224 algebra::vec<m,T>, algebra::mat<1,m,U> >
00225 {
00226 typedef algebra::mat<m, m, mln_trait_op_times(T, U)> ret;
00227 };
00228
00229
00230
00231 template < unsigned n, unsigned m, typename T,
00232 typename S >
00233 struct set_precise_binary_< op::times,
00234 algebra::mat<n,m,T>, mln::value::scalar_<S> >
00235 {
00236 typedef algebra::mat<n, m, mln_trait_op_times(T, S)> ret;
00237 };
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251 template < unsigned n, unsigned m, typename T,
00252 typename S >
00253 struct set_precise_binary_< op::div,
00254 algebra::mat<n,m,T>, mln::value::scalar_<S> >
00255 {
00256 typedef algebra::mat<n, m, mln_trait_op_div(T, S)> ret;
00257 };
00258
00259 }
00260
00261
00262
00263 namespace algebra
00264 {
00265
00266
00267
00268 template <unsigned n, unsigned m, typename T, typename U>
00269 bool
00270 operator==(const mat<n,m,T>& lhs, const mat<n,m,U>& rhs);
00271
00272
00273
00274 template <unsigned n, unsigned m, typename T>
00275 mat<n, m, mln_trait_op_uminus(T)>
00276 operator-(const mat<n,m,T>& lhs);
00277
00278
00279
00280 template <unsigned n, unsigned m, typename T, typename U>
00281 mat<n, m, mln_trait_op_plus(T,U)>
00282 operator+(const mat<n,m,T>& lhs, const mat<n,m,U>& rhs);
00283
00284
00285
00286 template <unsigned n, unsigned m, typename T, typename U>
00287 mat<n, m, mln_trait_op_minus(T,U)>
00288 operator-(const mat<n,m,T>& lhs, const mat<n,m,U>& rhs);
00289
00290
00291
00292 template <unsigned n, unsigned o, typename T,
00293 unsigned m, typename U>
00294 mat<n, m, mln_sum_product(T,U)>
00295 operator*(const mat<n,o,T>& lhs, const mat<o,m,U>& rhs);
00296
00297 template <unsigned o, typename T,
00298 typename U>
00299 mln_sum_product(T,U)
00300 operator*(const mat<1,o,T>& lhs, const mat<o,1,U>& rhs);
00301
00302
00303
00304 template <unsigned n, unsigned m, typename T,
00305 typename U>
00306 vec<n, mln_sum_product(T,U)>
00307 operator*(const mat<n,m,T>& lhs, const vec<m,U>& rhs);
00308
00309 template <unsigned m, typename T,
00310 typename U>
00311 mln_sum_product(T,U)
00312 operator*(const mat<1,m,T>& lhs, const vec<m,U>& rhs);
00313
00314
00315
00316 template <unsigned m, typename T, typename U>
00317 mat<m, m, mln_trait_op_times(T,U)>
00318 operator*(const vec<m,T>& lhs, const mat<1,m,U>& rhs);
00319
00320
00321
00322 template <unsigned n, unsigned m, typename T,
00323 typename S>
00324 mat<n, m, mln_trait_op_times(T,S)>
00325 operator*(const mat<n,m,T>& lhs, const value::scalar_<S>& s);
00326
00327
00328
00329 template <unsigned n, unsigned m, typename T, typename S>
00330 mat<n, m, mln_trait_op_div(T,S)>
00331 operator/(const mat<n,m,T>& lhs, const value::scalar_<S>& s);
00332
00333
00334
00335 template <unsigned n, unsigned m, typename T>
00336 std::ostream&
00337 operator<<(std::ostream& ostr, const mat<n,m,T>& v);
00338
00339
00340
00341
00342
00343 template<unsigned n, typename T>
00344 mln_sum(T)
00345 tr(const mat<n,n,T>& m);
00346
00347
00348
00349
00350 template<typename T>
00351 mln_sum_product(T,T)
00352 det(const mat<2,2,T>& m);
00353
00354 template<typename T>
00355 mln_sum_product(T,T)
00356 det(const mat<3,3,T>& m);
00357
00358
00359
00360 # ifndef MLN_INCLUDE_ONLY
00361
00362
00363
00364
00365 template <unsigned n, typename T>
00366 template <typename U>
00367 inline
00368 vec<n,T>::operator mat<n,1,U>() const
00369 {
00370 mlc_converts_to(T, U)::check();
00371 mat<n,1,U> tmp;
00372 for (unsigned i = 0; i < n; ++i)
00373 tmp(i, 0) = data_[i];
00374 return tmp;
00375 }
00376
00377
00378
00379
00380 template <unsigned n, typename T>
00381 template <typename U>
00382 inline
00383 vec<n,T>::vec(const mat<n, 1, U>& rhs)
00384 {
00385 mlc_converts_to(T, U)::check();
00386 for (unsigned i = 0; i < n; ++i)
00387 data_[i] = rhs(i, 0);
00388 }
00389
00390 template <unsigned n, typename T>
00391 template <typename U>
00392 inline
00393 vec<n,T>&
00394 vec<n,T>::operator=(const mat<n, 1, U>& rhs)
00395 {
00396 mlc_converts_to(T, U)::check();
00397 for (unsigned i = 0; i < n; ++i)
00398 data_[i] = rhs(i, 0);
00399 return *this;
00400 }
00401
00402
00403
00404
00405
00406 template <unsigned n, unsigned m, typename T>
00407 const mat<n,m,T>
00408 mat<n,m,T>::Id = mat<n,m,T>::identity();
00409
00410 template <unsigned n, unsigned m, typename T>
00411 inline
00412 mat<n,m,T>
00413 mat<n,m,T>::identity()
00414 {
00415 static mat<n,m,T> id_;
00416 static bool flower = true;
00417 if (flower)
00418 {
00419 for (unsigned i = 0; i < n; ++i)
00420 for (unsigned j = 0; j < m; ++j)
00421 id_(i, j) = (i == j);
00422 flower = false;
00423 }
00424 return id_;
00425 }
00426
00427 template <unsigned n, unsigned m, typename T>
00428 inline
00429 mat<n,m,T>::mat()
00430 {
00431 }
00432
00433 template <unsigned n, unsigned m, typename T>
00434 inline
00435 mat<n,m,T>::mat(const literal::zero_t&)
00436 {
00437 this->set_all(0);
00438 }
00439
00440 template <unsigned n, unsigned m, typename T>
00441 inline
00442 void
00443 mat<n,m,T>::set_id_()
00444 {
00445 for (unsigned i = 0; i < n; ++i)
00446 for (unsigned j = 0; j < m; ++j)
00447 if (i == j)
00448 data_[i][j] = literal::one;
00449 else
00450 data_[i][j] = literal::zero;
00451 }
00452
00453 template <unsigned n, unsigned m, typename T>
00454 inline
00455 mat<n,m,T>::mat(const literal::one_t&)
00456 {
00457 this->set_id_();
00458 }
00459
00460 template <unsigned n, unsigned m, typename T>
00461 inline
00462 mat<n,m,T>::mat(const literal::identity_t&)
00463 {
00464 this->set_id_();
00465 }
00466
00467 template <unsigned n, unsigned m, typename T>
00468 template <typename U>
00469 inline
00470 mat<n,m,T>::mat(const mat<n,m,U>& rhs)
00471 {
00472 for (unsigned i = 0; i < n; ++i)
00473 for (unsigned j = 0; j < m; ++j)
00474 data_[i][j] = static_cast<T>( rhs(i, j) );
00475 }
00476
00477 template <unsigned n, unsigned m, typename T>
00478 template <typename F>
00479 inline
00480 mat<n,m,T>::mat(const Function_v2v<F>& f_)
00481 {
00482 mlc_converts_to(mln_result(F), T)::check();
00483 const F& f = exact(f_);
00484 for (unsigned i = 0; i < n; ++i)
00485 for (unsigned j = 0; j < m; ++j)
00486 data_[i][j] = static_cast<T>( f(i * n + j) );
00487 }
00488
00489 template <unsigned n, unsigned m, typename T>
00490 template <typename U>
00491 inline
00492 mat<n,m,T>&
00493 mat<n,m,T>::operator=(const mat<n,m,U>& rhs)
00494 {
00495 for (unsigned i = 0; i < n; ++i)
00496 for (unsigned j = 0; j < m; ++j)
00497 data_[i][j] = static_cast<T>( rhs(i, j) );
00498 return *this;
00499 }
00500
00501 template <unsigned n, unsigned m, typename T>
00502 inline
00503 const T&
00504 mat<n,m,T>::operator()(unsigned i, unsigned j) const
00505 {
00506 mln_precondition(i < n && j < m);
00507 return data_[i][j];
00508 }
00509
00510 template <unsigned n, unsigned m, typename T>
00511 inline
00512 T&
00513 mat<n,m,T>::operator()(unsigned i, unsigned j)
00514 {
00515 mln_precondition(i < n && j < m);
00516 return data_[i][j];
00517 }
00518
00519 template <unsigned n, unsigned m, typename T>
00520 inline
00521 void mat<n,m,T>::set_all(const T& val)
00522 {
00523 for (unsigned i = 0; i < n; ++i)
00524 for (unsigned j = 0; j < m; ++j)
00525 data_[i][j] = val;
00526 }
00527
00528 template <unsigned n, unsigned m, typename T>
00529 inline
00530 unsigned mat<n,m,T>::size() const
00531 {
00532 return n * m;
00533 }
00534
00535 template <unsigned n, unsigned m, typename T>
00536 inline
00537 mat<m,n,T>
00538 mat<n,m,T>::t() const
00539 {
00540 mat<m,n,T> tmp;
00541 for (unsigned i = 0; i < n; ++i)
00542 for (unsigned j = 0; j < m; ++j)
00543 tmp(j,i) = data_[i][j];
00544 return tmp;
00545 }
00546
00547
00548 namespace internal
00549 {
00550
00551 template <typename T>
00552 inline
00553 mat<2,2,float>
00554 inverse(const mat<2,2,T>& m)
00555 {
00556 float d = det(m);
00557 mln_precondition(d != 0);
00558 return make<float>( + m(1,1) / d, - m(0,1) / d,
00559 - m(1,0) / d, + m(0,0) / d );
00560 }
00561
00562 template <typename T>
00563 inline
00564 mat<3,3,float>
00565 inverse(const mat<3,3,T>& m)
00566 {
00567 float d = det(m);
00568 mln_precondition(d != 0);
00569 return make<float>( det(make(m(1,1), m(1,2),
00570 m(2,1), m(2,2))),
00571
00572 det(make(m(0,2), m(0,1),
00573 m(2,2), m(2,1))),
00574
00575 det(make(m(0,1), m(0,2),
00576 m(1,1), m(1,2))),
00577
00578
00579 det(make(m(1,2), m(1,0),
00580 m(2,2), m(2,0))),
00581
00582 det(make(m(0,0), m(0,2),
00583 m(2,0), m(2,2))),
00584
00585 det(make(m(0,2), m(0,0),
00586 m(1,2), m(1,0))),
00587
00588 det(make(m(1,0), m(1,1),
00589 m(2,0), m(2,1))),
00590
00591 det(make(m(0,1), m(0,0),
00592 m(2,1), m(2,0))),
00593
00594 det(make(m(0,0), m(0,1),
00595 m(1,0), m(1,1)))
00596 ) / d;
00597 }
00598
00599 }
00600
00601 template <unsigned n, unsigned m, typename T>
00602 inline
00603 mat<n,m,T>
00604 mat<n,m,T>::_1() const
00605 {
00606 mlc_bool(m == n)::check();
00607 return internal::inverse(*this);
00608 }
00609
00610
00611
00612
00613 template <typename T>
00614 inline
00615 mat<2,2,T>
00616 make(const T& t00, const T& t01,
00617 const T& t10, const T& t11)
00618 {
00619 mat<2,2,T> tmp;
00620 tmp(0, 0) = t00; tmp(0, 1) = t01;
00621 tmp(1, 0) = t10; tmp(1, 1) = t11;
00622 return tmp;
00623 }
00624
00625 template <typename T>
00626 inline
00627 mat<3,3,T>
00628 make(const T& t00, const T& t01, const T& t02,
00629 const T& t10, const T& t11, const T& t12,
00630 const T& t20, const T& t21, const T& t22)
00631 {
00632 mat<3,3,T> tmp;
00633 tmp(0, 0) = t00; tmp(0, 1) = t01; tmp(0, 2) = t02;
00634 tmp(1, 0) = t10; tmp(1, 1) = t11; tmp(1, 2) = t12;
00635 tmp(2, 0) = t20; tmp(2, 1) = t21; tmp(2, 2) = t22;
00636 return tmp;
00637 }
00638
00639
00640
00641
00642
00643 template <unsigned n, unsigned m, typename T, typename U>
00644 inline
00645 bool
00646 operator==(const mat<n,m,T>& lhs, const mat<n,m,U>& rhs)
00647 {
00648 for (unsigned i = 0; i < n; ++i)
00649 for (unsigned j = 0; j < m; ++j)
00650 if (lhs(i, j) != rhs(i, j))
00651 return false;
00652 return true;
00653 }
00654
00655 template <unsigned n, unsigned m, typename T, typename U>
00656 inline
00657 mat<n, m, mln_trait_op_plus(T,U)>
00658 operator+(const mat<n,m,T>& lhs, const mat<n,m,U>& rhs)
00659 {
00660 mat<n, m, mln_trait_op_plus(T,U)> tmp;
00661 for (unsigned i = 0; i < n; ++i)
00662 for (unsigned j = 0; j < m; ++j)
00663 tmp(i, j) = lhs(i, j) + rhs(i, j);
00664 return tmp;
00665 }
00666
00667 template <unsigned n, unsigned m, typename T, typename U>
00668 inline
00669 mat<n,m, mln_trait_op_minus(T,U)>
00670 operator-(const mat<n,m,T>& lhs, const mat<n,m,U>& rhs)
00671 {
00672 mat<n,m, mln_trait_op_minus(T,U)> tmp;
00673 for (unsigned i = 0; i < n; ++i)
00674 for (unsigned j = 0; j < m; ++j)
00675 tmp(i, j) = lhs(i, j) - rhs(i, j);
00676 return tmp;
00677 }
00678
00679 template <unsigned n, unsigned m, typename T>
00680 inline
00681 mat<n,m, mln_trait_op_uminus(T)>
00682 operator-(const mat<n,m,T>& rhs)
00683 {
00684 mat<n,m, mln_trait_op_uminus(T)> tmp;
00685 for (unsigned i = 0; i < n; ++i)
00686 for (unsigned j = 0; i < m; ++i)
00687 tmp(i, j) = - rhs(i, j);
00688 return tmp;
00689 }
00690
00691
00692
00693 template <unsigned n, unsigned o, typename T,
00694 unsigned m, typename U>
00695 inline
00696 mat<n, m, mln_sum_product(T,U)>
00697 operator*(const mat<n,o,T>& lhs, const mat<o,m,U>& rhs)
00698 {
00699 mat<n,m, mln_sum_product(T,U)> tmp;
00700 for (unsigned i = 0; i < n; ++i)
00701 for (unsigned j = 0; j < m; ++j)
00702 {
00703 tmp(i, j) = literal::zero;
00704 for (unsigned k = 0; k < o; ++k)
00705 tmp(i, j) += lhs(i, k) * rhs(k, j);
00706 }
00707 return tmp;
00708 }
00709
00710 template <unsigned o, typename T,
00711 typename U>
00712 inline
00713 mln_sum_product(T,U)
00714 operator*(const mat<1,o,T>& lhs, const mat<o,1,U>& rhs)
00715 {
00716 mln_sum_product(T,U) tmp(literal::zero);
00717 for (unsigned k = 0; k < o; ++k)
00718 tmp += lhs(0, k) * rhs(k, 0);
00719 return tmp;
00720 }
00721
00722
00723
00724 template <unsigned n, unsigned m, typename T,
00725 typename U>
00726 inline
00727 vec<n, mln_sum_product(T,U)>
00728 operator*(const mat<n,m,T>& lhs, const vec<m,U>& rhs)
00729 {
00730 vec<n, mln_sum_product(T,U)> tmp;
00731 for (unsigned i = 0; i < n; ++i)
00732 {
00733 mln_sum_product(T,U) sum(literal::zero);
00734 for (unsigned j = 0; j < m; ++j)
00735 sum += lhs(i, j) * rhs[j];
00736 tmp[i] = sum;
00737 }
00738 return tmp;
00739 }
00740
00741 template <unsigned m, typename T,
00742 typename U>
00743 inline
00744 mln_sum_product(T,U)
00745 operator*(const mat<1,m,T>& lhs, const vec<m,U>& rhs)
00746 {
00747 mln_sum_product(T,U) tmp(literal::zero);
00748 for (unsigned j = 0; j < m; ++j)
00749 tmp += lhs(0, j) * rhs[j];
00750 return tmp;
00751 }
00752
00753
00754
00755 template <unsigned m, typename T,
00756 typename U>
00757 inline
00758 mat<m, m, mln_trait_op_times(T,U)>
00759 operator*(const vec<m,T>& lhs, const mat<1,m,U>& rhs)
00760 {
00761 mat<m, m, mln_trait_op_times(T,U)> tmp;
00762 for (unsigned i = 0; i < m; ++i)
00763 for (unsigned j = 0; j < m; ++j)
00764 tmp(i, j) = lhs[i] * rhs(0, j);
00765 return tmp;
00766 }
00767
00768
00769
00770 template <unsigned n, unsigned m, typename T, typename S>
00771 inline
00772 mat<n, m, mln_trait_op_times(T,S)>
00773 operator*(const mat<n,m,T>& lhs, const value::scalar_<S>& s_)
00774 {
00775 S s = s_.to_equiv();
00776 mat<n, m, mln_trait_op_times(T,S)> tmp;
00777 for (unsigned i = 0; i < n; ++i)
00778 for (unsigned j = 0; j < m; ++j)
00779 tmp(i, j) = lhs(i, j) * s;
00780 return tmp;
00781 }
00782
00783 template <unsigned n, unsigned m, typename T, typename S>
00784 inline
00785 mat<n,m, mln_trait_op_div(T,S)>
00786 operator/(const mat<n,m,T>& lhs, const value::scalar_<S>& s_)
00787 {
00788 S s = s_.to_equiv();
00789 mat<n,m, mln_trait_op_times(T,S)> tmp;
00790 for (unsigned i = 0; i < n; ++i)
00791 for (unsigned j = 0; j < m; ++j)
00792 tmp(i,j) = lhs(i, j) / s;
00793 return tmp;
00794 }
00795
00796
00797
00798 template <unsigned n, unsigned m, typename T>
00799 inline
00800 std::ostream&
00801 operator<<(std::ostream& ostr, const mat<n,m,T>& v)
00802 {
00803 for (unsigned i = 0; i < n; ++i)
00804 {
00805 ostr << '[';
00806 for (unsigned j = 0; j < m; ++j)
00807 ostr << debug::format(v(i, j)) << (j == m - 1 ? "]" : ", ");
00808 ostr << std::endl;
00809 }
00810 return ostr;
00811 }
00812
00813
00814
00815
00816 template<unsigned n, typename T>
00817 inline
00818 mln_sum(T)
00819 tr(const mat<n,n,T>& m)
00820 {
00821 mln_sum(T) tr_ = literal::zero;
00822 for (unsigned i = 0; i < n; ++i)
00823 tr_ += m(i,i);
00824 return tr_;
00825 }
00826
00827
00828
00829
00830 template<typename T>
00831 inline
00832 mln_sum_product(T,T)
00833 det(const mat<2,2,T>& m)
00834 {
00835 return m(0,0) * m(1,1) - m(0,1) * m(1,0);
00836 }
00837
00838 template<typename T>
00839 inline
00840 mln_sum_product(T,T)
00841 det(const mat<3,3,T>& m)
00842 {
00843 return
00844 + m(0,0) * m(1,1) * m(2,2)
00845 - m(0,0) * m(1,2) * m(2,1)
00846 - m(0,1) * m(1,0) * m(2,2)
00847 + m(0,1) * m(1,2) * m(2,0)
00848 + m(0,2) * m(1,0) * m(2,1)
00849 - m(0,2) * m(1,1) * m(2,0);
00850 }
00851
00852
00853
00854
00855 template <unsigned n, typename T>
00856 inline
00857 mat<1,n,T>
00858 vec<n,T>::t() const
00859 {
00860 mat<1,n,T> tmp;
00861 for (unsigned i = 0; i < n; ++i)
00862 tmp(0,i) = data_[i];
00863 return tmp;
00864 }
00865
00866 # endif // ! MLN_INCLUDE_ONLY
00867
00868 }
00869
00870 }
00871
00872 # include <mln/make/mat.hh>
00873
00874 #endif // ! MLN_ALGEBRA_MAT_HH