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