Commit f825990c authored by Davis King's avatar Davis King

Changed the matrix operations so that they result in shorter type names

when compiled.  This avoids problems in compilers like visual studio.

--HG--
extra : convert_revision : svn%3Afdd8eb12-d10e-0410-9acb-85c331704f74/trunk%402301
parent 2801ca62
...@@ -16,19 +16,20 @@ namespace dlib ...@@ -16,19 +16,20 @@ namespace dlib
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
#define DLIB_MATRIX_SIMPLE_STD_FUNCTION(name) template <typename EXP> \ #define DLIB_MATRIX_SIMPLE_STD_FUNCTION(name) struct op_##name { \
struct op_##name : has_nondestructive_aliasing, preserves_dimensions<EXP> \ template <typename EXP> \
struct op : has_nondestructive_aliasing, preserves_dimensions<EXP> \
{ \ { \
typedef typename EXP::type type; \ typedef typename EXP::type type; \
template <typename M> \ template <typename M> \
static type apply ( const M& m, long r, long c) \ static type apply ( const M& m, long r, long c) \
{ return static_cast<type>(std::name(m(r,c))); } \ { return static_cast<type>(std::name(m(r,c))); } \
}; \ };}; \
template < typename EXP > \ 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) \ 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)); \ return matrix_exp<exp>(exp(m)); \
} }
...@@ -57,51 +58,57 @@ DLIB_MATRIX_SIMPLE_STD_FUNCTION(atan) ...@@ -57,51 +58,57 @@ DLIB_MATRIX_SIMPLE_STD_FUNCTION(atan)
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
template <typename EXP> struct op_sigmoid
struct op_sigmoid : has_nondestructive_aliasing, preserves_dimensions<EXP>
{ {
typedef typename EXP::type type; template <typename EXP>
template <typename M> struct op : has_nondestructive_aliasing, preserves_dimensions<EXP>
static type apply ( const M& m, long r, long c) {
{ typedef typename EXP::type type;
const double e = 2.718281828459045235360287471352; template <typename M>
double temp = std::pow(e,-m(r,c)); static type apply ( const M& m, long r, long c)
return static_cast<type>(1.0/(1.0 + temp)); {
} const double e = 2.718281828459045235360287471352;
double temp = std::pow(e,-m(r,c));
return static_cast<type>(1.0/(1.0 + temp));
}
};
}; };
template < template <
typename EXP 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 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)); return matrix_exp<exp>(exp(m));
} }
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
template <typename EXP> struct op_round_zeros
struct op_round_zeros : has_nondestructive_aliasing, preserves_dimensions<EXP>
{ {
typedef typename EXP::type type; template <typename EXP>
template <typename M, typename T> struct op : has_nondestructive_aliasing, preserves_dimensions<EXP>
static type apply ( const M& m, const T& eps, long r, long c) {
{ typedef typename EXP::type type;
const type temp = m(r,c); template <typename M, typename T>
if (temp >= eps || temp <= -eps) static type apply ( const M& m, const T& eps, long r, long c)
return temp; {
else const type temp = m(r,c);
return 0; if (temp >= eps || temp <= -eps)
} return temp;
else
return 0;
}
};
}; };
template < template <
typename EXP 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 const matrix_exp<EXP>& m
) )
{ {
...@@ -111,14 +118,14 @@ DLIB_MATRIX_SIMPLE_STD_FUNCTION(atan) ...@@ -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,double>::value == true ||
is_same_type<typename EXP::type,long 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())); return matrix_exp<exp>(exp(m,10*std::numeric_limits<typename EXP::type>::epsilon()));
} }
template < template <
typename EXP 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, const matrix_exp<EXP>& m,
typename EXP::type eps typename EXP::type eps
) )
...@@ -129,70 +136,79 @@ DLIB_MATRIX_SIMPLE_STD_FUNCTION(atan) ...@@ -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,double>::value == true ||
is_same_type<typename EXP::type,long 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)); return matrix_exp<exp>(exp(m,eps));
} }
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
template <typename EXP> struct op_cubed
struct op_cubed : has_nondestructive_aliasing, preserves_dimensions<EXP>
{ {
typedef typename EXP::type type; template <typename EXP>
template <typename M> struct op : has_nondestructive_aliasing, preserves_dimensions<EXP>
static type apply ( const M& m, long r, long c) {
{ return m(r,c)*m(r,c)*m(r,c); } 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 < template <
typename EXP 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 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)); return matrix_exp<exp>(exp(m));
} }
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
template <typename EXP> struct op_squared
struct op_squared : has_nondestructive_aliasing, preserves_dimensions<EXP>
{ {
typedef typename EXP::type type; template <typename EXP>
template <typename M> struct op : has_nondestructive_aliasing, preserves_dimensions<EXP>
static type apply ( const M& m, long r, long c) {
{ return m(r,c)*m(r,c); } 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 < template <
typename EXP 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 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)); return matrix_exp<exp>(exp(m));
} }
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
template <typename EXP> struct op_pow
struct op_pow : has_nondestructive_aliasing, preserves_dimensions<EXP>
{ {
typedef typename EXP::type type; template <typename EXP>
template <typename M, typename S> struct op : has_nondestructive_aliasing, preserves_dimensions<EXP>
static type apply ( const M& m, const S& s, long r, long c) {
{ return static_cast<type>(std::pow(m(r,c),s)); } 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 < template <
typename EXP, typename EXP,
typename S 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 matrix_exp<EXP>& m,
const S& s const S& s
) )
...@@ -203,31 +219,34 @@ DLIB_MATRIX_SIMPLE_STD_FUNCTION(atan) ...@@ -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,double>::value == true ||
is_same_type<typename EXP::type,long 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)); return matrix_exp<exp>(exp(m,s));
} }
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
template <typename EXP> struct op_reciprocal
struct op_reciprocal : has_nondestructive_aliasing, preserves_dimensions<EXP>
{ {
typedef typename EXP::type type; template <typename EXP>
template <typename M> struct op : has_nondestructive_aliasing, preserves_dimensions<EXP>
static type apply ( const M& m, long r, long c) {
{ typedef typename EXP::type type;
const type temp = m(r,c); template <typename M>
if (temp != 0) static type apply ( const M& m, long r, long c)
return static_cast<type>(1.0/temp); {
else const type temp = m(r,c);
return 0; if (temp != 0)
} return static_cast<type>(1.0/temp);
else
return 0;
}
};
}; };
template < template <
typename EXP 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 const matrix_exp<EXP>& m
) )
{ {
...@@ -237,27 +256,30 @@ DLIB_MATRIX_SIMPLE_STD_FUNCTION(atan) ...@@ -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,double>::value == true ||
is_same_type<typename EXP::type,long 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)); return matrix_exp<exp>(exp(m));
} }
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
template <typename EXP> struct op_normalize
struct op_normalize : has_nondestructive_aliasing, preserves_dimensions<EXP>
{ {
typedef typename EXP::type type; template <typename EXP>
template <typename M> struct op : has_nondestructive_aliasing, preserves_dimensions<EXP>
static type apply ( const M& m, const type& s, long r, long c) {
{ typedef typename EXP::type type;
return m(r,c)*s; template <typename M>
} static type apply ( const M& m, const type& s, long r, long c)
{
return m(r,c)*s;
}
};
}; };
template < template <
typename EXP 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 const matrix_exp<EXP>& m
) )
{ {
...@@ -267,7 +289,7 @@ DLIB_MATRIX_SIMPLE_STD_FUNCTION(atan) ...@@ -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,double>::value == true ||
is_same_type<typename EXP::type,long 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))); typename EXP::type temp = std::sqrt(sum(squared(m)));
if (temp != 0.0) if (temp != 0.0)
...@@ -278,21 +300,24 @@ DLIB_MATRIX_SIMPLE_STD_FUNCTION(atan) ...@@ -278,21 +300,24 @@ DLIB_MATRIX_SIMPLE_STD_FUNCTION(atan)
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
template <typename EXP> struct op_round
struct op_round : has_nondestructive_aliasing, preserves_dimensions<EXP>
{ {
typedef typename EXP::type type; template <typename EXP>
template <typename M> struct op : has_nondestructive_aliasing, preserves_dimensions<EXP>
static type apply ( const M& m, long r, long c) {
{ typedef typename EXP::type type;
return static_cast<type>(std::floor(m(r,c)+0.5)); 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 < template <
typename EXP 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 const matrix_exp<EXP>& m
) )
{ {
...@@ -302,27 +327,30 @@ DLIB_MATRIX_SIMPLE_STD_FUNCTION(atan) ...@@ -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,double>::value == true ||
is_same_type<typename EXP::type,long 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)); return matrix_exp<exp>(exp(m));
} }
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
template <typename EXP1, typename EXP2> struct op_complex_matrix
struct op_complex_matrix : has_nondestructive_aliasing, preserves_dimensions<EXP1,EXP2>
{ {
typedef std::complex<typename EXP1::type> type; template <typename EXP1, typename EXP2>
struct op : has_nondestructive_aliasing, preserves_dimensions<EXP1,EXP2>
template <typename M1, typename M2> {
static type apply ( const M1& m1, const M2& m2 , long r, long c) typedef std::complex<typename EXP1::type> type;
{ return type(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 type(m1(r,c),m2(r,c)); }
};
}; };
template < template <
typename EXP1, typename EXP1,
typename EXP2 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<EXP1>& real_part,
const matrix_exp<EXP2>& imag_part const matrix_exp<EXP2>& imag_part
) )
...@@ -340,73 +368,82 @@ DLIB_MATRIX_SIMPLE_STD_FUNCTION(atan) ...@@ -340,73 +368,82 @@ DLIB_MATRIX_SIMPLE_STD_FUNCTION(atan)
<< "\n\timag_part.nr(): " << imag_part.nr() << "\n\timag_part.nr(): " << imag_part.nr()
<< "\n\timag_part.nc(): " << imag_part.nc() << "\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)); return matrix_exp<exp>(exp(real_part,imag_part));
} }
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
template <typename EXP> struct op_norm
struct op_norm : has_nondestructive_aliasing, preserves_dimensions<EXP>
{ {
typedef typename EXP::type::value_type type; template <typename EXP>
template <typename M> struct op : has_nondestructive_aliasing, preserves_dimensions<EXP>
static type apply ( const M& m, long r, long c) {
{ return std::norm(m(r,c)); } 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 < template <
typename EXP 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 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)); return matrix_exp<exp>(exp(m));
} }
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
template <typename EXP> struct op_real
struct op_real : has_nondestructive_aliasing, preserves_dimensions<EXP>
{ {
typedef typename EXP::type::value_type type; template <typename EXP>
template <typename M> struct op : has_nondestructive_aliasing, preserves_dimensions<EXP>
static type apply ( const M& m, long r, long c) {
{ return std::real(m(r,c)); } 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 < template <
typename EXP 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 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)); return matrix_exp<exp>(exp(m));
} }
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
template <typename EXP> struct op_imag
struct op_imag : has_nondestructive_aliasing, preserves_dimensions<EXP>
{ {
typedef typename EXP::type::value_type type; template <typename EXP>
template <typename M> struct op : has_nondestructive_aliasing, preserves_dimensions<EXP>
static type apply ( const M& m, long r, long c) {
{ return std::imag(m(r,c)); } 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 < template <
typename EXP 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 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)); return matrix_exp<exp>(exp(m));
} }
......
...@@ -895,7 +895,7 @@ namespace dlib ...@@ -895,7 +895,7 @@ namespace dlib
template < template <
typename M, typename M,
typename OP typename OP_
> >
class matrix_unary_exp class matrix_unary_exp
{ {
...@@ -904,6 +904,8 @@ namespace dlib ...@@ -904,6 +904,8 @@ namespace dlib
- must be a matrix_exp or matrix_ref object (or - must be a matrix_exp or matrix_ref object (or
an object with a compatible interface). an object with a compatible interface).
!*/ !*/
typedef typename OP_::template op<M> OP;
public: public:
typedef typename OP::type type; typedef typename OP::type type;
typedef matrix_unary_exp ref_type; typedef matrix_unary_exp ref_type;
...@@ -1179,7 +1181,7 @@ namespace dlib ...@@ -1179,7 +1181,7 @@ namespace dlib
template < template <
typename M, typename M,
typename S, typename S,
typename OP typename OP_
> >
class matrix_scalar_binary_exp class matrix_scalar_binary_exp
{ {
...@@ -1188,6 +1190,8 @@ namespace dlib ...@@ -1188,6 +1190,8 @@ namespace dlib
- must be a matrix_exp or matrix_ref object (or - must be a matrix_exp or matrix_ref object (or
an object with a compatible interface). an object with a compatible interface).
!*/ !*/
typedef typename OP_::template op<M> OP;
public: public:
typedef typename OP::type type; typedef typename OP::type type;
typedef matrix_scalar_binary_exp ref_type; typedef matrix_scalar_binary_exp ref_type;
...@@ -1240,7 +1244,7 @@ namespace dlib ...@@ -1240,7 +1244,7 @@ namespace dlib
template < template <
typename M1, typename M1,
typename M2, typename M2,
typename OP typename OP_
> >
class matrix_binary_exp class matrix_binary_exp
{ {
...@@ -1249,6 +1253,8 @@ namespace dlib ...@@ -1249,6 +1253,8 @@ namespace dlib
- must be a matrix_exp or matrix_ref object (or - must be a matrix_exp or matrix_ref object (or
an object with a compatible interface). an object with a compatible interface).
!*/ !*/
typedef typename OP_::template op<M1,M2> OP;
public: public:
typedef typename OP::type type; typedef typename OP::type type;
typedef matrix_binary_exp ref_type; typedef matrix_binary_exp ref_type;
...@@ -1743,66 +1749,73 @@ namespace dlib ...@@ -1743,66 +1749,73 @@ namespace dlib
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
template <typename EXP> struct op_trans
struct op_trans : has_destructive_aliasing
{ {
const static long NR = EXP::NC; template <typename EXP>
const static long NC = EXP::NR; struct op : has_destructive_aliasing
typedef typename EXP::type type; {
typedef typename EXP::mem_manager_type mem_manager_type; const static long NR = EXP::NC;
template <typename M> const static long NC = EXP::NR;
static type apply ( const M& m, long r, long c) typedef typename EXP::type type;
{ return m(c,r); } typedef typename EXP::mem_manager_type mem_manager_type;
template <typename M>
template <typename M> static type apply ( const M& m, long r, long c)
static long nr (const M& m) { return m.nc(); } { return m(c,r); }
template <typename M>
static long nc (const M& m) { return m.nr(); } 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 < template <
typename EXP 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 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)); return matrix_exp<exp>(exp(m));
} }
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
template <typename EXP, long R, long C> template <long R, long C>
struct op_removerc : has_destructive_aliasing struct op_removerc
{ {
const static long NR = EXP::NR - 1; template <typename EXP>
const static long NC = EXP::NC - 1; struct op : has_destructive_aliasing
typedef typename EXP::type type; {
typedef typename EXP::mem_manager_type mem_manager_type; const static long NR = EXP::NR - 1;
template <typename M> const static long NC = EXP::NC - 1;
static type apply ( const M& m, long r, long c) typedef typename EXP::type type;
{ typedef typename EXP::mem_manager_type mem_manager_type;
if (r < R) template <typename M>
{ static type apply ( const M& m, long r, long c)
if (c < C) {
return m(r,c); if (r < R)
else {
return m(r,c+1); if (c < C)
} return m(r,c);
else else
{ return m(r,c+1);
if (c < C) }
return m(r+1,c);
else 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> template <typename M>
static long nr (const M& m) { return m.nr() - 1; } static long nr (const M& m) { return m.nr() - 1; }
template <typename M> template <typename M>
static long nc (const M& m) { return m.nc() - 1; } static long nc (const M& m) { return m.nc() - 1; }
};
}; };
template < template <
...@@ -1810,7 +1823,7 @@ namespace dlib ...@@ -1810,7 +1823,7 @@ namespace dlib
long C, long C,
typename EXP 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 const matrix_exp<EXP>& m
) )
{ {
...@@ -1826,33 +1839,36 @@ namespace dlib ...@@ -1826,33 +1839,36 @@ namespace dlib
<< "\n\tR: " << R << "\n\tR: " << R
<< "\n\tC: " << C << "\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)); return matrix_exp<exp>(exp(m));
} }
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
template <typename EXP> struct op_diag
struct op_diag : has_destructive_aliasing
{ {
const static long NR = EXP::NC; template <typename EXP>
const static long NC = 1; struct op : has_destructive_aliasing
typedef typename EXP::type type; {
typedef typename EXP::mem_manager_type mem_manager_type; const static long NR = EXP::NC;
template <typename M> const static long NC = 1;
static type apply ( const M& m, long r, long c) typedef typename EXP::type type;
{ return m(r,r); } typedef typename EXP::mem_manager_type mem_manager_type;
template <typename M>
template <typename M> static type apply ( const M& m, long r, long c)
static long nr (const M& m) { return m.nr(); } { return m(r,r); }
template <typename M>
static long nc (const M& m) { return 1; } template <typename M>
static long nr (const M& m) { return m.nr(); }
template <typename M>
static long nc (const M& m) { return 1; }
};
}; };
template < template <
typename EXP 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 const matrix_exp<EXP>& m
) )
{ {
...@@ -1864,30 +1880,34 @@ namespace dlib ...@@ -1864,30 +1880,34 @@ namespace dlib
<< "\n\tm.nr(): " << m.nr() << "\n\tm.nr(): " << m.nr()
<< "\n\tm.nc(): " << m.nc() << "\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)); return matrix_exp<exp>(exp(m));
} }
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
template <typename EXP, typename target_type> template <typename target_type>
struct op_cast : has_nondestructive_aliasing, preserves_dimensions<EXP> struct op_cast
{ {
typedef target_type type; template <typename EXP>
template <typename M> struct op : has_nondestructive_aliasing, preserves_dimensions<EXP>
static type apply ( const M& m, long r, long c) {
{ return static_cast<target_type>(m(r,c)); } 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 < template <
typename target_type, typename target_type,
typename EXP 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 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)); return matrix_exp<exp>(exp(m));
} }
...@@ -2740,13 +2760,17 @@ namespace dlib ...@@ -2740,13 +2760,17 @@ namespace dlib
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
template <long R, long C, typename EXP> template <long R, long C>
struct op_rotate : has_destructive_aliasing, preserves_dimensions<EXP> struct op_rotate
{ {
typedef typename EXP::type type; template <typename EXP>
template <typename M> struct op : has_destructive_aliasing, preserves_dimensions<EXP>
static type apply ( const M& m, long r, long c) {
{ return m((r+R)%m.nr(),(c+C)%m.nc()); } 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 < template <
...@@ -2754,7 +2778,7 @@ namespace dlib ...@@ -2754,7 +2778,7 @@ namespace dlib
long C, long C,
typename EXP 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 const matrix_exp<EXP>& m
) )
{ {
...@@ -2770,27 +2794,30 @@ namespace dlib ...@@ -2770,27 +2794,30 @@ namespace dlib
<< "\n\tR: " << R << "\n\tR: " << R
<< "\n\tC: " << C << "\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)); return matrix_exp<exp>(exp(m));
} }
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
template <typename EXP1, typename EXP2, typename EXP3 = void, typename EXP4 = void> struct op_pointwise_multiply
struct op_pointwise_multiply : public has_nondestructive_aliasing, public preserves_dimensions<EXP1,EXP2,EXP3,EXP4>
{ {
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> template <typename M1, typename M2>
static type apply ( const M1& m1, const M2& m2 , long r, long c) static type apply ( const M1& m1, const M2& m2 , long r, long c)
{ return m1(r,c)*m2(r,c); } { return m1(r,c)*m2(r,c); }
};
}; };
template < template <
typename EXP1, typename EXP1,
typename EXP2 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<EXP1>& a,
const matrix_exp<EXP2>& b const matrix_exp<EXP2>& b
) )
...@@ -2807,8 +2834,8 @@ namespace dlib ...@@ -2807,8 +2834,8 @@ namespace dlib
<< "\n\tb.nr(): " << b.nr() << "\n\tb.nr(): " << b.nr()
<< "\n\tb.nc(): " << b.nc() << "\n\tb.nc(): " << b.nc()
); );
typedef matrix_binary_exp<matrix_exp<EXP1>,matrix_exp<EXP2>,op_pointwise_multiply<EXP1,EXP2> > exp; typedef matrix_binary_exp<EXP1,EXP2,op_pointwise_multiply> exp;
return matrix_exp<exp>(exp(a,b)); return matrix_exp<exp>(exp(a.ref(),b.ref()));
} }
template < template <
...@@ -2816,9 +2843,7 @@ namespace dlib ...@@ -2816,9 +2843,7 @@ namespace dlib
typename EXP2, typename EXP2,
typename EXP3 typename EXP3
> >
inline const matrix_exp< inline const matrix_exp<matrix_binary_exp<matrix_binary_exp<EXP1,EXP2,op_pointwise_multiply>,EXP3,op_pointwise_multiply> >
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> > >
pointwise_multiply ( pointwise_multiply (
const matrix_exp<EXP1>& a, const matrix_exp<EXP1>& a,
const matrix_exp<EXP2>& b, const matrix_exp<EXP2>& b,
...@@ -2843,10 +2868,10 @@ namespace dlib ...@@ -2843,10 +2868,10 @@ namespace dlib
<< "\n\tc.nr(): " << c.nr() << "\n\tc.nr(): " << c.nr()
<< "\n\tc.nc(): " << c.nc() << "\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<EXP1,EXP2,op_pointwise_multiply> exp;
typedef matrix_binary_exp< exp , matrix_exp<EXP3>, op_pointwise_multiply<EXP1,EXP2,EXP3> > exp2; 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 < template <
...@@ -2856,9 +2881,9 @@ namespace dlib ...@@ -2856,9 +2881,9 @@ namespace dlib
typename EXP4 typename EXP4
> >
inline const matrix_exp< 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_binary_exp<EXP1,EXP2,op_pointwise_multiply> ,
matrix_binary_exp<matrix_exp<EXP3>,matrix_exp<EXP4>,op_pointwise_multiply<EXP3,EXP4> >, matrix_binary_exp<EXP3,EXP4,op_pointwise_multiply>,
op_pointwise_multiply<EXP1,EXP2,EXP3,EXP4> > > op_pointwise_multiply> >
pointwise_multiply ( pointwise_multiply (
const matrix_exp<EXP1>& a, const matrix_exp<EXP1>& a,
const matrix_exp<EXP2>& b, const matrix_exp<EXP2>& b,
...@@ -2890,11 +2915,11 @@ namespace dlib ...@@ -2890,11 +2915,11 @@ namespace dlib
<< "\n\td.nr(): " << d.nr() << "\n\td.nr(): " << d.nr()
<< "\n\td.nc(): " << d.nc() << "\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<EXP1,EXP2,op_pointwise_multiply> exp1;
typedef matrix_binary_exp<matrix_exp<EXP3>,matrix_exp<EXP4>,op_pointwise_multiply<EXP3,EXP4> > exp2; typedef matrix_binary_exp<EXP3,EXP4,op_pointwise_multiply> exp2;
typedef matrix_binary_exp< exp1 , exp2, op_pointwise_multiply<EXP1,EXP2,EXP3,EXP4> > exp3; typedef matrix_binary_exp< exp1 , exp2, op_pointwise_multiply> exp3;
return matrix_exp<exp3>(exp3(exp1(a,b),exp2(c,d))); return matrix_exp<exp3>(exp3(exp1(a.ref(),b.ref()),exp2(c.ref(),d.ref())));
} }
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
...@@ -3072,22 +3097,26 @@ namespace dlib ...@@ -3072,22 +3097,26 @@ namespace dlib
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
template <long lower, long upper, typename EXP> template <long lower, long upper>
struct op_clamp : has_nondestructive_aliasing, preserves_dimensions<EXP> 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> template <typename M>
static type apply ( const M& m, long r, long c) static type apply ( const M& m, long r, long c)
{ {
const type temp = m(r,c); const type temp = m(r,c);
if (temp > static_cast<type>(upper)) if (temp > static_cast<type>(upper))
return static_cast<type>(upper); return static_cast<type>(upper);
else if (temp < static_cast<type>(lower)) else if (temp < static_cast<type>(lower))
return static_cast<type>(lower); return static_cast<type>(lower);
else else
return temp; return temp;
} }
};
}; };
template < template <
...@@ -3095,11 +3124,11 @@ namespace dlib ...@@ -3095,11 +3124,11 @@ namespace dlib
long u, long u,
typename EXP 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 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)); return matrix_exp<exp>(exp(m));
} }
...@@ -3134,29 +3163,32 @@ namespace dlib ...@@ -3134,29 +3163,32 @@ namespace dlib
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
template <typename EXP1, typename EXP2> struct op_scale_columns
struct op_scale_columns : has_nondestructive_aliasing
{ {
typedef typename EXP1::type type; template <typename EXP1, typename EXP2>
typedef typename EXP1::mem_manager_type mem_manager_type; struct op : has_nondestructive_aliasing
const static long NR = EXP1::NR; {
const static long NC = EXP1::NC; typedef typename EXP1::type type;
typedef typename EXP1::mem_manager_type mem_manager_type;
template <typename M1, typename M2> const static long NR = EXP1::NR;
static type apply ( const M1& m1, const M2& m2 , long r, long c) const static long NC = EXP1::NC;
{ return m1(r,c)*m2(c); }
template <typename M1, typename M2>
template <typename M1, typename M2> static type apply ( const M1& m1, const M2& m2 , long r, long c)
static long nr (const M1& m1, const M2& ) { return m1.nr(); } { return m1(r,c)*m2(c); }
template <typename M1, typename M2>
static long nc (const M1& m1, const M2& ) { return m1.nc(); } 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 < template <
typename EXP1, typename EXP1,
typename EXP2 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<EXP1>& m,
const matrix_exp<EXP2>& v const matrix_exp<EXP2>& v
) )
...@@ -3173,7 +3205,7 @@ namespace dlib ...@@ -3173,7 +3205,7 @@ namespace dlib
<< "\n\tv.nr(): " << v.nr() << "\n\tv.nr(): " << v.nr()
<< "\n\tv.nc(): " << v.nc() << "\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)); return matrix_exp<exp>(exp(m,v));
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment