ivl 679
|
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