summaryrefslogtreecommitdiffstats
path: root/ml/dlib/dlib/matrix/matrix_op.h
diff options
context:
space:
mode:
Diffstat (limited to 'ml/dlib/dlib/matrix/matrix_op.h')
-rw-r--r--ml/dlib/dlib/matrix/matrix_op.h479
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_
+