• Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Classes
  • Files
  • File List

mat.hh

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

Generated on Tue Oct 4 2011 15:24:03 for Milena (Olena) by  doxygen 1.7.1