ivl 679
ivl/details/array_2d/functions/array_2d_functions.hpp
00001 /* This file is part of the ivl C++ library <http://image.ntua.gr/ivl>.
00002    A C++ template library extending syntax towards mathematical notation.
00003 
00004    Copyright (C) 2012 Yannis Avrithis <iavr@image.ntua.gr>
00005    Copyright (C) 2012 Kimon Kontosis <kimonas@image.ntua.gr>
00006 
00007    ivl is free software; you can redistribute it and/or modify
00008    it under the terms of the GNU Lesser General Public License 
00009    version 3 as published by the Free Software Foundation.
00010 
00011    Alternatively, you can redistribute it and/or modify it under the terms 
00012    of the GNU General Public License version 2 as published by the Free 
00013    Software Foundation.
00014 
00015    ivl is distributed in the hope that it will be useful,
00016    but WITHOUT ANY WARRANTY; without even the implied warranty of
00017    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
00018    See the GNU General Public License for more details.
00019 
00020    You should have received a copy of the GNU General Public License 
00021    and a copy of the GNU Lesser General Public License along 
00022    with ivl. If not, see <http://www.gnu.org/licenses/>. */
00023 
00024 #ifndef IVL_ARRAY_2D_DETAILS_ARRAY_2D_FUNCTIONS_HPP
00025 #define IVL_ARRAY_2D_DETAILS_ARRAY_2D_FUNCTIONS_HPP
00026 
00027 
00028 namespace ivl {
00029 
00030 
00031 // TODO: this is not good :p
00032 // TODO: put this somewhere!
00033 
00034 // ----------
00035 // concat
00036 
00037 template<class T, class T2, class S2>
00038 ivl::concat<
00039         //TODO: used to need const. investigate
00040         const typename core_details::matrix_based<T>::base_class, 
00041         const array_2d<T2, S2>, 1> operator ,(
00042                 const core_details::matrix_based<T>& l, const array_2d<T2, S2>& r)
00043 {
00044         const array_2d<T2, S2>* ptr = &r;
00045         return internal::reftpl(l.base(), ptr);
00046 }
00047 
00048 /*
00049 todo: GREAT PROBLEMS
00050 template<class T, class T2, class S2>
00051 ivl::concat<
00052         //TODO: used to need const. investigate
00053         const typename core_details::matrix_based<T>::base_class, 
00054         const array_2d<T2, S2>, 0> operator ,(
00055                 const core_details::matrix_based<T>& l, const array_2d<T2, S2>* r)
00056 {
00057         return internal::reftpl(l.base(), r);
00058 }
00059 */
00060 
00061 template<class T, class T2, class S2>
00062 inline
00063 array_nd<typename core_details::matrix_based<T>::base_class::elem_type, 
00064         data::catarray<
00065                 const typename core_details::matrix_based<T>::base_class::base_class,
00066                 const array_nd<T2, S2>, 1> > operator ,(
00067                 const core_details::matrix_based<T>& l, const array_2d<T2, S2>* r)
00068 {
00069         array_nd<typename core_details::matrix_based<T>::base_class::elem_type, 
00070         data::catarray<
00071                 const typename core_details::matrix_based<T>::base_class::base_class,
00072                 const array_nd<T2, S2>, 1> > rv;
00073         const array_2d<T2, S2>* ptr = &r;
00074         rv.init(l, r);
00075         return rv;
00076 }
00077 
00078 // ---------
00079 
00080 template<class T, class T2, class S2>
00081 ret<array_2d<typename T::elem_type> > operator *(const core_details::matrix_based<T>& l,
00082                                                                                         const array_2d<T2, S2>& r)
00083 {
00084         return mtimes(l.t, r);
00085 }
00086 
00087 template<class T, class K>
00088 core_details::matrix_based<array_2d<typename T::elem_type> > operator *(
00089         const core_details::matrix_based<T>& l, const core_details::matrix_based<K>& r)
00090 {
00091         return mtimes(l.t, r.t);
00092 }
00093 
00094 
00096 template <class T, class D>
00097 inline
00098 typename array_2d<T, D>::create_similar flipud(const array_2d<T, D>& a)
00099 { return flipdim(a, 0); }
00100 
00102 template <class T, class D>
00103 inline
00104 typename array_2d<T, D>::create_similar fliplr(const array_2d<T, D>& a)
00105 { return flipdim(a, 1); }
00106 
00108 template <class T, class S>
00109 inline
00110 array<T> diag(const array_2d<T, S>& a, int k = 0)
00111 {
00112         CHECK(size_t(std::abs(k)) <= std::min(a.rows(), a.columns()), erange);
00113 
00114         size_t end = std::min(a.rows(), a.columns()) - std::abs(k);
00115         size_t step = a.rows() + 1;
00116         size_t j = (k < 0 ? -k * a.rows() : k);
00117         array<T> c(end);
00118 
00119         for (size_t i = 0; i < end; i++, j+=step)
00120                 c[i] = a[j];
00121         return c;
00122 }
00123 
00125 template <class T, class S>
00126 inline
00127 array_2d<T> diag(const array<T, S>& a, int k = 0)
00128 {
00129         size_t n = a.length() + std::abs(k);
00130         array_2d<T> r(n, n);
00131         size_t i;
00132         size_t len = n * n;
00133         for(i = 0; i < len; i++) r[i] = 0;
00134 
00135         size_t pos = 0;
00136         if(k <= 0) pos -= k; else pos += n * k;
00137 
00138         for(i = 0; i < n; i++) {
00139                 r[pos] = a[i];
00140                 pos += n + 1;
00141         }
00142 
00143         return r;
00144 }
00145 
00147 template <class T>
00148 inline
00149 array_2d<T> eye(size_t s, const T& zero = 0, const T& one = 1)
00150 {
00151         array_2d<T> c(s,s);
00152 
00153         for (size_t i = 0; i < s; i++)
00154                 for (size_t j = 0; j < s; j++)
00155                         c(i, j) = (i == j) ? one : zero;
00156 
00157         return c;
00158 }
00159 
00161 template <class T, class D>
00162 inline
00163 array_2d<T> eye(const array<size_t, D>& indx,
00164                                 const T& zero = 0, const T& one = 1)
00165 {
00166         CHECK(indx.length() == 2, eshape);
00167 
00168         size_t rows = indx[0];
00169         size_t cols = indx[1];
00170         array_2d<T> c(rows, cols);
00171 
00172         for (size_t i = 0; i < rows; i++)
00173                 for (size_t j = 0; j < cols; j++)
00174                         c(i, j) = (i == j) ? one : zero;
00175 
00176         return c;
00177 }
00178 
00180 template <class T, class S>
00181 inline
00182 typename
00183 array_2d<T, S>::create_similar tril(const array_2d<T, S>& a, int k = 0)
00184 {
00185         typename array_2d<T, S>::create_similar c(a.size());
00186 
00187         for (size_t i = 0; i < a.columns(); i++)
00188                 for (size_t j = 0; j < a.rows(); j++)
00189                         c[i * a.rows() + j] = ((int)j < (int)(i - k) ?
00190                         0 : a[i * a.rows() + j]);
00191         return c;
00192 }
00193 
00195 template <class T, class S>
00196 inline
00197 typename
00198 array_2d<T, S>::create_similar triu(const array_2d<T, S>& a, int k = 0)
00199 {
00200         typename array_2d<T, S>::create_similar c(a.size());
00201 
00202         for (size_t i = 0; i < a.columns(); i++)
00203                 for (size_t j = 0; j < a.rows(); j++)
00204                         c[i * a.rows() + j] = ((int)j > (int)(i - k) ?
00205                         0 : a[i * a.rows() + j]);
00206         return c;
00207 }
00208 
00210 template <class T, class S>
00211 inline
00212 typename
00213 array_2d<T, S>::create_new rot90(const array_2d<T, S>& a, int k = 1)
00214 {
00215         if (k < 0) k = 4 - (-k % 4);
00216         else k = k % 4;
00217         typename array_2d<T, S>::create_new c(a);
00218 
00219         for (size_t repeat = 0; (int)repeat < k; repeat++)
00220                 c = transpose(fliplr(c));
00221         return c;
00222 }
00223 
00224 
00226 template <class T, class S>
00227 inline
00228 typename
00229 array_2d<T, S>::create_new transpose(const array_2d<T, S>& a)
00230 {
00231         typename array_2d<T, S>::create_new c(a.columns(), a.rows());
00232 
00233         for (size_t i = 0; i < c.columns(); i++)
00234                 for (size_t j = 0; j < c.rows(); j++)
00235                 c[i * c.rows() + j] = a[j * a.rows() + i];
00236         return c;
00237 }
00238 
00239 //todo place this somewhere
00240 template<class T, class S>
00241 array_2d<T, normal_2d> array_common_base<array_2d<T, S> >::operator()(
00242         const core_details::transpose_arg& c) const
00243 {
00244         return transpose(this->to_current());
00245 }
00246 
00247 //todo: consistency!
00248 template <class T>
00249 inline
00250 array_2d<T> ones(size_t r, size_t c)
00251 {
00252         return array_2d<T>(r, c, T(1));
00253 }
00254 
00256 template <class T, class S, class D>
00257 inline
00258 typename
00259 array_2d<T, S>::create_new horzcat(
00260         const array_2d<T, S>& a, const array_2d<T, D>& b)
00261 {
00262         return cat<T>(1, a, b);
00263 }
00264 
00266 template <class T, class S, class D>
00267 inline
00268 typename
00269 array_2d<T, S>::create_new vertcat(
00270         const array_2d<T, S>& a, const array_2d<T, D>& b)
00271 {
00272         return cat<T>(0, a, b);
00273 }
00274 
00275 template <class T>
00276 inline
00277 array_2d<T> inf(const size_t m, const size_t n)
00278 {
00279         return array_2d<T>(m, n, std::numeric_limits<T>::infinity());
00280 }
00281 
00282 template <class T>
00283 inline
00284 array_2d<T> inf(const size_t m)
00285 {
00286         return array_2d<T>(m, m, std::numeric_limits<T>::infinity());
00287 }
00288 
00290 template <class T> inline
00291 array<array<T> > unwrap(const array_2d<T>& a)
00292 {
00293         array<array<T> > c(a.rows());
00294 
00295         for(size_t i = 0; i < a.rows(); i++)
00296                 c[i] = a(i, all());
00297 
00298         return c;
00299 }
00300 
00301 
00303 template <class T>
00304 inline
00305 array_2d<T> wrap(const array<array<T> > a)
00306 {
00307         array_2d<T> c(a.size(), a[0].size());
00308 
00309         for(size_t i = 0; i < a.size(); i++)
00310                 c(i, all()) = a[i];
00311 
00312         return c;
00313 }
00314 
00316 template<class T, class S, class D>
00317 inline
00318 typename ivl::array_2d<T, S>::create_new
00319         mtimes(const ivl::array_2d<T, S> &x, const ivl::array_2d<T, D> &y)
00320 {
00321         ivl::size_array xsize = x.size(); // get size of x
00322         ivl::size_array ysize = y.size(); // get size of y
00323 
00324         CHECK(xsize[1] == ysize[0], eshape);
00325 
00326         ivl::array_2d<T> m(xsize[0], ysize[1]);
00327         for(size_t row = 0;row < xsize[0]; row++)
00328                 for(size_t col = 0;col < ysize[1]; col++)
00329                 {
00330                         m(row, col)=0;
00331                         for(size_t i=0;i < xsize[1]; i++)
00332                         m(row, col) += x(row, i) * y(i, col);
00333                 }
00334       return m;
00335 }
00336 
00337 } // namespace ivl
00338 
00339 #endif // IVL_ARRAY_2D_DETAILS_ARRAY_2D_FUNCTIONS_HPP
00340 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations