sustaining_gazes/lib/3rdParty/dlib/include/dlib/matrix/matrix_op.h

480 lines
23 KiB
C++

// 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_