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

mat.hh

00001 // Copyright (C) 2006, 2007, 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_METAL_MAT_HH
00027 # define MLN_METAL_MAT_HH
00028 
00035 # include <iostream>
00036 
00037 # include <mln/core/concept/object.hh>
00038 # include <mln/core/concept/function.hh>
00039 # include <mln/core/contract.hh>
00040 # include <mln/trait/all.hh>
00041 # include <mln/trait/value_.hh>
00042 # include <mln/metal/vec.hh>
00043 
00044 
00045 // FIXME: Document.
00046 
00047 
00048 
00049 namespace mln
00050 {
00051 
00052 
00053   // Fwd decl.
00054   namespace metal {
00055     template <unsigned n, unsigned m, typename T> class mat;
00056   }
00057 
00058 
00059   namespace trait
00060   {
00061 
00062     template <unsigned n, unsigned m, typename T>
00063     struct value_< metal::mat<n,m,T> >
00064     {
00065       typedef trait::value::nature::matrix nature;
00066       typedef trait::value::kind::data     kind;
00067 
00068       enum {
00069         nbits = n * m * mln_nbits(T),
00070         card  = n * m * mln_card(T)
00071       };
00072       typedef mln_value_quant_from_(card)  quant;
00073 
00074       typedef metal::mat<n, m, mln_sum(T)> sum;
00075     };
00076 
00077   } // end of namespace mln::trait
00078 
00079 
00080 
00081   namespace metal
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       }
00099 
00100       template <typename U>
00101       mat(const mat<n,m,U>& rhs);
00102 
00104       template <typename F>
00105       mat(const Function_v2v<F>& f);
00106 
00107       template <typename U>
00108       mat& operator=(const mat<n,m,U>& rhs);
00109 
00110       const T& operator()(unsigned i, unsigned j) const;
00111 
00112       T& operator()(unsigned i, unsigned j);
00113 
00114       void set_all(const T& val);
00115 
00116       unsigned size() const;
00117 
00118       static mat identity();
00119 
00120     private:
00121       T data_[n][m];
00122     };
00123 
00124   }
00125 
00126 
00127   namespace trait
00128   {
00129 
00130     // Unarys.
00131 
00132     template < template<class> class Name,
00133                unsigned n, unsigned m, typename T >
00134     struct set_precise_unary_< Name, metal::mat<n,m,T> >
00135     {
00136       typedef metal::mat<n, m, mln_trait_unary(Name, T)> ret;
00137     };
00138 
00139     // Default for binarys; works for (+), (-), comparisons, and promote.
00140 
00141     template < template<class, class> class Name,
00142                unsigned n, unsigned m, typename T, typename U>
00143     struct set_precise_binary_< Name, metal::mat<n,m,T>, metal::mat<n,m,U> >
00144     {
00145       typedef metal::mat<n, m, mln_trait_binary(Name, T, U)> ret;
00146     };
00147 
00148     // mat * mat
00149 
00150     template < unsigned n, unsigned o, typename T,
00151                unsigned m, typename U >
00152     struct set_precise_binary_< op::times, metal::mat<n,o,T>, metal::mat<o,m,U> >
00153     {
00154       typedef metal::mat<n, m, mln_sum_product(T, U)> ret;
00155     };
00156 
00157     template < unsigned n, typename T, typename U >
00158     struct set_precise_binary_< op::times, metal::mat<n,n,T>, metal::mat<n,n,U> >
00159     { // Disambiguate between both previous defs.
00160       typedef metal::mat<n, n, mln_sum_product(T, U)> ret;
00161     };
00162 
00163     // mat * vec
00164 
00165     template < unsigned n, unsigned m, typename T,
00166                typename U >
00167     struct set_precise_binary_< op::times, metal::mat<n,m,T>, metal::vec<m,U> >
00168     {
00169       typedef metal::vec<n, mln_sum_product(T, U)> ret;
00170     };
00171 
00172     // mat * s
00173 
00174     template < template<class, class> class Name,
00175                unsigned n, unsigned m, typename T,
00176                typename S >
00177     struct set_precise_binary_< Name, metal::mat<n,m,T>, mln::value::scalar_<S> >
00178     {
00179       typedef metal::mat<n, m, mln_trait_binary(Name, T, S)> ret;
00180     };
00181 
00182     template < template<class, class> class Name,
00183                unsigned n, unsigned m, typename T,
00184                typename S >
00185     struct set_binary_< Name,
00186                         mln::Object, metal::mat<n,m,T>,
00187                         mln::value::Scalar, S >
00188     {
00189       typedef metal::mat<n, m, mln_trait_binary(Name, T, S)> ret;
00190     };
00191 
00192   } // end of namespace mln::trait
00193 
00194 
00195 
00196   namespace metal
00197   {
00198 
00199     // ==
00200 
00201     template <unsigned n, unsigned m, typename T, typename U>
00202     bool
00203     operator==(mat<n,m,T>& lhs, const mat<n,m,U>& rhs);
00204 
00205     // +
00206 
00207     template <unsigned n, unsigned m, typename T, typename U>
00208     mat<n, m, mln_trait_op_plus(T,U)>
00209     operator+(mat<n,m,T>& lhs, const mat<n,m,U>& rhs);
00210 
00211     // -
00212 
00213     template <unsigned n, unsigned m, typename T, typename U>
00214     mat<n, m, mln_trait_op_minus(T,U)>
00215     operator-(const mat<n,m,T>& lhs, const mat<n,m,U>& rhs);
00216 
00217     // - (unary)
00218 
00219     template <unsigned n, unsigned m, typename T>
00220     mat<n, m, mln_trait_op_uminus(T)>
00221     operator-(const mat<n,m,T>& lhs);
00222 
00223     // mat * mat
00224 
00225     template <unsigned n, unsigned o, typename T,
00226               unsigned m, typename U>
00227     mat<n, m, mln_sum_product(T,U)>
00228     operator*(const mat<n,o,T>& lhs, const mat<o,m,U>& rhs);
00229 
00230     // mat * vec
00231 
00232     template <unsigned n, unsigned m, typename T,
00233               typename U>
00234     vec<n, mln_sum_product(T,U)>
00235     operator*(const mat<n,m,T>& lhs, const vec<m,U>& rhs);
00236 
00237     // mat * s
00238 
00239     template <unsigned n, unsigned m, typename T,
00240               typename S>
00241     mat<n, m, mln_trait_op_times(T,S)>
00242     operator*(const mat<n,m,T>& lhs, const value::scalar_<S>& s);
00243 
00244     // mat / s
00245 
00246     template <unsigned n, unsigned m, typename T, typename S>
00247     mat<n, m, mln_trait_op_div(T,S)>
00248     operator/(const mat<n,m,T>& lhs, const value::scalar_<S>& s);
00249 
00250     // <<
00251     
00252     template <unsigned n, unsigned m, typename T>
00253     std::ostream&
00254     operator<<(std::ostream& ostr, const mat<n,m,T>& v);
00255 
00256 
00257 
00258 # ifndef MLN_INCLUDE_ONLY
00259 
00260     template <unsigned n, unsigned m, typename T>
00261     const mat<n,m,T> mat<n,m,T>::Id = mat<n,m,T>::identity();
00262 
00263     template <unsigned n, unsigned m, typename T>
00264     inline
00265     mat<n,m,T> mat<n,m,T>::identity()
00266     {
00267       static mat<n,m,T> id_;
00268       static bool flower = true;
00269       if (flower)
00270         {
00271           for (unsigned i = 0; i < n; ++i)
00272             for (unsigned j = 0; j < m; ++j)
00273               id_(i, j) = (i == j);
00274           flower = false;
00275         }
00276       return id_;
00277     }
00278 
00279     template <unsigned n, unsigned m, typename T>
00280     template <typename U>
00281     inline
00282     mat<n,m,T>::mat(const mat<n,m,U>& rhs)
00283     {
00284       for (unsigned i = 0; i < n; ++i)
00285         for (unsigned j = 0; j < m; ++j)
00286           data_[i][j] = rhs(i, j);
00287     }
00288     
00289     template <unsigned n, unsigned m, typename T>
00290     template <typename F>
00291     inline
00292     mat<n,m,T>::mat(const Function_v2v<F>& f_)
00293     {
00294       mlc_converts_to(mln_result(F), T)::check();
00295       const F& f = exact(f_);
00296       for (unsigned i = 0; i < n; ++i)
00297         for (unsigned j = 0; j < m; ++j)
00298           data_[i][j] = f(i * n + j);
00299     }
00300 
00301     template <unsigned n, unsigned m, typename T>
00302     template <typename U>
00303     inline
00304     mat<n,m,T>&
00305     mat<n,m,T>::operator=(const mat<n,m,U>& rhs)
00306     {
00307       for (unsigned i = 0; i < n; ++i)
00308         for (unsigned j = 0; j < m; ++j)
00309           data_[i][j] = rhs(i, j);
00310       return *this;
00311     }
00312     
00313     template <unsigned n, unsigned m, typename T>
00314     inline
00315     const T&
00316     mat<n,m,T>::operator()(unsigned i, unsigned j) const
00317     {
00318       mln_precondition(i < n && j < m);
00319       return data_[i][j];
00320     }
00321     
00322     template <unsigned n, unsigned m, typename T>
00323     inline
00324     T&
00325     mat<n,m,T>::operator()(unsigned i, unsigned j)
00326     {
00327       mln_precondition(i < n && j < m);
00328       return data_[i][j];
00329     }
00330     
00331     template <unsigned n, unsigned m, typename T>
00332     inline
00333     void mat<n,m,T>::set_all(const T& val)
00334     {
00335       for (unsigned i = 0; i < n; ++i)
00336         for (unsigned j = 0; j < m; ++j)
00337           data_[i][j] = val;
00338     }
00339     
00340     template <unsigned n, unsigned m, typename T>
00341     inline
00342     unsigned mat<n,m,T>::size() const
00343     {
00344       return n * m;
00345     }
00346     
00347 
00348     // Operators.
00349 
00350 
00351     template <unsigned n, unsigned m, typename T, typename U>
00352     inline
00353     bool
00354     operator==(const mat<n,m,T>& lhs, const mat<n,m,U>& rhs)
00355     {
00356       for (unsigned i = 0; i < n; ++i)
00357         for (unsigned j = 0; j < m; ++j)
00358           if (lhs(i, j) != rhs(i, j))
00359             return false;
00360       return true;
00361     }
00362 
00363     template <unsigned n, unsigned m, typename T, typename U>
00364     inline
00365     mat<n, m, mln_trait_op_plus(T,U)>
00366     operator+(const mat<n,m,T>& lhs, const mat<n,m,U>& rhs)
00367     {
00368       mat<n, m, mln_trait_op_plus(T,U)> tmp;
00369       for (unsigned i = 0; i < n; ++i)
00370         for (unsigned j = 0; j < m; ++j)
00371           tmp[i][j] = lhs(i, j) + rhs(i, j);
00372       return tmp;
00373     }
00374 
00375     template <unsigned n, unsigned m, typename T, typename U>
00376     inline
00377     mat<n,m, mln_trait_op_minus(T,U)>
00378     operator-(const mat<n,m,T>& lhs, const mat<n,m,U>& rhs)
00379     {
00380       mat<n,m, mln_trait_op_minus(T,U)> tmp;
00381       for (unsigned i = 0; i < n; ++i)
00382         for (unsigned j = 0; j < m; ++j)
00383           tmp(i, j) = lhs(i, j) - rhs(i, j);
00384       return tmp;
00385     }
00386 
00387     template <unsigned n, unsigned m, typename T>
00388     inline
00389     mat<n,m, mln_trait_op_uminus(T)>
00390     operator-(const mat<n,m,T>& rhs)
00391     {
00392       mat<n,m, mln_trait_op_uminus(T)> tmp;
00393       for (unsigned i = 0; i < n; ++i)
00394         for (unsigned j = 0; i < m; ++i)
00395           tmp(i, j) = - rhs(i, j);
00396       return tmp;
00397     }
00398 
00399     template <unsigned n, unsigned o, typename T,
00400               unsigned m, typename U>
00401     inline
00402     mat<n, m, mln_sum_product(T,U)>
00403     operator*(const mat<n,o,T>& lhs, const mat<o,m,U>& rhs)
00404     {
00405       mat<n,m, mln_sum_product(T,U)> tmp;
00406       for (unsigned i = 0; i < n; ++i)
00407         for (unsigned j = 0; j < m; ++j)
00408           {
00409             tmp(i, j) = literal::zero;
00410             for (unsigned k = 0; k < o; ++k)
00411               tmp(i, j) += lhs(i, k) * rhs(k, j);
00412           }
00413       return tmp;
00414     }
00415 
00416     template <unsigned n, unsigned m, typename T,
00417               typename U>
00418     inline
00419     vec<n, mln_sum_product(T,U)>
00420     operator*(const mat<n,m,T>& lhs, const vec<m,U>& rhs)
00421     {
00422       vec<n, mln_sum_product(T,U)> tmp;
00423       for (unsigned i = 0; i < n; ++i)
00424         {
00425           mln_sum_product(T,U) sum(literal::zero);
00426           for (unsigned j = 0; j < m; ++j)
00427             sum += lhs(i, j) * rhs[j];
00428           tmp[i] = sum;
00429         }
00430       return tmp;
00431     }
00432 
00433     template <unsigned n, unsigned m, typename T, typename S>
00434     inline
00435     mat<n, m, mln_trait_op_times(T,S)>
00436     operator*(const mat<n,m,T>& lhs, const value::scalar_<S>& s_)
00437     {
00438       S s = s_.to_equiv();
00439       mat<n, m, mln_trait_op_times(T,S)> tmp;
00440       for (unsigned i = 0; i < n; ++i)
00441         for (unsigned j = 0; j < m; ++j)
00442           tmp(i, j) = lhs(i, j) * s;
00443       return tmp;
00444     }
00445 
00446     template <unsigned n, unsigned m, typename T, typename S>
00447     inline
00448     mat<n,m, mln_trait_op_div(T,S)>
00449     operator/(const mat<n,m,T>& lhs, const value::scalar_<S>& s_)
00450     {
00451       S s = s_.to_equiv();
00452       mat<n,m, mln_trait_op_times(T,S)> tmp;
00453       for (unsigned i = 0; i < n; ++i)
00454         for (unsigned j = 0; j < m; ++j)
00455           tmp[i][j] = lhs(i, j) / s;
00456       return tmp;
00457     }
00458 
00459     // <<
00460     
00461     template <unsigned n, unsigned m, typename T>
00462     inline
00463     std::ostream&
00464     operator<<(std::ostream& ostr, const mat<n,m,T>& v)
00465     {
00466       for (unsigned i = 0; i < n; ++i)
00467         {
00468           ostr << '[';
00469           for (unsigned j = 0; j < m; ++j)
00470             ostr << debug::format(v(i, j)) << (j == m - 1 ? "]" : ", ");
00471           ostr << std::endl;
00472         }
00473       return ostr;
00474     }
00475 
00476 # endif // ! MLN_INCLUDE_ONLY
00477     
00478   } // end of namespace mln::metal
00479 
00480 } // end of namespace mln
00481 
00482 # include <mln/make/mat.hh>
00483 
00484 #endif // ! MLN_METAL_MAT_HH

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