diff --git a/dlib/matrix/matrix_math_functions.h b/dlib/matrix/matrix_math_functions.h index 8f7f67fe9405032c930b6f2928fb7c74d6e54ede..15546bc0d7ef550307232007d8ed837081cf81f2 100644 --- a/dlib/matrix/matrix_math_functions.h +++ b/dlib/matrix/matrix_math_functions.h @@ -16,19 +16,20 @@ namespace dlib // ---------------------------------------------------------------------------------------- -#define DLIB_MATRIX_SIMPLE_STD_FUNCTION(name) template <typename EXP> \ - struct op_##name : has_nondestructive_aliasing, preserves_dimensions<EXP> \ +#define DLIB_MATRIX_SIMPLE_STD_FUNCTION(name) struct op_##name { \ + template <typename EXP> \ + struct op : has_nondestructive_aliasing, preserves_dimensions<EXP> \ { \ typedef typename EXP::type type; \ template <typename M> \ static type apply ( const M& m, long r, long c) \ { return static_cast<type>(std::name(m(r,c))); } \ - }; \ + };}; \ template < typename EXP > \ - const matrix_exp<matrix_unary_exp<matrix_exp<EXP>,op_##name<EXP> > > name ( \ + const matrix_exp<matrix_unary_exp<matrix_exp<EXP>,op_##name> > name ( \ const matrix_exp<EXP>& m) \ { \ - typedef matrix_unary_exp<matrix_exp<EXP>,op_##name<EXP> > exp; \ + typedef matrix_unary_exp<matrix_exp<EXP>,op_##name> exp; \ return matrix_exp<exp>(exp(m)); \ } @@ -57,51 +58,57 @@ DLIB_MATRIX_SIMPLE_STD_FUNCTION(atan) // ---------------------------------------------------------------------------------------- - template <typename EXP> - struct op_sigmoid : has_nondestructive_aliasing, preserves_dimensions<EXP> + struct op_sigmoid { - typedef typename EXP::type type; - template <typename M> - static type apply ( const M& m, long r, long c) - { - const double e = 2.718281828459045235360287471352; - double temp = std::pow(e,-m(r,c)); - return static_cast<type>(1.0/(1.0 + temp)); - } + template <typename EXP> + struct op : has_nondestructive_aliasing, preserves_dimensions<EXP> + { + typedef typename EXP::type type; + template <typename M> + static type apply ( const M& m, long r, long c) + { + const double e = 2.718281828459045235360287471352; + double temp = std::pow(e,-m(r,c)); + return static_cast<type>(1.0/(1.0 + temp)); + } + }; }; template < typename EXP > - const matrix_exp<matrix_unary_exp<matrix_exp<EXP>,op_sigmoid<EXP> > > sigmoid ( + const matrix_exp<matrix_unary_exp<matrix_exp<EXP>,op_sigmoid> > sigmoid ( const matrix_exp<EXP>& m ) { - typedef matrix_unary_exp<matrix_exp<EXP>,op_sigmoid<EXP> > exp; + typedef matrix_unary_exp<matrix_exp<EXP>,op_sigmoid> exp; return matrix_exp<exp>(exp(m)); } // ---------------------------------------------------------------------------------------- - template <typename EXP> - struct op_round_zeros : has_nondestructive_aliasing, preserves_dimensions<EXP> + struct op_round_zeros { - typedef typename EXP::type type; - template <typename M, typename T> - static type apply ( const M& m, const T& eps, long r, long c) - { - const type temp = m(r,c); - if (temp >= eps || temp <= -eps) - return temp; - else - return 0; - } + template <typename EXP> + struct op : has_nondestructive_aliasing, preserves_dimensions<EXP> + { + typedef typename EXP::type type; + template <typename M, typename T> + static type apply ( const M& m, const T& eps, long r, long c) + { + const type temp = m(r,c); + if (temp >= eps || temp <= -eps) + return temp; + else + return 0; + } + }; }; template < typename EXP > - const matrix_exp<matrix_scalar_binary_exp<matrix_exp<EXP>,typename EXP::type,op_round_zeros<EXP> > > round_zeros ( + const matrix_exp<matrix_scalar_binary_exp<matrix_exp<EXP>,typename EXP::type,op_round_zeros> > round_zeros ( const matrix_exp<EXP>& m ) { @@ -111,14 +118,14 @@ DLIB_MATRIX_SIMPLE_STD_FUNCTION(atan) is_same_type<typename EXP::type,double>::value == true || is_same_type<typename EXP::type,long double>::value == true )); - typedef matrix_scalar_binary_exp<matrix_exp<EXP>,typename EXP::type, op_round_zeros<EXP> > exp; + typedef matrix_scalar_binary_exp<matrix_exp<EXP>,typename EXP::type, op_round_zeros> exp; return matrix_exp<exp>(exp(m,10*std::numeric_limits<typename EXP::type>::epsilon())); } template < typename EXP > - const matrix_exp<matrix_scalar_binary_exp<matrix_exp<EXP>,typename EXP::type,op_round_zeros<EXP> > > round_zeros ( + const matrix_exp<matrix_scalar_binary_exp<matrix_exp<EXP>,typename EXP::type,op_round_zeros> > round_zeros ( const matrix_exp<EXP>& m, typename EXP::type eps ) @@ -129,70 +136,79 @@ DLIB_MATRIX_SIMPLE_STD_FUNCTION(atan) is_same_type<typename EXP::type,double>::value == true || is_same_type<typename EXP::type,long double>::value == true )); - typedef matrix_scalar_binary_exp<matrix_exp<EXP>,typename EXP::type, op_round_zeros<EXP> > exp; + typedef matrix_scalar_binary_exp<matrix_exp<EXP>,typename EXP::type, op_round_zeros> exp; return matrix_exp<exp>(exp(m,eps)); } // ---------------------------------------------------------------------------------------- - template <typename EXP> - struct op_cubed : has_nondestructive_aliasing, preserves_dimensions<EXP> + struct op_cubed { - typedef typename EXP::type type; - template <typename M> - static type apply ( const M& m, long r, long c) - { return m(r,c)*m(r,c)*m(r,c); } + template <typename EXP> + struct op : has_nondestructive_aliasing, preserves_dimensions<EXP> + { + typedef typename EXP::type type; + template <typename M> + static type apply ( const M& m, long r, long c) + { return m(r,c)*m(r,c)*m(r,c); } + }; }; template < typename EXP > - const matrix_exp<matrix_unary_exp<matrix_exp<EXP>,op_cubed<EXP> > > cubed ( + const matrix_exp<matrix_unary_exp<matrix_exp<EXP>,op_cubed> > cubed ( const matrix_exp<EXP>& m ) { - typedef matrix_unary_exp<matrix_exp<EXP>,op_cubed<EXP> > exp; + typedef matrix_unary_exp<matrix_exp<EXP>,op_cubed> exp; return matrix_exp<exp>(exp(m)); } // ---------------------------------------------------------------------------------------- - template <typename EXP> - struct op_squared : has_nondestructive_aliasing, preserves_dimensions<EXP> + struct op_squared { - typedef typename EXP::type type; - template <typename M> - static type apply ( const M& m, long r, long c) - { return m(r,c)*m(r,c); } + template <typename EXP> + struct op : has_nondestructive_aliasing, preserves_dimensions<EXP> + { + typedef typename EXP::type type; + template <typename M> + static type apply ( const M& m, long r, long c) + { return m(r,c)*m(r,c); } + }; }; template < typename EXP > - const matrix_exp<matrix_unary_exp<matrix_exp<EXP>,op_squared<EXP> > > squared ( + const matrix_exp<matrix_unary_exp<matrix_exp<EXP>,op_squared> > squared ( const matrix_exp<EXP>& m ) { - typedef matrix_unary_exp<matrix_exp<EXP>,op_squared<EXP> > exp; + typedef matrix_unary_exp<matrix_exp<EXP>,op_squared> exp; return matrix_exp<exp>(exp(m)); } // ---------------------------------------------------------------------------------------- - template <typename EXP> - struct op_pow : has_nondestructive_aliasing, preserves_dimensions<EXP> + struct op_pow { - typedef typename EXP::type type; - template <typename M, typename S> - static type apply ( const M& m, const S& s, long r, long c) - { return static_cast<type>(std::pow(m(r,c),s)); } + template <typename EXP> + struct op : has_nondestructive_aliasing, preserves_dimensions<EXP> + { + typedef typename EXP::type type; + template <typename M, typename S> + static type apply ( const M& m, const S& s, long r, long c) + { return static_cast<type>(std::pow(m(r,c),s)); } + }; }; template < typename EXP, typename S > - const matrix_exp<matrix_scalar_binary_exp<matrix_exp<EXP>,typename EXP::type,op_pow<EXP> > > pow ( + const matrix_exp<matrix_scalar_binary_exp<matrix_exp<EXP>,typename EXP::type,op_pow> > pow ( const matrix_exp<EXP>& m, const S& s ) @@ -203,31 +219,34 @@ DLIB_MATRIX_SIMPLE_STD_FUNCTION(atan) is_same_type<typename EXP::type,double>::value == true || is_same_type<typename EXP::type,long double>::value == true )); - typedef matrix_scalar_binary_exp<matrix_exp<EXP>,typename EXP::type,op_pow<EXP> > exp; + typedef matrix_scalar_binary_exp<matrix_exp<EXP>,typename EXP::type,op_pow> exp; return matrix_exp<exp>(exp(m,s)); } // ---------------------------------------------------------------------------------------- - template <typename EXP> - struct op_reciprocal : has_nondestructive_aliasing, preserves_dimensions<EXP> + struct op_reciprocal { - typedef typename EXP::type type; - template <typename M> - static type apply ( const M& m, long r, long c) - { - const type temp = m(r,c); - if (temp != 0) - return static_cast<type>(1.0/temp); - else - return 0; - } + template <typename EXP> + struct op : has_nondestructive_aliasing, preserves_dimensions<EXP> + { + typedef typename EXP::type type; + template <typename M> + static type apply ( const M& m, long r, long c) + { + const type temp = m(r,c); + if (temp != 0) + return static_cast<type>(1.0/temp); + else + return 0; + } + }; }; template < typename EXP > - const matrix_exp<matrix_unary_exp<matrix_exp<EXP>,op_reciprocal<EXP> > > reciprocal ( + const matrix_exp<matrix_unary_exp<matrix_exp<EXP>,op_reciprocal> > reciprocal ( const matrix_exp<EXP>& m ) { @@ -237,27 +256,30 @@ DLIB_MATRIX_SIMPLE_STD_FUNCTION(atan) is_same_type<typename EXP::type,double>::value == true || is_same_type<typename EXP::type,long double>::value == true )); - typedef matrix_unary_exp<matrix_exp<EXP>,op_reciprocal<EXP> > exp; + typedef matrix_unary_exp<matrix_exp<EXP>,op_reciprocal> exp; return matrix_exp<exp>(exp(m)); } // ---------------------------------------------------------------------------------------- - template <typename EXP> - struct op_normalize : has_nondestructive_aliasing, preserves_dimensions<EXP> + struct op_normalize { - typedef typename EXP::type type; - template <typename M> - static type apply ( const M& m, const type& s, long r, long c) - { - return m(r,c)*s; - } + template <typename EXP> + struct op : has_nondestructive_aliasing, preserves_dimensions<EXP> + { + typedef typename EXP::type type; + template <typename M> + static type apply ( const M& m, const type& s, long r, long c) + { + return m(r,c)*s; + } + }; }; template < typename EXP > - const matrix_exp<matrix_scalar_binary_exp<matrix_exp<EXP>,typename EXP::type,op_normalize<EXP> > > normalize ( + const matrix_exp<matrix_scalar_binary_exp<matrix_exp<EXP>,typename EXP::type,op_normalize> > normalize ( const matrix_exp<EXP>& m ) { @@ -267,7 +289,7 @@ DLIB_MATRIX_SIMPLE_STD_FUNCTION(atan) is_same_type<typename EXP::type,double>::value == true || is_same_type<typename EXP::type,long double>::value == true )); - typedef matrix_scalar_binary_exp<matrix_exp<EXP>,typename EXP::type, op_normalize<EXP> > exp; + typedef matrix_scalar_binary_exp<matrix_exp<EXP>,typename EXP::type, op_normalize> exp; typename EXP::type temp = std::sqrt(sum(squared(m))); if (temp != 0.0) @@ -278,21 +300,24 @@ DLIB_MATRIX_SIMPLE_STD_FUNCTION(atan) // ---------------------------------------------------------------------------------------- - template <typename EXP> - struct op_round : has_nondestructive_aliasing, preserves_dimensions<EXP> + struct op_round { - typedef typename EXP::type type; - template <typename M> - static type apply ( const M& m, long r, long c) - { - return static_cast<type>(std::floor(m(r,c)+0.5)); - } + template <typename EXP> + struct op : has_nondestructive_aliasing, preserves_dimensions<EXP> + { + typedef typename EXP::type type; + template <typename M> + static type apply ( const M& m, long r, long c) + { + return static_cast<type>(std::floor(m(r,c)+0.5)); + } + }; }; template < typename EXP > - const matrix_exp<matrix_unary_exp<matrix_exp<EXP>,op_round<EXP> > > round ( + const matrix_exp<matrix_unary_exp<matrix_exp<EXP>,op_round> > round ( const matrix_exp<EXP>& m ) { @@ -302,27 +327,30 @@ DLIB_MATRIX_SIMPLE_STD_FUNCTION(atan) is_same_type<typename EXP::type,double>::value == true || is_same_type<typename EXP::type,long double>::value == true )); - typedef matrix_unary_exp<matrix_exp<EXP>,op_round<EXP> > exp; + typedef matrix_unary_exp<matrix_exp<EXP>,op_round> exp; return matrix_exp<exp>(exp(m)); } // ---------------------------------------------------------------------------------------- - template <typename EXP1, typename EXP2> - struct op_complex_matrix : has_nondestructive_aliasing, preserves_dimensions<EXP1,EXP2> + struct op_complex_matrix { - typedef std::complex<typename EXP1::type> type; - - template <typename M1, typename M2> - static type apply ( const M1& m1, const M2& m2 , long r, long c) - { return type(m1(r,c),m2(r,c)); } + template <typename EXP1, typename EXP2> + struct op : has_nondestructive_aliasing, preserves_dimensions<EXP1,EXP2> + { + typedef std::complex<typename EXP1::type> type; + + template <typename M1, typename M2> + static type apply ( const M1& m1, const M2& m2 , long r, long c) + { return type(m1(r,c),m2(r,c)); } + }; }; template < typename EXP1, typename EXP2 > - const matrix_exp<matrix_binary_exp<matrix_exp<EXP1>,matrix_exp<EXP2>,op_complex_matrix<EXP1,EXP2> > > complex_matrix ( + const matrix_exp<matrix_binary_exp<matrix_exp<EXP1>,matrix_exp<EXP2>,op_complex_matrix> > complex_matrix ( const matrix_exp<EXP1>& real_part, const matrix_exp<EXP2>& imag_part ) @@ -340,73 +368,82 @@ DLIB_MATRIX_SIMPLE_STD_FUNCTION(atan) << "\n\timag_part.nr(): " << imag_part.nr() << "\n\timag_part.nc(): " << imag_part.nc() ); - typedef matrix_binary_exp<matrix_exp<EXP1>,matrix_exp<EXP2>,op_complex_matrix<EXP1,EXP2> > exp; + typedef matrix_binary_exp<matrix_exp<EXP1>,matrix_exp<EXP2>,op_complex_matrix> exp; return matrix_exp<exp>(exp(real_part,imag_part)); } // ---------------------------------------------------------------------------------------- - template <typename EXP> - struct op_norm : has_nondestructive_aliasing, preserves_dimensions<EXP> + struct op_norm { - typedef typename EXP::type::value_type type; - template <typename M> - static type apply ( const M& m, long r, long c) - { return std::norm(m(r,c)); } + template <typename EXP> + struct op : has_nondestructive_aliasing, preserves_dimensions<EXP> + { + typedef typename EXP::type::value_type type; + template <typename M> + static type apply ( const M& m, long r, long c) + { return std::norm(m(r,c)); } + }; }; template < typename EXP > - const matrix_exp<matrix_unary_exp<matrix_exp<EXP>,op_norm<EXP> > > norm ( + const matrix_exp<matrix_unary_exp<matrix_exp<EXP>,op_norm> > norm ( const matrix_exp<EXP>& m ) { - typedef matrix_unary_exp<matrix_exp<EXP>,op_norm<EXP> > exp; + typedef matrix_unary_exp<matrix_exp<EXP>,op_norm> exp; return matrix_exp<exp>(exp(m)); } // ---------------------------------------------------------------------------------------- - template <typename EXP> - struct op_real : has_nondestructive_aliasing, preserves_dimensions<EXP> + struct op_real { - typedef typename EXP::type::value_type type; - template <typename M> - static type apply ( const M& m, long r, long c) - { return std::real(m(r,c)); } + template <typename EXP> + struct op : has_nondestructive_aliasing, preserves_dimensions<EXP> + { + typedef typename EXP::type::value_type type; + template <typename M> + static type apply ( const M& m, long r, long c) + { return std::real(m(r,c)); } + }; }; template < typename EXP > - const matrix_exp<matrix_unary_exp<matrix_exp<EXP>,op_real<EXP> > > real ( + const matrix_exp<matrix_unary_exp<matrix_exp<EXP>,op_real> > real ( const matrix_exp<EXP>& m ) { - typedef matrix_unary_exp<matrix_exp<EXP>,op_real<EXP> > exp; + typedef matrix_unary_exp<matrix_exp<EXP>,op_real> exp; return matrix_exp<exp>(exp(m)); } // ---------------------------------------------------------------------------------------- - template <typename EXP> - struct op_imag : has_nondestructive_aliasing, preserves_dimensions<EXP> + struct op_imag { - typedef typename EXP::type::value_type type; - template <typename M> - static type apply ( const M& m, long r, long c) - { return std::imag(m(r,c)); } + template <typename EXP> + struct op : has_nondestructive_aliasing, preserves_dimensions<EXP> + { + typedef typename EXP::type::value_type type; + template <typename M> + static type apply ( const M& m, long r, long c) + { return std::imag(m(r,c)); } + }; }; template < typename EXP > - const matrix_exp<matrix_unary_exp<matrix_exp<EXP>,op_imag<EXP> > > imag ( + const matrix_exp<matrix_unary_exp<matrix_exp<EXP>,op_imag> > imag ( const matrix_exp<EXP>& m ) { - typedef matrix_unary_exp<matrix_exp<EXP>,op_imag<EXP> > exp; + typedef matrix_unary_exp<matrix_exp<EXP>,op_imag> exp; return matrix_exp<exp>(exp(m)); } diff --git a/dlib/matrix/matrix_utilities.h b/dlib/matrix/matrix_utilities.h index 8e7c3f774796f9864c6212138e11a1f2c89c2799..f2c91baedafb149def042e6c6e3436d3e55dd37c 100644 --- a/dlib/matrix/matrix_utilities.h +++ b/dlib/matrix/matrix_utilities.h @@ -895,7 +895,7 @@ namespace dlib template < typename M, - typename OP + typename OP_ > class matrix_unary_exp { @@ -904,6 +904,8 @@ namespace dlib - must be a matrix_exp or matrix_ref object (or an object with a compatible interface). !*/ + typedef typename OP_::template op<M> OP; + public: typedef typename OP::type type; typedef matrix_unary_exp ref_type; @@ -1179,7 +1181,7 @@ namespace dlib template < typename M, typename S, - typename OP + typename OP_ > class matrix_scalar_binary_exp { @@ -1188,6 +1190,8 @@ namespace dlib - must be a matrix_exp or matrix_ref object (or an object with a compatible interface). !*/ + typedef typename OP_::template op<M> OP; + public: typedef typename OP::type type; typedef matrix_scalar_binary_exp ref_type; @@ -1240,7 +1244,7 @@ namespace dlib template < typename M1, typename M2, - typename OP + typename OP_ > class matrix_binary_exp { @@ -1249,6 +1253,8 @@ namespace dlib - must be a matrix_exp or matrix_ref object (or an object with a compatible interface). !*/ + typedef typename OP_::template op<M1,M2> OP; + public: typedef typename OP::type type; typedef matrix_binary_exp ref_type; @@ -1743,66 +1749,73 @@ namespace dlib // ---------------------------------------------------------------------------------------- - template <typename EXP> - struct op_trans : has_destructive_aliasing + struct op_trans { - const static long NR = EXP::NC; - const static long NC = EXP::NR; - typedef typename EXP::type type; - typedef typename EXP::mem_manager_type mem_manager_type; - template <typename M> - static type apply ( const M& m, long r, long c) - { return m(c,r); } - - template <typename M> - static long nr (const M& m) { return m.nc(); } - template <typename M> - static long nc (const M& m) { return m.nr(); } + template <typename EXP> + struct op : has_destructive_aliasing + { + const static long NR = EXP::NC; + const static long NC = EXP::NR; + typedef typename EXP::type type; + typedef typename EXP::mem_manager_type mem_manager_type; + template <typename M> + static type apply ( const M& m, long r, long c) + { return m(c,r); } + + template <typename M> + static long nr (const M& m) { return m.nc(); } + template <typename M> + static long nc (const M& m) { return m.nr(); } + }; }; template < typename EXP > - const matrix_exp<matrix_unary_exp<matrix_exp<EXP>,op_trans<EXP> > > trans ( + const matrix_exp<matrix_unary_exp<matrix_exp<EXP>,op_trans> > trans ( const matrix_exp<EXP>& m ) { - typedef matrix_unary_exp<matrix_exp<EXP>,op_trans<EXP> > exp; + typedef matrix_unary_exp<matrix_exp<EXP>,op_trans> exp; return matrix_exp<exp>(exp(m)); } // ---------------------------------------------------------------------------------------- - template <typename EXP, long R, long C> - struct op_removerc : has_destructive_aliasing + template <long R, long C> + struct op_removerc { - const static long NR = EXP::NR - 1; - const static long NC = EXP::NC - 1; - typedef typename EXP::type type; - typedef typename EXP::mem_manager_type mem_manager_type; - template <typename M> - static type apply ( const M& m, long r, long c) - { - if (r < R) - { - if (c < C) - return m(r,c); - else - return m(r,c+1); - } - else - { - if (c < C) - return m(r+1,c); + template <typename EXP> + struct op : has_destructive_aliasing + { + const static long NR = EXP::NR - 1; + const static long NC = EXP::NC - 1; + typedef typename EXP::type type; + typedef typename EXP::mem_manager_type mem_manager_type; + template <typename M> + static type apply ( const M& m, long r, long c) + { + if (r < R) + { + if (c < C) + return m(r,c); + else + return m(r,c+1); + } else - return m(r+1,c+1); + { + if (c < C) + return m(r+1,c); + else + return m(r+1,c+1); + } } - } - template <typename M> - static long nr (const M& m) { return m.nr() - 1; } - template <typename M> - static long nc (const M& m) { return m.nc() - 1; } + template <typename M> + static long nr (const M& m) { return m.nr() - 1; } + template <typename M> + static long nc (const M& m) { return m.nc() - 1; } + }; }; template < @@ -1810,7 +1823,7 @@ namespace dlib long C, typename EXP > - const matrix_exp<matrix_unary_exp<matrix_exp<EXP>,op_removerc<EXP,R,C> > > removerc ( + const matrix_exp<matrix_unary_exp<matrix_exp<EXP>,op_removerc<R,C> > > removerc ( const matrix_exp<EXP>& m ) { @@ -1826,33 +1839,36 @@ namespace dlib << "\n\tR: " << R << "\n\tC: " << C ); - typedef matrix_unary_exp<matrix_exp<EXP>,op_removerc<EXP,R,C> > exp; + typedef matrix_unary_exp<matrix_exp<EXP>,op_removerc<R,C> > exp; return matrix_exp<exp>(exp(m)); } // ---------------------------------------------------------------------------------------- - template <typename EXP> - struct op_diag : has_destructive_aliasing + struct op_diag { - const static long NR = EXP::NC; - const static long NC = 1; - typedef typename EXP::type type; - typedef typename EXP::mem_manager_type mem_manager_type; - template <typename M> - static type apply ( const M& m, long r, long c) - { return m(r,r); } - - template <typename M> - static long nr (const M& m) { return m.nr(); } - template <typename M> - static long nc (const M& m) { return 1; } + template <typename EXP> + struct op : has_destructive_aliasing + { + const static long NR = EXP::NC; + const static long NC = 1; + typedef typename EXP::type type; + typedef typename EXP::mem_manager_type mem_manager_type; + template <typename M> + static type apply ( const M& m, long r, long c) + { return m(r,r); } + + template <typename M> + static long nr (const M& m) { return m.nr(); } + template <typename M> + static long nc (const M& m) { return 1; } + }; }; template < typename EXP > - const matrix_exp<matrix_unary_exp<matrix_exp<EXP>,op_diag<EXP> > > diag ( + const matrix_exp<matrix_unary_exp<matrix_exp<EXP>,op_diag> > diag ( const matrix_exp<EXP>& m ) { @@ -1864,30 +1880,34 @@ namespace dlib << "\n\tm.nr(): " << m.nr() << "\n\tm.nc(): " << m.nc() ); - typedef matrix_unary_exp<matrix_exp<EXP>,op_diag<EXP> > exp; + typedef matrix_unary_exp<matrix_exp<EXP>,op_diag> exp; return matrix_exp<exp>(exp(m)); } // ---------------------------------------------------------------------------------------- - template <typename EXP, typename target_type> - struct op_cast : has_nondestructive_aliasing, preserves_dimensions<EXP> + template <typename target_type> + struct op_cast { - typedef target_type type; - template <typename M> - static type apply ( const M& m, long r, long c) - { return static_cast<target_type>(m(r,c)); } + template <typename EXP> + struct op : has_nondestructive_aliasing, preserves_dimensions<EXP> + { + typedef target_type type; + template <typename M> + static type apply ( const M& m, long r, long c) + { return static_cast<target_type>(m(r,c)); } + }; }; template < typename target_type, typename EXP > - const matrix_exp<matrix_unary_exp<matrix_exp<EXP>,op_cast<EXP,target_type> > > matrix_cast ( + const matrix_exp<matrix_unary_exp<matrix_exp<EXP>,op_cast<target_type> > > matrix_cast ( const matrix_exp<EXP>& m ) { - typedef matrix_unary_exp<matrix_exp<EXP>,op_cast<EXP,target_type> > exp; + typedef matrix_unary_exp<matrix_exp<EXP>,op_cast<target_type> > exp; return matrix_exp<exp>(exp(m)); } @@ -2740,13 +2760,17 @@ namespace dlib // ---------------------------------------------------------------------------------------- - template <long R, long C, typename EXP> - struct op_rotate : has_destructive_aliasing, preserves_dimensions<EXP> + template <long R, long C> + struct op_rotate { - typedef typename EXP::type type; - template <typename M> - static type apply ( const M& m, long r, long c) - { return m((r+R)%m.nr(),(c+C)%m.nc()); } + template <typename EXP> + struct op : has_destructive_aliasing, preserves_dimensions<EXP> + { + typedef typename EXP::type type; + template <typename M> + static type apply ( const M& m, long r, long c) + { return m((r+R)%m.nr(),(c+C)%m.nc()); } + }; }; template < @@ -2754,7 +2778,7 @@ namespace dlib long C, typename EXP > - const matrix_exp<matrix_unary_exp<matrix_exp<EXP>,op_rotate<R,C,EXP> > > rotate ( + const matrix_exp<matrix_unary_exp<matrix_exp<EXP>,op_rotate<R,C> > > rotate ( const matrix_exp<EXP>& m ) { @@ -2770,27 +2794,30 @@ namespace dlib << "\n\tR: " << R << "\n\tC: " << C ); - typedef matrix_unary_exp<matrix_exp<EXP>,op_rotate<R,C,EXP> > exp; + typedef matrix_unary_exp<matrix_exp<EXP>,op_rotate<R,C> > exp; return matrix_exp<exp>(exp(m)); } // ---------------------------------------------------------------------------------------- - template <typename EXP1, typename EXP2, typename EXP3 = void, typename EXP4 = void> - struct op_pointwise_multiply : public has_nondestructive_aliasing, public preserves_dimensions<EXP1,EXP2,EXP3,EXP4> + struct op_pointwise_multiply { - typedef typename EXP1::type type; + template <typename EXP1, typename EXP2> + struct op : public has_nondestructive_aliasing, public preserves_dimensions<EXP1,EXP2> + { + typedef typename EXP1::type type; - template <typename M1, typename M2> - static type apply ( const M1& m1, const M2& m2 , long r, long c) - { return m1(r,c)*m2(r,c); } + template <typename M1, typename M2> + static type apply ( const M1& m1, const M2& m2 , long r, long c) + { return m1(r,c)*m2(r,c); } + }; }; template < typename EXP1, typename EXP2 > - inline const matrix_exp<matrix_binary_exp<matrix_exp<EXP1>,matrix_exp<EXP2>,op_pointwise_multiply<EXP1,EXP2> > > pointwise_multiply ( + inline const matrix_exp<matrix_binary_exp<EXP1,EXP2,op_pointwise_multiply> > pointwise_multiply ( const matrix_exp<EXP1>& a, const matrix_exp<EXP2>& b ) @@ -2807,8 +2834,8 @@ namespace dlib << "\n\tb.nr(): " << b.nr() << "\n\tb.nc(): " << b.nc() ); - typedef matrix_binary_exp<matrix_exp<EXP1>,matrix_exp<EXP2>,op_pointwise_multiply<EXP1,EXP2> > exp; - return matrix_exp<exp>(exp(a,b)); + typedef matrix_binary_exp<EXP1,EXP2,op_pointwise_multiply> exp; + return matrix_exp<exp>(exp(a.ref(),b.ref())); } template < @@ -2816,9 +2843,7 @@ namespace dlib typename EXP2, typename EXP3 > - inline const matrix_exp< - matrix_binary_exp< matrix_binary_exp<matrix_exp<EXP1>,matrix_exp<EXP2>,op_pointwise_multiply<EXP1,EXP2> > , - matrix_exp<EXP3>, op_pointwise_multiply<EXP1,EXP2,EXP3> > > + inline const matrix_exp<matrix_binary_exp<matrix_binary_exp<EXP1,EXP2,op_pointwise_multiply>,EXP3,op_pointwise_multiply> > pointwise_multiply ( const matrix_exp<EXP1>& a, const matrix_exp<EXP2>& b, @@ -2843,10 +2868,10 @@ namespace dlib << "\n\tc.nr(): " << c.nr() << "\n\tc.nc(): " << c.nc() ); - typedef matrix_binary_exp<matrix_exp<EXP1>,matrix_exp<EXP2>,op_pointwise_multiply<EXP1,EXP2> > exp; - typedef matrix_binary_exp< exp , matrix_exp<EXP3>, op_pointwise_multiply<EXP1,EXP2,EXP3> > exp2; + typedef matrix_binary_exp<EXP1,EXP2,op_pointwise_multiply> exp; + typedef matrix_binary_exp<exp , EXP3, op_pointwise_multiply> exp2; - return matrix_exp<exp2>(exp2(exp(a,b),c)); + return matrix_exp<exp2>(exp2(exp(a.ref(),b.ref()),c.ref())); } template < @@ -2856,9 +2881,9 @@ namespace dlib typename EXP4 > inline const matrix_exp< - matrix_binary_exp< matrix_binary_exp<matrix_exp<EXP1>,matrix_exp<EXP2>,op_pointwise_multiply<EXP1,EXP2> > , - matrix_binary_exp<matrix_exp<EXP3>,matrix_exp<EXP4>,op_pointwise_multiply<EXP3,EXP4> >, - op_pointwise_multiply<EXP1,EXP2,EXP3,EXP4> > > + matrix_binary_exp<matrix_binary_exp<EXP1,EXP2,op_pointwise_multiply> , + matrix_binary_exp<EXP3,EXP4,op_pointwise_multiply>, + op_pointwise_multiply> > pointwise_multiply ( const matrix_exp<EXP1>& a, const matrix_exp<EXP2>& b, @@ -2890,11 +2915,11 @@ namespace dlib << "\n\td.nr(): " << d.nr() << "\n\td.nc(): " << d.nc() ); - typedef matrix_binary_exp<matrix_exp<EXP1>,matrix_exp<EXP2>,op_pointwise_multiply<EXP1,EXP2> > exp1; - typedef matrix_binary_exp<matrix_exp<EXP3>,matrix_exp<EXP4>,op_pointwise_multiply<EXP3,EXP4> > exp2; + typedef matrix_binary_exp<EXP1,EXP2,op_pointwise_multiply> exp1; + typedef matrix_binary_exp<EXP3,EXP4,op_pointwise_multiply> exp2; - typedef matrix_binary_exp< exp1 , exp2, op_pointwise_multiply<EXP1,EXP2,EXP3,EXP4> > exp3; - return matrix_exp<exp3>(exp3(exp1(a,b),exp2(c,d))); + typedef matrix_binary_exp< exp1 , exp2, op_pointwise_multiply> exp3; + return matrix_exp<exp3>(exp3(exp1(a.ref(),b.ref()),exp2(c.ref(),d.ref()))); } // ---------------------------------------------------------------------------------------- @@ -3072,22 +3097,26 @@ namespace dlib // ---------------------------------------------------------------------------------------- - template <long lower, long upper, typename EXP> - struct op_clamp : has_nondestructive_aliasing, preserves_dimensions<EXP> + template <long lower, long upper> + struct op_clamp { - typedef typename EXP::type type; + template <typename EXP> + struct op : has_nondestructive_aliasing, preserves_dimensions<EXP> + { + typedef typename EXP::type type; - template <typename M> - static type apply ( const M& m, long r, long c) - { - const type temp = m(r,c); - if (temp > static_cast<type>(upper)) - return static_cast<type>(upper); - else if (temp < static_cast<type>(lower)) - return static_cast<type>(lower); - else - return temp; - } + template <typename M> + static type apply ( const M& m, long r, long c) + { + const type temp = m(r,c); + if (temp > static_cast<type>(upper)) + return static_cast<type>(upper); + else if (temp < static_cast<type>(lower)) + return static_cast<type>(lower); + else + return temp; + } + }; }; template < @@ -3095,11 +3124,11 @@ namespace dlib long u, typename EXP > - const matrix_exp<matrix_unary_exp<matrix_exp<EXP>,op_clamp<l,u,EXP> > > clamp ( + const matrix_exp<matrix_unary_exp<matrix_exp<EXP>,op_clamp<l,u> > > clamp ( const matrix_exp<EXP>& m ) { - typedef matrix_unary_exp<matrix_exp<EXP>,op_clamp<l,u,EXP> > exp; + typedef matrix_unary_exp<matrix_exp<EXP>,op_clamp<l,u> > exp; return matrix_exp<exp>(exp(m)); } @@ -3134,29 +3163,32 @@ namespace dlib // ---------------------------------------------------------------------------------------- - template <typename EXP1, typename EXP2> - struct op_scale_columns : has_nondestructive_aliasing + struct op_scale_columns { - typedef typename EXP1::type type; - typedef typename EXP1::mem_manager_type mem_manager_type; - const static long NR = EXP1::NR; - const static long NC = EXP1::NC; - - template <typename M1, typename M2> - static type apply ( const M1& m1, const M2& m2 , long r, long c) - { return m1(r,c)*m2(c); } - - template <typename M1, typename M2> - static long nr (const M1& m1, const M2& ) { return m1.nr(); } - template <typename M1, typename M2> - static long nc (const M1& m1, const M2& ) { return m1.nc(); } + template <typename EXP1, typename EXP2> + struct op : has_nondestructive_aliasing + { + typedef typename EXP1::type type; + typedef typename EXP1::mem_manager_type mem_manager_type; + const static long NR = EXP1::NR; + const static long NC = EXP1::NC; + + template <typename M1, typename M2> + static type apply ( const M1& m1, const M2& m2 , long r, long c) + { return m1(r,c)*m2(c); } + + template <typename M1, typename M2> + static long nr (const M1& m1, const M2& ) { return m1.nr(); } + template <typename M1, typename M2> + static long nc (const M1& m1, const M2& ) { return m1.nc(); } + }; }; template < typename EXP1, typename EXP2 > - const matrix_exp<matrix_binary_exp<matrix_exp<EXP1>,matrix_exp<EXP2>,op_scale_columns<EXP1,EXP2> > > scale_columns ( + const matrix_exp<matrix_binary_exp<matrix_exp<EXP1>,matrix_exp<EXP2>,op_scale_columns> > scale_columns ( const matrix_exp<EXP1>& m, const matrix_exp<EXP2>& v ) @@ -3173,7 +3205,7 @@ namespace dlib << "\n\tv.nr(): " << v.nr() << "\n\tv.nc(): " << v.nc() ); - typedef matrix_binary_exp<matrix_exp<EXP1>,matrix_exp<EXP2>,op_scale_columns<EXP1,EXP2> > exp; + typedef matrix_binary_exp<matrix_exp<EXP1>,matrix_exp<EXP2>,op_scale_columns> exp; return matrix_exp<exp>(exp(m,v)); }