Milena (Olena)
User documentation 2.0a Id
|
00001 // Copyright (C) 2006, 2008, 2009 EPITA Research and Development Laboratory (LRDE) 00002 // 00003 // This file is part of Olena. 00004 // 00005 // Olena is free software: you can redistribute it and/or modify it under 00006 // the terms of the GNU General Public License as published by the Free 00007 // Software Foundation, version 2 of the License. 00008 // 00009 // Olena is distributed in the hope that it will be useful, 00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00012 // General Public License for more details. 00013 // 00014 // You should have received a copy of the GNU General Public License 00015 // along with Olena. If not, see <http://www.gnu.org/licenses/>. 00016 // 00017 // As a special exception, you may use this file as part of a free 00018 // software project without restriction. Specifically, if other files 00019 // instantiate templates or use macros or inline functions from this 00020 // file, or you compile this file and link it with other files to produce 00021 // an executable, this file does not by itself cause the resulting 00022 // executable to be covered by the GNU General Public License. This 00023 // exception does not however invalidate any other reasons why the 00024 // executable file might be covered by the GNU General Public License. 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 // FIXME: Document. 00045 00046 00047 00048 namespace mln 00049 { 00050 00051 00052 // Forward declaration. 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 } // end of namespace mln::trait 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 } // end of namespace algebra 00150 00151 00152 00153 namespace trait 00154 { 00155 00156 // - mat 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 // mat + mat 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 // mat - mat 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 // mat * mat 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 // mat * vec 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; // a scalar 00217 }; 00218 00219 // vec * mat 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 // mat * s 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 // template < template<class, class> class Name, 00240 // unsigned n, unsigned m, typename T, 00241 // typename S > 00242 // struct set_binary_< Name, 00243 // mln::Object, algebra::mat<n,m,T>, 00244 // mln::value::Scalar, S > 00245 // { 00246 // typedef algebra::mat<n, m, mln_trait_binary(Name, T, S)> ret; 00247 // }; 00248 00249 // mat / s 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 } // end of namespace mln::trait 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 // - mat 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 // mat + mat 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 // mat - mat 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 // mat * mat 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 // mat * vec 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) // scalar 00312 operator*(const mat<1,m,T>& lhs, const vec<m,U>& rhs); 00313 00314 // vec * mat 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 // mat * s 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 // mat / s 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 // Trace. 00342 00343 template<unsigned n, typename T> 00344 mln_sum(T) 00345 tr(const mat<n,n,T>& m); 00346 00347 00348 // Determinant. 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 // vec -> mat 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 // mat -> vec 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 // Id 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 } // end of namespace algebra::inverse 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 // "Make" routines. 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 // Operators. 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 // mat * mat 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 // mat * vec 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) // scalar 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 // vec * mat 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 // mat * s 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 // Trace. 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 // Determinant. 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 // vec methods. 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 } // end of namespace mln::algebra 00869 00870 } // end of namespace mln 00871 00872 # include <mln/make/mat.hh> 00873 00874 #endif // ! MLN_ALGEBRA_MAT_HH