diff options
Diffstat (limited to 'ml/dlib/dlib/matrix/matrix_op.h')
-rw-r--r-- | ml/dlib/dlib/matrix/matrix_op.h | 479 |
1 files changed, 479 insertions, 0 deletions
diff --git a/ml/dlib/dlib/matrix/matrix_op.h b/ml/dlib/dlib/matrix/matrix_op.h new file mode 100644 index 000000000..524a775eb --- /dev/null +++ b/ml/dlib/dlib/matrix/matrix_op.h @@ -0,0 +1,479 @@ +// Copyright (C) 2010 Davis E. King (davis@dlib.net) +// License: Boost Software License See LICENSE.txt for the full license. +#ifndef DLIB_MATRIx_OP_H_ +#define DLIB_MATRIx_OP_H_ + +#include "matrix_exp.h" + + +namespace dlib +{ + +// ---------------------------------------------------------------------------------------- + + template <typename OP > + class matrix_op; + + template < typename OP > + struct matrix_traits<matrix_op<OP> > + { + typedef typename OP::type type; + typedef typename OP::const_ret_type const_ret_type; + typedef typename OP::mem_manager_type mem_manager_type; + typedef typename OP::layout_type layout_type; + const static long NR = OP::NR; + const static long NC = OP::NC; + const static long cost = OP::cost; + }; + + template < + typename OP + > + class matrix_op : public matrix_exp<matrix_op<OP> > + { + /*! + WHAT THIS OBJECT REPRESENTS + The matrix_op is simply a tool for reducing the amount of boilerplate + you need to write when creating matrix expressions. + !*/ + + public: + typedef typename matrix_traits<matrix_op>::type type; + typedef typename matrix_traits<matrix_op>::const_ret_type const_ret_type; + typedef typename matrix_traits<matrix_op>::mem_manager_type mem_manager_type; + typedef typename matrix_traits<matrix_op>::layout_type layout_type; + const static long NR = matrix_traits<matrix_op>::NR; + const static long NC = matrix_traits<matrix_op>::NC; + const static long cost = matrix_traits<matrix_op>::cost; + + private: + // This constructor exists simply for the purpose of causing a compile time error if + // someone tries to create an instance of this object with the wrong kind of object. + template <typename T1> + matrix_op (T1); + public: + + matrix_op ( + const OP& op_ + ) : + op(op_) + {} + + const_ret_type operator() ( + long r, + long c + ) const { return op.apply(r,c); } + + const_ret_type operator() ( long i ) const + { return matrix_exp<matrix_op>::operator()(i); } + + template <typename U> + bool aliases ( + const matrix_exp<U>& item + ) const { return op.aliases(item); } + + template <typename U> + bool destructively_aliases ( + const matrix_exp<U>& item + ) const { return op.destructively_aliases(item); } + + long nr ( + ) const { return op.nr(); } + + long nc ( + ) const { return op.nc(); } + + + const OP op; + }; + +// ---------------------------------------------------------------------------------------- + + template <typename OP > + class matrix_diag_op; + + template < typename OP > + struct matrix_traits<matrix_diag_op<OP> > + { + typedef typename OP::type type; + typedef typename OP::const_ret_type const_ret_type; + typedef typename OP::mem_manager_type mem_manager_type; + typedef typename OP::layout_type layout_type; + const static long NR = OP::NR; + const static long NC = OP::NC; + const static long cost = OP::cost; + }; + + template < + typename OP + > + class matrix_diag_op : public matrix_diag_exp<matrix_diag_op<OP> > + { + /*! + WHAT THIS OBJECT REPRESENTS + The matrix_diag_op is simply a tool for reducing the amount of boilerplate + you need to write when creating matrix expressions. + !*/ + + public: + typedef typename matrix_traits<matrix_diag_op>::type type; + typedef typename matrix_traits<matrix_diag_op>::const_ret_type const_ret_type; + typedef typename matrix_traits<matrix_diag_op>::mem_manager_type mem_manager_type; + typedef typename matrix_traits<matrix_diag_op>::layout_type layout_type; + const static long NR = matrix_traits<matrix_diag_op>::NR; + const static long NC = matrix_traits<matrix_diag_op>::NC; + const static long cost = matrix_traits<matrix_diag_op>::cost; + + private: + // This constructor exists simply for the purpose of causing a compile time error if + // someone tries to create an instance of this object with the wrong kind of object. + template <typename T1> + matrix_diag_op (T1); + public: + + matrix_diag_op ( + const OP& op_ + ) : + op(op_) + {} + + const_ret_type operator() ( + long r, + long c + ) const { return op.apply(r,c); } + + const_ret_type operator() ( long i ) const + { return matrix_exp<matrix_diag_op>::operator()(i); } + + template <typename U> + bool aliases ( + const matrix_exp<U>& item + ) const { return op.aliases(item); } + + template <typename U> + bool destructively_aliases ( + const matrix_exp<U>& item + ) const { return op.destructively_aliases(item); } + + long nr ( + ) const { return op.nr(); } + + long nc ( + ) const { return op.nc(); } + + + const OP op; + }; + +// ---------------------------------------------------------------------------------------- + + struct does_not_alias + { + /*! + This is a partial implementation of a matrix operator that never aliases + another expression. + !*/ + + template <typename U> bool aliases ( const U& ) const { return false; } + template <typename U> bool destructively_aliases ( const U& ) const { return false; } + }; + +// ---------------------------------------------------------------------------------------- + + template <typename M> + struct basic_op_m + { + /*! + This is a partial implementation of a matrix operator that preserves + the dimensions of its argument and doesn't have destructive aliasing. + !*/ + + private: + // This constructor exists simply for the purpose of causing a compile time error if + // someone tries to create an instance of this object with the wrong kind of object. + template <typename T1> + basic_op_m (T1); + public: + + basic_op_m( + const M& m_ + ) : m(m_){} + + const M& m; + + const static long NR = M::NR; + const static long NC = M::NC; + typedef typename M::mem_manager_type mem_manager_type; + typedef typename M::layout_type layout_type; + + long nr () const { return m.nr(); } + long nc () const { return m.nc(); } + + template <typename U> bool aliases ( const matrix_exp<U>& item) const + { return m.aliases(item); } + template <typename U> bool destructively_aliases ( const matrix_exp<U>& item) const + { return m.destructively_aliases(item); } + + }; + +// ---------------------------------------------------------------------------------------- + + template <typename M1, typename M2> + struct basic_op_mm + { + /*! + This is a partial implementation of a matrix operator that preserves + the dimensions of its arguments and doesn't have destructive aliasing. + !*/ + + private: + // This constructor exists simply for the purpose of causing a compile time error if + // someone tries to create an instance of this object with the wrong kind of object. + template <typename T1, typename T2> + basic_op_mm (T1, T2); + public: + + basic_op_mm( + const M1& m1_, + const M2& m2_ + ) : m1(m1_), m2(m2_){} + + const M1& m1; + const M2& m2; + + const static long NR = M1::NR; + const static long NC = M1::NC; + typedef typename M1::mem_manager_type mem_manager_type; + typedef typename M1::layout_type layout_type; + + long nr () const { return m1.nr(); } + long nc () const { return m1.nc(); } + + template <typename U> bool aliases ( const matrix_exp<U>& item) const + { return m1.aliases(item) || m2.aliases(item); } + template <typename U> bool destructively_aliases ( const matrix_exp<U>& item) const + { return m1.destructively_aliases(item) || m2.destructively_aliases(item); } + + }; + +// ---------------------------------------------------------------------------------------- + + template <typename M1, typename M2, typename M3> + struct basic_op_mmm + { + /*! + This is a partial implementation of a matrix operator that preserves + the dimensions of its arguments and doesn't have destructive aliasing. + !*/ + + private: + // This constructor exists simply for the purpose of causing a compile time error if + // someone tries to create an instance of this object with the wrong kind of object. + template <typename T1, typename T2, typename T3> + basic_op_mmm (T1, T2, T3); + public: + + basic_op_mmm( + const M1& m1_, + const M2& m2_, + const M3& m3_ + ) : m1(m1_), m2(m2_), m3(m3_){} + + const M1& m1; + const M2& m2; + const M3& m3; + + const static long NR = M1::NR; + const static long NC = M1::NC; + typedef typename M1::mem_manager_type mem_manager_type; + typedef typename M1::layout_type layout_type; + + long nr () const { return m1.nr(); } + long nc () const { return m1.nc(); } + + template <typename U> bool aliases ( const matrix_exp<U>& item) const + { return m1.aliases(item) || m2.aliases(item) || m3.aliases(item); } + template <typename U> bool destructively_aliases ( const matrix_exp<U>& item) const + { return m1.destructively_aliases(item) || m2.destructively_aliases(item) || + m3.destructively_aliases(item);} + + }; + +// ---------------------------------------------------------------------------------------- + + template <typename M1, typename M2, typename M3, typename M4> + struct basic_op_mmmm + { + /*! + This is a partial implementation of a matrix operator that preserves + the dimensions of its arguments and doesn't have destructive aliasing. + !*/ + + private: + // This constructor exists simply for the purpose of causing a compile time error if + // someone tries to create an instance of this object with the wrong kind of object. + template <typename T1, typename T2, typename T3, typename T4> + basic_op_mmmm (T1, T2, T3, T4); + public: + + basic_op_mmmm( + const M1& m1_, + const M2& m2_, + const M3& m3_, + const M4& m4_ + ) : m1(m1_), m2(m2_), m3(m3_), m4(m4_){} + + const M1& m1; + const M2& m2; + const M3& m3; + const M4& m4; + + const static long NR = M1::NR; + const static long NC = M1::NC; + typedef typename M1::mem_manager_type mem_manager_type; + typedef typename M1::layout_type layout_type; + + long nr () const { return m1.nr(); } + long nc () const { return m1.nc(); } + + template <typename U> bool aliases ( const matrix_exp<U>& item) const + { return m1.aliases(item) || m2.aliases(item) || m3.aliases(item) || m4.aliases(item); } + template <typename U> bool destructively_aliases ( const matrix_exp<U>& item) const + { return m1.destructively_aliases(item) || m2.destructively_aliases(item) || + m3.destructively_aliases(item) || m4.destructively_aliases(item);} + + }; + +// ---------------------------------------------------------------------------------------- + +#define DLIB_DEFINE_OP_M(op_name, function, extra_cost) \ + template <typename M> \ + struct op_name \ + { \ + op_name( \ + const M& m_ \ + ) : m(m_){} \ + \ + const M& m; \ + \ + const static long cost = M::cost+(extra_cost); \ + const static long NR = M::NR; \ + const static long NC = M::NC; \ + typedef typename M::type type; \ + typedef const typename M::type const_ret_type; \ + typedef typename M::mem_manager_type mem_manager_type; \ + typedef typename M::layout_type layout_type; \ + \ + const_ret_type apply (long r, long c) const { return function(m(r,c)); } \ + \ + long nr () const { return m.nr(); } \ + long nc () const { return m.nc(); } \ + \ + template <typename U> bool aliases ( const matrix_exp<U>& item) const \ + { return m.aliases(item); } \ + template <typename U> bool destructively_aliases ( const matrix_exp<U>& item) const \ + { return m.destructively_aliases(item); } \ + \ + } + +#define DLIB_DEFINE_FUNCTION_M(op_name, name, function, extra_cost) \ + DLIB_DEFINE_OP_M(op_name, function, extra_cost); \ + template < typename M > \ + const matrix_op<op_name<M> > name ( const matrix_exp<M>& m) \ + { \ + typedef op_name<M> op; \ + return matrix_op<op>(op(m.ref())); \ + } + +// ---------------------------------------------------------------------------------------- + +#define DLIB_DEFINE_OP_MS(op_name, function, extra_cost) \ + template <typename M, typename S> \ + struct op_name \ + { \ + op_name( \ + const M& m_, \ + const S& s_ \ + ) : m(m_), s(s_){} \ + \ + const M& m; \ + const S s; \ + \ + const static long cost = M::cost+(extra_cost); \ + const static long NR = M::NR; \ + const static long NC = M::NC; \ + typedef typename M::type type; \ + typedef const typename M::type const_ret_type; \ + typedef typename M::mem_manager_type mem_manager_type; \ + typedef typename M::layout_type layout_type; \ + \ + const_ret_type apply (long r, long c) const { return function(m(r,c), s); } \ + \ + long nr () const { return m.nr(); } \ + long nc () const { return m.nc(); } \ + \ + template <typename U> bool aliases ( const matrix_exp<U>& item) const \ + { return m.aliases(item); } \ + template <typename U> bool destructively_aliases ( const matrix_exp<U>& item) const \ + { return m.destructively_aliases(item); } \ + \ + } + +#define DLIB_DEFINE_FUNCTION_MS(op_name, name, function, extra_cost) \ + DLIB_DEFINE_OP_MS(op_name, function, extra_cost); \ + template < typename M, typename S > \ + const matrix_op<op_name<M, S> > name ( const matrix_exp<M>& m, const S& s) \ + { \ + typedef op_name<M, S> op; \ + return matrix_op<op>(op(m.ref(), s)); \ + } + +// ---------------------------------------------------------------------------------------- + +#define DLIB_DEFINE_OP_SM(op_name, function, extra_cost) \ + template <typename S, typename M> \ + struct op_name \ + { \ + op_name( \ + const S& s_, \ + const M& m_ \ + ) : m(m_), s(s_){} \ + \ + const M& m; \ + const S s; \ + \ + const static long cost = M::cost+(extra_cost); \ + const static long NR = M::NR; \ + const static long NC = M::NC; \ + typedef typename M::type type; \ + typedef const typename M::type const_ret_type; \ + typedef typename M::mem_manager_type mem_manager_type; \ + typedef typename M::layout_type layout_type; \ + \ + const_ret_type apply (long r, long c) const { return function(s, m(r,c)); } \ + \ + long nr () const { return m.nr(); } \ + long nc () const { return m.nc(); } \ + \ + template <typename U> bool aliases ( const matrix_exp<U>& item) const \ + { return m.aliases(item); } \ + template <typename U> bool destructively_aliases ( const matrix_exp<U>& item) const \ + { return m.destructively_aliases(item); } \ + \ + } + +#define DLIB_DEFINE_FUNCTION_SM(op_name, name, function, extra_cost) \ + DLIB_DEFINE_OP_SM(op_name, function, extra_cost); \ + template < typename S, typename M > \ + const matrix_op<op_name<S, M> > name (const S& s, const matrix_exp<M>& m) \ + { \ + typedef op_name<S, M> op; \ + return matrix_op<op>(op(s, m.ref())); \ + } + +// ---------------------------------------------------------------------------------------- + +} + +#endif // DLIB_MATRIx_OP_H_ + |