Commit dd08cc4f authored by Davis King's avatar Davis King

Refactored a bunch of the matrix code into a cleaner form. I also added a

cost member to all the matrix expressions so that the complexity of an
expression can be measured and temporaries introduced when appropriate.

--HG--
extra : convert_revision : svn%3Afdd8eb12-d10e-0410-9acb-85c331704f74/trunk%402732
parent 14121d95
...@@ -45,7 +45,7 @@ namespace dlib ...@@ -45,7 +45,7 @@ namespace dlib
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
template <typename T> template <typename T, typename helper = void>
struct is_matrix : public default_is_kind_value struct is_matrix : public default_is_kind_value
{ {
/*! /*!
...@@ -54,6 +54,9 @@ namespace dlib ...@@ -54,6 +54,9 @@ namespace dlib
- else - else
- is_matrix<T>::value == false - is_matrix<T>::value == false
!*/ !*/
// Don't set the helper to anything. Just let it be void.
ASSERT_ARE_SAME_TYPE(helper,void);
}; };
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
......
...@@ -29,72 +29,6 @@ ...@@ -29,72 +29,6 @@
namespace dlib namespace dlib
{ {
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
template <
typename T,
long num_rows,
long num_cols,
typename mem_manager,
typename layout
>
class matrix_ref
{
public:
typedef T type;
typedef matrix_ref ref_type;
typedef mem_manager mem_manager_type;
typedef layout layout_type;
const static long NR = num_rows;
const static long NC = num_cols;
matrix_ref (
const matrix<T,num_rows,num_cols,mem_manager,layout>& m_
) : m(m_) {}
matrix_ref (
const matrix_ref& i_
) : m(i_.m) {}
const T& operator() (
long r,
long c
) const { return m(r,c); }
long nr (
) const { return m.nr(); }
long nc (
) const { return m.nc(); }
long size (
) const { return m.size(); }
template <typename U, long iNR, long iNC, typename mm, typename l >
bool aliases (
const matrix<U,iNR,iNC,mm,l>& item
) const { return false; }
template <typename U, long iNR, long iNC, typename mm, typename l>
bool destructively_aliases (
const matrix<U,iNR,iNC,mm,l>& item
) const { return false; }
bool aliases (
const matrix<T,num_rows,num_cols,mem_manager,layout>& item
) const { return (&m == &item); }
const matrix_ref ref(
) const { return *this; }
private:
// no assignment operator
matrix_ref& operator=(const matrix_ref&);
const matrix<T,num_rows,num_cols,mem_manager,layout>& m; // This is the item contained by this expression.
};
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
...@@ -102,48 +36,65 @@ namespace dlib ...@@ -102,48 +36,65 @@ namespace dlib
// We want to return the compile time constant if our NR and NC dimensions // We want to return the compile time constant if our NR and NC dimensions
// aren't zero but if they are then we want to call ref_.nx() and return // aren't zero but if they are then we want to call ref_.nx() and return
// the correct values. // the correct values.
template < typename ref_type, long NR > template < typename exp_type, long NR >
struct get_nr_helper struct get_nr_helper
{ {
static inline long get(const ref_type&) { return NR; } static inline long get(const exp_type&) { return NR; }
}; };
template < typename ref_type > template < typename exp_type >
struct get_nr_helper<ref_type,0> struct get_nr_helper<exp_type,0>
{ {
static inline long get(const ref_type& m) { return m.nr(); } static inline long get(const exp_type& m) { return m.nr(); }
}; };
template < typename ref_type, long NC > template < typename exp_type, long NC >
struct get_nc_helper struct get_nc_helper
{ {
static inline long get(const ref_type&) { return NC; } static inline long get(const exp_type&) { return NC; }
}; };
template < typename ref_type > template < typename exp_type >
struct get_nc_helper<ref_type,0> struct get_nc_helper<exp_type,0>
{ {
static inline long get(const ref_type& m) { return m.nc(); } static inline long get(const exp_type& m) { return m.nc(); }
}; };
template <typename EXP>
struct matrix_traits
{
typedef typename EXP::type type;
typedef typename EXP::mem_manager_type mem_manager_type;
// TODO
//typedef typename EXP::layout_type layout_type;
const static long NR = EXP::NR;
const static long NC = EXP::NC;
const static long cost = EXP::cost;
};
// the matrix_exp for statically sized matrices
template < template <
typename EXP typename EXP
> >
class matrix_exp class matrix_exp
{ {
/*!
REQUIREMENTS ON EXP
EXP should be something convertible to a matrix_exp. That is,
it should inherit from matrix_exp
!*/
public: public:
typedef typename EXP::type type; typedef typename matrix_traits<EXP>::type type;
typedef typename EXP::ref_type ref_type; typedef typename matrix_traits<EXP>::mem_manager_type mem_manager_type;
typedef typename EXP::mem_manager_type mem_manager_type; // TODO
const static long NR = EXP::NR; //typedef typename matrix_traits<EXP>::layout_type layout_type;
const static long NC = EXP::NC; const static long NR = matrix_traits<EXP>::NR;
typedef matrix<type,NR,NC,mem_manager_type> matrix_type; const static long NC = matrix_traits<EXP>::NC;
const static long cost = matrix_traits<EXP>::cost;
matrix_exp ( typedef matrix<type,NR,NC,mem_manager_type> matrix_type;
const EXP& exp typedef EXP exp_type;
) : ref_(exp.ref()) {}
inline const type operator() ( inline const type operator() (
long r, long r,
...@@ -193,10 +144,10 @@ namespace dlib ...@@ -193,10 +144,10 @@ namespace dlib
) const { return nr()*nc(); } ) const { return nr()*nc(); }
long nr ( long nr (
) const { return get_nr_helper<ref_type,NR>::get(ref_); } ) const { return get_nr_helper<exp_type,NR>::get(ref_); }
long nc ( long nc (
) const { return get_nc_helper<ref_type,NC>::get(ref_); } ) const { return get_nc_helper<exp_type,NC>::get(ref_); }
template <typename U, long iNR, long iNC, typename mm, typename l > template <typename U, long iNR, long iNC, typename mm, typename l >
bool aliases ( bool aliases (
...@@ -208,7 +159,7 @@ namespace dlib ...@@ -208,7 +159,7 @@ namespace dlib
const matrix<U,iNR,iNC,mm,l>& item const matrix<U,iNR,iNC,mm,l>& item
) const { return ref_.destructively_aliases(item); } ) const { return ref_.destructively_aliases(item); }
const ref_type& ref ( const exp_type& ref (
) const { return ref_; } ) const { return ref_; }
inline operator const type ( inline operator const type (
...@@ -226,32 +177,31 @@ namespace dlib ...@@ -226,32 +177,31 @@ namespace dlib
return ref_(0,0); return ref_(0,0);
} }
protected:
explicit matrix_exp (
const EXP& exp
) : ref_(exp) {}
matrix_exp(const matrix_exp& item) : ref_(item.ref_) {}
private: private:
matrix_exp& operator= (const matrix_exp&);
const ref_type ref_; const exp_type& ref_;
}; };
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
// something is a matrix if it is convertible to a matrix_exp object
template <typename T> template <typename T>
struct is_matrix<matrix_exp<T> > { static const bool value = true; }; struct is_matrix<T, typename enable_if<is_convertible<T, const matrix_exp<typename T::exp_type>& > >::type >
template <typename T, long NR, long NC, typename mm, typename l> { static const bool value = true; };
struct is_matrix<matrix_ref<T,NR,NC,mm,l> > { static const bool value = true; };
template <typename T, long NR, long NC, typename mm, typename l>
struct is_matrix<matrix<T,NR,NC,mm,l> > { static const bool value = true; };
template <typename T>
struct is_matrix<T&> { static const bool value = is_matrix<T>::value; };
template <typename T>
struct is_matrix<const T&> { static const bool value = is_matrix<T>::value; };
template <typename T>
struct is_matrix<const T> { static const bool value = is_matrix<T>::value; };
/* /*
is_matrix<T>::value == 1 if T is a matrix type else 0 is_matrix<T>::value == 1 if T is a matrix type else 0
*/ */
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
// This template will perform the needed loop for element multiplication using whichever // This template will perform the needed loop for element multiplication using whichever
// dimension is provided as a compile time constant (if one is at all). // dimension is provided as a compile time constant (if one is at all).
...@@ -264,9 +214,10 @@ namespace dlib ...@@ -264,9 +214,10 @@ namespace dlib
struct matrix_multiply_helper struct matrix_multiply_helper
{ {
typedef typename LHS::type type; typedef typename LHS::type type;
template <typename RHS_, typename LHS_>
inline const static type eval ( inline const static type eval (
const RHS& rhs, const RHS_& rhs,
const LHS& lhs, const LHS_& lhs,
long r, long r,
long c long c
) )
...@@ -288,9 +239,10 @@ namespace dlib ...@@ -288,9 +239,10 @@ namespace dlib
struct matrix_multiply_helper <LHS,RHS,lhs_nc,0> struct matrix_multiply_helper <LHS,RHS,lhs_nc,0>
{ {
typedef typename LHS::type type; typedef typename LHS::type type;
template <typename RHS_, typename LHS_>
inline const static type eval ( inline const static type eval (
const RHS& rhs, const RHS_& rhs,
const LHS& lhs, const LHS_& lhs,
long r, long r,
long c long c
) )
...@@ -304,33 +256,66 @@ namespace dlib ...@@ -304,33 +256,66 @@ namespace dlib
} }
}; };
template <typename LHS, typename RHS>
class matrix_multiply_exp;
template <typename LHS, typename RHS>
struct matrix_traits<matrix_multiply_exp<LHS,RHS> >
{
typedef typename LHS::type type;
typedef typename LHS::mem_manager_type mem_manager_type;
const static long NR = LHS::NR;
const static long NC = RHS::NC;
const static bool lhs_is_costly = (LHS::cost > 4)&&(RHS::NC != 1);
const static bool rhs_is_costly = (RHS::cost > 4)&&(LHS::NR != 1);
// Note that if we decide that one of the matrices is too costly we will evaluate it
// into a temporary. Doing this resets its cost back to 1.
const static long lhs_cost = ((lhs_is_costly==true)? 1 : (LHS::cost));
const static long rhs_cost = ((rhs_is_costly==true)? 1 : (RHS::cost));
// The cost of evaluating an element of a matrix multiply is the cost of evaluating elements from
// RHS and LHS times the number of rows/columns in the RHS/LHS matrix. If we don't know the matrix
// dimensions then just assume it is really large.
const static long cost = (lhs_cost+rhs_cost)*
((tmax<LHS::NC,RHS::NR>::value!=0)? (tmax<LHS::NC,RHS::NR>::value):(10000));
};
template <typename T, bool is_ref> struct conditional_matrix_temp { typedef typename T::matrix_type type; };
template <typename T> struct conditional_matrix_temp<T,true> { typedef T& type; };
template < template <
typename LHS, typename LHS,
typename RHS, typename RHS
unsigned long count = 0
> >
class matrix_multiply_exp class matrix_multiply_exp : public matrix_exp<matrix_multiply_exp<LHS,RHS> >
{ {
/*! /*!
REQUIREMENTS ON LHS AND RHS REQUIREMENTS ON LHS AND RHS
- they must be matrix_exp or matrix_ref objects (or - must be matrix_exp objects.
objects with a compatible interface).
!*/ !*/
public: public:
typedef typename LHS::type type;
typedef matrix_multiply_exp ref_type;
typedef typename LHS::mem_manager_type mem_manager_type;
const static long NR = LHS::NR;
const static long NC = RHS::NC;
matrix_multiply_exp ( typedef typename matrix_traits<matrix_multiply_exp>::type type;
const matrix_multiply_exp& item typedef typename matrix_traits<matrix_multiply_exp>::mem_manager_type mem_manager_type;
) : lhs(item.lhs), rhs(item.rhs) {} const static long NR = matrix_traits<matrix_multiply_exp>::NR;
const static long NC = matrix_traits<matrix_multiply_exp>::NC;
const static long cost = matrix_traits<matrix_multiply_exp>::cost;
const static bool lhs_is_costly = matrix_traits<matrix_multiply_exp>::lhs_is_costly;
const static bool rhs_is_costly = matrix_traits<matrix_multiply_exp>::rhs_is_costly;
typedef typename conditional_matrix_temp<const LHS,lhs_is_costly == false>::type LHS_ref_type;
typedef typename conditional_matrix_temp<const RHS,rhs_is_costly == false>::type RHS_ref_type;
inline matrix_multiply_exp ( inline matrix_multiply_exp (
const LHS& lhs_, const LHS& lhs_,
const RHS& rhs_ const RHS& rhs_
) : ) :
matrix_exp<matrix_multiply_exp>(*this),
lhs(lhs_), lhs(lhs_),
rhs(rhs_) rhs(rhs_)
{ {
...@@ -360,6 +345,9 @@ namespace dlib ...@@ -360,6 +345,9 @@ namespace dlib
return matrix_multiply_helper<LHS,RHS>::eval(rhs,lhs,r,c); return matrix_multiply_helper<LHS,RHS>::eval(rhs,lhs,r,c);
} }
inline const type operator() ( long i ) const
{ return matrix_exp<matrix_multiply_exp>::operator()(i); }
long nr ( long nr (
) const { return lhs.nr(); } ) const { return lhs.nr(); }
...@@ -376,129 +364,62 @@ namespace dlib ...@@ -376,129 +364,62 @@ namespace dlib
const matrix<U,iNR,iNC,mm,l>& item const matrix<U,iNR,iNC,mm,l>& item
) const { return aliases(item); } ) const { return aliases(item); }
const ref_type& ref( LHS_ref_type lhs;
) const { return *this; } RHS_ref_type rhs;
const LHS lhs;
const RHS rhs;
}; };
template < template < typename EXP1, typename EXP2 >
typename T, inline const matrix_multiply_exp<EXP1, EXP2> operator* (
long NR,
long NC,
typename EXP1,
typename EXP2,
typename MM,
typename L
>
inline const matrix_exp<matrix_multiply_exp<EXP1, matrix_multiply_exp<EXP2,typename matrix<T,NR,NC,MM,L>::ref_type >,0 > > operator* (
const matrix_exp<matrix_multiply_exp<EXP1,EXP2,1> >& m1,
const matrix<T,NR,NC,MM,L>& m2
)
{
// We are going to reorder the order of evaluation of the terms here. This way the
// multiplication will go faster.
typedef matrix_multiply_exp<EXP2,typename matrix<T,NR,NC,MM,L>::ref_type > exp_inner;
typedef matrix_multiply_exp<EXP1, exp_inner,0 > exp_outer;
return matrix_exp<exp_outer>(exp_outer(m1.ref().lhs,exp_inner(m1.ref().rhs,m2)));
}
template <
typename EXP1,
typename EXP2
>
inline const matrix_exp<matrix_multiply_exp<EXP1, EXP2 > > operator* (
const matrix_exp<EXP1>& m1, const matrix_exp<EXP1>& m1,
const matrix_exp<EXP2>& m2 const matrix_exp<EXP2>& m2
) )
{ {
typedef matrix_multiply_exp<EXP1, EXP2> exp; return matrix_multiply_exp<EXP1, EXP2>(m1.ref(), m2.ref());
return matrix_exp<exp>(exp(m1.ref(),m2.ref()));
} }
template < // ----------------------------------------------------------------------------------------
typename T,
long NR,
long NC,
typename EXP,
typename MM,
typename L
>
inline const matrix_exp<matrix_multiply_exp<typename matrix<T,NR,NC,MM,L>::ref_type, matrix_exp<EXP> > > operator* (
const matrix<T,NR,NC,MM,L>& m1,
const matrix_exp<EXP>& m2
)
{
typedef matrix_multiply_exp<typename matrix<T,NR,NC,MM,L>::ref_type, matrix_exp<EXP> > exp;
return matrix_exp<exp>(exp(m1,m2));
}
template < template <typename LHS, typename RHS>
typename T, class matrix_add_exp;
long NR,
long NC,
typename EXP,
typename MM,
typename L
>
inline const matrix_exp<matrix_multiply_exp< matrix_exp<EXP>, typename matrix<T,NR,NC,MM,L>::ref_type, 1> > operator* (
const matrix_exp<EXP>& m1,
const matrix<T,NR,NC,MM,L>& m2
)
{
typedef matrix_multiply_exp< matrix_exp<EXP>, typename matrix<T,NR,NC,MM,L>::ref_type, 1 > exp;
return matrix_exp<exp>(exp(m1,m2));
}
template < template <typename LHS, typename RHS>
typename T, struct matrix_traits<matrix_add_exp<LHS,RHS> >
long NR1,
long NC1,
long NR2,
long NC2,
typename MM1,
typename MM2,
typename L1,
typename L2
>
inline const matrix_exp<matrix_multiply_exp<typename matrix<T,NR1,NC1,MM1,L1>::ref_type,typename matrix<T,NR2,NC2,MM2,L2>::ref_type > > operator* (
const matrix<T,NR1,NC1,MM1,L1>& m1,
const matrix<T,NR2,NC2,MM2,L2>& m2
)
{ {
typedef matrix_multiply_exp<typename matrix<T,NR1,NC1,MM1,L1>::ref_type, typename matrix<T,NR2,NC2,MM2,L2>::ref_type > exp; typedef typename LHS::type type;
return matrix_exp<exp>(exp(m1,m2)); typedef typename LHS::mem_manager_type mem_manager_type;
} const static long NR = (RHS::NR > LHS::NR) ? RHS::NR : LHS::NR;
const static long NC = (RHS::NC > LHS::NC) ? RHS::NC : LHS::NC;
// ---------------------------------------------------------------------------------------- const static long cost = LHS::cost+RHS::cost;
};
template < template <
typename LHS, typename LHS,
typename RHS typename RHS
> >
class matrix_add_expression class matrix_add_exp : public matrix_exp<matrix_add_exp<LHS,RHS> >
{ {
/*! /*!
REQUIREMENTS ON LHS AND RHS REQUIREMENTS ON LHS AND RHS
- they must be matrix_exp or matrix_ref objects (or - must be matrix_exp objects.
objects with a compatible interface).
!*/ !*/
public: public:
typedef typename LHS::type type; typedef typename matrix_traits<matrix_add_exp>::type type;
typedef typename LHS::mem_manager_type mem_manager_type; typedef typename matrix_traits<matrix_add_exp>::mem_manager_type mem_manager_type;
typedef matrix_add_expression ref_type; const static long NR = matrix_traits<matrix_add_exp>::NR;
const static long NR = (RHS::NR > LHS::NR) ? RHS::NR : LHS::NR; const static long NC = matrix_traits<matrix_add_exp>::NC;
const static long NC = (RHS::NC > LHS::NC) ? RHS::NC : LHS::NC; const static long cost = matrix_traits<matrix_add_exp>::cost;
matrix_add_expression ( /*
const matrix_add_expression& item matrix_add_exp (
) : lhs(item.lhs), rhs(item.rhs) {} const matrix_add_exp& item
) : matrix_exp<matrix_add_exp>(*this), lhs(item.lhs), rhs(item.rhs) {}
matrix_add_expression ( */
matrix_add_exp (
const LHS& lhs_, const LHS& lhs_,
const RHS& rhs_ const RHS& rhs_
) : ) :
matrix_exp<matrix_add_exp>(*this),
lhs(lhs_), lhs(lhs_),
rhs(rhs_) rhs(rhs_)
{ {
...@@ -526,6 +447,9 @@ namespace dlib ...@@ -526,6 +447,9 @@ namespace dlib
long c long c
) const { return lhs(r,c) + rhs(r,c); } ) const { return lhs(r,c) + rhs(r,c); }
inline const type operator() ( long i ) const
{ return matrix_exp<matrix_add_exp>::operator()(i); }
template <typename U, long iNR, long iNC , typename mm, typename l> template <typename U, long iNR, long iNC , typename mm, typename l>
bool aliases ( bool aliases (
const matrix<U,iNR,iNC,mm,l>& item const matrix<U,iNR,iNC,mm,l>& item
...@@ -536,56 +460,65 @@ namespace dlib ...@@ -536,56 +460,65 @@ namespace dlib
const matrix<U,iNR,iNC,mm,l>& item const matrix<U,iNR,iNC,mm,l>& item
) const { return lhs.destructively_aliases(item) || rhs.destructively_aliases(item); } ) const { return lhs.destructively_aliases(item) || rhs.destructively_aliases(item); }
const ref_type& ref(
) const { return *this; }
long nr ( long nr (
) const { return lhs.nr(); } ) const { return lhs.nr(); }
long nc ( long nc (
) const { return lhs.nc(); } ) const { return lhs.nc(); }
const LHS lhs; const LHS& lhs;
const RHS rhs; const RHS& rhs;
}; };
template < template <
typename EXP1, typename EXP1,
typename EXP2 typename EXP2
> >
inline const matrix_exp<matrix_add_expression<EXP1, EXP2 > > operator+ ( inline const matrix_add_exp<EXP1, EXP2> operator+ (
const matrix_exp<EXP1>& m1, const matrix_exp<EXP1>& m1,
const matrix_exp<EXP2>& m2 const matrix_exp<EXP2>& m2
) )
{ {
typedef matrix_add_expression<EXP1, EXP2 > exp; return matrix_add_exp<EXP1, EXP2>(m1.ref(),m2.ref());
return matrix_exp<exp>(exp(m1.ref(),m2.ref()));
} }
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
template <typename LHS, typename RHS>
class matrix_subtract_exp;
template <typename LHS, typename RHS>
struct matrix_traits<matrix_subtract_exp<LHS,RHS> >
{
typedef typename LHS::type type;
typedef typename LHS::mem_manager_type mem_manager_type;
const static long NR = (RHS::NR > LHS::NR) ? RHS::NR : LHS::NR;
const static long NC = (RHS::NC > LHS::NC) ? RHS::NC : LHS::NC;
const static long cost = LHS::cost+RHS::cost;
};
template < template <
typename LHS, typename LHS,
typename RHS typename RHS
> >
class matrix_subtract_exp class matrix_subtract_exp : public matrix_exp<matrix_subtract_exp<LHS,RHS> >
{ {
/*! /*!
REQUIREMENTS ON LHS AND RHS REQUIREMENTS ON LHS AND RHS
- they must be matrix_exp or matrix_ref objects (or - must be matrix_exp objects.
objects with a compatible interface).
!*/ !*/
public: public:
typedef typename LHS::type type; typedef typename matrix_traits<matrix_subtract_exp>::type type;
typedef typename LHS::mem_manager_type mem_manager_type; typedef typename matrix_traits<matrix_subtract_exp>::mem_manager_type mem_manager_type;
typedef matrix_subtract_exp ref_type; const static long NR = matrix_traits<matrix_subtract_exp>::NR;
const static long NR = (RHS::NR > LHS::NR) ? RHS::NR : LHS::NR; const static long NC = matrix_traits<matrix_subtract_exp>::NC;
const static long NC = (RHS::NC > LHS::NC) ? RHS::NC : LHS::NC; const static long cost = matrix_traits<matrix_subtract_exp>::cost;
matrix_subtract_exp ( matrix_subtract_exp (
const LHS& lhs_, const LHS& lhs_,
const RHS& rhs_ const RHS& rhs_
) : ) : matrix_exp<matrix_subtract_exp>(*this),
lhs(lhs_), lhs(lhs_),
rhs(rhs_) rhs(rhs_)
{ {
...@@ -613,6 +546,9 @@ namespace dlib ...@@ -613,6 +546,9 @@ namespace dlib
long c long c
) const { return lhs(r,c) - rhs(r,c); } ) const { return lhs(r,c) - rhs(r,c); }
inline const type operator() ( long i ) const
{ return matrix_exp<matrix_subtract_exp>::operator()(i); }
template <typename U, long iNR, long iNC, typename mm, typename l > template <typename U, long iNR, long iNC, typename mm, typename l >
bool aliases ( bool aliases (
const matrix<U,iNR,iNC, mm,l>& item const matrix<U,iNR,iNC, mm,l>& item
...@@ -623,59 +559,69 @@ namespace dlib ...@@ -623,59 +559,69 @@ namespace dlib
const matrix<U,iNR,iNC,mm,l>& item const matrix<U,iNR,iNC,mm,l>& item
) const { return lhs.destructively_aliases(item) || rhs.destructively_aliases(item); } ) const { return lhs.destructively_aliases(item) || rhs.destructively_aliases(item); }
const ref_type& ref(
) const { return *this; }
long nr ( long nr (
) const { return lhs.nr(); } ) const { return lhs.nr(); }
long nc ( long nc (
) const { return lhs.nc(); } ) const { return lhs.nc(); }
const LHS lhs; const LHS& lhs;
const RHS rhs; const RHS& rhs;
}; };
template < template <
typename EXP1, typename EXP1,
typename EXP2 typename EXP2
> >
inline const matrix_exp<matrix_subtract_exp<EXP1, EXP2 > > operator- ( inline const matrix_subtract_exp<EXP1, EXP2> operator- (
const matrix_exp<EXP1>& m1, const matrix_exp<EXP1>& m1,
const matrix_exp<EXP2>& m2 const matrix_exp<EXP2>& m2
) )
{ {
typedef matrix_subtract_exp<EXP1, EXP2 > exp; return matrix_subtract_exp<EXP1, EXP2>(m1.ref(),m2.ref());
return matrix_exp<exp>(exp(m1.ref(),m2.ref()));
} }
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
template <typename M, typename S>
class matrix_div_scal_exp;
template <typename M, typename S>
struct matrix_traits<matrix_div_scal_exp<M,S> >
{
typedef typename M::type type;
typedef typename M::mem_manager_type mem_manager_type;
const static long NR = M::NR;
const static long NC = M::NC;
const static long cost = M::cost+1;
};
template < template <
typename M, typename M,
typename S typename S
> >
class matrix_divscal_exp class matrix_div_scal_exp : public matrix_exp<matrix_div_scal_exp<M,S> >
{ {
/*! /*!
REQUIREMENTS ON M REQUIREMENTS ON M
- must be a matrix_exp or matrix_ref object (or - must be a matrix_exp object.
an object with a compatible interface).
REQUIREMENTS ON S REQUIREMENTS ON S
- must be some kind of scalar type - must be some kind of scalar type capable of dividing the elements
of a matrix of type M
!*/ !*/
public: public:
typedef typename M::type type; typedef typename matrix_traits<matrix_div_scal_exp>::type type;
typedef typename M::mem_manager_type mem_manager_type; typedef typename matrix_traits<matrix_div_scal_exp>::mem_manager_type mem_manager_type;
typedef matrix_divscal_exp ref_type; const static long NR = matrix_traits<matrix_div_scal_exp>::NR;
const static long NR = M::NR; const static long NC = matrix_traits<matrix_div_scal_exp>::NC;
const static long NC = M::NC; const static long cost = matrix_traits<matrix_div_scal_exp>::cost;
matrix_divscal_exp ( matrix_div_scal_exp (
const M& m_, const M& m_,
const S& s_ const S& s_
) : ) :
matrix_exp<matrix_div_scal_exp>(*this),
m(m_), m(m_),
s(s_) s(s_)
{} {}
...@@ -685,6 +631,9 @@ namespace dlib ...@@ -685,6 +631,9 @@ namespace dlib
long c long c
) const { return m(r,c)/s; } ) const { return m(r,c)/s; }
inline const type operator() ( long i ) const
{ return matrix_exp<matrix_div_scal_exp>::operator()(i); }
template <typename U, long iNR, long iNC, typename mm , typename l> template <typename U, long iNR, long iNC, typename mm , typename l>
bool aliases ( bool aliases (
const matrix<U,iNR,iNC,mm,l>& item const matrix<U,iNR,iNC,mm,l>& item
...@@ -695,16 +644,13 @@ namespace dlib ...@@ -695,16 +644,13 @@ namespace dlib
const matrix<U,iNR,iNC,mm,l>& item const matrix<U,iNR,iNC,mm,l>& item
) const { return m.destructively_aliases(item); } ) const { return m.destructively_aliases(item); }
const ref_type& ref(
) const { return *this; }
long nr ( long nr (
) const { return m.nr(); } ) const { return m.nr(); }
long nc ( long nc (
) const { return m.nc(); } ) const { return m.nc(); }
const M m; const M& m;
const S s; const S s;
}; };
...@@ -712,42 +658,54 @@ namespace dlib ...@@ -712,42 +658,54 @@ namespace dlib
typename EXP, typename EXP,
typename S typename S
> >
inline const matrix_exp<matrix_divscal_exp<matrix_exp<EXP>, S> > operator/ ( inline const matrix_div_scal_exp<EXP, S> operator/ (
const matrix_exp<EXP>& m, const matrix_exp<EXP>& m,
const S& s const S& s
) )
{ {
typedef matrix_divscal_exp<matrix_exp<EXP>,S > exp; return matrix_div_scal_exp<EXP,S>(m.ref(),s);
return matrix_exp<exp>(exp(m,s));
} }
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
template <typename M, typename S>
class matrix_mul_scal_exp;
template <typename M, typename S>
struct matrix_traits<matrix_mul_scal_exp<M,S> >
{
typedef typename M::type type;
typedef typename M::mem_manager_type mem_manager_type;
const static long NR = M::NR;
const static long NC = M::NC;
const static long cost = M::cost+1;
};
template < template <
typename M, typename M,
typename S typename S
> >
class matrix_mulscal_exp class matrix_mul_scal_exp : public matrix_exp<matrix_mul_scal_exp<M,S> >
{ {
/*! /*!
REQUIREMENTS ON M REQUIREMENTS ON M
- must be a matrix_exp or matrix_ref object (or - must be a matrix_exp object.
an object with a compatible interface).
REQUIREMENTS ON S REQUIREMENTS ON S
- must be some kind of scalar type - must be some kind of scalar type
!*/ !*/
public: public:
typedef typename M::type type; typedef typename matrix_traits<matrix_mul_scal_exp>::type type;
typedef typename M::mem_manager_type mem_manager_type; typedef typename matrix_traits<matrix_mul_scal_exp>::mem_manager_type mem_manager_type;
typedef matrix_mulscal_exp ref_type; const static long NR = matrix_traits<matrix_mul_scal_exp>::NR;
const static long NR = M::NR; const static long NC = matrix_traits<matrix_mul_scal_exp>::NC;
const static long NC = M::NC; const static long cost = matrix_traits<matrix_mul_scal_exp>::cost;
matrix_mulscal_exp ( matrix_mul_scal_exp (
const M& m_, const M& m_,
const S& s_ const S& s_
) : ) :
matrix_exp<matrix_mul_scal_exp>(*this),
m(m_), m(m_),
s(s_) s(s_)
{} {}
...@@ -757,6 +715,9 @@ namespace dlib ...@@ -757,6 +715,9 @@ namespace dlib
long c long c
) const { return m(r,c)*s; } ) const { return m(r,c)*s; }
inline const type operator() ( long i ) const
{ return matrix_exp<matrix_mul_scal_exp>::operator()(i); }
template <typename U, long iNR, long iNC , typename mm, typename l> template <typename U, long iNR, long iNC , typename mm, typename l>
bool aliases ( bool aliases (
const matrix<U,iNR,iNC,mm,l>& item const matrix<U,iNR,iNC,mm,l>& item
...@@ -767,16 +728,13 @@ namespace dlib ...@@ -767,16 +728,13 @@ namespace dlib
const matrix<U,iNR,iNC,mm,l>& item const matrix<U,iNR,iNC,mm,l>& item
) const { return m.destructively_aliases(item); } ) const { return m.destructively_aliases(item); }
const ref_type& ref(
) const { return *this; }
long nr ( long nr (
) const { return m.nr(); } ) const { return m.nr(); }
long nc ( long nc (
) const { return m.nc(); } ) const { return m.nc(); }
const M m; const M& m;
const S s; const S s;
}; };
...@@ -784,73 +742,67 @@ namespace dlib ...@@ -784,73 +742,67 @@ namespace dlib
typename EXP, typename EXP,
typename S typename S
> >
inline const matrix_exp<matrix_mulscal_exp<matrix_exp<EXP>, S> > operator* ( inline typename disable_if<is_matrix<S>, const matrix_mul_scal_exp<EXP, S> >::type operator* (
const matrix_exp<EXP>& m, const matrix_exp<EXP>& m,
const S& s const S& s
) )
{ {
typedef matrix_mulscal_exp<matrix_exp<EXP>,S > exp; return matrix_mul_scal_exp<EXP,S>(m.ref(),s);
return matrix_exp<exp>(exp(m,s));
} }
template < template <
typename EXP, typename EXP,
typename S typename S
> >
inline const matrix_exp<matrix_mulscal_exp<matrix_exp<EXP>, S> > operator* ( inline typename disable_if<is_matrix<S>, const matrix_mul_scal_exp<EXP, S> >::type operator* (
const S& s, const S& s,
const matrix_exp<EXP>& m const matrix_exp<EXP>& m
) )
{ {
typedef matrix_mulscal_exp<matrix_exp<EXP>,S > exp; return matrix_mul_scal_exp<EXP,S>(m.ref(),s);
return matrix_exp<exp>(exp(m,s));
} }
template < template <
typename EXP typename EXP
> >
inline const matrix_exp<matrix_mulscal_exp<matrix_exp<EXP>, float> > operator/ ( inline const matrix_mul_scal_exp<EXP, float> operator/ (
const matrix_exp<EXP>& m, const matrix_exp<EXP>& m,
const float& s const float& s
) )
{ {
typedef matrix_mulscal_exp<matrix_exp<EXP>,float > exp; return matrix_mul_scal_exp<EXP,float>(m.ref(),1.0f/s);
return matrix_exp<exp>(exp(m,1.0f/s));
} }
template < template <
typename EXP typename EXP
> >
inline const matrix_exp<matrix_mulscal_exp<matrix_exp<EXP>, double> > operator/ ( inline const matrix_mul_scal_exp<EXP, double> operator/ (
const matrix_exp<EXP>& m, const matrix_exp<EXP>& m,
const double& s const double& s
) )
{ {
typedef matrix_mulscal_exp<matrix_exp<EXP>,double > exp; return matrix_mul_scal_exp<EXP,double>(m.ref(),1.0/s);
return matrix_exp<exp>(exp(m,1.0/s));
} }
template < template <
typename EXP typename EXP
> >
inline const matrix_exp<matrix_mulscal_exp<matrix_exp<EXP>, long double> > operator/ ( inline const matrix_mul_scal_exp<matrix_exp<EXP>, long double> operator/ (
const matrix_exp<EXP>& m, const matrix_exp<EXP>& m,
const long double& s const long double& s
) )
{ {
typedef matrix_mulscal_exp<matrix_exp<EXP>,long double > exp; return matrix_mul_scal_exp<EXP,long double>(m.ref(),1.0/s);
return matrix_exp<exp>(exp(m,1.0/s));
} }
template < template <
typename EXP typename EXP
> >
inline const matrix_exp<matrix_mulscal_exp<matrix_exp<EXP>, int> > operator- ( inline const matrix_mul_scal_exp<EXP, int> operator- (
const matrix_exp<EXP>& m const matrix_exp<EXP>& m
) )
{ {
typedef matrix_mulscal_exp<matrix_exp<EXP>,int > exp; return matrix_mul_scal_exp<EXP,int>(m.ref(),-1);
return matrix_exp<exp>(exp(m,-1));
} }
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
...@@ -899,26 +851,44 @@ namespace dlib ...@@ -899,26 +851,44 @@ namespace dlib
typename mem_manager, typename mem_manager,
typename layout typename layout
> >
class matrix : public matrix_exp<matrix_ref<T,num_rows,num_cols, mem_manager,layout> > struct matrix_traits<matrix<T,num_rows, num_cols, mem_manager, layout> >
{ {
COMPILE_TIME_ASSERT(num_rows >= 0 && num_cols >= 0);
public:
typedef T type; typedef T type;
typedef matrix_ref<T,num_rows,num_cols,mem_manager,layout> ref_type;
typedef mem_manager mem_manager_type; typedef mem_manager mem_manager_type;
typedef layout layout_type; typedef layout layout_type;
const static long NR = num_rows; const static long NR = num_rows;
const static long NC = num_cols; const static long NC = num_cols;
const static long cost = 1;
};
template <
typename T,
long num_rows,
long num_cols,
typename mem_manager,
typename layout
>
class matrix : public matrix_exp<matrix<T,num_rows,num_cols, mem_manager,layout> >
{
COMPILE_TIME_ASSERT(num_rows >= 0 && num_cols >= 0);
matrix () : matrix_exp<matrix_ref<T,num_rows,num_cols, mem_manager, layout> >(ref_type(*this)) public:
typedef typename matrix_traits<matrix>::type type;
typedef typename matrix_traits<matrix>::mem_manager_type mem_manager_type;
typedef typename matrix_traits<matrix>::layout_type layout_type;
const static long NR = matrix_traits<matrix>::NR;
const static long NC = matrix_traits<matrix>::NC;
const static long cost = matrix_traits<matrix>::cost;
matrix () : matrix_exp<matrix>(*this)
{ {
} }
explicit matrix ( explicit matrix (
long length long length
) : matrix_exp<matrix_ref<T,num_rows,num_cols, mem_manager, layout> >(ref_type(*this)) ) : matrix_exp<matrix>(*this)
{ {
// This object you are trying to call matrix(length) on is not a column or // This object you are trying to call matrix(length) on is not a column or
// row vector. // row vector.
...@@ -963,7 +933,7 @@ namespace dlib ...@@ -963,7 +933,7 @@ namespace dlib
matrix ( matrix (
long rows, long rows,
long cols long cols
) : matrix_exp<matrix_ref<T,num_rows,num_cols, mem_manager, layout> >(ref_type(*this)) ) : matrix_exp<matrix>(*this)
{ {
DLIB_ASSERT( (NR == 0 || NR == rows) && ( NC == 0 || NC == cols) && DLIB_ASSERT( (NR == 0 || NR == rows) && ( NC == 0 || NC == cols) &&
rows >= 0 && cols >= 0, rows >= 0 && cols >= 0,
...@@ -980,8 +950,11 @@ namespace dlib ...@@ -980,8 +950,11 @@ namespace dlib
template <typename EXP> template <typename EXP>
matrix ( matrix (
const matrix_exp<EXP>& m const matrix_exp<EXP>& m
): matrix_exp<matrix_ref<T,num_rows,num_cols, mem_manager, layout> >(ref_type(*this)) ): matrix_exp<matrix>(*this)
{ {
using namespace std;
// TODO
//cout << "copy" << endl;
// You get an error on this line if the matrix m contains a type that isn't // You get an error on this line if the matrix m contains a type that isn't
// the same as the type contained in the target matrix. // the same as the type contained in the target matrix.
COMPILE_TIME_ASSERT((is_same_type<typename EXP::type,type>::value == true) || COMPILE_TIME_ASSERT((is_same_type<typename EXP::type,type>::value == true) ||
...@@ -1008,8 +981,11 @@ namespace dlib ...@@ -1008,8 +981,11 @@ namespace dlib
matrix ( matrix (
const matrix& m const matrix& m
): matrix_exp<matrix_ref<T,num_rows,num_cols, mem_manager, layout> >(ref_type(*this)) ): matrix_exp<matrix>(*this)
{ {
using namespace std;
// TODO
//cout << "copy" << endl;
data.set_size(m.nr(),m.nc()); data.set_size(m.nr(),m.nc());
matrix_assign(*this, m); matrix_assign(*this, m);
} }
...@@ -1017,7 +993,7 @@ namespace dlib ...@@ -1017,7 +993,7 @@ namespace dlib
template <typename U, size_t len> template <typename U, size_t len>
matrix ( matrix (
U (&array)[len] U (&array)[len]
): matrix_exp<matrix_ref<T,num_rows,num_cols, mem_manager, layout> >(ref_type(*this)) ): matrix_exp<matrix>(*this)
{ {
COMPILE_TIME_ASSERT(NR*NC == len && len > 0); COMPILE_TIME_ASSERT(NR*NC == len && len > 0);
size_t idx = 0; size_t idx = 0;
...@@ -1399,6 +1375,20 @@ namespace dlib ...@@ -1399,6 +1375,20 @@ namespace dlib
data.swap(item.data); data.swap(item.data);
} }
template <typename U, long iNR, long iNC, typename mm, typename l >
bool aliases (
const matrix<U,iNR,iNC,mm,l>& item
) const { return false; }
template <typename U, long iNR, long iNC, typename mm, typename l>
bool destructively_aliases (
const matrix<U,iNR,iNC,mm,l>& item
) const { return false; }
bool aliases (
const matrix& item
) const { return (this == &item); }
private: private:
struct literal_assign_helper struct literal_assign_helper
{ {
......
...@@ -167,6 +167,7 @@ namespace dlib ...@@ -167,6 +167,7 @@ namespace dlib
const static long NR = EXP::NR; const static long NR = EXP::NR;
const static long NC = EXP::NC; const static long NC = EXP::NC;
typedef matrix<type,NR,NC, mem_manager_type> matrix_type; typedef matrix<type,NR,NC, mem_manager_type> matrix_type;
const static long cost = EXP::cost;
matrix_exp ( matrix_exp (
const EXP& exp const EXP& exp
......
...@@ -50,6 +50,9 @@ namespace dlib ...@@ -50,6 +50,9 @@ namespace dlib
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
// TODO
#if 0
template < template <
typename matrix_dest_type, typename matrix_dest_type,
typename EXP1, typename EXP1,
...@@ -117,6 +120,7 @@ namespace dlib ...@@ -117,6 +120,7 @@ namespace dlib
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
#endif
} }
......
// Copyright (C) 2006 Davis E. King (davisking@users.sourceforge.net)
// License: Boost Software License See LICENSE.txt for the full license.
#ifndef DLIB_MATRIx_EXPRESSIONS_H_
#define DLIB_MATRIx_EXPRESSIONS_H_
#include "matrix_fwd.h"
namespace dlib
{
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
// General matrix expressions that take operator structs
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
template < typename M, typename OP_ >
class matrix_unary_exp;
template < typename M, typename OP_ >
struct matrix_traits<matrix_unary_exp<M,OP_> >
{
typedef typename OP_::template op<M> OP;
typedef typename OP::type type;
typedef typename OP::mem_manager_type mem_manager_type;
const static long NR = OP::NR;
const static long NC = OP::NC;
const static long cost = OP::cost;
};
template <
typename M,
typename OP_
>
class matrix_unary_exp : public matrix_exp<matrix_unary_exp<M,OP_> >
{
/*!
REQUIREMENTS ON M
- must be an object that inherits from matrix_exp
!*/
typedef typename OP_::template op<M> OP;
public:
typedef typename matrix_traits<matrix_unary_exp>::type type;
typedef typename matrix_traits<matrix_unary_exp>::mem_manager_type mem_manager_type;
const static long NR = matrix_traits<matrix_unary_exp>::NR;
const static long NC = matrix_traits<matrix_unary_exp>::NC;
const static long cost = matrix_traits<matrix_unary_exp>::cost;
matrix_unary_exp (
const M& m_
) :
matrix_exp<matrix_unary_exp>(*this),
m(m_)
{}
const typename OP::type operator() (
long r,
long c
) const { return OP::apply(m,r,c); }
const typename OP::type operator() ( long i ) const
{ return matrix_exp<matrix_unary_exp>::operator()(i); }
template <typename U, long iNR, long iNC, typename MM, typename L >
bool aliases (
const matrix<U,iNR,iNC,MM,L>& item
) const { return m.aliases(item); }
template <typename U, long iNR, long iNC, typename MM, typename L >
bool destructively_aliases (
const matrix<U,iNR,iNC,MM,L>& item
) const { return OP::destructively_aliases(m,item); }
long nr (
) const { return OP::nr(m); }
long nc (
) const { return OP::nc(m); }
private:
const M& m;
};
// ----------------------------------------------------------------------------------------
template < typename M, typename S, typename OP_ >
class matrix_scalar_binary_exp;
template < typename M, typename S, typename OP_ >
struct matrix_traits<matrix_scalar_binary_exp<M,S,OP_> >
{
typedef typename OP_::template op<M> OP;
typedef typename OP::type type;
typedef typename OP::mem_manager_type mem_manager_type;
const static long NR = OP::NR;
const static long NC = OP::NC;
const static long cost = OP::cost;
};
template <
typename M,
typename S,
typename OP_
>
class matrix_scalar_binary_exp : public matrix_exp<matrix_scalar_binary_exp<M,S,OP_> >
{
/*!
REQUIREMENTS ON M
- must be an object that inherits from matrix_exp
!*/
typedef typename OP_::template op<M> OP;
public:
typedef typename matrix_traits<matrix_scalar_binary_exp>::type type;
typedef typename matrix_traits<matrix_scalar_binary_exp>::mem_manager_type mem_manager_type;
const static long NR = matrix_traits<matrix_scalar_binary_exp>::NR;
const static long NC = matrix_traits<matrix_scalar_binary_exp>::NC;
const static long cost = matrix_traits<matrix_scalar_binary_exp>::cost;
matrix_scalar_binary_exp (
const M& m_,
const S& s_
) :
matrix_exp<matrix_scalar_binary_exp>(*this),
m(m_),
s(s_)
{
COMPILE_TIME_ASSERT(is_matrix<S>::value == false);
}
const typename OP::type operator() (
long r,
long c
) const { return OP::apply(m,s,r,c); }
const typename OP::type operator() ( long i ) const
{ return matrix_exp<matrix_scalar_binary_exp>::operator()(i); }
template <typename U, long iNR, long iNC, typename MM, typename L >
bool aliases (
const matrix<U,iNR,iNC,MM,L>& item
) const { return m.aliases(item); }
template <typename U, long iNR, long iNC , typename MM, typename L>
bool destructively_aliases (
const matrix<U,iNR,iNC,MM,L>& item
) const { return OP::destructively_aliases(m,item); }
long nr (
) const { return OP::nr(m); }
long nc (
) const { return OP::nc(m); }
private:
const M& m;
const S s;
};
// ----------------------------------------------------------------------------------------
template < typename M, typename S, typename OP_ >
class matrix_scalar_ternary_exp;
template < typename M, typename S, typename OP_ >
struct matrix_traits<matrix_scalar_ternary_exp<M,S,OP_> >
{
typedef typename OP_::template op<M> OP;
typedef typename OP::type type;
typedef typename OP::mem_manager_type mem_manager_type;
const static long NR = OP::NR;
const static long NC = OP::NC;
const static long cost = OP::cost;
};
template <
typename M,
typename S,
typename OP_
>
class matrix_scalar_ternary_exp : public matrix_exp<matrix_scalar_ternary_exp<M,S,OP_> >
{
/*!
REQUIREMENTS ON M
- must be an object that inherits from matrix_exp
!*/
typedef typename OP_::template op<M> OP;
public:
typedef typename matrix_traits<matrix_scalar_ternary_exp>::type type;
typedef typename matrix_traits<matrix_scalar_ternary_exp>::mem_manager_type mem_manager_type;
const static long NR = matrix_traits<matrix_scalar_ternary_exp>::NR;
const static long NC = matrix_traits<matrix_scalar_ternary_exp>::NC;
const static long cost = matrix_traits<matrix_scalar_ternary_exp>::cost;
matrix_scalar_ternary_exp (
const M& m_,
const S& s1_,
const S& s2_
) :
matrix_exp<matrix_scalar_ternary_exp>(*this),
m(m_),
s1(s1_),
s2(s2_)
{
COMPILE_TIME_ASSERT(is_matrix<S>::value == false);
}
const typename OP::type operator() (
long r,
long c
) const { return OP::apply(m,s1,s2,r,c); }
const typename OP::type operator() ( long i ) const
{ return matrix_exp<matrix_scalar_ternary_exp>::operator()(i); }
template <typename U, long iNR, long iNC, typename MM, typename L>
bool aliases (
const matrix<U,iNR,iNC,MM,L>& item
) const { return m.aliases(item); }
template <typename U, long iNR, long iNC , typename MM, typename L>
bool destructively_aliases (
const matrix<U,iNR,iNC,MM,L>& item
) const { return OP::destructively_aliases(m,item); }
long nr (
) const { return OP::nr(m); }
long nc (
) const { return OP::nc(m); }
private:
const M& m;
const S s1;
const S s2;
};
// ----------------------------------------------------------------------------------------
template < typename M1, typename M2, typename OP_ >
class matrix_binary_exp;
template < typename M1, typename M2, typename OP_ >
struct matrix_traits<matrix_binary_exp<M1,M2,OP_> >
{
typedef typename OP_::template op<M1,M2> OP;
typedef typename OP::type type;
typedef typename OP::mem_manager_type mem_manager_type;
const static long NR = OP::NR;
const static long NC = OP::NC;
const static long cost = OP::cost;
};
template <
typename M1,
typename M2,
typename OP_
>
class matrix_binary_exp : public matrix_exp<matrix_binary_exp<M1,M2,OP_> >
{
/*!
REQUIREMENTS ON M1 AND M2
- must be objects that inherit from matrix_exp
!*/
typedef typename OP_::template op<M1,M2> OP;
public:
typedef typename matrix_traits<matrix_binary_exp>::type type;
typedef typename matrix_traits<matrix_binary_exp>::mem_manager_type mem_manager_type;
const static long NR = matrix_traits<matrix_binary_exp>::NR;
const static long NC = matrix_traits<matrix_binary_exp>::NC;
const static long cost = matrix_traits<matrix_binary_exp>::cost;
matrix_binary_exp (
const M1& m1_,
const M2& m2_
) :
matrix_exp<matrix_binary_exp>(*this),
m1(m1_),
m2(m2_)
{}
const typename OP::type operator() (
long r,
long c
) const { return OP::apply(m1,m2,r,c); }
const typename OP::type operator() ( long i ) const
{ return matrix_exp<matrix_binary_exp>::operator()(i); }
template <typename U, long iNR, long iNC, typename MM, typename L >
bool aliases (
const matrix<U,iNR,iNC,MM,L>& item
) const { return m1.aliases(item) || m2.aliases(item); }
template <typename U, long iNR, long iNC, typename MM, typename L >
bool destructively_aliases (
const matrix<U,iNR,iNC,MM,L>& item
) const { return OP::destructively_aliases(m1,m2,item); }
long nr (
) const { return OP::nr(m1,m2); }
long nc (
) const { return OP::nc(m1,m2); }
private:
const M1& m1;
const M2& m2;
};
// ----------------------------------------------------------------------------------------
template < typename M1, typename M2, typename M3, typename OP_ >
class matrix_ternary_exp;
template < typename M1, typename M2, typename M3, typename OP_ >
struct matrix_traits<matrix_ternary_exp<M1,M2,M3,OP_> >
{
typedef typename OP_::template op<M1,M2,M3> OP;
typedef typename OP::type type;
typedef typename OP::mem_manager_type mem_manager_type;
const static long NR = OP::NR;
const static long NC = OP::NC;
const static long cost = OP::cost;
};
template <
typename M1,
typename M2,
typename M3,
typename OP_
>
class matrix_ternary_exp : public matrix_exp<matrix_ternary_exp<M1,M2,M3,OP_> >
{
/*!
REQUIREMENTS ON M1, M2 AND M3
- must be objects that inherit from matrix_exp
!*/
typedef typename OP_::template op<M1,M2,M3> OP;
public:
typedef typename matrix_traits<matrix_ternary_exp>::type type;
typedef typename matrix_traits<matrix_ternary_exp>::mem_manager_type mem_manager_type;
const static long NR = matrix_traits<matrix_ternary_exp>::NR;
const static long NC = matrix_traits<matrix_ternary_exp>::NC;
const static long cost = matrix_traits<matrix_ternary_exp>::cost;
matrix_ternary_exp (
const M1& m1_,
const M2& m2_,
const M3& m3_
) :
matrix_exp<matrix_ternary_exp>(*this),
m1(m1_),
m2(m2_),
m3(m3_)
{}
const typename OP::type operator() (
long r,
long c
) const { return OP::apply(m1,m2,m3,r,c); }
const typename OP::type operator() ( long i ) const
{ return matrix_exp<matrix_ternary_exp>::operator()(i); }
template <typename U, long iNR, long iNC, typename MM, typename L >
bool aliases (
const matrix<U,iNR,iNC,MM,L>& item
) const { return m1.aliases(item) || m2.aliases(item) || m3.aliases(item); }
template <typename U, long iNR, long iNC, typename MM, typename L >
bool destructively_aliases (
const matrix<U,iNR,iNC,MM,L>& item
) const { return OP::destructively_aliases(m1,m2,m3,item); }
long nr (
) const { return OP::nr(m1,m2,m3); }
long nc (
) const { return OP::nc(m1,m2,m3); }
private:
const M1& m1;
const M2& m2;
const M3& m3;
};
// ----------------------------------------------------------------------------------------
template < typename M1, typename M2, typename M3, typename M4, typename OP_ >
class matrix_fourary_exp;
template < typename M1, typename M2, typename M3, typename M4, typename OP_ >
struct matrix_traits<matrix_fourary_exp<M1,M2,M3,M4,OP_> >
{
typedef typename OP_::template op<M1,M2,M3,M4> OP;
typedef typename OP::type type;
typedef typename OP::mem_manager_type mem_manager_type;
const static long NR = OP::NR;
const static long NC = OP::NC;
const static long cost = OP::cost;
};
template <
typename M1,
typename M2,
typename M3,
typename M4,
typename OP_
>
class matrix_fourary_exp : public matrix_exp<matrix_fourary_exp<M1,M2,M3,M4,OP_> >
{
/*!
REQUIREMENTS ON M1, M2, M3 AND M4
- must be objects that inherit from matrix_exp
!*/
typedef typename OP_::template op<M1,M2,M3,M4> OP;
public:
typedef typename matrix_traits<matrix_fourary_exp>::type type;
typedef typename matrix_traits<matrix_fourary_exp>::mem_manager_type mem_manager_type;
const static long NR = matrix_traits<matrix_fourary_exp>::NR;
const static long NC = matrix_traits<matrix_fourary_exp>::NC;
const static long cost = matrix_traits<matrix_fourary_exp>::cost;
matrix_fourary_exp (
const M1& m1_,
const M2& m2_,
const M3& m3_,
const M4& m4_
) :
matrix_exp<matrix_fourary_exp>(*this),
m1(m1_),
m2(m2_),
m3(m3_),
m4(m4_)
{}
const typename OP::type operator() (
long r,
long c
) const { return OP::apply(m1,m2,m3,m4,r,c); }
const typename OP::type operator() ( long i ) const
{ return matrix_exp<matrix_fourary_exp>::operator()(i); }
template <typename U, long iNR, long iNC, typename MM, typename L >
bool aliases (
const matrix<U,iNR,iNC,MM,L>& item
) const { return m1.aliases(item) || m2.aliases(item) || m3.aliases(item) || m4.aliases(item); }
template <typename U, long iNR, long iNC, typename MM, typename L >
bool destructively_aliases (
const matrix<U,iNR,iNC,MM,L>& item
) const { return OP::destructively_aliases(m1,m2,m3,m4,item); }
long nr (
) const { return OP::nr(m1,m2,m3,m4); }
long nc (
) const { return OP::nc(m1,m2,m3,m4); }
private:
const M1& m1;
const M2& m2;
const M3& m3;
const M4& m4;
};
// ----------------------------------------------------------------------------------------
template < typename S, typename OP >
class dynamic_matrix_scalar_unary_exp;
template < typename S, typename OP >
struct matrix_traits<dynamic_matrix_scalar_unary_exp<S,OP> >
{
typedef typename OP::type type;
typedef typename OP::mem_manager_type mem_manager_type;
const static long NR = OP::NR;
const static long NC = OP::NC;
const static long cost = OP::cost;
};
template <
typename S,
typename OP
>
class dynamic_matrix_scalar_unary_exp : public matrix_exp<dynamic_matrix_scalar_unary_exp<S,OP> >
{
/*!
REQUIREMENTS ON S
should be some scalar type
!*/
public:
typedef typename matrix_traits<dynamic_matrix_scalar_unary_exp>::type type;
typedef typename matrix_traits<dynamic_matrix_scalar_unary_exp>::mem_manager_type mem_manager_type;
const static long NR = matrix_traits<dynamic_matrix_scalar_unary_exp>::NR;
const static long NC = matrix_traits<dynamic_matrix_scalar_unary_exp>::NC;
const static long cost = matrix_traits<dynamic_matrix_scalar_unary_exp>::cost;
dynamic_matrix_scalar_unary_exp (
long nr__,
long nc__,
const S& s_
) :
matrix_exp<dynamic_matrix_scalar_unary_exp>(*this),
nr_(nr__),
nc_(nc__),
s(s_)
{
COMPILE_TIME_ASSERT(is_matrix<S>::value == false);
}
const typename OP::type operator() (
long r,
long c
) const { return OP::apply(s,r,c); }
const typename OP::type operator() ( long i ) const
{ return matrix_exp<dynamic_matrix_scalar_unary_exp>::operator()(i); }
template <typename U, long iNR, long iNC, typename MM, typename L >
bool aliases (
const matrix<U,iNR,iNC,MM,L>& item
) const { return false; }
template <typename U, long iNR, long iNC , typename MM, typename L>
bool destructively_aliases (
const matrix<U,iNR,iNC,MM,L>& item
) const { return false; }
long nr (
) const { return nr_; }
long nc (
) const { return nc_; }
private:
const long nr_;
const long nc_;
const S s;
};
// ----------------------------------------------------------------------------------------
template <typename S, typename OP>
class matrix_scalar_unary_exp;
template <typename S, typename OP>
struct matrix_traits<matrix_scalar_unary_exp<S,OP> >
{
typedef typename OP::type type;
typedef typename OP::mem_manager_type mem_manager_type;
const static long NR = OP::NR;
const static long NC = OP::NC;
const static long cost = OP::cost;
};
template <
typename S,
typename OP
>
class matrix_scalar_unary_exp : public matrix_exp<matrix_scalar_unary_exp<S,OP> >
{
/*!
REQUIREMENTS ON S
should be some scalar type
!*/
public:
typedef typename matrix_traits<matrix_scalar_unary_exp>::type type;
typedef typename matrix_traits<matrix_scalar_unary_exp>::mem_manager_type mem_manager_type;
const static long NR = matrix_traits<matrix_scalar_unary_exp>::NR;
const static long NC = matrix_traits<matrix_scalar_unary_exp>::NC;
const static long cost = matrix_traits<matrix_scalar_unary_exp>::cost;
matrix_scalar_unary_exp (
const S& s_
) :
matrix_exp<matrix_scalar_unary_exp>(*this),
s(s_)
{
COMPILE_TIME_ASSERT(is_matrix<S>::value == false);
}
const typename OP::type operator() (
long r,
long c
) const { return OP::apply(s,r,c); }
const typename OP::type operator() ( long i ) const
{ return matrix_exp<matrix_scalar_unary_exp>::operator()(i); }
template <typename U, long iNR, long iNC, typename MM, typename L >
bool aliases (
const matrix<U,iNR,iNC,MM,L>& item
) const { return false; }
template <typename U, long iNR, long iNC, typename MM, typename L >
bool destructively_aliases (
const matrix<U,iNR,iNC,MM,L>& item
) const { return false; }
long nr (
) const { return NR; }
long nc (
) const { return NC; }
private:
const S s;
};
// ----------------------------------------------------------------------------------------
template <typename OP>
class matrix_zeroary_exp;
template <typename OP>
struct matrix_traits<matrix_zeroary_exp<OP> >
{
typedef typename OP::type type;
typedef typename OP::mem_manager_type mem_manager_type;
const static long NR = OP::NR;
const static long NC = OP::NC;
const static long cost = OP::cost;
};
template <
typename OP
>
class matrix_zeroary_exp : public matrix_exp<matrix_zeroary_exp<OP> >
{
public:
typedef typename matrix_traits<matrix_zeroary_exp>::type type;
typedef typename matrix_traits<matrix_zeroary_exp>::mem_manager_type mem_manager_type;
const static long NR = matrix_traits<matrix_zeroary_exp>::NR;
const static long NC = matrix_traits<matrix_zeroary_exp>::NC;
const static long cost = matrix_traits<matrix_zeroary_exp>::cost;
matrix_zeroary_exp (
) :
matrix_exp<matrix_zeroary_exp>(*this)
{}
const typename OP::type operator() (
long r,
long c
) const { return OP::apply(r,c); }
const typename OP::type operator() ( long i ) const
{ return matrix_exp<matrix_zeroary_exp>::operator()(i); }
template <typename U, long iNR, long iNC , typename MM, typename L>
bool aliases (
const matrix<U,iNR,iNC,MM,L>& item
) const { return false; }
template <typename U, long iNR, long iNC, typename MM, typename L >
bool destructively_aliases (
const matrix<U,iNR,iNC,MM,L>& item
) const { return false; }
long nr (
) const { return NR; }
long nc (
) const { return NC; }
};
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
// Specialized matrix expressions
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
template < typename M, typename EXPr, typename EXPc >
class matrix_sub_range_exp;
template < typename M, typename EXPr, typename EXPc >
struct matrix_traits<matrix_sub_range_exp<M,EXPr,EXPc> >
{
typedef typename M::type type;
typedef typename M::mem_manager_type mem_manager_type;
const static long NR = EXPr::NR*EXPr::NC;
const static long NC = EXPc::NR*EXPr::NC;
const static long cost = EXPr::cost+EXPc::cost+M::cost;
};
template <
typename M,
typename EXPr,
typename EXPc
>
class matrix_sub_range_exp : public matrix_exp<matrix_sub_range_exp<M,EXPr,EXPc> >
{
/*!
REQUIREMENTS ON M, EXPr and EXPc
- must be objects that inherit from matrix_exp
!*/
public:
typedef typename matrix_traits<matrix_sub_range_exp>::type type;
typedef typename matrix_traits<matrix_sub_range_exp>::mem_manager_type mem_manager_type;
const static long NR = matrix_traits<matrix_sub_range_exp>::NR;
const static long NC = matrix_traits<matrix_sub_range_exp>::NC;
const static long cost = matrix_traits<matrix_sub_range_exp>::cost;
matrix_sub_range_exp (
const M& m_,
const EXPr& rows_,
const EXPc& cols_
) :
matrix_exp<matrix_sub_range_exp>(*this),
m(m_),
rows(rows_),
cols(cols_)
{
}
const typename M::type operator() (
long r,
long c
) const { return m(rows(r),cols(c)); }
const typename M::type operator() ( long i ) const
{ return matrix_exp<matrix_sub_range_exp>::operator()(i); }
template <typename U, long iNR, long iNC, typename MM, typename L >
bool aliases (
const matrix<U,iNR,iNC,MM,L>& item
) const { return m.aliases(item) || rows.aliases(item) || cols.aliases(item); }
template <typename U, long iNR, long iNC , typename MM, typename L>
bool destructively_aliases (
const matrix<U,iNR,iNC,MM,L>& item
) const { return m.aliases(item) || rows.aliases(item) || cols.aliases(item); }
long nr (
) const { return rows.size(); }
long nc (
) const { return cols.size(); }
private:
const M& m;
const EXPr& rows;
const EXPc& cols;
};
// ----------------------------------------------------------------------------------------
template <typename M>
class matrix_std_vector_exp;
template <typename M>
struct matrix_traits<matrix_std_vector_exp<M> >
{
typedef typename M::value_type type;
typedef typename memory_manager<char>::kernel_1a mem_manager_type;
const static long NR = 0;
const static long NC = 1;
const static long cost = 1;
};
template <
typename M
>
class matrix_std_vector_exp : public matrix_exp<matrix_std_vector_exp<M> >
{
/*!
REQUIREMENTS ON M
- must be a std::vector object (or
an object with a compatible interface).
!*/
public:
typedef typename matrix_traits<matrix_std_vector_exp>::type type;
typedef typename matrix_traits<matrix_std_vector_exp>::mem_manager_type mem_manager_type;
const static long NR = matrix_traits<matrix_std_vector_exp>::NR;
const static long NC = matrix_traits<matrix_std_vector_exp>::NC;
const static long cost = matrix_traits<matrix_std_vector_exp>::cost;
matrix_std_vector_exp (
const M& m_
) :
matrix_exp<matrix_std_vector_exp>(*this),
m(m_)
{
}
const typename M::value_type operator() (
long r,
long
) const { return m[r]; }
const typename M::value_type operator() ( long i ) const
{ return m[i]; }
template <typename U, long iNR, long iNC, typename MM, typename L>
bool aliases (
const matrix<U,iNR,iNC,MM,L>& item
) const { return false; }
template <typename U, long iNR, long iNC , typename MM, typename L>
bool destructively_aliases (
const matrix<U,iNR,iNC,MM,L>& item
) const { return false; }
long nr (
) const { return m.size(); }
long nc (
) const { return 1; }
private:
const M& m;
};
// ----------------------------------------------------------------------------------------
template <typename M>
class matrix_array_exp;
template <typename M>
struct matrix_traits<matrix_array_exp<M> >
{
typedef typename M::type type;
typedef typename M::mem_manager_type mem_manager_type;
const static long NR = 0;
const static long NC = 1;
const static long cost = 1;
};
template <
typename M
>
class matrix_array_exp : public matrix_exp<matrix_array_exp<M> >
{
/*!
REQUIREMENTS ON M
- must be a dlib::array object (or
an object with a compatible interface).
!*/
public:
typedef typename matrix_traits<matrix_array_exp>::type type;
typedef typename matrix_traits<matrix_array_exp>::mem_manager_type mem_manager_type;
const static long NR = matrix_traits<matrix_array_exp>::NR;
const static long NC = matrix_traits<matrix_array_exp>::NC;
const static long cost = matrix_traits<matrix_array_exp>::cost;
matrix_array_exp (
const M& m_
) :
matrix_exp<matrix_array_exp>(*this),
m(m_)
{
}
const typename M::type operator() (
long r,
long
) const { return m[r]; }
const typename M::type operator() ( long i ) const
{ return m[i]; }
template <typename U, long iNR, long iNC, typename MM, typename L>
bool aliases (
const matrix<U,iNR,iNC,MM,L>& item
) const { return false; }
template <typename U, long iNR, long iNC , typename MM, typename L>
bool destructively_aliases (
const matrix<U,iNR,iNC,MM,L>& item
) const { return false; }
long nr (
) const { return m.size(); }
long nc (
) const { return 1; }
private:
const M& m;
};
// ----------------------------------------------------------------------------------------
template <typename M>
class matrix_array2d_exp;
template <typename M>
struct matrix_traits<matrix_array2d_exp<M> >
{
typedef typename M::type type;
typedef typename M::mem_manager_type mem_manager_type;
const static long NR = 0;
const static long NC = 0;
const static long cost = 1;
};
template <
typename M
>
class matrix_array2d_exp : public matrix_exp<matrix_array2d_exp<M> >
{
/*!
REQUIREMENTS ON M
- must be a dlib::array2d object (or
an object with a compatible interface).
!*/
public:
typedef typename matrix_traits<matrix_array2d_exp>::type type;
typedef typename matrix_traits<matrix_array2d_exp>::mem_manager_type mem_manager_type;
const static long NR = matrix_traits<matrix_array2d_exp>::NR;
const static long NC = matrix_traits<matrix_array2d_exp>::NC;
const static long cost = matrix_traits<matrix_array2d_exp>::cost;
matrix_array2d_exp (
const M& m_
) :
matrix_exp<matrix_array2d_exp>(*this),
m(m_)
{
}
const typename M::type operator() (
long r,
long c
) const { return m[r][c]; }
const typename M::type operator() ( long i ) const
{ return matrix_exp<matrix_array2d_exp>::operator()(i); }
template <typename U, long iNR, long iNC, typename MM, typename L>
bool aliases (
const matrix<U,iNR,iNC,MM,L>& item
) const { return false; }
template <typename U, long iNR, long iNC , typename MM, typename L>
bool destructively_aliases (
const matrix<U,iNR,iNC,MM,L>& item
) const { return false; }
long nr (
) const { return m.nr(); }
long nc (
) const { return m.nc(); }
private:
const M& m;
};
// ----------------------------------------------------------------------------------------
template <typename M>
class matrix_sub_exp;
template <typename M>
struct matrix_traits<matrix_sub_exp<M> >
{
typedef typename M::type type;
typedef typename M::mem_manager_type mem_manager_type;
const static long NR = 0;
const static long NC = 0;
const static long cost = M::cost+1;
};
template <
typename M
>
class matrix_sub_exp : public matrix_exp<matrix_sub_exp<M> >
{
/*!
REQUIREMENTS ON M
- must be an object that inherits from matrix_exp
!*/
public:
typedef typename matrix_traits<matrix_sub_exp>::type type;
typedef typename matrix_traits<matrix_sub_exp>::mem_manager_type mem_manager_type;
const static long NR = matrix_traits<matrix_sub_exp>::NR;
const static long NC = matrix_traits<matrix_sub_exp>::NC;
const static long cost = matrix_traits<matrix_sub_exp>::cost;
matrix_sub_exp (
const M& m_,
const long& r__,
const long& c__,
const long& nr__,
const long& nc__
) :
matrix_exp<matrix_sub_exp>(*this),
m(m_),
r_(r__),
c_(c__),
nr_(nr__),
nc_(nc__)
{
}
const typename M::type operator() (
long r,
long c
) const { return m(r+r_,c+c_); }
const typename M::type operator() ( long i ) const
{ return matrix_exp<matrix_sub_exp>::operator()(i); }
template <typename U, long iNR, long iNC, typename MM, typename L >
bool aliases (
const matrix<U,iNR,iNC,MM,L>& item
) const { return m.aliases(item); }
template <typename U, long iNR, long iNC , typename MM, typename L>
bool destructively_aliases (
const matrix<U,iNR,iNC,MM,L>& item
) const { return m.aliases(item); }
long nr (
) const { return nr_; }
long nc (
) const { return nc_; }
private:
const M& m;
const long r_, c_, nr_, nc_;
};
// ----------------------------------------------------------------------------------------
class matrix_range_exp;
template <>
struct matrix_traits<matrix_range_exp>
{
typedef long type;
typedef memory_manager<char>::kernel_1a mem_manager_type;
const static long NR = 0;
const static long NC = 1;
const static long cost = 1;
};
class matrix_range_exp : public matrix_exp<matrix_range_exp>
{
public:
typedef matrix_traits<matrix_range_exp>::type type;
typedef matrix_traits<matrix_range_exp>::mem_manager_type mem_manager_type;
const static long NR = matrix_traits<matrix_range_exp>::NR;
const static long NC = matrix_traits<matrix_range_exp>::NC;
const static long cost = matrix_traits<matrix_range_exp>::cost;
matrix_range_exp (
long start_,
long end_
) :
matrix_exp<matrix_range_exp>(*this)
{
start = start_;
if (start_ <= end_)
inc = 1;
else
inc = -1;
nr_ = std::abs(end_ - start_) + 1;
}
matrix_range_exp (
long start_,
long inc_,
long end_
) :
matrix_exp<matrix_range_exp>(*this)
{
start = start_;
nr_ = std::abs(end_ - start_)/inc_ + 1;
if (start_ <= end_)
inc = inc_;
else
inc = -inc_;
}
long operator() (
long r,
long c
) const { return start + r*inc; }
long operator() (
long r
) const { return start + r*inc; }
template <typename U, long iNR, long iNC , typename MM, typename L>
bool aliases (
const matrix<U,iNR,iNC,MM,L>& item
) const { return false; }
template <typename U, long iNR, long iNC, typename MM, typename L >
bool destructively_aliases (
const matrix<U,iNR,iNC,MM,L>& item
) const { return false; }
long nr (
) const { return nr_; }
long nc (
) const { return NC; }
long nr_;
long start;
long inc;
};
// ----------------------------------------------------------------------------------------
template <long start, long inc_, long end>
class matrix_range_static_exp;
template <long start, long inc_, long end>
struct matrix_traits<matrix_range_static_exp<start,inc_,end> >
{
typedef long type;
typedef memory_manager<char>::kernel_1a mem_manager_type;
const static long NR = tabs<(end - start)>::value/inc_ + 1;
const static long NC = 1;
const static long cost = 1;
};
template <long start, long inc_, long end>
class matrix_range_static_exp : public matrix_exp<matrix_range_static_exp<start,inc_,end> >
{
public:
typedef typename matrix_traits<matrix_range_static_exp>::type type;
typedef typename matrix_traits<matrix_range_static_exp>::mem_manager_type mem_manager_type;
const static long NR = matrix_traits<matrix_range_static_exp>::NR;
const static long NC = matrix_traits<matrix_range_static_exp>::NC;
const static long cost = matrix_traits<matrix_range_static_exp>::cost;
const static long inc = (start <= end)?inc_:-inc_;
matrix_range_static_exp (
) :
matrix_exp<matrix_range_static_exp>(*this)
{}
long operator() (
long r,
long c
) const { return start + r*inc; }
long operator() (
long r
) const { return start + r*inc; }
template <typename U, long iNR, long iNC , typename MM, typename L>
bool aliases (
const matrix<U,iNR,iNC,MM,L>& item
) const { return false; }
template <typename U, long iNR, long iNC, typename MM, typename L >
bool destructively_aliases (
const matrix<U,iNR,iNC,MM,L>& item
) const { return false; }
long nr (
) const { return NR; }
long nc (
) const { return NC; }
};
// ----------------------------------------------------------------------------------------
}
#endif // DLIB_MATRIx_UTILITIES_
...@@ -17,45 +17,45 @@ namespace dlib ...@@ -17,45 +17,45 @@ namespace dlib
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
#define DLIB_MATRIX_SIMPLE_STD_FUNCTION(name) struct op_##name { \ #define DLIB_MATRIX_SIMPLE_STD_FUNCTION(name,extra_cost) struct op_##name { \
template <typename EXP> \ template <typename EXP> \
struct op : has_nondestructive_aliasing, preserves_dimensions<EXP> \ struct op : has_nondestructive_aliasing, preserves_dimensions<EXP> \
{ \ { \
const static long cost = EXP::cost+(extra_cost); \
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> > name ( \ const matrix_unary_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; \ return matrix_unary_exp<EXP,op_##name>(m.ref()); \
return matrix_exp<exp>(exp(m)); \
} }
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
DLIB_MATRIX_SIMPLE_STD_FUNCTION(abs) DLIB_MATRIX_SIMPLE_STD_FUNCTION(abs,3)
DLIB_MATRIX_SIMPLE_STD_FUNCTION(sqrt) DLIB_MATRIX_SIMPLE_STD_FUNCTION(sqrt,7)
DLIB_MATRIX_SIMPLE_STD_FUNCTION(log) DLIB_MATRIX_SIMPLE_STD_FUNCTION(log,7)
DLIB_MATRIX_SIMPLE_STD_FUNCTION(log10) DLIB_MATRIX_SIMPLE_STD_FUNCTION(log10,7)
DLIB_MATRIX_SIMPLE_STD_FUNCTION(exp) DLIB_MATRIX_SIMPLE_STD_FUNCTION(exp,7)
DLIB_MATRIX_SIMPLE_STD_FUNCTION(conj) DLIB_MATRIX_SIMPLE_STD_FUNCTION(conj,1)
DLIB_MATRIX_SIMPLE_STD_FUNCTION(ceil) DLIB_MATRIX_SIMPLE_STD_FUNCTION(ceil,2)
DLIB_MATRIX_SIMPLE_STD_FUNCTION(floor) DLIB_MATRIX_SIMPLE_STD_FUNCTION(floor,20)
DLIB_MATRIX_SIMPLE_STD_FUNCTION(sin) DLIB_MATRIX_SIMPLE_STD_FUNCTION(sin,7)
DLIB_MATRIX_SIMPLE_STD_FUNCTION(cos) DLIB_MATRIX_SIMPLE_STD_FUNCTION(cos,7)
DLIB_MATRIX_SIMPLE_STD_FUNCTION(tan) DLIB_MATRIX_SIMPLE_STD_FUNCTION(tan,7)
DLIB_MATRIX_SIMPLE_STD_FUNCTION(sinh) DLIB_MATRIX_SIMPLE_STD_FUNCTION(sinh,7)
DLIB_MATRIX_SIMPLE_STD_FUNCTION(cosh) DLIB_MATRIX_SIMPLE_STD_FUNCTION(cosh,7)
DLIB_MATRIX_SIMPLE_STD_FUNCTION(tanh) DLIB_MATRIX_SIMPLE_STD_FUNCTION(tanh,7)
DLIB_MATRIX_SIMPLE_STD_FUNCTION(asin) DLIB_MATRIX_SIMPLE_STD_FUNCTION(asin,7)
DLIB_MATRIX_SIMPLE_STD_FUNCTION(acos) DLIB_MATRIX_SIMPLE_STD_FUNCTION(acos,7)
DLIB_MATRIX_SIMPLE_STD_FUNCTION(atan) DLIB_MATRIX_SIMPLE_STD_FUNCTION(atan,7)
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
...@@ -64,6 +64,7 @@ DLIB_MATRIX_SIMPLE_STD_FUNCTION(atan) ...@@ -64,6 +64,7 @@ DLIB_MATRIX_SIMPLE_STD_FUNCTION(atan)
template <typename EXP> template <typename EXP>
struct op : has_nondestructive_aliasing, preserves_dimensions<EXP> struct op : has_nondestructive_aliasing, preserves_dimensions<EXP>
{ {
const static long cost = EXP::cost+7;
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)
...@@ -76,12 +77,11 @@ DLIB_MATRIX_SIMPLE_STD_FUNCTION(atan) ...@@ -76,12 +77,11 @@ DLIB_MATRIX_SIMPLE_STD_FUNCTION(atan)
template < template <
typename EXP typename EXP
> >
const matrix_exp<matrix_unary_exp<matrix_exp<EXP>,op_sigmoid> > sigmoid ( const matrix_unary_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; return matrix_unary_exp<EXP,op_sigmoid>(m.ref());
return matrix_exp<exp>(exp(m));
} }
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
...@@ -91,6 +91,7 @@ DLIB_MATRIX_SIMPLE_STD_FUNCTION(atan) ...@@ -91,6 +91,7 @@ DLIB_MATRIX_SIMPLE_STD_FUNCTION(atan)
template <typename EXP> template <typename EXP>
struct op : has_nondestructive_aliasing, preserves_dimensions<EXP> struct op : has_nondestructive_aliasing, preserves_dimensions<EXP>
{ {
const static long cost = EXP::cost+1;
typedef typename EXP::type type; typedef typename EXP::type type;
template <typename M, typename T> template <typename M, typename T>
static type apply ( const M& m, const T& eps, long r, long c) static type apply ( const M& m, const T& eps, long r, long c)
...@@ -107,28 +108,27 @@ DLIB_MATRIX_SIMPLE_STD_FUNCTION(atan) ...@@ -107,28 +108,27 @@ DLIB_MATRIX_SIMPLE_STD_FUNCTION(atan)
template < template <
typename EXP typename EXP
> >
const matrix_exp<matrix_scalar_binary_exp<matrix_exp<EXP>,typename EXP::type,op_round_zeros> > round_zeros ( const matrix_scalar_binary_exp<EXP,typename EXP::type,op_round_zeros> round_zeros (
const matrix_exp<EXP>& m const matrix_exp<EXP>& m
) )
{ {
// you can only round matrices that contain built in scalar types like double, long, float, etc... // you can only round matrices that contain built in scalar types like double, long, float, etc...
COMPILE_TIME_ASSERT(is_built_in_scalar_type<typename EXP::type>::value); COMPILE_TIME_ASSERT(is_built_in_scalar_type<typename EXP::type>::value);
typedef matrix_scalar_binary_exp<matrix_exp<EXP>,typename EXP::type, op_round_zeros> exp; typedef matrix_scalar_binary_exp<EXP,typename EXP::type, op_round_zeros> exp;
return matrix_exp<exp>(exp(m,10*std::numeric_limits<typename EXP::type>::epsilon())); return exp(m.ref(),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> > round_zeros ( const matrix_scalar_binary_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
) )
{ {
// you can only round matrices that contain built in scalar types like double, long, float, etc... // you can only round matrices that contain built in scalar types like double, long, float, etc...
COMPILE_TIME_ASSERT(is_built_in_scalar_type<typename EXP::type>::value); COMPILE_TIME_ASSERT(is_built_in_scalar_type<typename EXP::type>::value);
typedef matrix_scalar_binary_exp<matrix_exp<EXP>,typename EXP::type, op_round_zeros> exp; return matrix_scalar_binary_exp<EXP,typename EXP::type, op_round_zeros>(m.ref(),eps);
return matrix_exp<exp>(exp(m,eps));
} }
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
...@@ -138,6 +138,7 @@ DLIB_MATRIX_SIMPLE_STD_FUNCTION(atan) ...@@ -138,6 +138,7 @@ DLIB_MATRIX_SIMPLE_STD_FUNCTION(atan)
template <typename EXP> template <typename EXP>
struct op : has_nondestructive_aliasing, preserves_dimensions<EXP> struct op : has_nondestructive_aliasing, preserves_dimensions<EXP>
{ {
const static long cost = EXP::cost+2;
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)
...@@ -151,12 +152,11 @@ DLIB_MATRIX_SIMPLE_STD_FUNCTION(atan) ...@@ -151,12 +152,11 @@ DLIB_MATRIX_SIMPLE_STD_FUNCTION(atan)
template < template <
typename EXP typename EXP
> >
const matrix_exp<matrix_unary_exp<matrix_exp<EXP>,op_cubed> > cubed ( const matrix_unary_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; return matrix_unary_exp<EXP,op_cubed>(m.ref());
return matrix_exp<exp>(exp(m));
} }
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
...@@ -166,6 +166,7 @@ DLIB_MATRIX_SIMPLE_STD_FUNCTION(atan) ...@@ -166,6 +166,7 @@ DLIB_MATRIX_SIMPLE_STD_FUNCTION(atan)
template <typename EXP> template <typename EXP>
struct op : has_nondestructive_aliasing, preserves_dimensions<EXP> struct op : has_nondestructive_aliasing, preserves_dimensions<EXP>
{ {
const static long cost = EXP::cost+1;
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)
...@@ -179,12 +180,11 @@ DLIB_MATRIX_SIMPLE_STD_FUNCTION(atan) ...@@ -179,12 +180,11 @@ DLIB_MATRIX_SIMPLE_STD_FUNCTION(atan)
template < template <
typename EXP typename EXP
> >
const matrix_exp<matrix_unary_exp<matrix_exp<EXP>,op_squared> > squared ( const matrix_unary_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; return matrix_unary_exp<EXP,op_squared>(m.ref());
return matrix_exp<exp>(exp(m));
} }
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
...@@ -194,6 +194,7 @@ DLIB_MATRIX_SIMPLE_STD_FUNCTION(atan) ...@@ -194,6 +194,7 @@ DLIB_MATRIX_SIMPLE_STD_FUNCTION(atan)
template <typename EXP> template <typename EXP>
struct op : has_nondestructive_aliasing, preserves_dimensions<EXP> struct op : has_nondestructive_aliasing, preserves_dimensions<EXP>
{ {
const static long cost = EXP::cost+4;
typedef typename EXP::type type; typedef typename EXP::type type;
template <typename M, typename S> template <typename M, typename S>
static type apply ( const M& m, const S& s, long r, long c) static type apply ( const M& m, const S& s, long r, long c)
...@@ -205,7 +206,7 @@ DLIB_MATRIX_SIMPLE_STD_FUNCTION(atan) ...@@ -205,7 +206,7 @@ DLIB_MATRIX_SIMPLE_STD_FUNCTION(atan)
typename EXP, typename EXP,
typename S typename S
> >
const matrix_exp<matrix_scalar_binary_exp<matrix_exp<EXP>,typename EXP::type,op_pow> > pow ( const matrix_scalar_binary_exp<EXP,typename EXP::type,op_pow> pow (
const matrix_exp<EXP>& m, const matrix_exp<EXP>& m,
const S& s const S& s
) )
...@@ -216,8 +217,7 @@ DLIB_MATRIX_SIMPLE_STD_FUNCTION(atan) ...@@ -216,8 +217,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_pow> exp; return matrix_scalar_binary_exp<EXP,typename EXP::type,op_pow>(m.ref(),s);
return matrix_exp<exp>(exp(m,s));
} }
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
...@@ -227,6 +227,7 @@ DLIB_MATRIX_SIMPLE_STD_FUNCTION(atan) ...@@ -227,6 +227,7 @@ DLIB_MATRIX_SIMPLE_STD_FUNCTION(atan)
template <typename EXP> template <typename EXP>
struct op : has_nondestructive_aliasing, preserves_dimensions<EXP> struct op : has_nondestructive_aliasing, preserves_dimensions<EXP>
{ {
const static long cost = EXP::cost+2;
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)
...@@ -243,7 +244,7 @@ DLIB_MATRIX_SIMPLE_STD_FUNCTION(atan) ...@@ -243,7 +244,7 @@ DLIB_MATRIX_SIMPLE_STD_FUNCTION(atan)
template < template <
typename EXP typename EXP
> >
const matrix_exp<matrix_unary_exp<matrix_exp<EXP>,op_reciprocal> > reciprocal ( const matrix_unary_exp<EXP,op_reciprocal> reciprocal (
const matrix_exp<EXP>& m const matrix_exp<EXP>& m
) )
{ {
...@@ -253,8 +254,7 @@ DLIB_MATRIX_SIMPLE_STD_FUNCTION(atan) ...@@ -253,8 +254,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_unary_exp<matrix_exp<EXP>,op_reciprocal> exp; return matrix_unary_exp<EXP,op_reciprocal>(m.ref());
return matrix_exp<exp>(exp(m));
} }
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
...@@ -264,6 +264,7 @@ DLIB_MATRIX_SIMPLE_STD_FUNCTION(atan) ...@@ -264,6 +264,7 @@ DLIB_MATRIX_SIMPLE_STD_FUNCTION(atan)
template <typename EXP> template <typename EXP>
struct op : has_nondestructive_aliasing, preserves_dimensions<EXP> struct op : has_nondestructive_aliasing, preserves_dimensions<EXP>
{ {
const static long cost = EXP::cost+1;
typedef typename EXP::type type; typedef typename EXP::type type;
template <typename M> template <typename M>
static type apply ( const M& m, const type& s, long r, long c) static type apply ( const M& m, const type& s, long r, long c)
...@@ -276,7 +277,7 @@ DLIB_MATRIX_SIMPLE_STD_FUNCTION(atan) ...@@ -276,7 +277,7 @@ DLIB_MATRIX_SIMPLE_STD_FUNCTION(atan)
template < template <
typename EXP typename EXP
> >
const matrix_exp<matrix_scalar_binary_exp<matrix_exp<EXP>,typename EXP::type,op_normalize> > normalize ( const matrix_scalar_binary_exp<EXP,typename EXP::type,op_normalize> normalize (
const matrix_exp<EXP>& m const matrix_exp<EXP>& m
) )
{ {
...@@ -286,13 +287,13 @@ DLIB_MATRIX_SIMPLE_STD_FUNCTION(atan) ...@@ -286,13 +287,13 @@ 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; typedef matrix_scalar_binary_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)
temp = 1.0/temp; temp = 1.0/temp;
return matrix_exp<exp>(exp(m,temp)); return exp(m.ref(),temp);
} }
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
...@@ -302,6 +303,7 @@ DLIB_MATRIX_SIMPLE_STD_FUNCTION(atan) ...@@ -302,6 +303,7 @@ DLIB_MATRIX_SIMPLE_STD_FUNCTION(atan)
template <typename EXP, typename enabled = void> template <typename EXP, typename enabled = void>
struct op : has_nondestructive_aliasing, preserves_dimensions<EXP> struct op : has_nondestructive_aliasing, preserves_dimensions<EXP>
{ {
const static long cost = EXP::cost+3;
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)
...@@ -314,6 +316,7 @@ DLIB_MATRIX_SIMPLE_STD_FUNCTION(atan) ...@@ -314,6 +316,7 @@ DLIB_MATRIX_SIMPLE_STD_FUNCTION(atan)
struct op<EXP,typename enable_if_c<std::numeric_limits<typename EXP::type>::is_integer>::type > struct op<EXP,typename enable_if_c<std::numeric_limits<typename EXP::type>::is_integer>::type >
: has_nondestructive_aliasing, preserves_dimensions<EXP> : has_nondestructive_aliasing, preserves_dimensions<EXP>
{ {
const static long cost = EXP::cost;
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)
...@@ -326,14 +329,14 @@ DLIB_MATRIX_SIMPLE_STD_FUNCTION(atan) ...@@ -326,14 +329,14 @@ DLIB_MATRIX_SIMPLE_STD_FUNCTION(atan)
template < template <
typename EXP typename EXP
> >
const matrix_exp<matrix_unary_exp<matrix_exp<EXP>,op_round> > round ( const matrix_unary_exp<EXP,op_round> round (
const matrix_exp<EXP>& m const matrix_exp<EXP>& m
) )
{ {
// you can only round matrices that contain built in scalar types like double, long, float, etc... // you can only round matrices that contain built in scalar types like double, long, float, etc...
COMPILE_TIME_ASSERT(is_built_in_scalar_type<typename EXP::type>::value); COMPILE_TIME_ASSERT(is_built_in_scalar_type<typename EXP::type>::value);
typedef matrix_unary_exp<matrix_exp<EXP>,op_round> exp; typedef matrix_unary_exp<EXP,op_round> exp;
return matrix_exp<exp>(exp(m)); return exp(m.ref());
} }
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
...@@ -343,6 +346,7 @@ DLIB_MATRIX_SIMPLE_STD_FUNCTION(atan) ...@@ -343,6 +346,7 @@ DLIB_MATRIX_SIMPLE_STD_FUNCTION(atan)
template <typename EXP1, typename EXP2> template <typename EXP1, typename EXP2>
struct op : has_nondestructive_aliasing, preserves_dimensions<EXP1,EXP2> struct op : has_nondestructive_aliasing, preserves_dimensions<EXP1,EXP2>
{ {
const static long cost = EXP1::cost+EXP2::cost+1;
typedef std::complex<typename EXP1::type> type; typedef std::complex<typename EXP1::type> type;
template <typename M1, typename M2> template <typename M1, typename M2>
...@@ -355,7 +359,7 @@ DLIB_MATRIX_SIMPLE_STD_FUNCTION(atan) ...@@ -355,7 +359,7 @@ DLIB_MATRIX_SIMPLE_STD_FUNCTION(atan)
typename EXP1, typename EXP1,
typename EXP2 typename EXP2
> >
const matrix_exp<matrix_binary_exp<matrix_exp<EXP1>,matrix_exp<EXP2>,op_complex_matrix> > complex_matrix ( const matrix_binary_exp<EXP1,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
) )
...@@ -373,8 +377,8 @@ DLIB_MATRIX_SIMPLE_STD_FUNCTION(atan) ...@@ -373,8 +377,8 @@ 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> exp; typedef matrix_binary_exp<EXP1,EXP2,op_complex_matrix> exp;
return matrix_exp<exp>(exp(real_part,imag_part)); return exp(real_part.ref(),imag_part.ref());
} }
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
...@@ -384,6 +388,7 @@ DLIB_MATRIX_SIMPLE_STD_FUNCTION(atan) ...@@ -384,6 +388,7 @@ DLIB_MATRIX_SIMPLE_STD_FUNCTION(atan)
template <typename EXP> template <typename EXP>
struct op : has_nondestructive_aliasing, preserves_dimensions<EXP> struct op : has_nondestructive_aliasing, preserves_dimensions<EXP>
{ {
const static long cost = EXP::cost+2;
typedef typename EXP::type::value_type type; typedef typename EXP::type::value_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)
...@@ -394,12 +399,12 @@ DLIB_MATRIX_SIMPLE_STD_FUNCTION(atan) ...@@ -394,12 +399,12 @@ DLIB_MATRIX_SIMPLE_STD_FUNCTION(atan)
template < template <
typename EXP typename EXP
> >
const matrix_exp<matrix_unary_exp<matrix_exp<EXP>,op_norm> > norm ( const matrix_unary_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; typedef matrix_unary_exp<EXP,op_norm> exp;
return matrix_exp<exp>(exp(m)); return exp(m.ref());
} }
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
...@@ -409,6 +414,7 @@ DLIB_MATRIX_SIMPLE_STD_FUNCTION(atan) ...@@ -409,6 +414,7 @@ DLIB_MATRIX_SIMPLE_STD_FUNCTION(atan)
template <typename EXP> template <typename EXP>
struct op : has_nondestructive_aliasing, preserves_dimensions<EXP> struct op : has_nondestructive_aliasing, preserves_dimensions<EXP>
{ {
const static long cost = EXP::cost;
typedef typename EXP::type::value_type type; typedef typename EXP::type::value_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)
...@@ -419,12 +425,12 @@ DLIB_MATRIX_SIMPLE_STD_FUNCTION(atan) ...@@ -419,12 +425,12 @@ DLIB_MATRIX_SIMPLE_STD_FUNCTION(atan)
template < template <
typename EXP typename EXP
> >
const matrix_exp<matrix_unary_exp<matrix_exp<EXP>,op_real> > real ( const matrix_unary_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; typedef matrix_unary_exp<EXP,op_real> exp;
return matrix_exp<exp>(exp(m)); return exp(m.ref());
} }
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
...@@ -434,6 +440,7 @@ DLIB_MATRIX_SIMPLE_STD_FUNCTION(atan) ...@@ -434,6 +440,7 @@ DLIB_MATRIX_SIMPLE_STD_FUNCTION(atan)
template <typename EXP> template <typename EXP>
struct op : has_nondestructive_aliasing, preserves_dimensions<EXP> struct op : has_nondestructive_aliasing, preserves_dimensions<EXP>
{ {
const static long cost = EXP::cost;
typedef typename EXP::type::value_type type; typedef typename EXP::type::value_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)
...@@ -444,12 +451,12 @@ DLIB_MATRIX_SIMPLE_STD_FUNCTION(atan) ...@@ -444,12 +451,12 @@ DLIB_MATRIX_SIMPLE_STD_FUNCTION(atan)
template < template <
typename EXP typename EXP
> >
const matrix_exp<matrix_unary_exp<matrix_exp<EXP>,op_imag> > imag ( const matrix_unary_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; typedef matrix_unary_exp<EXP,op_imag> exp;
return matrix_exp<exp>(exp(m)); return exp(m.ref());
} }
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include <vector> #include <vector>
#include <algorithm> #include <algorithm>
#include "../std_allocator.h" #include "../std_allocator.h"
#include "matrix_expressions.h"
...@@ -97,6 +98,7 @@ namespace dlib ...@@ -97,6 +98,7 @@ namespace dlib
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
/* TODO remove this
template < template <
typename OP typename OP
> >
...@@ -114,6 +116,7 @@ namespace dlib ...@@ -114,6 +116,7 @@ namespace dlib
typename OP typename OP
> >
class matrix_binary_exp; class matrix_binary_exp;
*/
struct has_destructive_aliasing struct has_destructive_aliasing
{ {
...@@ -129,6 +132,23 @@ namespace dlib ...@@ -129,6 +132,23 @@ namespace dlib
const M2& m2, const M2& m2,
const matrix<U,iNR,iNC,MM,L>& item const matrix<U,iNR,iNC,MM,L>& item
) { return m1.aliases(item) || m2.aliases(item) ; } ) { return m1.aliases(item) || m2.aliases(item) ; }
template <typename M1, typename M2, typename M3, typename U, long iNR, long iNC, typename MM, typename L >
static bool destructively_aliases (
const M1& m1,
const M2& m2,
const M3& m3,
const matrix<U,iNR,iNC,MM,L>& item
) { return m1.aliases(item) || m2.aliases(item) || m3.aliases(item); }
template <typename M1, typename M2, typename M3, typename M4, typename U, long iNR, long iNC, typename MM, typename L >
static bool destructively_aliases (
const M1& m1,
const M2& m2,
const M3& m3,
const M4& m4,
const matrix<U,iNR,iNC,MM,L>& item
) { return m1.aliases(item) || m2.aliases(item) || m3.aliases(item) || m4.aliases(item); }
}; };
struct has_nondestructive_aliasing struct has_nondestructive_aliasing
...@@ -145,6 +165,26 @@ namespace dlib ...@@ -145,6 +165,26 @@ namespace dlib
const M2& m2, const M2& m2,
const matrix<U,iNR,iNC, MM, L>& item const matrix<U,iNR,iNC, MM, L>& item
) { return m1.destructively_aliases(item) || m2.destructively_aliases(item) ; } ) { return m1.destructively_aliases(item) || m2.destructively_aliases(item) ; }
template <typename M1, typename M2, typename M3, typename U, long iNR, long iNC, typename MM, typename L >
static bool destructively_aliases (
const M1& m1,
const M2& m2,
const M3& m3,
const matrix<U,iNR,iNC, MM, L>& item
) { return m1.destructively_aliases(item) || m2.destructively_aliases(item) || m3.destructively_aliases(item) ; }
template <typename M1, typename M2, typename M3, typename M4, typename U, long iNR, long iNC, typename MM, typename L >
static bool destructively_aliases (
const M1& m1,
const M2& m2,
const M3& m3,
const M4& m4,
const matrix<U,iNR,iNC, MM, L>& item
) { return m1.destructively_aliases(item) ||
m2.destructively_aliases(item) ||
m3.destructively_aliases(item) ||
m4.destructively_aliases(item) ; }
}; };
template <typename EXP1, typename EXP2 = void, typename EXP3 = void, typename EXP4 = void> template <typename EXP1, typename EXP2 = void, typename EXP3 = void, typename EXP4 = void>
...@@ -163,6 +203,16 @@ namespace dlib ...@@ -163,6 +203,16 @@ namespace dlib
static long nr (const M1& m1, const M2& ) { return m1.nr(); } static long nr (const M1& m1, const M2& ) { return m1.nr(); }
template <typename M1, typename M2> template <typename M1, typename M2>
static long nc (const M1& m1, const M2& ) { return m1.nc(); } static long nc (const M1& m1, const M2& ) { return m1.nc(); }
template <typename M1, typename M2, typename M3>
static long nr (const M1& m1, const M2&, const M3& ) { return m1.nr(); }
template <typename M1, typename M2, typename M3>
static long nc (const M1& m1, const M2&, const M3& ) { return m1.nc(); }
template <typename M1, typename M2, typename M3, typename M4>
static long nr (const M1& m1, const M2&, const M3&, const M4& ) { return m1.nr(); }
template <typename M1, typename M2, typename M3, typename M4>
static long nc (const M1& m1, const M2&, const M3&, const M4& ) { return m1.nc(); }
}; };
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
...@@ -1180,773 +1230,32 @@ convergence: ...@@ -1180,773 +1230,32 @@ convergence:
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
template <
typename OP
>
class matrix_zeroary_exp
{
public:
typedef typename OP::type type;
typedef matrix_zeroary_exp ref_type;
typedef typename OP::mem_manager_type mem_manager_type;
const static long NR = OP::NR;
const static long NC = OP::NC;
const typename OP::type operator() (
long r,
long c
) const { return OP::apply(r,c); }
template <typename U, long iNR, long iNC , typename MM, typename L>
bool aliases (
const matrix<U,iNR,iNC,MM,L>& item
) const { return false; }
template <typename U, long iNR, long iNC, typename MM, typename L >
bool destructively_aliases (
const matrix<U,iNR,iNC,MM,L>& item
) const { return false; }
long nr (
) const { return NR; }
long nc (
) const { return NC; }
const ref_type& ref(
) const { return *this; }
};
// ----------------------------------------------------------------------------------------
template <
typename S,
typename OP
>
class dynamic_matrix_scalar_unary_exp
{
/*!
REQUIREMENTS ON S
- must NOT be a matrix_exp or matrix_ref object (or
an object with a compatible interface).
!*/
public:
typedef typename OP::type type;
typedef dynamic_matrix_scalar_unary_exp ref_type;
typedef typename OP::mem_manager_type mem_manager_type;
const static long NR = OP::NR;
const static long NC = OP::NC;
dynamic_matrix_scalar_unary_exp (
long nr__,
long nc__,
const S& s_
) :
nr_(nr__),
nc_(nc__),
s(s_)
{
COMPILE_TIME_ASSERT(is_matrix<S>::value == false);
}
const typename OP::type operator() (
long r,
long c
) const { return OP::apply(s,r,c); }
template <typename U, long iNR, long iNC, typename MM, typename L >
bool aliases (
const matrix<U,iNR,iNC,MM,L>& item
) const { return false; }
template <typename U, long iNR, long iNC , typename MM, typename L>
bool destructively_aliases (
const matrix<U,iNR,iNC,MM,L>& item
) const { return false; }
const ref_type& ref(
) const { return *this; }
long nr (
) const { return nr_; }
long nc (
) const { return nc_; }
private:
const long nr_;
const long nc_;
const S s;
};
// ----------------------------------------------------------------------------------------
template <
typename S,
typename OP
>
class matrix_scalar_unary_exp
{
/*!
REQUIREMENTS ON S
- must NOT be a matrix_exp or matrix_ref object (or
an object with a compatible interface).
!*/
public:
typedef typename OP::type type;
typedef matrix_scalar_unary_exp ref_type;
typedef typename OP::mem_manager_type mem_manager_type;
const static long NR = OP::NR;
const static long NC = OP::NC;
matrix_scalar_unary_exp (
const S& s_
) :
s(s_)
{
COMPILE_TIME_ASSERT(is_matrix<S>::value == false);
}
const typename OP::type operator() (
long r,
long c
) const { return OP::apply(s,r,c); }
template <typename U, long iNR, long iNC, typename MM, typename L >
bool aliases (
const matrix<U,iNR,iNC,MM,L>& item
) const { return false; }
template <typename U, long iNR, long iNC, typename MM, typename L >
bool destructively_aliases (
const matrix<U,iNR,iNC,MM,L>& item
) const { return false; }
const ref_type& ref(
) const { return *this; }
long nr (
) const { return NR; }
long nc (
) const { return NC; }
private:
const S s;
};
// ----------------------------------------------------------------------------------------
template <
typename M,
typename OP_
>
class matrix_unary_exp
{
/*!
REQUIREMENTS ON M
- 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;
typedef typename OP::mem_manager_type mem_manager_type;
const static long NR = OP::NR;
const static long NC = OP::NC;
matrix_unary_exp (
const M& m_
) :
m(m_)
{}
const typename OP::type operator() (
long r,
long c
) const { return OP::apply(m,r,c); }
template <typename U, long iNR, long iNC, typename MM, typename L >
bool aliases (
const matrix<U,iNR,iNC,MM,L>& item
) const { return m.aliases(item); }
template <typename U, long iNR, long iNC, typename MM, typename L >
bool destructively_aliases (
const matrix<U,iNR,iNC,MM,L>& item
) const { return OP::destructively_aliases(m,item); }
const ref_type& ref(
) const { return *this; }
long nr (
) const { return OP::nr(m); }
long nc (
) const { return OP::nc(m); }
private:
const M m;
};
// ----------------------------------------------------------------------------------------
template <
typename M
>
class matrix_std_vector_exp
{
/*!
REQUIREMENTS ON M
- must be a std::vector object (or
an object with a compatible interface).
!*/
public:
typedef typename M::value_type type;
typedef matrix_std_vector_exp ref_type;
typedef typename memory_manager<char>::kernel_1a mem_manager_type;
const static long NR = 0;
const static long NC = 1;
matrix_std_vector_exp (
const M& m_
) :
m(m_)
{
}
const typename M::value_type operator() (
long r,
long
) const { return m[r]; }
template <typename U, long iNR, long iNC, typename MM, typename L>
bool aliases (
const matrix<U,iNR,iNC,MM,L>& item
) const { return false; }
template <typename U, long iNR, long iNC , typename MM, typename L>
bool destructively_aliases (
const matrix<U,iNR,iNC,MM,L>& item
) const { return false; }
const ref_type& ref(
) const { return *this; }
long nr (
) const { return m.size(); }
long nc (
) const { return 1; }
private:
const M& m;
};
// ----------------------------------------------------------------------------------------
template <
typename M
>
class matrix_vector_exp
{
/*!
REQUIREMENTS ON M
- must be a dlib::array object (or
an object with a compatible interface).
!*/
public:
typedef typename M::type type;
typedef matrix_vector_exp ref_type;
typedef typename M::mem_manager_type mem_manager_type;
const static long NR = 0;
const static long NC = 1;
matrix_vector_exp (
const M& m_
) :
m(m_)
{
}
const typename M::type operator() (
long r,
long
) const { return m[r]; }
template <typename U, long iNR, long iNC, typename MM, typename L>
bool aliases (
const matrix<U,iNR,iNC,MM,L>& item
) const { return false; }
template <typename U, long iNR, long iNC , typename MM, typename L>
bool destructively_aliases (
const matrix<U,iNR,iNC,MM,L>& item
) const { return false; }
const ref_type& ref(
) const { return *this; }
long nr (
) const { return m.size(); }
long nc (
) const { return 1; }
private:
const M& m;
};
// ----------------------------------------------------------------------------------------
template <
typename M
>
class matrix_array_exp
{
/*!
REQUIREMENTS ON M
- must be a dlib::array2d object (or
an object with a compatible interface).
!*/
public:
typedef typename M::type type;
typedef matrix_array_exp ref_type;
typedef typename M::mem_manager_type mem_manager_type;
const static long NR = 0;
const static long NC = 0;
matrix_array_exp (
const M& m_
) :
m(m_)
{
}
const typename M::type operator() (
long r,
long c
) const { return m[r][c]; }
template <typename U, long iNR, long iNC, typename MM, typename L>
bool aliases (
const matrix<U,iNR,iNC,MM,L>& item
) const { return false; }
template <typename U, long iNR, long iNC , typename MM, typename L>
bool destructively_aliases (
const matrix<U,iNR,iNC,MM,L>& item
) const { return false; }
const ref_type& ref(
) const { return *this; }
long nr (
) const { return m.nr(); }
long nc (
) const { return m.nc(); }
private:
const M& m;
};
// ----------------------------------------------------------------------------------------
template <
typename M
>
class matrix_sub_exp
{
/*!
REQUIREMENTS ON M
- must be a matrix_exp or matrix_ref object (or
an object with a compatible interface).
!*/
public:
typedef typename M::type type;
typedef matrix_sub_exp ref_type;
typedef typename M::mem_manager_type mem_manager_type;
const static long NR = 0;
const static long NC = 0;
matrix_sub_exp (
const M& m_,
const long& r__,
const long& c__,
const long& nr__,
const long& nc__
) :
m(m_),
r_(r__),
c_(c__),
nr_(nr__),
nc_(nc__)
{
}
const typename M::type operator() (
long r,
long c
) const { return m(r+r_,c+c_); }
template <typename U, long iNR, long iNC, typename MM, typename L >
bool aliases (
const matrix<U,iNR,iNC,MM,L>& item
) const { return m.aliases(item); }
template <typename U, long iNR, long iNC , typename MM, typename L>
bool destructively_aliases (
const matrix<U,iNR,iNC,MM,L>& item
) const { return m.aliases(item); }
const ref_type& ref(
) const { return *this; }
long nr (
) const { return nr_; }
long nc (
) const { return nc_; }
private:
const M m;
const long r_, c_, nr_, nc_;
};
// ----------------------------------------------------------------------------------------
template <
typename M,
typename S,
typename OP_
>
class matrix_scalar_binary_exp
{
/*!
REQUIREMENTS ON M
- 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;
typedef typename OP::mem_manager_type mem_manager_type;
const static long NR = OP::NR;
const static long NC = OP::NC;
matrix_scalar_binary_exp (
const M& m_,
const S& s_
) :
m(m_),
s(s_)
{
COMPILE_TIME_ASSERT(is_matrix<S>::value == false);
}
const typename OP::type operator() (
long r,
long c
) const { return OP::apply(m,s,r,c); }
template <typename U, long iNR, long iNC, typename MM, typename L >
bool aliases (
const matrix<U,iNR,iNC,MM,L>& item
) const { return m.aliases(item); }
template <typename U, long iNR, long iNC , typename MM, typename L>
bool destructively_aliases (
const matrix<U,iNR,iNC,MM,L>& item
) const { return OP::destructively_aliases(m,item); }
const ref_type& ref(
) const { return *this; }
long nr (
) const { return OP::nr(m); }
long nc (
) const { return OP::nc(m); }
private:
const M m;
const S s;
};
// ----------------------------------------------------------------------------------------
template <
typename M,
typename S,
typename OP_
>
class matrix_scalar_trinary_exp
{
/*!
REQUIREMENTS ON M
- 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_trinary_exp ref_type;
typedef typename OP::mem_manager_type mem_manager_type;
const static long NR = OP::NR;
const static long NC = OP::NC;
matrix_scalar_trinary_exp (
const M& m_,
const S& s1_,
const S& s2_
) :
m(m_),
s1(s1_),
s2(s2_)
{
COMPILE_TIME_ASSERT(is_matrix<S>::value == false);
}
const typename OP::type operator() (
long r,
long c
) const { return OP::apply(m,s1,s2,r,c); }
template <typename U, long iNR, long iNC, typename MM, typename L>
bool aliases (
const matrix<U,iNR,iNC,MM,L>& item
) const { return m.aliases(item); }
template <typename U, long iNR, long iNC , typename MM, typename L>
bool destructively_aliases (
const matrix<U,iNR,iNC,MM,L>& item
) const { return OP::destructively_aliases(m,item); }
const ref_type& ref(
) const { return *this; }
long nr (
) const { return OP::nr(m); }
long nc (
) const { return OP::nc(m); }
private:
const M m;
const S s1;
const S s2;
};
// ----------------------------------------------------------------------------------------
template <
typename M1,
typename M2,
typename OP_
>
class matrix_binary_exp
{
/*!
REQUIREMENTS ON M1 AND M2
- 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;
typedef typename OP::mem_manager_type mem_manager_type;
const static long NR = OP::NR;
const static long NC = OP::NC;
matrix_binary_exp (
const M1& m1_,
const M2& m2_
) :
m1(m1_),
m2(m2_)
{}
const typename OP::type operator() (
long r,
long c
) const { return OP::apply(m1,m2,r,c); }
template <typename U, long iNR, long iNC, typename MM, typename L >
bool aliases (
const matrix<U,iNR,iNC,MM,L>& item
) const { return m1.aliases(item) || m2.aliases(item); }
template <typename U, long iNR, long iNC, typename MM, typename L >
bool destructively_aliases (
const matrix<U,iNR,iNC,MM,L>& item
) const { return OP::destructively_aliases(m1,m2,item); }
const ref_type& ref(
) const { return *this; }
long nr (
) const { return OP::nr(m1,m2); }
long nc (
) const { return OP::nc(m1,m2); }
private:
const M1 m1;
const M2 m2;
};
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
class matrix_range_exp
{
public:
typedef long type;
typedef matrix_range_exp ref_type;
typedef memory_manager<char>::kernel_1a mem_manager_type;
const static long NR = 0;
const static long NC = 1;
matrix_range_exp (
long start_,
long end_
)
{
start = start_;
if (start_ <= end_)
inc = 1;
else
inc = -1;
nr_ = std::abs(end_ - start_) + 1;
}
matrix_range_exp (
long start_,
long inc_,
long end_
)
{
start = start_;
nr_ = std::abs(end_ - start_)/inc_ + 1;
if (start_ <= end_)
inc = inc_;
else
inc = -inc_;
}
long operator() (
long r,
long c
) const { return start + r*inc; }
template <typename U, long iNR, long iNC , typename MM, typename L>
bool aliases (
const matrix<U,iNR,iNC,MM,L>& item
) const { return false; }
template <typename U, long iNR, long iNC, typename MM, typename L >
bool destructively_aliases (
const matrix<U,iNR,iNC,MM,L>& item
) const { return false; }
long nr (
) const { return nr_; }
long nc (
) const { return NC; }
const ref_type& ref(
) const { return *this; }
long nr_;
long start;
long inc;
};
// ----------------------------------------------------------------------------------------
template <long start, long inc_, long end>
class matrix_range_static_exp
{
public:
typedef long type;
typedef matrix_range_static_exp ref_type;
typedef memory_manager<char>::kernel_1a mem_manager_type;
const static long inc = (start <= end)?inc_:-inc_;
const static long NR = tabs<(end - start)>::value/inc_ + 1;
const static long NC = 1;
long operator() (
long r,
long c
) const { return start + r*inc; }
template <typename U, long iNR, long iNC , typename MM, typename L>
bool aliases (
const matrix<U,iNR,iNC,MM,L>& item
) const { return false; }
template <typename U, long iNR, long iNC, typename MM, typename L >
bool destructively_aliases (
const matrix<U,iNR,iNC,MM,L>& item
) const { return false; }
long nr (
) const { return NR; }
long nc (
) const { return NC; }
const ref_type& ref(
) const { return *this; }
};
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
template <long start, long inc, long end> template <long start, long inc, long end>
const matrix_exp<matrix_range_static_exp<start,inc,end> > range ( const matrix_range_static_exp<start,inc,end> range (
) )
{ {
COMPILE_TIME_ASSERT(inc > 0); COMPILE_TIME_ASSERT(inc > 0);
return matrix_exp<matrix_range_static_exp<start,inc,end> >(matrix_range_static_exp<start,inc,end>()); return matrix_range_static_exp<start,inc,end>();
} }
template <long start, long end> template <long start, long end>
const matrix_exp<matrix_range_static_exp<start,1,end> > range ( const matrix_range_static_exp<start,1,end> range (
) )
{ {
return matrix_exp<matrix_range_static_exp<start,1,end> >(matrix_range_static_exp<start,1,end>()); return matrix_range_static_exp<start,1,end>();
} }
inline const matrix_exp<matrix_range_exp> range ( inline const matrix_range_exp range (
long start, long start,
long end long end
) )
{ {
return matrix_exp<matrix_range_exp>(matrix_range_exp(start,end)); return matrix_range_exp(start,end);
} }
inline const matrix_exp<matrix_range_exp> range ( inline const matrix_range_exp range (
long start, long start,
long inc, long inc,
long end long end
...@@ -1960,7 +1269,7 @@ convergence: ...@@ -1960,7 +1269,7 @@ convergence:
<< "\n\tend: " << end << "\n\tend: " << end
); );
return matrix_exp<matrix_range_exp>(matrix_range_exp(start,inc,end)); return matrix_range_exp(start,inc,end);
} }
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
...@@ -1981,13 +1290,12 @@ convergence: ...@@ -1981,13 +1290,12 @@ convergence:
template < template <
typename array_type typename array_type
> >
const typename disable_if<is_matrix<array_type>,matrix_exp<matrix_array_exp<array_type> > >::type const typename disable_if<is_matrix<array_type>,matrix_array2d_exp<array_type> >::type
array_to_matrix ( array_to_matrix (
const array_type& array const array_type& array
) )
{ {
typedef matrix_array_exp<array_type> exp; return matrix_array2d_exp<array_type>(array);
return matrix_exp<exp>(exp(array));
} }
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
...@@ -1995,13 +1303,13 @@ convergence: ...@@ -1995,13 +1303,13 @@ convergence:
template < template <
typename vector_type typename vector_type
> >
const typename disable_if<is_matrix<vector_type>,matrix_exp<matrix_vector_exp<vector_type> > >::type const typename disable_if<is_matrix<vector_type>,matrix_array_exp<vector_type> >::type
vector_to_matrix ( vector_to_matrix (
const vector_type& vector const vector_type& vector
) )
{ {
typedef matrix_vector_exp<vector_type> exp; typedef matrix_array_exp<vector_type> exp;
return matrix_exp<exp>(exp(vector)); return exp(vector);
} }
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
...@@ -2012,6 +1320,10 @@ convergence: ...@@ -2012,6 +1320,10 @@ convergence:
const typename enable_if<is_matrix<vector_type>,vector_type>::type& vector_to_matrix ( const typename enable_if<is_matrix<vector_type>,vector_type>::type& vector_to_matrix (
const vector_type& vector const vector_type& vector
) )
/*!
This overload catches the case where the argument to this function is
already a matrix.
!*/
{ {
return vector; return vector;
} }
...@@ -2022,12 +1334,12 @@ convergence: ...@@ -2022,12 +1334,12 @@ convergence:
typename value_type, typename value_type,
typename alloc typename alloc
> >
const matrix_exp<matrix_std_vector_exp<std::vector<value_type,alloc> > > vector_to_matrix ( const matrix_std_vector_exp<std::vector<value_type,alloc> > vector_to_matrix (
const std::vector<value_type,alloc>& vector const std::vector<value_type,alloc>& vector
) )
{ {
typedef matrix_std_vector_exp<std::vector<value_type,alloc> > exp; typedef matrix_std_vector_exp<std::vector<value_type,alloc> > exp;
return matrix_exp<exp>(exp(vector)); return exp(vector);
} }
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
...@@ -2036,12 +1348,12 @@ convergence: ...@@ -2036,12 +1348,12 @@ convergence:
typename value_type, typename value_type,
typename alloc typename alloc
> >
const matrix_exp<matrix_std_vector_exp<std_vector_c<value_type,alloc> > > vector_to_matrix ( const matrix_std_vector_exp<std_vector_c<value_type,alloc> > vector_to_matrix (
const std_vector_c<value_type,alloc>& vector const std_vector_c<value_type,alloc>& vector
) )
{ {
typedef matrix_std_vector_exp<std_vector_c<value_type,alloc> > exp; typedef matrix_std_vector_exp<std_vector_c<value_type,alloc> > exp;
return matrix_exp<exp>(exp(vector)); return exp(vector);
} }
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
...@@ -2061,7 +1373,7 @@ convergence: ...@@ -2061,7 +1373,7 @@ convergence:
template < template <
typename EXP typename EXP
> >
const matrix_exp<matrix_sub_exp<matrix_exp<EXP> > > subm ( const matrix_sub_exp<EXP> subm (
const matrix_exp<EXP>& m, const matrix_exp<EXP>& m,
long r, long r,
long c, long c,
...@@ -2080,8 +1392,8 @@ convergence: ...@@ -2080,8 +1392,8 @@ convergence:
<< "\n\tnc: " << nc << "\n\tnc: " << nc
); );
typedef matrix_sub_exp<matrix_exp<EXP> > exp; typedef matrix_sub_exp<EXP> exp;
return matrix_exp<exp>(exp(m,r,c,nr,nc)); return exp(m.ref(),r,c,nr,nc);
} }
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
...@@ -2089,7 +1401,7 @@ convergence: ...@@ -2089,7 +1401,7 @@ convergence:
template < template <
typename EXP typename EXP
> >
const matrix_exp<matrix_sub_exp<matrix_exp<EXP> > > subm ( const matrix_sub_exp<EXP> subm (
const matrix_exp<EXP>& m, const matrix_exp<EXP>& m,
const rectangle& rect const rectangle& rect
) )
...@@ -2105,80 +1417,18 @@ convergence: ...@@ -2105,80 +1417,18 @@ convergence:
<< "\n\trect.bottom(): " << rect.bottom() << "\n\trect.bottom(): " << rect.bottom()
); );
typedef matrix_sub_exp<matrix_exp<EXP> > exp; typedef matrix_sub_exp<EXP> exp;
return matrix_exp<exp>(exp(m,rect.top(),rect.left(),rect.height(),rect.width())); return exp(m.ref(),rect.top(),rect.left(),rect.height(),rect.width());
} }
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
template <
typename M,
typename EXPr,
typename EXPc
>
class matrix_sub_range_exp
{
/*!
REQUIREMENTS ON M, EXPr and EXPc
- must be a matrix_exp or matrix_ref object (or
an object with a compatible interface).
!*/
public:
typedef typename M::type type;
typedef matrix_sub_range_exp ref_type;
typedef typename M::mem_manager_type mem_manager_type;
const static long NR = EXPr::NR*EXPr::NC;
const static long NC = EXPc::NR*EXPr::NC;
matrix_sub_range_exp (
const M& m_,
const EXPr& rows_,
const EXPc& cols_
) :
m(m_),
rows(rows_),
cols(cols_)
{
}
const typename M::type operator() (
long r,
long c
) const { return m(rows(r),cols(c)); }
template <typename U, long iNR, long iNC, typename MM, typename L >
bool aliases (
const matrix<U,iNR,iNC,MM,L>& item
) const { return m.aliases(item) || rows.aliases(item) || cols.aliases(item); }
template <typename U, long iNR, long iNC , typename MM, typename L>
bool destructively_aliases (
const matrix<U,iNR,iNC,MM,L>& item
) const { return m.aliases(item) || rows.aliases(item) || cols.aliases(item); }
const ref_type& ref(
) const { return *this; }
long nr (
) const { return rows.size(); }
long nc (
) const { return cols.size(); }
private:
const M m;
const EXPr rows;
const EXPc cols;
};
template < template <
typename EXP, typename EXP,
typename EXPr, typename EXPr,
typename EXPc typename EXPc
> >
const matrix_exp<matrix_sub_range_exp<matrix_exp<EXP>,matrix_exp<EXPr>,matrix_exp<EXPc> > > subm ( const matrix_sub_range_exp<EXP,EXPr,EXPc> subm (
const matrix_exp<EXP>& m, const matrix_exp<EXP>& m,
const matrix_exp<EXPr>& rows, const matrix_exp<EXPr>& rows,
const matrix_exp<EXPc>& cols const matrix_exp<EXPc>& cols
...@@ -2204,8 +1454,8 @@ convergence: ...@@ -2204,8 +1454,8 @@ convergence:
<< "\n\tcols.nc(): " << cols.nc() << "\n\tcols.nc(): " << cols.nc()
); );
typedef matrix_sub_range_exp<matrix_exp<EXP>,matrix_exp<EXPr>,matrix_exp<EXPc> > exp; typedef matrix_sub_range_exp<EXP,EXPr,EXPc> exp;
return matrix_exp<exp>(exp(m,rows,cols)); return exp(m.ref(),rows.ref(),cols.ref());
} }
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
...@@ -2215,6 +1465,7 @@ convergence: ...@@ -2215,6 +1465,7 @@ convergence:
template <typename EXP> template <typename EXP>
struct op : has_destructive_aliasing struct op : has_destructive_aliasing
{ {
const static long cost = EXP::cost;
const static long NR = 1; const static long NR = 1;
const static long NC = EXP::NC; const static long NC = EXP::NC;
typedef typename EXP::type type; typedef typename EXP::type type;
...@@ -2233,7 +1484,7 @@ convergence: ...@@ -2233,7 +1484,7 @@ convergence:
template < template <
typename EXP typename EXP
> >
const matrix_exp<matrix_scalar_binary_exp<matrix_exp<EXP>,long,op_rowm> > rowm ( const matrix_scalar_binary_exp<EXP,long,op_rowm> rowm (
const matrix_exp<EXP>& m, const matrix_exp<EXP>& m,
long row long row
) )
...@@ -2246,8 +1497,8 @@ convergence: ...@@ -2246,8 +1497,8 @@ convergence:
<< "\n\trow: " << row << "\n\trow: " << row
); );
typedef matrix_scalar_binary_exp<matrix_exp<EXP>,long,op_rowm> exp; typedef matrix_scalar_binary_exp<EXP,long,op_rowm> exp;
return matrix_exp<exp>(exp(m,row)); return exp(m.ref(),row);
} }
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
...@@ -2257,6 +1508,7 @@ convergence: ...@@ -2257,6 +1508,7 @@ convergence:
template <typename EXP1, typename EXP2> template <typename EXP1, typename EXP2>
struct op : has_destructive_aliasing struct op : has_destructive_aliasing
{ {
const static long cost = EXP1::cost+EXP2::cost;
typedef typename EXP1::type type; typedef typename EXP1::type type;
typedef typename EXP1::mem_manager_type mem_manager_type; typedef typename EXP1::mem_manager_type mem_manager_type;
const static long NR = EXP2::NC*EXP2::NR; const static long NR = EXP2::NC*EXP2::NR;
...@@ -2277,7 +1529,7 @@ convergence: ...@@ -2277,7 +1529,7 @@ convergence:
typename EXP1, typename EXP1,
typename EXP2 typename EXP2
> >
const matrix_exp<matrix_binary_exp<matrix_exp<EXP1>,matrix_exp<EXP2>,op_rowm_range> > rowm ( const matrix_binary_exp<EXP1,EXP2,op_rowm_range> rowm (
const matrix_exp<EXP1>& m, const matrix_exp<EXP1>& m,
const matrix_exp<EXP2>& rows const matrix_exp<EXP2>& rows
) )
...@@ -2296,8 +1548,8 @@ convergence: ...@@ -2296,8 +1548,8 @@ convergence:
<< "\n\trows.nc(): " << rows.nc() << "\n\trows.nc(): " << rows.nc()
); );
typedef matrix_binary_exp<matrix_exp<EXP1>,matrix_exp<EXP2>,op_rowm_range> exp; typedef matrix_binary_exp<EXP1,EXP2,op_rowm_range> exp;
return matrix_exp<exp>(exp(m,rows)); return exp(m.ref(),rows.ref());
} }
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
...@@ -2307,6 +1559,7 @@ convergence: ...@@ -2307,6 +1559,7 @@ convergence:
template <typename EXP> template <typename EXP>
struct op : has_destructive_aliasing struct op : has_destructive_aliasing
{ {
const static long cost = EXP::cost;
const static long NR = EXP::NR; const static long NR = EXP::NR;
const static long NC = 1; const static long NC = 1;
typedef typename EXP::type type; typedef typename EXP::type type;
...@@ -2325,7 +1578,7 @@ convergence: ...@@ -2325,7 +1578,7 @@ convergence:
template < template <
typename EXP typename EXP
> >
const matrix_exp<matrix_scalar_binary_exp<matrix_exp<EXP>,long,op_colm> > colm ( const matrix_scalar_binary_exp<EXP,long,op_colm> colm (
const matrix_exp<EXP>& m, const matrix_exp<EXP>& m,
long col long col
) )
...@@ -2338,8 +1591,8 @@ convergence: ...@@ -2338,8 +1591,8 @@ convergence:
<< "\n\tcol: " << col << "\n\tcol: " << col
); );
typedef matrix_scalar_binary_exp<matrix_exp<EXP>,long,op_colm> exp; typedef matrix_scalar_binary_exp<EXP,long,op_colm> exp;
return matrix_exp<exp>(exp(m,col)); return exp(m.ref(),col);
} }
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
...@@ -2353,6 +1606,7 @@ convergence: ...@@ -2353,6 +1606,7 @@ convergence:
typedef typename EXP1::mem_manager_type mem_manager_type; typedef typename EXP1::mem_manager_type mem_manager_type;
const static long NR = EXP1::NR; const static long NR = EXP1::NR;
const static long NC = EXP2::NC*EXP2::NR; const static long NC = EXP2::NC*EXP2::NR;
const static long cost = EXP1::cost+EXP2::cost;
template <typename M1, typename M2> template <typename M1, typename M2>
static type apply ( const M1& m1, const M2& cols , long r, long c) static type apply ( const M1& m1, const M2& cols , long r, long c)
...@@ -2369,7 +1623,7 @@ convergence: ...@@ -2369,7 +1623,7 @@ convergence:
typename EXP1, typename EXP1,
typename EXP2 typename EXP2
> >
const matrix_exp<matrix_binary_exp<matrix_exp<EXP1>,matrix_exp<EXP2>,op_colm_range> > colm ( const matrix_binary_exp<EXP1,EXP2,op_colm_range> colm (
const matrix_exp<EXP1>& m, const matrix_exp<EXP1>& m,
const matrix_exp<EXP2>& cols const matrix_exp<EXP2>& cols
) )
...@@ -2388,8 +1642,8 @@ convergence: ...@@ -2388,8 +1642,8 @@ convergence:
<< "\n\tcols.nc(): " << cols.nc() << "\n\tcols.nc(): " << cols.nc()
); );
typedef matrix_binary_exp<matrix_exp<EXP1>,matrix_exp<EXP2>,op_colm_range> exp; typedef matrix_binary_exp<EXP1,EXP2,op_colm_range> exp;
return matrix_exp<exp>(exp(m,cols)); return exp(m.ref(),cols.ref());
} }
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
...@@ -2585,7 +1839,7 @@ convergence: ...@@ -2585,7 +1839,7 @@ convergence:
}; };
template <typename T, long NR, long NC, typename mm, typename l, typename EXPr, typename EXPc> template <typename T, long NR, long NC, typename mm, typename l, typename EXPr, typename EXPc>
assignable_sub_range_matrix<T,NR,NC,mm,l,matrix_exp<EXPr>,matrix_exp<EXPc> > set_subm ( assignable_sub_range_matrix<T,NR,NC,mm,l,EXPr,EXPc > set_subm (
matrix<T,NR,NC,mm,l>& m, matrix<T,NR,NC,mm,l>& m,
const matrix_exp<EXPr>& rows, const matrix_exp<EXPr>& rows,
const matrix_exp<EXPc>& cols const matrix_exp<EXPc>& cols
...@@ -2607,13 +1861,13 @@ convergence: ...@@ -2607,13 +1861,13 @@ convergence:
<< "\n\tcols.nc(): " << cols.nc() << "\n\tcols.nc(): " << cols.nc()
); );
return assignable_sub_range_matrix<T,NR,NC,mm,l,matrix_exp<EXPr>,matrix_exp<EXPc> >(m,rows,cols); return assignable_sub_range_matrix<T,NR,NC,mm,l,EXPr,EXPc >(m,rows.ref(),cols.ref());
} }
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
template <typename T, long NR, long NC, typename mm, typename l, typename EXPr> template <typename T, long NR, long NC, typename mm, typename l, typename EXPr>
assignable_sub_range_matrix<T,NR,NC,mm,l,matrix_exp<EXPr>,matrix_exp<matrix_range_exp> > set_rowm ( assignable_sub_range_matrix<T,NR,NC,mm,l,EXPr,matrix_range_exp > set_rowm (
matrix<T,NR,NC,mm,l>& m, matrix<T,NR,NC,mm,l>& m,
const matrix_exp<EXPr>& rows const matrix_exp<EXPr>& rows
) )
...@@ -2629,13 +1883,13 @@ convergence: ...@@ -2629,13 +1883,13 @@ convergence:
<< "\n\trows.nc(): " << rows.nc() << "\n\trows.nc(): " << rows.nc()
); );
return assignable_sub_range_matrix<T,NR,NC,mm,l,matrix_exp<EXPr>,matrix_exp<matrix_range_exp> >(m,rows,range(0,m.nc()-1)); return assignable_sub_range_matrix<T,NR,NC,mm,l,EXPr,matrix_range_exp >(m,rows.ref(),range(0,m.nc()-1));
} }
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
template <typename T, long NR, long NC, typename mm, typename l, typename EXPc> template <typename T, long NR, long NC, typename mm, typename l, typename EXPc>
assignable_sub_range_matrix<T,NR,NC,mm,l,matrix_exp<matrix_range_exp>,matrix_exp<EXPc> > set_colm ( assignable_sub_range_matrix<T,NR,NC,mm,l,matrix_range_exp,EXPc > set_colm (
matrix<T,NR,NC,mm,l>& m, matrix<T,NR,NC,mm,l>& m,
const matrix_exp<EXPc>& cols const matrix_exp<EXPc>& cols
) )
...@@ -2651,7 +1905,7 @@ convergence: ...@@ -2651,7 +1905,7 @@ convergence:
<< "\n\tcols.nc(): " << cols.nc() << "\n\tcols.nc(): " << cols.nc()
); );
return assignable_sub_range_matrix<T,NR,NC,mm,l,matrix_exp<matrix_range_exp>,matrix_exp<EXPc> >(m,range(0,m.nr()-1),cols); return assignable_sub_range_matrix<T,NR,NC,mm,l,matrix_range_exp,EXPc >(m,range(0,m.nr()-1),cols.ref());
} }
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
...@@ -2836,6 +2090,7 @@ convergence: ...@@ -2836,6 +2090,7 @@ convergence:
template <typename EXP> template <typename EXP>
struct op : has_destructive_aliasing struct op : has_destructive_aliasing
{ {
const static long cost = EXP::cost;
const static long NR = EXP::NC; const static long NR = EXP::NC;
const static long NC = EXP::NR; const static long NC = EXP::NR;
typedef typename EXP::type type; typedef typename EXP::type type;
...@@ -2854,12 +2109,12 @@ convergence: ...@@ -2854,12 +2109,12 @@ convergence:
template < template <
typename EXP typename EXP
> >
const matrix_exp<matrix_unary_exp<matrix_exp<EXP>,op_trans> > trans ( const matrix_unary_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; typedef matrix_unary_exp<EXP,op_trans> exp;
return matrix_exp<exp>(exp(m)); return exp(m.ref());
} }
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
...@@ -2870,6 +2125,7 @@ convergence: ...@@ -2870,6 +2125,7 @@ convergence:
template <typename EXP> template <typename EXP>
struct op : has_destructive_aliasing struct op : has_destructive_aliasing
{ {
const static long cost = EXP::cost+2;
const static long NR = (EXP::NR==0) ? 0 : (EXP::NR - 1); const static long NR = (EXP::NR==0) ? 0 : (EXP::NR - 1);
const static long NC = (EXP::NC==0) ? 0 : (EXP::NC - 1); const static long NC = (EXP::NC==0) ? 0 : (EXP::NC - 1);
typedef typename EXP::type type; typedef typename EXP::type type;
...@@ -2905,6 +2161,7 @@ convergence: ...@@ -2905,6 +2161,7 @@ convergence:
template <typename EXP> template <typename EXP>
struct op : has_destructive_aliasing struct op : has_destructive_aliasing
{ {
const static long cost = EXP::cost+2;
const static long NR = (EXP::NR==0) ? 0 : (EXP::NR - 1); const static long NR = (EXP::NR==0) ? 0 : (EXP::NR - 1);
const static long NC = (EXP::NC==0) ? 0 : (EXP::NC - 1); const static long NC = (EXP::NC==0) ? 0 : (EXP::NC - 1);
typedef typename EXP::type type; typedef typename EXP::type type;
...@@ -2940,7 +2197,7 @@ convergence: ...@@ -2940,7 +2197,7 @@ convergence:
long C, long C,
typename EXP typename EXP
> >
const matrix_exp<matrix_unary_exp<matrix_exp<EXP>,op_removerc<R,C> > > removerc ( const matrix_unary_exp<EXP,op_removerc<R,C> > removerc (
const matrix_exp<EXP>& m const matrix_exp<EXP>& m
) )
{ {
...@@ -2956,14 +2213,14 @@ convergence: ...@@ -2956,14 +2213,14 @@ convergence:
<< "\n\tR: " << R << "\n\tR: " << R
<< "\n\tC: " << C << "\n\tC: " << C
); );
typedef matrix_unary_exp<matrix_exp<EXP>,op_removerc<R,C> > exp; typedef matrix_unary_exp<EXP,op_removerc<R,C> > exp;
return matrix_exp<exp>(exp(m)); return exp(m.ref());
} }
template < template <
typename EXP typename EXP
> >
const matrix_exp<matrix_scalar_trinary_exp<matrix_exp<EXP>,long,op_removerc2> > removerc ( const matrix_scalar_ternary_exp<EXP,long,op_removerc2> removerc (
const matrix_exp<EXP>& m, const matrix_exp<EXP>& m,
long R, long R,
long C long C
...@@ -2977,8 +2234,8 @@ convergence: ...@@ -2977,8 +2234,8 @@ convergence:
<< "\n\tR: " << R << "\n\tR: " << R
<< "\n\tC: " << C << "\n\tC: " << C
); );
typedef matrix_scalar_trinary_exp<matrix_exp<EXP>,long,op_removerc2 > exp; typedef matrix_scalar_ternary_exp<EXP,long,op_removerc2 > exp;
return matrix_exp<exp>(exp(m,R,C)); return exp(m.ref(),R,C);
} }
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
...@@ -2989,6 +2246,7 @@ convergence: ...@@ -2989,6 +2246,7 @@ convergence:
template <typename EXP> template <typename EXP>
struct op : has_destructive_aliasing struct op : has_destructive_aliasing
{ {
const static long cost = EXP::cost+1;
const static long NR = EXP::NR; const static long NR = EXP::NR;
const static long NC = (EXP::NC==0) ? 0 : (EXP::NC - 1); const static long NC = (EXP::NC==0) ? 0 : (EXP::NC - 1);
typedef typename EXP::type type; typedef typename EXP::type type;
...@@ -3018,6 +2276,7 @@ convergence: ...@@ -3018,6 +2276,7 @@ convergence:
template <typename EXP> template <typename EXP>
struct op : has_destructive_aliasing struct op : has_destructive_aliasing
{ {
const static long cost = EXP::cost+1;
const static long NR = EXP::NR; const static long NR = EXP::NR;
const static long NC = (EXP::NC==0) ? 0 : (EXP::NC - 1); const static long NC = (EXP::NC==0) ? 0 : (EXP::NC - 1);
typedef typename EXP::type type; typedef typename EXP::type type;
...@@ -3046,7 +2305,7 @@ convergence: ...@@ -3046,7 +2305,7 @@ convergence:
long C, long C,
typename EXP typename EXP
> >
const matrix_exp<matrix_unary_exp<matrix_exp<EXP>,op_remove_col<C> > > remove_col ( const matrix_unary_exp<EXP,op_remove_col<C> > remove_col (
const matrix_exp<EXP>& m const matrix_exp<EXP>& m
) )
{ {
...@@ -3060,14 +2319,14 @@ convergence: ...@@ -3060,14 +2319,14 @@ convergence:
<< "\n\tm.nc(): " << m.nc() << "\n\tm.nc(): " << m.nc()
<< "\n\tC: " << C << "\n\tC: " << C
); );
typedef matrix_unary_exp<matrix_exp<EXP>,op_remove_col<C> > exp; typedef matrix_unary_exp<EXP,op_remove_col<C> > exp;
return matrix_exp<exp>(exp(m)); return exp(m.ref());
} }
template < template <
typename EXP typename EXP
> >
const matrix_exp<matrix_scalar_binary_exp<matrix_exp<EXP>,long,op_remove_col2 > > remove_col ( const matrix_scalar_binary_exp<EXP,long,op_remove_col2> remove_col (
const matrix_exp<EXP>& m, const matrix_exp<EXP>& m,
long C long C
) )
...@@ -3079,8 +2338,8 @@ convergence: ...@@ -3079,8 +2338,8 @@ convergence:
<< "\n\tm.nc(): " << m.nc() << "\n\tm.nc(): " << m.nc()
<< "\n\tC: " << C << "\n\tC: " << C
); );
typedef matrix_scalar_binary_exp<matrix_exp<EXP>,long,op_remove_col2 > exp; typedef matrix_scalar_binary_exp<EXP,long,op_remove_col2> exp;
return matrix_exp<exp>(exp(m,C)); return exp(m.ref(),C);
} }
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
...@@ -3091,6 +2350,7 @@ convergence: ...@@ -3091,6 +2350,7 @@ convergence:
template <typename EXP> template <typename EXP>
struct op : has_destructive_aliasing struct op : has_destructive_aliasing
{ {
const static long cost = EXP::cost+1;
const static long NR = (EXP::NR==0) ? 0 : (EXP::NR - 1); const static long NR = (EXP::NR==0) ? 0 : (EXP::NR - 1);
const static long NC = EXP::NC; const static long NC = EXP::NC;
typedef typename EXP::type type; typedef typename EXP::type type;
...@@ -3120,6 +2380,7 @@ convergence: ...@@ -3120,6 +2380,7 @@ convergence:
template <typename EXP> template <typename EXP>
struct op : has_destructive_aliasing struct op : has_destructive_aliasing
{ {
const static long cost = EXP::cost+1;
const static long NR = (EXP::NR==0) ? 0 : (EXP::NR - 1); const static long NR = (EXP::NR==0) ? 0 : (EXP::NR - 1);
const static long NC = EXP::NC; const static long NC = EXP::NC;
typedef typename EXP::type type; typedef typename EXP::type type;
...@@ -3148,7 +2409,7 @@ convergence: ...@@ -3148,7 +2409,7 @@ convergence:
long R, long R,
typename EXP typename EXP
> >
const matrix_exp<matrix_unary_exp<matrix_exp<EXP>,op_remove_row<R> > > remove_row ( const matrix_unary_exp<EXP,op_remove_row<R> > remove_row (
const matrix_exp<EXP>& m const matrix_exp<EXP>& m
) )
{ {
...@@ -3162,14 +2423,14 @@ convergence: ...@@ -3162,14 +2423,14 @@ convergence:
<< "\n\tm.nc(): " << m.nc() << "\n\tm.nc(): " << m.nc()
<< "\n\tR: " << R << "\n\tR: " << R
); );
typedef matrix_unary_exp<matrix_exp<EXP>,op_remove_row<R> > exp; typedef matrix_unary_exp<EXP,op_remove_row<R> > exp;
return matrix_exp<exp>(exp(m)); return exp(m.ref());
} }
template < template <
typename EXP typename EXP
> >
const matrix_exp<matrix_scalar_binary_exp<matrix_exp<EXP>,long,op_remove_row2> > remove_row ( const matrix_scalar_binary_exp<EXP,long,op_remove_row2> remove_row (
const matrix_exp<EXP>& m, const matrix_exp<EXP>& m,
long R long R
) )
...@@ -3181,8 +2442,8 @@ convergence: ...@@ -3181,8 +2442,8 @@ convergence:
<< "\n\tm.nc(): " << m.nc() << "\n\tm.nc(): " << m.nc()
<< "\n\tR: " << R << "\n\tR: " << R
); );
typedef matrix_scalar_binary_exp<matrix_exp<EXP>,long,op_remove_row2 > exp; typedef matrix_scalar_binary_exp<EXP,long,op_remove_row2 > exp;
return matrix_exp<exp>(exp(m,R)); return exp(m.ref(),R);
} }
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
...@@ -3192,6 +2453,7 @@ convergence: ...@@ -3192,6 +2453,7 @@ convergence:
template <typename EXP> template <typename EXP>
struct op : has_destructive_aliasing struct op : has_destructive_aliasing
{ {
const static long cost = EXP::cost+1;
const static long N = EXP::NC*EXP::NR; const static long N = EXP::NC*EXP::NR;
const static long NR = N; const static long NR = N;
const static long NC = N; const static long NC = N;
...@@ -3216,7 +2478,7 @@ convergence: ...@@ -3216,7 +2478,7 @@ convergence:
template < template <
typename EXP typename EXP
> >
const matrix_exp<matrix_unary_exp<matrix_exp<EXP>,op_diagm> > diagm ( const matrix_unary_exp<EXP,op_diagm> diagm (
const matrix_exp<EXP>& m const matrix_exp<EXP>& m
) )
{ {
...@@ -3228,8 +2490,8 @@ convergence: ...@@ -3228,8 +2490,8 @@ convergence:
<< "\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_diagm> exp; typedef matrix_unary_exp<EXP,op_diagm> exp;
return matrix_exp<exp>(exp(m)); return exp(m.ref());
} }
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
...@@ -3239,6 +2501,7 @@ convergence: ...@@ -3239,6 +2501,7 @@ convergence:
template <typename EXP> template <typename EXP>
struct op : has_destructive_aliasing struct op : has_destructive_aliasing
{ {
const static long cost = EXP::cost;
const static long NR = (EXP::NC&&EXP::NR)? (tmin<EXP::NR,EXP::NC>::value) : (0); const static long NR = (EXP::NC&&EXP::NR)? (tmin<EXP::NR,EXP::NC>::value) : (0);
const static long NC = 1; const static long NC = 1;
typedef typename EXP::type type; typedef typename EXP::type type;
...@@ -3257,12 +2520,12 @@ convergence: ...@@ -3257,12 +2520,12 @@ convergence:
template < template <
typename EXP typename EXP
> >
const matrix_exp<matrix_unary_exp<matrix_exp<EXP>,op_diag> > diag ( const matrix_unary_exp<EXP,op_diag> diag (
const matrix_exp<EXP>& m const matrix_exp<EXP>& m
) )
{ {
typedef matrix_unary_exp<matrix_exp<EXP>,op_diag> exp; typedef matrix_unary_exp<EXP,op_diag> exp;
return matrix_exp<exp>(exp(m)); return exp(m.ref());
} }
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
...@@ -3273,6 +2536,7 @@ convergence: ...@@ -3273,6 +2536,7 @@ convergence:
template <typename EXP> template <typename EXP>
struct op : has_nondestructive_aliasing, preserves_dimensions<EXP> struct op : has_nondestructive_aliasing, preserves_dimensions<EXP>
{ {
const static long cost = EXP::cost;
typedef target_type type; typedef target_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)
...@@ -3284,12 +2548,12 @@ convergence: ...@@ -3284,12 +2548,12 @@ convergence:
typename target_type, typename target_type,
typename EXP typename EXP
> >
const matrix_exp<matrix_unary_exp<matrix_exp<EXP>,op_cast<target_type> > > matrix_cast ( const matrix_unary_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<target_type> > exp; typedef matrix_unary_exp<EXP,op_cast<target_type> > exp;
return matrix_exp<exp>(exp(m)); return exp(m.ref());
} }
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
...@@ -4120,6 +3384,7 @@ convergence: ...@@ -4120,6 +3384,7 @@ convergence:
> >
struct op_uniform_matrix_3 : has_nondestructive_aliasing struct op_uniform_matrix_3 : has_nondestructive_aliasing
{ {
const static long cost = 1;
const static long NR = 0; const static long NR = 0;
const static long NC = 0; const static long NC = 0;
typedef typename memory_manager<char>::kernel_1a mem_manager_type; typedef typename memory_manager<char>::kernel_1a mem_manager_type;
...@@ -4131,7 +3396,7 @@ convergence: ...@@ -4131,7 +3396,7 @@ convergence:
template < template <
typename T typename T
> >
const matrix_exp<dynamic_matrix_scalar_unary_exp<T,op_uniform_matrix_3<T> > > uniform_matrix ( const dynamic_matrix_scalar_unary_exp<T,op_uniform_matrix_3<T> > uniform_matrix (
long nr, long nr,
long nc, long nc,
const T& val const T& val
...@@ -4144,7 +3409,7 @@ convergence: ...@@ -4144,7 +3409,7 @@ convergence:
<< "\n\tnc: " << nc << "\n\tnc: " << nc
); );
typedef dynamic_matrix_scalar_unary_exp<T,op_uniform_matrix_3<T> > exp; typedef dynamic_matrix_scalar_unary_exp<T,op_uniform_matrix_3<T> > exp;
return matrix_exp<exp>(exp(nr,nc,val)); return exp(nr,nc,val);
} }
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
...@@ -4156,6 +3421,7 @@ convergence: ...@@ -4156,6 +3421,7 @@ convergence:
> >
struct op_uniform_matrix_2 : has_nondestructive_aliasing struct op_uniform_matrix_2 : has_nondestructive_aliasing
{ {
const static long cost = 1;
const static long NR = NR_; const static long NR = NR_;
const static long NC = NC_; const static long NC = NC_;
typedef typename memory_manager<char>::kernel_1a mem_manager_type; typedef typename memory_manager<char>::kernel_1a mem_manager_type;
...@@ -4169,14 +3435,14 @@ convergence: ...@@ -4169,14 +3435,14 @@ convergence:
long NR, long NR,
long NC long NC
> >
const matrix_exp<matrix_scalar_unary_exp<T,op_uniform_matrix_2<T,NR,NC> > > uniform_matrix ( const matrix_scalar_unary_exp<T,op_uniform_matrix_2<T,NR,NC> > uniform_matrix (
const T& val const T& val
) )
{ {
COMPILE_TIME_ASSERT(NR > 0 && NC > 0); COMPILE_TIME_ASSERT(NR > 0 && NC > 0);
typedef matrix_scalar_unary_exp<T,op_uniform_matrix_2<T,NR,NC> > exp; typedef matrix_scalar_unary_exp<T,op_uniform_matrix_2<T,NR,NC> > exp;
return matrix_exp<exp>(exp(val)); return exp(val);
} }
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
...@@ -4189,6 +3455,7 @@ convergence: ...@@ -4189,6 +3455,7 @@ convergence:
> >
struct op_uniform_matrix : has_nondestructive_aliasing struct op_uniform_matrix : has_nondestructive_aliasing
{ {
const static long cost = 1;
const static long NR = NR_; const static long NR = NR_;
const static long NC = NC_; const static long NC = NC_;
typedef typename memory_manager<char>::kernel_1a mem_manager_type; typedef typename memory_manager<char>::kernel_1a mem_manager_type;
...@@ -4203,12 +3470,12 @@ convergence: ...@@ -4203,12 +3470,12 @@ convergence:
long NC, long NC,
T val T val
> >
const matrix_exp<matrix_zeroary_exp<op_uniform_matrix<T,NR,NC,val> > > uniform_matrix ( const matrix_zeroary_exp<op_uniform_matrix<T,NR,NC,val> > uniform_matrix (
) )
{ {
COMPILE_TIME_ASSERT(NR > 0 && NC > 0); COMPILE_TIME_ASSERT(NR > 0 && NC > 0);
typedef matrix_zeroary_exp<op_uniform_matrix<T,NR,NC,val> > exp; typedef matrix_zeroary_exp<op_uniform_matrix<T,NR,NC,val> > exp;
return matrix_exp<exp>(exp()); return exp();
} }
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
...@@ -4218,6 +3485,7 @@ convergence: ...@@ -4218,6 +3485,7 @@ convergence:
> >
struct op_identity_matrix_2 : has_nondestructive_aliasing struct op_identity_matrix_2 : has_nondestructive_aliasing
{ {
const static long cost = 1;
const static long NR = 0; const static long NR = 0;
const static long NC = 0; const static long NC = 0;
typedef typename memory_manager<char>::kernel_1a mem_manager_type; typedef typename memory_manager<char>::kernel_1a mem_manager_type;
...@@ -4229,7 +3497,7 @@ convergence: ...@@ -4229,7 +3497,7 @@ convergence:
template < template <
typename T typename T
> >
const matrix_exp<dynamic_matrix_scalar_unary_exp<T,op_identity_matrix_2<T> > > identity_matrix ( const dynamic_matrix_scalar_unary_exp<T,op_identity_matrix_2<T> > identity_matrix (
const long& size const long& size
) )
{ {
...@@ -4241,7 +3509,7 @@ convergence: ...@@ -4241,7 +3509,7 @@ convergence:
typedef dynamic_matrix_scalar_unary_exp<T,op_identity_matrix_2<T> > exp; typedef dynamic_matrix_scalar_unary_exp<T,op_identity_matrix_2<T> > exp;
// the scalar value of the dynamic_matrix_scalar_unary_exp just isn't // the scalar value of the dynamic_matrix_scalar_unary_exp just isn't
// used by this operator // used by this operator
return matrix_exp<exp>(exp(size,size,0)); return exp(size,size,0);
} }
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
...@@ -4252,6 +3520,7 @@ convergence: ...@@ -4252,6 +3520,7 @@ convergence:
> >
struct op_identity_matrix : has_nondestructive_aliasing struct op_identity_matrix : has_nondestructive_aliasing
{ {
const static long cost = 1;
const static long NR = N; const static long NR = N;
const static long NC = N; const static long NC = N;
typedef typename memory_manager<char>::kernel_1a mem_manager_type; typedef typename memory_manager<char>::kernel_1a mem_manager_type;
...@@ -4269,13 +3538,13 @@ convergence: ...@@ -4269,13 +3538,13 @@ convergence:
typename T, typename T,
long N long N
> >
const matrix_exp<matrix_zeroary_exp<op_identity_matrix<T,N> > > identity_matrix ( const matrix_zeroary_exp<op_identity_matrix<T,N> > identity_matrix (
) )
{ {
COMPILE_TIME_ASSERT(N > 0); COMPILE_TIME_ASSERT(N > 0);
typedef matrix_zeroary_exp<op_identity_matrix<T,N> > exp; typedef matrix_zeroary_exp<op_identity_matrix<T,N> > exp;
return matrix_exp<exp>(exp()); return exp();
} }
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
...@@ -4286,6 +3555,7 @@ convergence: ...@@ -4286,6 +3555,7 @@ convergence:
template <typename EXP> template <typename EXP>
struct op : has_destructive_aliasing, preserves_dimensions<EXP> struct op : has_destructive_aliasing, preserves_dimensions<EXP>
{ {
const static long cost = EXP::cost + 1;
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)
...@@ -4298,7 +3568,7 @@ convergence: ...@@ -4298,7 +3568,7 @@ convergence:
long C, long C,
typename EXP typename EXP
> >
const matrix_exp<matrix_unary_exp<matrix_exp<EXP>,op_rotate<R,C> > > rotate ( const matrix_unary_exp<EXP,op_rotate<R,C> > rotate (
const matrix_exp<EXP>& m const matrix_exp<EXP>& m
) )
{ {
...@@ -4314,8 +3584,8 @@ convergence: ...@@ -4314,8 +3584,8 @@ convergence:
<< "\n\tR: " << R << "\n\tR: " << R
<< "\n\tC: " << C << "\n\tC: " << C
); );
typedef matrix_unary_exp<matrix_exp<EXP>,op_rotate<R,C> > exp; typedef matrix_unary_exp<EXP,op_rotate<R,C> > exp;
return matrix_exp<exp>(exp(m)); return exp(m.ref());
} }
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
...@@ -4326,6 +3596,7 @@ convergence: ...@@ -4326,6 +3596,7 @@ convergence:
struct op : public has_nondestructive_aliasing, public preserves_dimensions<EXP1,EXP2> struct op : public has_nondestructive_aliasing, public preserves_dimensions<EXP1,EXP2>
{ {
typedef typename EXP1::type type; typedef typename EXP1::type type;
const static long cost = EXP1::cost + EXP2::cost + 1;
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)
...@@ -4337,7 +3608,7 @@ convergence: ...@@ -4337,7 +3608,7 @@ convergence:
typename EXP1, typename EXP1,
typename EXP2 typename EXP2
> >
inline const matrix_exp<matrix_binary_exp<EXP1,EXP2,op_pointwise_multiply> > pointwise_multiply ( inline const 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
) )
...@@ -4355,15 +3626,31 @@ convergence: ...@@ -4355,15 +3626,31 @@ convergence:
<< "\n\tb.nc(): " << b.nc() << "\n\tb.nc(): " << b.nc()
); );
typedef matrix_binary_exp<EXP1,EXP2,op_pointwise_multiply> exp; typedef matrix_binary_exp<EXP1,EXP2,op_pointwise_multiply> exp;
return matrix_exp<exp>(exp(a.ref(),b.ref())); return exp(a.ref(),b.ref());
} }
// ----------------------------------------------------------------------------------------
struct op_pointwise_multiply3
{
template <typename EXP1, typename EXP2, typename EXP3>
struct op : public has_nondestructive_aliasing, public preserves_dimensions<EXP1,EXP2,EXP3>
{
typedef typename EXP1::type type;
const static long cost = EXP1::cost + EXP2::cost + EXP3::cost + 2;
template <typename M1, typename M2, typename M3>
static type apply ( const M1& m1, const M2& m2, const M3& m3 , long r, long c)
{ return m1(r,c)*m2(r,c)*m3(r,c); }
};
};
template < template <
typename EXP1, typename EXP1,
typename EXP2, typename EXP2,
typename EXP3 typename EXP3
> >
inline const matrix_exp<matrix_binary_exp<matrix_binary_exp<EXP1,EXP2,op_pointwise_multiply>,EXP3,op_pointwise_multiply> > inline const matrix_ternary_exp<EXP1,EXP2,EXP3,op_pointwise_multiply3>
pointwise_multiply ( pointwise_multiply (
const matrix_exp<EXP1>& a, const matrix_exp<EXP1>& a,
const matrix_exp<EXP2>& b, const matrix_exp<EXP2>& b,
...@@ -4371,6 +3658,7 @@ convergence: ...@@ -4371,6 +3658,7 @@ convergence:
) )
{ {
COMPILE_TIME_ASSERT((is_same_type<typename EXP1::type,typename EXP2::type>::value == true)); COMPILE_TIME_ASSERT((is_same_type<typename EXP1::type,typename EXP2::type>::value == true));
COMPILE_TIME_ASSERT((is_same_type<typename EXP2::type,typename EXP3::type>::value == true));
COMPILE_TIME_ASSERT(EXP1::NR == EXP2::NR || EXP1::NR == 0 || EXP2::NR == 0); COMPILE_TIME_ASSERT(EXP1::NR == EXP2::NR || EXP1::NR == 0 || EXP2::NR == 0);
COMPILE_TIME_ASSERT(EXP1::NC == EXP2::NC || EXP1::NR == 0 || EXP2::NC == 0); COMPILE_TIME_ASSERT(EXP1::NC == EXP2::NC || EXP1::NR == 0 || EXP2::NC == 0);
COMPILE_TIME_ASSERT(EXP2::NR == EXP3::NR || EXP2::NR == 0 || EXP3::NR == 0); COMPILE_TIME_ASSERT(EXP2::NR == EXP3::NR || EXP2::NR == 0 || EXP3::NR == 0);
...@@ -4388,23 +3676,34 @@ convergence: ...@@ -4388,23 +3676,34 @@ convergence:
<< "\n\tc.nr(): " << c.nr() << "\n\tc.nr(): " << c.nr()
<< "\n\tc.nc(): " << c.nc() << "\n\tc.nc(): " << c.nc()
); );
typedef matrix_binary_exp<EXP1,EXP2,op_pointwise_multiply> exp; typedef matrix_ternary_exp<EXP1,EXP2,EXP3,op_pointwise_multiply3> exp;
typedef matrix_binary_exp<exp , EXP3, op_pointwise_multiply> exp2;
return matrix_exp<exp2>(exp2(exp(a.ref(),b.ref()),c.ref())); return exp(a.ref(),b.ref(),c.ref());
} }
// ----------------------------------------------------------------------------------------
struct op_pointwise_multiply4
{
template <typename EXP1, typename EXP2, typename EXP3, typename EXP4>
struct op : public has_nondestructive_aliasing, public preserves_dimensions<EXP1,EXP2,EXP3,EXP4>
{
typedef typename EXP1::type type;
const static long cost = EXP1::cost + EXP2::cost + EXP3::cost + EXP4::cost + 3;
template <typename M1, typename M2, typename M3, typename M4>
static type apply ( const M1& m1, const M2& m2, const M3& m3, const M4& m4 , long r, long c)
{ return m1(r,c)*m2(r,c)*m3(r,c)*m4(r,c); }
};
};
template < template <
typename EXP1, typename EXP1,
typename EXP2, typename EXP2,
typename EXP3, typename EXP3,
typename EXP4 typename EXP4
> >
inline const matrix_exp< inline const matrix_fourary_exp<EXP1,EXP2,EXP3,EXP4,op_pointwise_multiply4> pointwise_multiply (
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<EXP1>& a,
const matrix_exp<EXP2>& b, const matrix_exp<EXP2>& b,
const matrix_exp<EXP3>& c, const matrix_exp<EXP3>& c,
...@@ -4412,6 +3711,8 @@ convergence: ...@@ -4412,6 +3711,8 @@ convergence:
) )
{ {
COMPILE_TIME_ASSERT((is_same_type<typename EXP1::type,typename EXP2::type>::value == true)); COMPILE_TIME_ASSERT((is_same_type<typename EXP1::type,typename EXP2::type>::value == true));
COMPILE_TIME_ASSERT((is_same_type<typename EXP2::type,typename EXP3::type>::value == true));
COMPILE_TIME_ASSERT((is_same_type<typename EXP3::type,typename EXP4::type>::value == true));
COMPILE_TIME_ASSERT(EXP1::NR == EXP2::NR || EXP1::NR == 0 || EXP2::NR == 0); COMPILE_TIME_ASSERT(EXP1::NR == EXP2::NR || EXP1::NR == 0 || EXP2::NR == 0);
COMPILE_TIME_ASSERT(EXP1::NC == EXP2::NC || EXP1::NC == 0 || EXP2::NC == 0 ); COMPILE_TIME_ASSERT(EXP1::NC == EXP2::NC || EXP1::NC == 0 || EXP2::NC == 0 );
COMPILE_TIME_ASSERT(EXP2::NR == EXP3::NR || EXP2::NR == 0 || EXP3::NR == 0); COMPILE_TIME_ASSERT(EXP2::NR == EXP3::NR || EXP2::NR == 0 || EXP3::NR == 0);
...@@ -4435,11 +3736,9 @@ convergence: ...@@ -4435,11 +3736,9 @@ convergence:
<< "\n\td.nr(): " << d.nr() << "\n\td.nr(): " << d.nr()
<< "\n\td.nc(): " << d.nc() << "\n\td.nc(): " << d.nc()
); );
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> exp3; typedef matrix_fourary_exp<EXP1,EXP2,EXP3,EXP4,op_pointwise_multiply4> exp;
return matrix_exp<exp3>(exp3(exp1(a.ref(),b.ref()),exp2(c.ref(),d.ref()))); return exp(a.ref(),b.ref(),c.ref(),d.ref());
} }
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
...@@ -4624,6 +3923,7 @@ convergence: ...@@ -4624,6 +3923,7 @@ convergence:
struct op : has_nondestructive_aliasing, preserves_dimensions<EXP> struct op : has_nondestructive_aliasing, preserves_dimensions<EXP>
{ {
typedef typename EXP::type type; typedef typename EXP::type type;
const static long cost = EXP::cost + 1;
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)
...@@ -4644,12 +3944,12 @@ convergence: ...@@ -4644,12 +3944,12 @@ convergence:
long u, long u,
typename EXP typename EXP
> >
const matrix_exp<matrix_unary_exp<matrix_exp<EXP>,op_clamp<l,u> > > clamp ( const matrix_unary_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; typedef matrix_unary_exp<EXP,op_clamp<l,u> > exp;
return matrix_exp<exp>(exp(m)); return exp(m.ref());
} }
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
...@@ -4688,6 +3988,7 @@ convergence: ...@@ -4688,6 +3988,7 @@ convergence:
template <typename EXP1, typename EXP2> template <typename EXP1, typename EXP2>
struct op : has_nondestructive_aliasing struct op : has_nondestructive_aliasing
{ {
const static long cost = EXP1::cost + EXP2::cost + 1;
typedef typename EXP1::type type; typedef typename EXP1::type type;
typedef typename EXP1::mem_manager_type mem_manager_type; typedef typename EXP1::mem_manager_type mem_manager_type;
const static long NR = EXP1::NR; const static long NR = EXP1::NR;
...@@ -4708,7 +4009,7 @@ convergence: ...@@ -4708,7 +4009,7 @@ convergence:
typename EXP1, typename EXP1,
typename EXP2 typename EXP2
> >
const matrix_exp<matrix_binary_exp<matrix_exp<EXP1>,matrix_exp<EXP2>,op_scale_columns> > scale_columns ( const matrix_binary_exp<EXP1,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
) )
...@@ -4725,8 +4026,8 @@ convergence: ...@@ -4725,8 +4026,8 @@ convergence:
<< "\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> exp; typedef matrix_binary_exp<EXP1,EXP2,op_scale_columns> exp;
return matrix_exp<exp>(exp(m,v)); return exp(m.ref(),v.ref());
} }
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
...@@ -4842,6 +4143,7 @@ convergence: ...@@ -4842,6 +4143,7 @@ convergence:
template <typename EXP1, typename EXP2> template <typename EXP1, typename EXP2>
struct op : public has_destructive_aliasing struct op : public has_destructive_aliasing
{ {
const static long cost = EXP1::cost + EXP2::cost + 1;
const static long NR = EXP1::NR*EXP2::NR; const static long NR = EXP1::NR*EXP2::NR;
const static long NC = EXP1::NC*EXP2::NC; const static long NC = EXP1::NC*EXP2::NC;
typedef typename EXP1::type type; typedef typename EXP1::type type;
......
...@@ -300,7 +300,13 @@ namespace ...@@ -300,7 +300,13 @@ namespace
DLIB_CASSERT((round(m2*m1) == identity_matrix<double,4>()),""); DLIB_CASSERT((round(m2*m1) == identity_matrix<double,4>()),"");
DLIB_CASSERT((round(tmp(m2*m1)) == identity_matrix<double,4>()),""); DLIB_CASSERT((round(tmp(m2*m1)) == identity_matrix<double,4>()),"");
DLIB_CASSERT(round(m2*10000) == round(inv(m1)*10000),""); DLIB_CASSERT(round(m2*10000) == round(inv(m1)*10000),
round(m2*10000) - round(inv(m1)*10000)
<< "\n\n" << round(m2*10000)
<< "\n\n" << round(inv(m1)*10000)
<< "\n\n" << m2
<< "\n\n" << inv(m1)
);
DLIB_CASSERT(m1 == abs(-1*m1),""); DLIB_CASSERT(m1 == abs(-1*m1),"");
DLIB_CASSERT(abs(m2) == abs(-1*m2),""); DLIB_CASSERT(abs(m2) == abs(-1*m2),"");
......
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