ivl 679
ivl/details/corefunc/min.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_COREFUNC_MIN
00025 #define IVL_COREFUNC_MIN
00026 
00027 namespace ivl {
00028 
00029 static __attribute__ ((unused)) struct min_impl : public ivl_func<min_impl>
00030 {
00037         template<class J, class T, class S>
00038         void operate(J& s, sep, const array<T, S>& a)
00039         {
00040                 s = a[0];
00041                 for (size_t i = 1; i < a.length(); i++)
00042                         if (a[i] < s)
00043                                 s = a[i];
00044         }
00045 
00046         template<class T, class S>
00047         T operator()(const array<T, S>& a)
00048         {
00049                 return call<T>(a);
00050         }
00051         
00052         // ----- elem function call type
00053 
00054         template<class T, class J, class K>
00055         struct elem_class
00056         {
00057                 typedef types::number<12> cost;
00058                 typedef J default_ret_type;
00059                 typedef typename types::t_if<types::t_eq<T, types::term>,
00060                         default_ret_type, T>::type func_ret_type;
00061                 static inline func_ret_type elem_op(const J& elem1, const K& elem2)
00062                 {
00063                         return math::min(elem1, elem2);
00064                 }
00065         };
00066         
00067 
00068         template <class A1, class A2>
00069         typename binary_elem_func_result<
00070                 typename elem_class<
00071                         types::term,
00072                         typename types::get_value<A1>::type,
00073                         typename types::get_value<A2>::type>::default_ret_type,
00074                         elem_class, A1, A2>::type operator()(
00075                 const A1& a1, const A2& a2)
00076         {
00077                 return binary_elem_func_result<
00078                 typename elem_class<
00079                         types::term,
00080                         typename types::get_value<A1>::type,
00081                         typename types::get_value<A2>::type>::default_ret_type,
00082                         elem_class, A1, A2>::from(a1, a2);
00083         }
00084 
00085         // operate modes
00086         // ===============================================================
00087         // 
00088         // -------------- elem function mode
00089         template <class AO, class A1, class A2>
00090         void operate(AO& o, sep, const A1& a1, const A2& a2)
00091         {
00092                 // usually () operator calls the operate.
00093                 // however in the elem-func case, it is normal that the operate function calls the () operator
00094                 o = (*this)(a1, a2);
00095         }
00096 
00097 
00098         // --------------
00099 
00100         template<class J, class I, class T, class S>
00101         void operate(J& s, I& imin, sep, const array<T, S>& a)
00102         {
00103                 /* TODO: CHECK
00104                 typename array<T, S>::const_iterator cit = a.begin();
00105                 s = *cit;
00106                 cit++;
00107                 imin = 0;
00108                 for (size_t i = 1; i < a.length(); i++, cit++)
00109                         if (*cit > s) {
00110                                 imax = i;
00111                                 s = *cit;
00112                         }
00113                 */
00114                 s = a[0];
00115                 imin = 0;
00116                 for (size_t i = 1; i < a.length(); i++)
00117                         if (a[i] < s) {
00118                                 imin = i;
00119                                 s = a[i];
00120                         }
00121         }
00122 
00123 // --------------
00124         template<class J, class S1, class I, class S2, class T, class S, class E>
00125         void operate(array<J, S1>& s, array<I, S2>& imin, sep,
00126                                 const array_2d<T, S>& a,
00127                                 array<E, data::empty<> >, size_t dim)
00128         {
00129                 s.resize(a.size(1 - dim));
00130                 imin.resize(a.size(1 - dim));
00131 /*
00132                 for(size_t j = 0; j < a.size(1 - dim); j++) {
00133                         array<index_array> p = idx(j, j);
00134                         p[dim] = all();
00135                         _(s[j], imax[j]) = (*this)++(a(p));
00136                 }
00137 */
00138                 //std::cout << a << std::endl;
00139 
00140                 if(dim == 0) {
00141                         for(size_t j = 0; j < a.size(1 - dim); j++) {
00142                                 //TODO: what is this
00143                                 std::cout << a.as_columns()[j] << std::endl;
00144                                 (_, s[j], imin[j]) = (*this)++(a.as_columns()[j]);
00145                                 //std::cout << s[j] << " " << imax[j] << " " << std::endl;
00146                         }
00147                 } else
00148                         for(size_t j = 0; j < a.size(1 - dim); j++) {
00149                                 std::cout << a.as_rows()[j] << std::endl;
00150                                 (_, s[j], imin[j]) = (*this)++(a.as_rows()[j]);
00151                                 //std::cout << s[j] << " " << imax[j] << " " << std::endl;
00152                         }
00153 
00154         }
00155 
00156 
00157 } min;
00158 
00159 template<class T, class S>
00160 int arg_min(const array<T, S>& a)
00161 {
00162         int id;
00163         double m;
00164         (_, m, id) = min++(a);
00165         // ivl needs (_, _, id) = max++(a);
00166         return id;
00167 }
00168 
00169 
00170 } /* namespace ivl */
00171 
00172 #endif // IVL_COREFUNC_MIN
 All Classes Namespaces Files Functions Variables Typedefs Enumerations