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_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
00046
00047
00048
00049 namespace mln
00050 {
00051
00052
00053
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 }
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
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
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
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 {
00160 typedef metal::mat<n, n, mln_sum_product(T, U)> ret;
00161 };
00162
00163
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
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 }
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
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
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
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
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
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
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 }
00479
00480 }
00481
00482 # include <mln/make/mat.hh>
00483
00484 #endif // ! MLN_METAL_MAT_HH