Commit d55f589e authored by Davis King's avatar Davis King

Changed the matrix so that it isn't forced to use the one matrix_data object. Now

it has a template argument that lets you supply any kind of matrix layout object
you want.

--HG--
extra : convert_revision : svn%3Afdd8eb12-d10e-0410-9acb-85c331704f74/trunk%402704
parent dc85ffd1
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
#ifndef DLIB_MATRIx_ #ifndef DLIB_MATRIx_
#define DLIB_MATRIx_ #define DLIB_MATRIx_
#include "matrix_fwd.h"
#include "matrix_abstract.h" #include "matrix_abstract.h"
#include "../algs.h" #include "../algs.h"
#include "../serialize.h" #include "../serialize.h"
...@@ -11,6 +12,7 @@ ...@@ -11,6 +12,7 @@
#include <algorithm> #include <algorithm>
#include "../memory_manager.h" #include "../memory_manager.h"
#include "../is_kind.h" #include "../is_kind.h"
#include "matrix_data_layout.h"
#ifdef _MSC_VER #ifdef _MSC_VER
// Disable the following warnings for Visual Studio // Disable the following warnings for Visual Studio
...@@ -26,16 +28,6 @@ ...@@ -26,16 +28,6 @@
namespace dlib namespace dlib
{ {
// ----------------------------------------------------------------------------------------
template <
typename T,
long num_rows = 0,
long num_cols = 0,
typename mem_manager = memory_manager<char>::kernel_1a
>
class matrix;
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
...@@ -43,7 +35,8 @@ namespace dlib ...@@ -43,7 +35,8 @@ namespace dlib
typename T, typename T,
long num_rows, long num_rows,
long num_cols, long num_cols,
typename mem_manager typename mem_manager,
typename layout
> >
class matrix_ref class matrix_ref
{ {
...@@ -51,11 +44,12 @@ namespace dlib ...@@ -51,11 +44,12 @@ namespace dlib
typedef T type; typedef T type;
typedef matrix_ref ref_type; typedef matrix_ref ref_type;
typedef mem_manager mem_manager_type; typedef mem_manager mem_manager_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;
matrix_ref ( matrix_ref (
const matrix<T,num_rows,num_cols,mem_manager>& m_ const matrix<T,num_rows,num_cols,mem_manager,layout>& m_
) : m(m_) {} ) : m(m_) {}
matrix_ref ( matrix_ref (
...@@ -76,18 +70,18 @@ namespace dlib ...@@ -76,18 +70,18 @@ namespace dlib
long size ( long size (
) const { return m.size(); } ) const { return m.size(); }
template <typename U, long iNR, long iNC, typename mm > template <typename U, long iNR, long iNC, typename mm, typename l >
bool aliases ( bool aliases (
const matrix<U,iNR,iNC,mm>& item const matrix<U,iNR,iNC,mm,l>& item
) const { return false; } ) const { return false; }
template <typename U, long iNR, long iNC, typename mm> template <typename U, long iNR, long iNC, typename mm, typename l>
bool destructively_aliases ( bool destructively_aliases (
const matrix<U,iNR,iNC,mm>& item const matrix<U,iNR,iNC,mm,l>& item
) const { return false; } ) const { return false; }
bool aliases ( bool aliases (
const matrix<T,num_rows,num_cols,mem_manager>& item const matrix<T,num_rows,num_cols,mem_manager,layout>& item
) const { return (&m == &item); } ) const { return (&m == &item); }
const matrix_ref ref( const matrix_ref ref(
...@@ -97,412 +91,7 @@ namespace dlib ...@@ -97,412 +91,7 @@ namespace dlib
// no assignment operator // no assignment operator
matrix_ref& operator=(const matrix_ref&); matrix_ref& operator=(const matrix_ref&);
const matrix<T,num_rows,num_cols,mem_manager>& m; // This is the item contained by this expression. const matrix<T,num_rows,num_cols,mem_manager,layout>& m; // This is the item contained by this expression.
};
// ----------------------------------------------------------------------------------------
// this is a hack to avoid a compile time error in visual studio 8. I would just
// use sizeof(T) and be done with it but that won't compile. The idea here
// is to avoid using the stack allocation of the matrix_data object if it
// is going to contain another matrix and also avoid asking for the sizeof()
// the contained matrix.
template <typename T>
struct get_sizeof_helper
{
const static std::size_t val = sizeof(T);
};
template <typename T, long NR, long NC, typename mm>
struct get_sizeof_helper<matrix<T,NR,NC,mm> >
{
const static std::size_t val = 1000000;
};
template <
typename T,
long num_rows,
long num_cols,
typename mem_manager,
int val = static_switch <
// when the sizes are all non zero and small
(num_rows*num_cols*get_sizeof_helper<T>::val <= 64) && (num_rows != 0 && num_cols != 0),
// when the sizes are all non zero and big
(num_rows*num_cols*get_sizeof_helper<T>::val >= 65) && (num_rows != 0 && num_cols != 0),
num_rows == 0 && num_cols != 0,
num_rows != 0 && num_cols == 0,
num_rows == 0 && num_cols == 0
>::value
>
class matrix_data ;
/*!
WHAT THIS OBJECT REPRESENTS
This object represents the actual allocation of space for a matrix.
Small matrices allocate all their data on the stack and bigger ones
use a memory_manager to get their memory.
!*/
// ----------------------------------------------------------------------------------------
template <
typename T,
long num_rows,
long num_cols,
typename mem_manager
>
class matrix_data<T,num_rows,num_cols,mem_manager,1> : noncopyable // when the sizes are all non zero and small
{
public:
const static long NR = num_rows;
const static long NC = num_cols;
matrix_data() {}
T& operator() (
long r,
long c
) { return data[r][c]; }
const T& operator() (
long r,
long c
) const { return data[r][c]; }
T& operator() (
long i
) { return *(*data + i); }
const T& operator() (
long i
) const { return *(*data + i); }
void swap(
matrix_data& item
)
{
for (long r = 0; r < num_rows; ++r)
{
for (long c = 0; c < num_cols; ++c)
{
exchange((*this)(r,c),item(r,c));
}
}
}
long nr (
) const { return num_rows; }
long nc (
) const { return num_cols; }
void set_size (
long nr,
long nc
)
{
}
private:
T data[num_rows][num_cols];
};
// ----------------------------------------------------------------------------------------
template <
typename T,
long num_rows,
long num_cols,
typename mem_manager
>
class matrix_data<T,num_rows,num_cols,mem_manager,2> : noncopyable // when the sizes are all non zero and big
{
public:
const static long NR = num_rows;
const static long NC = num_cols;
matrix_data (
) { data = pool.allocate_array(num_rows*num_cols); }
~matrix_data ()
{ pool.deallocate_array(data); }
T& operator() (
long r,
long c
) { return data[r*num_cols + c]; }
const T& operator() (
long r,
long c
) const { return data[r*num_cols + c]; }
T& operator() (
long i
) { return data[i]; }
const T& operator() (
long i
) const { return data[i]; }
void swap(
matrix_data& item
)
{
std::swap(item.data,data);
pool.swap(item.pool);
}
long nr (
) const { return num_rows; }
long nc (
) const { return num_cols; }
void set_size (
long nr,
long nc
)
{
}
private:
T* data;
typename mem_manager::template rebind<T>::other pool;
};
// ----------------------------------------------------------------------------------------
template <
typename T,
long num_rows,
long num_cols,
typename mem_manager
>
class matrix_data<T,num_rows,num_cols,mem_manager,3> : noncopyable // when num_rows == 0 && num_cols != 0,
{
public:
const static long NR = num_rows;
const static long NC = num_cols;
matrix_data (
):data(0), nr_(0) { }
~matrix_data ()
{
if (data)
pool.deallocate_array(data);
}
T& operator() (
long r,
long c
) { return data[r*num_cols + c]; }
const T& operator() (
long r,
long c
) const { return data[r*num_cols + c]; }
T& operator() (
long i
) { return data[i]; }
const T& operator() (
long i
) const { return data[i]; }
void swap(
matrix_data& item
)
{
std::swap(item.data,data);
std::swap(item.nr_,nr_);
pool.swap(item.pool);
}
long nr (
) const { return nr_; }
long nc (
) const { return num_cols; }
void set_size (
long nr,
long nc
)
{
if (data)
{
pool.deallocate_array(data);
}
data = pool.allocate_array(nr*nc);
nr_ = nr;
}
private:
T* data;
long nr_;
typename mem_manager::template rebind<T>::other pool;
};
// ----------------------------------------------------------------------------------------
template <
typename T,
long num_rows,
long num_cols,
typename mem_manager
>
class matrix_data<T,num_rows,num_cols,mem_manager,4> : noncopyable // when num_rows != 0 && num_cols == 0
{
public:
const static long NR = num_rows;
const static long NC = num_cols;
matrix_data (
):data(0), nc_(0) { }
~matrix_data ()
{
if (data)
{
pool.deallocate_array(data);
}
}
T& operator() (
long r,
long c
) { return data[r*nc_ + c]; }
const T& operator() (
long r,
long c
) const { return data[r*nc_ + c]; }
T& operator() (
long i
) { return data[i]; }
const T& operator() (
long i
) const { return data[i]; }
void swap(
matrix_data& item
)
{
std::swap(item.data,data);
std::swap(item.nc_,nc_);
pool.swap(item.pool);
}
long nr (
) const { return num_rows; }
long nc (
) const { return nc_; }
void set_size (
long nr,
long nc
)
{
if (data)
{
pool.deallocate_array(data);
}
data = pool.allocate_array(nr*nc);
nc_ = nc;
}
private:
T* data;
long nc_;
typename mem_manager::template rebind<T>::other pool;
};
// ----------------------------------------------------------------------------------------
template <
typename T,
long num_rows,
long num_cols,
typename mem_manager
>
class matrix_data<T,num_rows,num_cols,mem_manager,5> : noncopyable // when num_rows == 0 && num_cols == 0
{
public:
const static long NR = num_rows;
const static long NC = num_cols;
matrix_data (
):data(0), nr_(0), nc_(0) { }
~matrix_data ()
{
if (data)
{
pool.deallocate_array(data);
}
}
T& operator() (
long r,
long c
) { return data[r*nc_ + c]; }
const T& operator() (
long r,
long c
) const { return data[r*nc_ + c]; }
T& operator() (
long i
) { return data[i]; }
const T& operator() (
long i
) const { return data[i]; }
void swap(
matrix_data& item
)
{
std::swap(item.data,data);
std::swap(item.nc_,nc_);
std::swap(item.nr_,nr_);
pool.swap(item.pool);
}
long nr (
) const { return nr_; }
long nc (
) const { return nc_; }
void set_size (
long nr,
long nc
)
{
if (data)
{
pool.deallocate_array(data);
}
data = pool.allocate_array(nr*nc);
nr_ = nr;
nc_ = nc;
}
private:
T* data;
long nr_;
long nc_;
typename mem_manager::template rebind<T>::other pool;
}; };
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
...@@ -608,14 +197,14 @@ namespace dlib ...@@ -608,14 +197,14 @@ namespace dlib
long nc ( long nc (
) const { return get_nc_helper<ref_type,NC>::get(ref_); } ) const { return get_nc_helper<ref_type,NC>::get(ref_); }
template <typename U, long iNR, long iNC, typename mm > template <typename U, long iNR, long iNC, typename mm, typename l >
bool aliases ( bool aliases (
const matrix<U,iNR,iNC,mm>& item const matrix<U,iNR,iNC,mm,l>& item
) const { return ref_.aliases(item); } ) const { return ref_.aliases(item); }
template <typename U, long iNR, long iNC , typename mm> template <typename U, long iNR, long iNC , typename mm, typename l>
bool destructively_aliases ( bool destructively_aliases (
const matrix<U,iNR,iNC,mm>& 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 ref_type& ref (
...@@ -647,10 +236,10 @@ namespace dlib ...@@ -647,10 +236,10 @@ namespace dlib
template <typename T> template <typename T>
struct is_matrix<matrix_exp<T> > { static const bool value = true; }; struct is_matrix<matrix_exp<T> > { static const bool value = true; };
template <typename T, long NR, long NC, typename mm> template <typename T, long NR, long NC, typename mm, typename l>
struct is_matrix<matrix_ref<T,NR,NC,mm> > { 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> template <typename T, long NR, long NC, typename mm, typename l>
struct is_matrix<matrix<T,NR,NC,mm> > { static const bool value = true; }; struct is_matrix<matrix<T,NR,NC,mm,l> > { static const bool value = true; };
template <typename T> template <typename T>
struct is_matrix<T&> { static const bool value = is_matrix<T>::value; }; struct is_matrix<T&> { static const bool value = is_matrix<T>::value; };
template <typename T> template <typename T>
...@@ -776,14 +365,14 @@ namespace dlib ...@@ -776,14 +365,14 @@ namespace dlib
long nc ( long nc (
) const { return rhs.nc(); } ) const { return rhs.nc(); }
template <typename U, long iNR, long iNC, typename mm > template <typename U, long iNR, long iNC, typename mm, typename l >
bool aliases ( bool aliases (
const matrix<U,iNR,iNC,mm>& item const matrix<U,iNR,iNC,mm,l>& item
) const { return lhs.aliases(item) || rhs.aliases(item); } ) const { return lhs.aliases(item) || rhs.aliases(item); }
template <typename U, long iNR, long iNC , typename mm> template <typename U, long iNR, long iNC , typename mm, typename l>
bool destructively_aliases ( bool destructively_aliases (
const matrix<U,iNR,iNC,mm>& item const matrix<U,iNR,iNC,mm,l>& item
) const { return aliases(item); } ) const { return aliases(item); }
const ref_type& ref( const ref_type& ref(
...@@ -799,16 +388,17 @@ namespace dlib ...@@ -799,16 +388,17 @@ namespace dlib
long NC, long NC,
typename EXP1, typename EXP1,
typename EXP2, typename EXP2,
typename MM typename MM,
typename L
> >
inline const matrix_exp<matrix_multiply_exp<EXP1, matrix_multiply_exp<EXP2,typename matrix<T,NR,NC,MM>::ref_type >,0 > > operator* ( 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_exp<matrix_multiply_exp<EXP1,EXP2,1> >& m1,
const matrix<T,NR,NC,MM>& m2 const matrix<T,NR,NC,MM,L>& m2
) )
{ {
// We are going to reorder the order of evaluation of the terms here. This way the // We are going to reorder the order of evaluation of the terms here. This way the
// multiplication will go faster. // multiplication will go faster.
typedef matrix_multiply_exp<EXP2,typename matrix<T,NR,NC,MM>::ref_type > exp_inner; 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; 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))); return matrix_exp<exp_outer>(exp_outer(m1.ref().lhs,exp_inner(m1.ref().rhs,m2)));
} }
...@@ -831,14 +421,15 @@ namespace dlib ...@@ -831,14 +421,15 @@ namespace dlib
long NR, long NR,
long NC, long NC,
typename EXP, typename EXP,
typename MM typename MM,
typename L
> >
inline const matrix_exp<matrix_multiply_exp<typename matrix<T,NR,NC,MM>::ref_type, matrix_exp<EXP> > > operator* ( 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>& m1, const matrix<T,NR,NC,MM,L>& m1,
const matrix_exp<EXP>& m2 const matrix_exp<EXP>& m2
) )
{ {
typedef matrix_multiply_exp<typename matrix<T,NR,NC,MM>::ref_type, matrix_exp<EXP> > exp; typedef matrix_multiply_exp<typename matrix<T,NR,NC,MM,L>::ref_type, matrix_exp<EXP> > exp;
return matrix_exp<exp>(exp(m1,m2)); return matrix_exp<exp>(exp(m1,m2));
} }
...@@ -847,14 +438,15 @@ namespace dlib ...@@ -847,14 +438,15 @@ namespace dlib
long NR, long NR,
long NC, long NC,
typename EXP, typename EXP,
typename MM typename MM,
typename L
> >
inline const matrix_exp<matrix_multiply_exp< matrix_exp<EXP>, typename matrix<T,NR,NC,MM>::ref_type, 1> > operator* ( 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_exp<EXP>& m1,
const matrix<T,NR,NC,MM>& m2 const matrix<T,NR,NC,MM,L>& m2
) )
{ {
typedef matrix_multiply_exp< matrix_exp<EXP>, typename matrix<T,NR,NC,MM>::ref_type, 1 > exp; 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)); return matrix_exp<exp>(exp(m1,m2));
} }
...@@ -865,14 +457,16 @@ namespace dlib ...@@ -865,14 +457,16 @@ namespace dlib
long NR2, long NR2,
long NC2, long NC2,
typename MM1, typename MM1,
typename MM2 typename MM2,
typename L1,
typename L2
> >
inline const matrix_exp<matrix_multiply_exp<typename matrix<T,NR1,NC1,MM1>::ref_type,typename matrix<T,NR2,NC2,MM2>::ref_type > > operator* ( 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>& m1, const matrix<T,NR1,NC1,MM1,L1>& m1,
const matrix<T,NR2,NC2,MM2>& m2 const matrix<T,NR2,NC2,MM2,L2>& m2
) )
{ {
typedef matrix_multiply_exp<typename matrix<T,NR1,NC1,MM1>::ref_type, typename matrix<T,NR2,NC2,MM2>::ref_type > exp; typedef matrix_multiply_exp<typename matrix<T,NR1,NC1,MM1,L1>::ref_type, typename matrix<T,NR2,NC2,MM2,L2>::ref_type > exp;
return matrix_exp<exp>(exp(m1,m2)); return matrix_exp<exp>(exp(m1,m2));
} }
...@@ -931,14 +525,14 @@ namespace dlib ...@@ -931,14 +525,14 @@ namespace dlib
long c long c
) const { return lhs(r,c) + rhs(r,c); } ) const { return lhs(r,c) + rhs(r,c); }
template <typename U, long iNR, long iNC , typename mm> template <typename U, long iNR, long iNC , typename mm, typename l>
bool aliases ( bool aliases (
const matrix<U,iNR,iNC,mm>& item const matrix<U,iNR,iNC,mm,l>& item
) const { return lhs.aliases(item) || rhs.aliases(item); } ) const { return lhs.aliases(item) || rhs.aliases(item); }
template <typename U, long iNR, long iNC, typename mm > template <typename U, long iNR, long iNC, typename mm, typename l >
bool destructively_aliases ( bool destructively_aliases (
const matrix<U,iNR,iNC,mm>& 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 ref_type& ref(
...@@ -1018,14 +612,14 @@ namespace dlib ...@@ -1018,14 +612,14 @@ namespace dlib
long c long c
) const { return lhs(r,c) - rhs(r,c); } ) const { return lhs(r,c) - rhs(r,c); }
template <typename U, long iNR, long iNC, typename mm > template <typename U, long iNR, long iNC, typename mm, typename l >
bool aliases ( bool aliases (
const matrix<U,iNR,iNC, mm>& item const matrix<U,iNR,iNC, mm,l>& item
) const { return lhs.aliases(item) || rhs.aliases(item); } ) const { return lhs.aliases(item) || rhs.aliases(item); }
template <typename U, long iNR, long iNC , typename mm> template <typename U, long iNR, long iNC , typename mm, typename l>
bool destructively_aliases ( bool destructively_aliases (
const matrix<U,iNR,iNC,mm>& 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 ref_type& ref(
...@@ -1090,14 +684,14 @@ namespace dlib ...@@ -1090,14 +684,14 @@ namespace dlib
long c long c
) const { return m(r,c)/s; } ) const { return m(r,c)/s; }
template <typename U, long iNR, long iNC, typename mm > template <typename U, long iNR, long iNC, typename mm , typename l>
bool aliases ( bool aliases (
const matrix<U,iNR,iNC,mm>& item const matrix<U,iNR,iNC,mm,l>& item
) const { return m.aliases(item); } ) const { return m.aliases(item); }
template <typename U, long iNR, long iNC, typename mm > template <typename U, long iNR, long iNC, typename mm, typename l >
bool destructively_aliases ( bool destructively_aliases (
const matrix<U,iNR,iNC,mm>& 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 ref_type& ref(
...@@ -1162,14 +756,14 @@ namespace dlib ...@@ -1162,14 +756,14 @@ namespace dlib
long c long c
) const { return m(r,c)*s; } ) const { return m(r,c)*s; }
template <typename U, long iNR, long iNC , typename mm> template <typename U, long iNR, long iNC , typename mm, typename l>
bool aliases ( bool aliases (
const matrix<U,iNR,iNC,mm>& item const matrix<U,iNR,iNC,mm,l>& item
) const { return m.aliases(item); } ) const { return m.aliases(item); }
template <typename U, long iNR, long iNC, typename mm > template <typename U, long iNR, long iNC, typename mm, typename l >
bool destructively_aliases ( bool destructively_aliases (
const matrix<U,iNR,iNC,mm>& 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 ref_type& ref(
...@@ -1332,27 +926,29 @@ namespace dlib ...@@ -1332,27 +926,29 @@ namespace dlib
typename T, typename T,
long num_rows, long num_rows,
long num_cols, long num_cols,
typename mem_manager typename mem_manager,
typename layout
> >
class matrix : public matrix_exp<matrix_ref<T,num_rows,num_cols, mem_manager> > class matrix : public matrix_exp<matrix_ref<T,num_rows,num_cols, mem_manager,layout> >
{ {
COMPILE_TIME_ASSERT(num_rows >= 0 && num_cols >= 0); COMPILE_TIME_ASSERT(num_rows >= 0 && num_cols >= 0);
public: public:
typedef T type; typedef T type;
typedef matrix_ref<T,num_rows,num_cols,mem_manager> ref_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;
const static long NR = num_rows; const static long NR = num_rows;
const static long NC = num_cols; const static long NC = num_cols;
matrix () : matrix_exp<matrix_ref<T,num_rows,num_cols, mem_manager> >(ref_type(*this)) matrix () : matrix_exp<matrix_ref<T,num_rows,num_cols, mem_manager, layout> >(ref_type(*this))
{ {
} }
explicit matrix ( explicit matrix (
long length long length
) : matrix_exp<matrix_ref<T,num_rows,num_cols, mem_manager> >(ref_type(*this)) ) : matrix_exp<matrix_ref<T,num_rows,num_cols, mem_manager, layout> >(ref_type(*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.
...@@ -1397,7 +993,7 @@ namespace dlib ...@@ -1397,7 +993,7 @@ namespace dlib
matrix ( matrix (
long rows, long rows,
long cols long cols
) : matrix_exp<matrix_ref<T,num_rows,num_cols, mem_manager> >(ref_type(*this)) ) : matrix_exp<matrix_ref<T,num_rows,num_cols, mem_manager, layout> >(ref_type(*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,
...@@ -1414,7 +1010,7 @@ namespace dlib ...@@ -1414,7 +1010,7 @@ 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> >(ref_type(*this)) ): matrix_exp<matrix_ref<T,num_rows,num_cols, mem_manager, layout> >(ref_type(*this))
{ {
// 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.
...@@ -1442,7 +1038,7 @@ namespace dlib ...@@ -1442,7 +1038,7 @@ namespace dlib
matrix ( matrix (
const matrix& m const matrix& m
): matrix_exp<matrix_ref<T,num_rows,num_cols, mem_manager> >(ref_type(*this)) ): matrix_exp<matrix_ref<T,num_rows,num_cols, mem_manager, layout> >(ref_type(*this))
{ {
data.set_size(m.nr(),m.nc()); data.set_size(m.nr(),m.nc());
matrix_assign(*this, m); matrix_assign(*this, m);
...@@ -1451,7 +1047,7 @@ namespace dlib ...@@ -1451,7 +1047,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> >(ref_type(*this)) ): matrix_exp<matrix_ref<T,num_rows,num_cols, mem_manager, layout> >(ref_type(*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;
...@@ -1726,7 +1322,7 @@ namespace dlib ...@@ -1726,7 +1322,7 @@ namespace dlib
} }
else else
{ {
// we have to use a temporary matrix_data object here because // we have to use a temporary matrix object here because
// this->data is aliased inside the matrix_exp m somewhere. // this->data is aliased inside the matrix_exp m somewhere.
matrix temp; matrix temp;
temp.set_size(m.nr(),m.nc()); temp.set_size(m.nr(),m.nc());
...@@ -1762,7 +1358,7 @@ namespace dlib ...@@ -1762,7 +1358,7 @@ namespace dlib
} }
else else
{ {
// we have to use a temporary matrix_data object here because // we have to use a temporary matrix object here because
// this->data is aliased inside the matrix_exp m somewhere. // this->data is aliased inside the matrix_exp m somewhere.
matrix temp; matrix temp;
temp.set_size(m.nr(),m.nc()); temp.set_size(m.nr(),m.nc());
...@@ -1834,33 +1430,34 @@ namespace dlib ...@@ -1834,33 +1430,34 @@ namespace dlib
} }
private: private:
matrix_data<T,NR,NC, mem_manager> data; typename layout::template layout<T,NR,NC,mem_manager> data;
}; };
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
template < template <
typename T, typename T,
long NR, long NR,
long NC, long NC,
typename mm typename mm,
typename l
> >
void swap( void swap(
matrix<T,NR,NC,mm>& a, matrix<T,NR,NC,mm,l>& a,
matrix<T,NR,NC,mm>& b matrix<T,NR,NC,mm,l>& b
) { a.swap(b); } ) { a.swap(b); }
template < template <
typename T, typename T,
long NR, long NR,
long NC, long NC,
typename mm typename mm,
typename l
> >
void serialize ( void serialize (
const matrix<T,NR,NC,mm>& item, const matrix<T,NR,NC,mm,l>& item,
std::ostream& out std::ostream& out
) )
{ {
...@@ -1886,10 +1483,11 @@ namespace dlib ...@@ -1886,10 +1483,11 @@ namespace dlib
typename T, typename T,
long NR, long NR,
long NC, long NC,
typename mm typename mm,
typename l
> >
void deserialize ( void deserialize (
matrix<T,NR,NC,mm>& item, matrix<T,NR,NC,mm,l>& item,
std::istream& in std::istream& in
) )
{ {
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#include "../serialize.h" #include "../serialize.h"
#include "../memory_manager.h" #include "../memory_manager.h"
#include "matrix_data_layout_abstract.h"
namespace dlib namespace dlib
{ {
...@@ -15,7 +16,8 @@ namespace dlib ...@@ -15,7 +16,8 @@ namespace dlib
typename T, typename T,
long num_rows, long num_rows,
long num_cols, long num_cols,
typename mem_manager typename mem_manager,
typename layout
> >
class matrix; class matrix;
...@@ -25,7 +27,8 @@ namespace dlib ...@@ -25,7 +27,8 @@ namespace dlib
typename T, typename T,
long num_rows, long num_rows,
long num_cols, long num_cols,
typename mem_manager typename mem_manager,
typename layout
> >
class matrix_ref class matrix_ref
{ {
...@@ -38,11 +41,12 @@ namespace dlib ...@@ -38,11 +41,12 @@ namespace dlib
typedef T type; typedef T type;
typedef matrix_ref ref_type; typedef matrix_ref ref_type;
typedef mem_manager mem_manager_type; typedef mem_manager mem_manager_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;
matrix_ref ( matrix_ref (
const matrix<T,num_rows,num_cols,mem_manager>& m const matrix<T,num_rows,num_cols,mem_manager,layout>& m
); );
/*! /*!
ensures ensures
...@@ -92,18 +96,18 @@ namespace dlib ...@@ -92,18 +96,18 @@ namespace dlib
- returns nr()*nc() - returns nr()*nc()
!*/ !*/
template <typename U, long iNR, long iNC, typename mm> template <typename U, long iNR, long iNC, typename mm, typename l>
bool destructively_aliases ( bool destructively_aliases (
const matrix<U,iNR,iNC,mm>& item const matrix<U,iNR,iNC,mm,l>& item
) const; ) const;
/*! /*!
ensures ensures
- returns false - returns false
!*/ !*/
template <typename U, long iNR, long iNC, typename mm> template <typename U, long iNR, long iNC, typename mm, typename l>
bool aliases ( bool aliases (
const matrix<U,iNR,iNC,mm>& item const matrix<U,iNR,iNC,mm,l>& item
) const; ) const;
/*! /*!
ensures ensures
...@@ -234,9 +238,9 @@ namespace dlib ...@@ -234,9 +238,9 @@ namespace dlib
- returns nr()*nc() - returns nr()*nc()
!*/ !*/
template <typename U, long iNR, long iNC , typename mm> template <typename U, long iNR, long iNC , typename mm, typename l>
bool aliases ( bool aliases (
const matrix<U,iNR,iNC,mm>& item const matrix<U,iNR,iNC,mm,l>& item
) const; ) const;
/*! /*!
ensures ensures
...@@ -247,9 +251,9 @@ namespace dlib ...@@ -247,9 +251,9 @@ namespace dlib
- returns false - returns false
!*/ !*/
template <typename U, long iNR, long iNC, typename mm > template <typename U, long iNR, long iNC, typename mm, typename l>
bool destructively_aliases ( bool destructively_aliases (
const matrix<U,iNR,iNC,mm>& item const matrix<U,iNR,iNC,mm,l>& item
) const; ) const;
/*! /*!
ensures ensures
...@@ -404,9 +408,10 @@ namespace dlib ...@@ -404,9 +408,10 @@ namespace dlib
typename T, typename T,
long num_rows = 0, long num_rows = 0,
long num_cols = 0, long num_cols = 0,
typename mem_manager = memory_manager<char>::kernel_1a typename mem_manager = memory_manager<char>::kernel_1a,
typename layout = default_matrix_layout
> >
class matrix : public matrix_exp<matrix_ref<T,num_rows,num_cols,mem_manager> > class matrix : public matrix_exp<matrix_ref<T,num_rows,num_cols,mem_manager,layout> >
{ {
/*! /*!
REQUIREMENTS ON num_rows and num_cols REQUIREMENTS ON num_rows and num_cols
...@@ -418,6 +423,10 @@ namespace dlib ...@@ -418,6 +423,10 @@ namespace dlib
must be an implementation of memory_manager_stateless/memory_manager_stateless_kernel_abstract.h must be an implementation of memory_manager_stateless/memory_manager_stateless_kernel_abstract.h
mem_manager::type can be set to anything. mem_manager::type can be set to anything.
REQUIREMENTS ON layout
must be one of the layout objects defined in matrix/matrix_data_layout_abstract.h or an
object with a compatible interface.
INITIAL VALUE INITIAL VALUE
- if (num_rows > 0) then - if (num_rows > 0) then
- nr() == num_rows - nr() == num_rows
...@@ -445,16 +454,18 @@ namespace dlib ...@@ -445,16 +454,18 @@ namespace dlib
be detected at compile time. It also allows the compiler to perform loop be detected at compile time. It also allows the compiler to perform loop
unrolling which can result in substantially faster code. unrolling which can result in substantially faster code.
Also note that the elements of this matrix are contiguous in memory and Also note that the elements of this matrix are laid out in memory by the layout
stored in row major order. Additionally, all memory allocations are object supplied as a template argument to this class. The default_matrix_layout
performed using the memory manager object supplied as a template argument sets elements down contiguously in memory and in row major order. Additionally,
to this class. all memory allocations are performed using the memory manager object supplied as
a template argument to this class.
!*/ !*/
public: public:
typedef T type; typedef T type;
typedef matrix_ref<T,num_rows,num_cols,mem_manager> ref_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;
const static long NR = num_rows; const static long NR = num_rows;
const static long NC = num_cols; const static long NC = num_cols;
...@@ -754,11 +765,12 @@ namespace dlib ...@@ -754,11 +765,12 @@ namespace dlib
typename T, typename T,
long NR, long NR,
long NC, long NC,
typename mm typename mm,
typename l
> >
void swap( void swap(
matrix<T,NR,NC,mm>& a, matrix<T,NR,NC,mm,l>& a,
matrix<T,NR,NC,mm>& b matrix<T,NR,NC,mm,l>& b
) { a.swap(b); } ) { a.swap(b); }
/*! /*!
Provides a global swap function Provides a global swap function
...@@ -768,10 +780,11 @@ namespace dlib ...@@ -768,10 +780,11 @@ namespace dlib
typename T, typename T,
long NR, long NR,
long NC, long NC,
typename mm typename mm,
typename l
> >
void serialize ( void serialize (
const matrix<T,NR,NC,mm>& item, const matrix<T,NR,NC,mm,l>& item,
std::ostream& out std::ostream& out
); );
/*! /*!
...@@ -782,10 +795,11 @@ namespace dlib ...@@ -782,10 +795,11 @@ namespace dlib
typename T, typename T,
long NR, long NR,
long NC, long NC,
typename mm typename mm,
typename l
> >
void deserialize ( void deserialize (
matrix<T,NR,NC,mm>& item, matrix<T,NR,NC,mm,l>& item,
std::istream& in std::istream& in
); );
/*! /*!
......
// Copyright (C) 2006 Davis E. King (davisking@users.sourceforge.net)
// License: Boost Software License See LICENSE.txt for the full license.
#ifndef DLIB_MATRIx_DATA_LAYOUT_
#define DLIB_MATRIx_DATA_LAYOUT_
#include "../algs.h"
#include "matrix_fwd.h"
#include "matrix_data_layout_abstract.h"
namespace dlib
{
// ----------------------------------------------------------------------------------------
/*!
A matrix layout object is any object that contains a templated class called "layout"
with an interface identical to one below:
(Note that all the template arguments are just the template arguments from the dlib::matrix
object and the member functions are defined identically to the ones with the same
signatures inside the matrix object.)
struct matrix_layout
{
template <
typename T,
long num_rows,
long num_cols,
typename mem_manager
>
class layout
{
public:
T& operator() (
long r,
long c
);
const T& operator() (
long r,
long c
);
T& operator() (
long i
);
const T& operator() (
long i
) const;
void swap(
layout& item
);
long nr (
) const;
long nc (
) const;
void set_size (
long nr_,
long nc_
);
};
};
!*/
// ----------------------------------------------------------------------------------------
struct default_matrix_layout
{
// this is a hack to avoid a compile time error in visual studio 8. I would just
// use sizeof(T) and be done with it but that won't compile. The idea here
// is to avoid using the stack allocation of the layout object if it
// is going to contain another matrix and also avoid asking for the sizeof()
// the contained matrix.
template <typename T>
struct get_sizeof_helper
{
const static std::size_t val = sizeof(T);
};
template <typename T, long NR, long NC, typename mm, typename l>
struct get_sizeof_helper<matrix<T,NR,NC,mm,l> >
{
const static std::size_t val = 1000000;
};
template <
typename T,
long num_rows,
long num_cols,
typename mem_manager,
int val = static_switch <
// when the sizes are all non zero and small
(num_rows*num_cols*get_sizeof_helper<T>::val <= 64) && (num_rows != 0 && num_cols != 0),
// when the sizes are all non zero and big
(num_rows*num_cols*get_sizeof_helper<T>::val >= 65) && (num_rows != 0 && num_cols != 0),
num_rows == 0 && num_cols != 0,
num_rows != 0 && num_cols == 0,
num_rows == 0 && num_cols == 0
>::value
>
class layout ;
/*!
WHAT THIS OBJECT REPRESENTS
This object represents the actual allocation of space for a matrix.
Small matrices allocate all their data on the stack and bigger ones
use a memory_manager to get their memory.
!*/
// ------------------------------------------------------------------------------------
template <
typename T,
long num_rows,
long num_cols,
typename mem_manager
>
class layout<T,num_rows,num_cols,mem_manager,1> : noncopyable // when the sizes are all non zero and small
{
public:
const static long NR = num_rows;
const static long NC = num_cols;
layout() {}
T& operator() (
long r,
long c
) { return data[r][c]; }
const T& operator() (
long r,
long c
) const { return data[r][c]; }
T& operator() (
long i
) { return *(*data + i); }
const T& operator() (
long i
) const { return *(*data + i); }
void swap(
layout& item
)
{
for (long r = 0; r < num_rows; ++r)
{
for (long c = 0; c < num_cols; ++c)
{
exchange((*this)(r,c),item(r,c));
}
}
}
long nr (
) const { return num_rows; }
long nc (
) const { return num_cols; }
void set_size (
long nr,
long nc
)
{
}
private:
T data[num_rows][num_cols];
};
// ------------------------------------------------------------------------------------
template <
typename T,
long num_rows,
long num_cols,
typename mem_manager
>
class layout<T,num_rows,num_cols,mem_manager,2> : noncopyable // when the sizes are all non zero and big
{
public:
const static long NR = num_rows;
const static long NC = num_cols;
layout (
) { data = pool.allocate_array(num_rows*num_cols); }
~layout ()
{ pool.deallocate_array(data); }
T& operator() (
long r,
long c
) { return data[r*num_cols + c]; }
const T& operator() (
long r,
long c
) const { return data[r*num_cols + c]; }
T& operator() (
long i
) { return data[i]; }
const T& operator() (
long i
) const { return data[i]; }
void swap(
layout& item
)
{
std::swap(item.data,data);
pool.swap(item.pool);
}
long nr (
) const { return num_rows; }
long nc (
) const { return num_cols; }
void set_size (
long nr,
long nc
)
{
}
private:
T* data;
typename mem_manager::template rebind<T>::other pool;
};
// ------------------------------------------------------------------------------------
template <
typename T,
long num_rows,
long num_cols,
typename mem_manager
>
class layout<T,num_rows,num_cols,mem_manager,3> : noncopyable // when num_rows == 0 && num_cols != 0,
{
public:
const static long NR = num_rows;
const static long NC = num_cols;
layout (
):data(0), nr_(0) { }
~layout ()
{
if (data)
pool.deallocate_array(data);
}
T& operator() (
long r,
long c
) { return data[r*num_cols + c]; }
const T& operator() (
long r,
long c
) const { return data[r*num_cols + c]; }
T& operator() (
long i
) { return data[i]; }
const T& operator() (
long i
) const { return data[i]; }
void swap(
layout& item
)
{
std::swap(item.data,data);
std::swap(item.nr_,nr_);
pool.swap(item.pool);
}
long nr (
) const { return nr_; }
long nc (
) const { return num_cols; }
void set_size (
long nr,
long nc
)
{
if (data)
{
pool.deallocate_array(data);
}
data = pool.allocate_array(nr*nc);
nr_ = nr;
}
private:
T* data;
long nr_;
typename mem_manager::template rebind<T>::other pool;
};
// ------------------------------------------------------------------------------------
template <
typename T,
long num_rows,
long num_cols,
typename mem_manager
>
class layout<T,num_rows,num_cols,mem_manager,4> : noncopyable // when num_rows != 0 && num_cols == 0
{
public:
const static long NR = num_rows;
const static long NC = num_cols;
layout (
):data(0), nc_(0) { }
~layout ()
{
if (data)
{
pool.deallocate_array(data);
}
}
T& operator() (
long r,
long c
) { return data[r*nc_ + c]; }
const T& operator() (
long r,
long c
) const { return data[r*nc_ + c]; }
T& operator() (
long i
) { return data[i]; }
const T& operator() (
long i
) const { return data[i]; }
void swap(
layout& item
)
{
std::swap(item.data,data);
std::swap(item.nc_,nc_);
pool.swap(item.pool);
}
long nr (
) const { return num_rows; }
long nc (
) const { return nc_; }
void set_size (
long nr,
long nc
)
{
if (data)
{
pool.deallocate_array(data);
}
data = pool.allocate_array(nr*nc);
nc_ = nc;
}
private:
T* data;
long nc_;
typename mem_manager::template rebind<T>::other pool;
};
// ------------------------------------------------------------------------------------
template <
typename T,
long num_rows,
long num_cols,
typename mem_manager
>
class layout<T,num_rows,num_cols,mem_manager,5> : noncopyable // when num_rows == 0 && num_cols == 0
{
public:
const static long NR = num_rows;
const static long NC = num_cols;
layout (
):data(0), nr_(0), nc_(0) { }
~layout ()
{
if (data)
{
pool.deallocate_array(data);
}
}
T& operator() (
long r,
long c
) { return data[r*nc_ + c]; }
const T& operator() (
long r,
long c
) const { return data[r*nc_ + c]; }
T& operator() (
long i
) { return data[i]; }
const T& operator() (
long i
) const { return data[i]; }
void swap(
layout& item
)
{
std::swap(item.data,data);
std::swap(item.nc_,nc_);
std::swap(item.nr_,nr_);
pool.swap(item.pool);
}
long nr (
) const { return nr_; }
long nc (
) const { return nc_; }
void set_size (
long nr,
long nc
)
{
if (data)
{
pool.deallocate_array(data);
}
data = pool.allocate_array(nr*nc);
nr_ = nr;
nc_ = nc;
}
private:
T* data;
long nr_;
long nc_;
typename mem_manager::template rebind<T>::other pool;
};
};
// ----------------------------------------------------------------------------------------
}
#endif // DLIB_MATRIx_DATA_LAYOUT_
// Copyright (C) 2008 Davis E. King (davisking@users.sourceforge.net)
// License: Boost Software License See LICENSE.txt for the full license.
#undef DLIB_MATRIx_DATA_LAYOUT_ABSTRACT_
#ifdef DLIB_MATRIx_DATA_LAYOUT_ABSTRACT_
#include "../algs.h"
namespace dlib
{
// ----------------------------------------------------------------------------------------
struct default_matrix_layout
{
/*!
This is the default matrix layout. Any matrix object that uses this
layout will be laid out in memory in row major order. Additionally,
all elements are contiguous (e.g. there isn't any padding at the ends of
rows or anything like that)
!*/
};
// ----------------------------------------------------------------------------------------
}
#endif // DLIB_MATRIx_DATA_LAYOUT_ABSTRACT_
// Copyright (C) 2006 Davis E. King (davisking@users.sourceforge.net)
// License: Boost Software License See LICENSE.txt for the full license.
#ifndef DLIB_MATRIx_FWD
#define DLIB_MATRIx_FWD
#include "../memory_manager.h"
namespace dlib
{
// ----------------------------------------------------------------------------------------
struct default_matrix_layout;
// ----------------------------------------------------------------------------------------
template <
typename T,
long num_rows = 0,
long num_cols = 0,
typename mem_manager = memory_manager<char>::kernel_1a,
typename layout = default_matrix_layout
>
class matrix;
// ----------------------------------------------------------------------------------------
}
#endif // DLIB_MATRIx_FWD
...@@ -117,33 +117,33 @@ namespace dlib ...@@ -117,33 +117,33 @@ namespace dlib
struct has_destructive_aliasing struct has_destructive_aliasing
{ {
template <typename M, typename U, long iNR, long iNC, typename MM > template <typename M, typename U, long iNR, long iNC, typename MM, typename L >
static bool destructively_aliases ( static bool destructively_aliases (
const M& m, const M& m,
const matrix<U,iNR,iNC,MM>& item const matrix<U,iNR,iNC,MM,L>& item
) { return m.aliases(item); } ) { return m.aliases(item); }
template <typename M1, typename M2, typename U, long iNR, long iNC, typename MM > template <typename M1, typename M2, typename U, long iNR, long iNC, typename MM, typename L >
static bool destructively_aliases ( static bool destructively_aliases (
const M1& m1, const M1& m1,
const M2& m2, const M2& m2,
const matrix<U,iNR,iNC,MM>& item const matrix<U,iNR,iNC,MM,L>& item
) { return m1.aliases(item) || m2.aliases(item) ; } ) { return m1.aliases(item) || m2.aliases(item) ; }
}; };
struct has_nondestructive_aliasing struct has_nondestructive_aliasing
{ {
template <typename M, typename U, long iNR, long iNC, typename MM > template <typename M, typename U, long iNR, long iNC, typename MM, typename L >
static bool destructively_aliases ( static bool destructively_aliases (
const M& m, const M& m,
const matrix<U,iNR,iNC,MM>& item const matrix<U,iNR,iNC,MM,L>& item
) { return m.destructively_aliases(item); } ) { return m.destructively_aliases(item); }
template <typename M1, typename M2, typename U, long iNR, long iNC, typename MM > template <typename M1, typename M2, typename U, long iNR, long iNC, typename MM, typename L >
static bool destructively_aliases ( static bool destructively_aliases (
const M1& m1, const M1& m1,
const M2& m2, const M2& m2,
const matrix<U,iNR,iNC, MM>& 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) ; }
}; };
...@@ -317,13 +317,17 @@ namespace dlib ...@@ -317,13 +317,17 @@ namespace dlib
typename MM1, typename MM1,
typename MM2, typename MM2,
typename MM3, typename MM3,
typename MM4 typename MM4,
typename L1,
typename L2,
typename L3,
typename L4
> >
bool svdcmp( bool svdcmp(
matrix<T,M,N,MM1>& a, matrix<T,M,N,MM1,L1>& a,
matrix<T,wN,wX,MM2>& w, matrix<T,wN,wX,MM2,L2>& w,
matrix<T,vN,vN,MM3>& v, matrix<T,vN,vN,MM3,L3>& v,
matrix<T,rN,rX,MM4>& rv1 matrix<T,rN,rX,MM4,L4>& rv1
) )
/*! ( this function is derived from the one in numerical recipes in C chapter 2.6) /*! ( this function is derived from the one in numerical recipes in C chapter 2.6)
requires requires
...@@ -632,13 +636,16 @@ namespace dlib ...@@ -632,13 +636,16 @@ namespace dlib
long NX, long NX,
typename MM1, typename MM1,
typename MM2, typename MM2,
typename MM3 typename MM3,
typename L1,
typename L2,
typename L3
> >
bool ludcmp ( bool ludcmp (
matrix<T,N,N,MM1>& a, matrix<T,N,N,MM1,L1>& a,
matrix<long,N,NX,MM2>& indx, matrix<long,N,NX,MM2,L2>& indx,
T& d, T& d,
matrix<T,N,NX,MM3> vv matrix<T,N,NX,MM3,L3> vv
) )
/*! /*!
( this function is derived from the one in numerical recipes in C chapter 2.3) ( this function is derived from the one in numerical recipes in C chapter 2.3)
...@@ -728,12 +735,15 @@ namespace dlib ...@@ -728,12 +735,15 @@ namespace dlib
long NX, long NX,
typename MM1, typename MM1,
typename MM2, typename MM2,
typename MM3 typename MM3,
typename L1,
typename L2,
typename L3
> >
void lubksb ( void lubksb (
const matrix<T,N,N,MM1>& a, const matrix<T,N,N,MM1,L1>& a,
const matrix<long,N,NX,MM2>& indx, const matrix<long,N,NX,MM2,L2>& indx,
matrix<T,N,NX,MM3>& b matrix<T,N,NX,MM3,L3>& b
) )
/*! /*!
( this function is derived from the one in numerical recipes in C chapter 2.3) ( this function is derived from the one in numerical recipes in C chapter 2.3)
...@@ -788,15 +798,18 @@ namespace dlib ...@@ -788,15 +798,18 @@ namespace dlib
long vN, long vN,
typename MM1, typename MM1,
typename MM2, typename MM2,
typename MM3 typename MM3,
typename L1,
typename L2,
typename L3
> >
long svd2 ( long svd2 (
bool withu, bool withu,
bool withv, bool withv,
const matrix_exp<EXP>& a, const matrix_exp<EXP>& a,
matrix<typename EXP::type,uM,uM,MM1>& u, matrix<typename EXP::type,uM,uM,MM1,L1>& u,
matrix<typename EXP::type,qN,qX,MM2>& q, matrix<typename EXP::type,qN,qX,MM2,L2>& q,
matrix<typename EXP::type,vN,vN,MM3>& v matrix<typename EXP::type,vN,vN,MM3,L3>& v
) )
{ {
/* /*
...@@ -1186,14 +1199,14 @@ convergence: ...@@ -1186,14 +1199,14 @@ convergence:
long c long c
) const { return OP::apply(r,c); } ) const { return OP::apply(r,c); }
template <typename U, long iNR, long iNC , typename MM> template <typename U, long iNR, long iNC , typename MM, typename L>
bool aliases ( bool aliases (
const matrix<U,iNR,iNC,MM>& item const matrix<U,iNR,iNC,MM,L>& item
) const { return false; } ) const { return false; }
template <typename U, long iNR, long iNC, typename MM > template <typename U, long iNR, long iNC, typename MM, typename L >
bool destructively_aliases ( bool destructively_aliases (
const matrix<U,iNR,iNC,MM>& item const matrix<U,iNR,iNC,MM,L>& item
) const { return false; } ) const { return false; }
long nr ( long nr (
...@@ -1244,14 +1257,14 @@ convergence: ...@@ -1244,14 +1257,14 @@ convergence:
long c long c
) const { return OP::apply(s,r,c); } ) const { return OP::apply(s,r,c); }
template <typename U, long iNR, long iNC, typename MM > template <typename U, long iNR, long iNC, typename MM, typename L >
bool aliases ( bool aliases (
const matrix<U,iNR,iNC,MM>& item const matrix<U,iNR,iNC,MM,L>& item
) const { return false; } ) const { return false; }
template <typename U, long iNR, long iNC , typename MM> template <typename U, long iNR, long iNC , typename MM, typename L>
bool destructively_aliases ( bool destructively_aliases (
const matrix<U,iNR,iNC,MM>& item const matrix<U,iNR,iNC,MM,L>& item
) const { return false; } ) const { return false; }
const ref_type& ref( const ref_type& ref(
...@@ -1303,14 +1316,14 @@ convergence: ...@@ -1303,14 +1316,14 @@ convergence:
long c long c
) const { return OP::apply(s,r,c); } ) const { return OP::apply(s,r,c); }
template <typename U, long iNR, long iNC, typename MM > template <typename U, long iNR, long iNC, typename MM, typename L >
bool aliases ( bool aliases (
const matrix<U,iNR,iNC,MM>& item const matrix<U,iNR,iNC,MM,L>& item
) const { return false; } ) const { return false; }
template <typename U, long iNR, long iNC, typename MM > template <typename U, long iNR, long iNC, typename MM, typename L >
bool destructively_aliases ( bool destructively_aliases (
const matrix<U,iNR,iNC,MM>& item const matrix<U,iNR,iNC,MM,L>& item
) const { return false; } ) const { return false; }
const ref_type& ref( const ref_type& ref(
...@@ -1360,14 +1373,14 @@ convergence: ...@@ -1360,14 +1373,14 @@ convergence:
long c long c
) const { return OP::apply(m,r,c); } ) const { return OP::apply(m,r,c); }
template <typename U, long iNR, long iNC, typename MM > template <typename U, long iNR, long iNC, typename MM, typename L >
bool aliases ( bool aliases (
const matrix<U,iNR,iNC,MM>& item const matrix<U,iNR,iNC,MM,L>& item
) const { return m.aliases(item); } ) const { return m.aliases(item); }
template <typename U, long iNR, long iNC, typename MM > template <typename U, long iNR, long iNC, typename MM, typename L >
bool destructively_aliases ( bool destructively_aliases (
const matrix<U,iNR,iNC,MM>& item const matrix<U,iNR,iNC,MM,L>& item
) const { return OP::destructively_aliases(m,item); } ) const { return OP::destructively_aliases(m,item); }
const ref_type& ref( const ref_type& ref(
...@@ -1415,14 +1428,14 @@ convergence: ...@@ -1415,14 +1428,14 @@ convergence:
long long
) const { return m[r]; } ) const { return m[r]; }
template <typename U, long iNR, long iNC, typename MM> template <typename U, long iNR, long iNC, typename MM, typename L>
bool aliases ( bool aliases (
const matrix<U,iNR,iNC,MM>& item const matrix<U,iNR,iNC,MM,L>& item
) const { return false; } ) const { return false; }
template <typename U, long iNR, long iNC , typename MM> template <typename U, long iNR, long iNC , typename MM, typename L>
bool destructively_aliases ( bool destructively_aliases (
const matrix<U,iNR,iNC,MM>& item const matrix<U,iNR,iNC,MM,L>& item
) const { return false; } ) const { return false; }
const ref_type& ref( const ref_type& ref(
...@@ -1470,14 +1483,14 @@ convergence: ...@@ -1470,14 +1483,14 @@ convergence:
long long
) const { return m[r]; } ) const { return m[r]; }
template <typename U, long iNR, long iNC, typename MM> template <typename U, long iNR, long iNC, typename MM, typename L>
bool aliases ( bool aliases (
const matrix<U,iNR,iNC,MM>& item const matrix<U,iNR,iNC,MM,L>& item
) const { return false; } ) const { return false; }
template <typename U, long iNR, long iNC , typename MM> template <typename U, long iNR, long iNC , typename MM, typename L>
bool destructively_aliases ( bool destructively_aliases (
const matrix<U,iNR,iNC,MM>& item const matrix<U,iNR,iNC,MM,L>& item
) const { return false; } ) const { return false; }
const ref_type& ref( const ref_type& ref(
...@@ -1524,14 +1537,14 @@ convergence: ...@@ -1524,14 +1537,14 @@ convergence:
long c long c
) const { return m[r][c]; } ) const { return m[r][c]; }
template <typename U, long iNR, long iNC, typename MM> template <typename U, long iNR, long iNC, typename MM, typename L>
bool aliases ( bool aliases (
const matrix<U,iNR,iNC,MM>& item const matrix<U,iNR,iNC,MM,L>& item
) const { return false; } ) const { return false; }
template <typename U, long iNR, long iNC , typename MM> template <typename U, long iNR, long iNC , typename MM, typename L>
bool destructively_aliases ( bool destructively_aliases (
const matrix<U,iNR,iNC,MM>& item const matrix<U,iNR,iNC,MM,L>& item
) const { return false; } ) const { return false; }
const ref_type& ref( const ref_type& ref(
...@@ -1586,14 +1599,14 @@ convergence: ...@@ -1586,14 +1599,14 @@ convergence:
long c long c
) const { return m(r+r_,c+c_); } ) const { return m(r+r_,c+c_); }
template <typename U, long iNR, long iNC, typename MM > template <typename U, long iNR, long iNC, typename MM, typename L >
bool aliases ( bool aliases (
const matrix<U,iNR,iNC,MM>& item const matrix<U,iNR,iNC,MM,L>& item
) const { return m.aliases(item); } ) const { return m.aliases(item); }
template <typename U, long iNR, long iNC , typename MM> template <typename U, long iNR, long iNC , typename MM, typename L>
bool destructively_aliases ( bool destructively_aliases (
const matrix<U,iNR,iNC,MM>& item const matrix<U,iNR,iNC,MM,L>& item
) const { return m.aliases(item); } ) const { return m.aliases(item); }
const ref_type& ref( const ref_type& ref(
...@@ -1649,14 +1662,14 @@ convergence: ...@@ -1649,14 +1662,14 @@ convergence:
long c long c
) const { return OP::apply(m,s,r,c); } ) const { return OP::apply(m,s,r,c); }
template <typename U, long iNR, long iNC, typename MM > template <typename U, long iNR, long iNC, typename MM, typename L >
bool aliases ( bool aliases (
const matrix<U,iNR,iNC,MM>& item const matrix<U,iNR,iNC,MM,L>& item
) const { return m.aliases(item); } ) const { return m.aliases(item); }
template <typename U, long iNR, long iNC , typename MM> template <typename U, long iNR, long iNC , typename MM, typename L>
bool destructively_aliases ( bool destructively_aliases (
const matrix<U,iNR,iNC,MM>& item const matrix<U,iNR,iNC,MM,L>& item
) const { return OP::destructively_aliases(m,item); } ) const { return OP::destructively_aliases(m,item); }
const ref_type& ref( const ref_type& ref(
...@@ -1714,14 +1727,14 @@ convergence: ...@@ -1714,14 +1727,14 @@ convergence:
long c long c
) const { return OP::apply(m,s1,s2,r,c); } ) const { return OP::apply(m,s1,s2,r,c); }
template <typename U, long iNR, long iNC, typename MM > template <typename U, long iNR, long iNC, typename MM, typename L>
bool aliases ( bool aliases (
const matrix<U,iNR,iNC,MM>& item const matrix<U,iNR,iNC,MM,L>& item
) const { return m.aliases(item); } ) const { return m.aliases(item); }
template <typename U, long iNR, long iNC , typename MM> template <typename U, long iNR, long iNC , typename MM, typename L>
bool destructively_aliases ( bool destructively_aliases (
const matrix<U,iNR,iNC,MM>& item const matrix<U,iNR,iNC,MM,L>& item
) const { return OP::destructively_aliases(m,item); } ) const { return OP::destructively_aliases(m,item); }
const ref_type& ref( const ref_type& ref(
...@@ -1776,14 +1789,14 @@ convergence: ...@@ -1776,14 +1789,14 @@ convergence:
long c long c
) const { return OP::apply(m1,m2,r,c); } ) const { return OP::apply(m1,m2,r,c); }
template <typename U, long iNR, long iNC, typename MM > template <typename U, long iNR, long iNC, typename MM, typename L >
bool aliases ( bool aliases (
const matrix<U,iNR,iNC,MM>& item const matrix<U,iNR,iNC,MM,L>& item
) const { return m1.aliases(item) || m2.aliases(item); } ) const { return m1.aliases(item) || m2.aliases(item); }
template <typename U, long iNR, long iNC, typename MM > template <typename U, long iNR, long iNC, typename MM, typename L >
bool destructively_aliases ( bool destructively_aliases (
const matrix<U,iNR,iNC,MM>& item const matrix<U,iNR,iNC,MM,L>& item
) const { return OP::destructively_aliases(m1,m2,item); } ) const { return OP::destructively_aliases(m1,m2,item); }
const ref_type& ref( const ref_type& ref(
...@@ -1839,14 +1852,14 @@ convergence: ...@@ -1839,14 +1852,14 @@ convergence:
long c long c
) const { return start + r*inc; } ) const { return start + r*inc; }
template <typename U, long iNR, long iNC , typename MM> template <typename U, long iNR, long iNC , typename MM, typename L>
bool aliases ( bool aliases (
const matrix<U,iNR,iNC,MM>& item const matrix<U,iNR,iNC,MM,L>& item
) const { return false; } ) const { return false; }
template <typename U, long iNR, long iNC, typename MM > template <typename U, long iNR, long iNC, typename MM, typename L >
bool destructively_aliases ( bool destructively_aliases (
const matrix<U,iNR,iNC,MM>& item const matrix<U,iNR,iNC,MM,L>& item
) const { return false; } ) const { return false; }
long nr ( long nr (
...@@ -1881,14 +1894,14 @@ convergence: ...@@ -1881,14 +1894,14 @@ convergence:
long c long c
) const { return start + r*inc; } ) const { return start + r*inc; }
template <typename U, long iNR, long iNC , typename MM> template <typename U, long iNR, long iNC , typename MM, typename L>
bool aliases ( bool aliases (
const matrix<U,iNR,iNC,MM>& item const matrix<U,iNR,iNC,MM,L>& item
) const { return false; } ) const { return false; }
template <typename U, long iNR, long iNC, typename MM > template <typename U, long iNR, long iNC, typename MM, typename L >
bool destructively_aliases ( bool destructively_aliases (
const matrix<U,iNR,iNC,MM>& item const matrix<U,iNR,iNC,MM,L>& item
) const { return false; } ) const { return false; }
long nr ( long nr (
...@@ -2134,14 +2147,14 @@ convergence: ...@@ -2134,14 +2147,14 @@ convergence:
long c long c
) const { return m(rows(r),cols(c)); } ) const { return m(rows(r),cols(c)); }
template <typename U, long iNR, long iNC, typename MM > template <typename U, long iNR, long iNC, typename MM, typename L >
bool aliases ( bool aliases (
const matrix<U,iNR,iNC,MM>& item const matrix<U,iNR,iNC,MM,L>& item
) const { return m.aliases(item) || rows.aliases(item) || cols.aliases(item); } ) const { return m.aliases(item) || rows.aliases(item) || cols.aliases(item); }
template <typename U, long iNR, long iNC , typename MM> template <typename U, long iNR, long iNC , typename MM, typename L>
bool destructively_aliases ( bool destructively_aliases (
const matrix<U,iNR,iNC,MM>& item const matrix<U,iNR,iNC,MM,L>& item
) const { return m.aliases(item) || rows.aliases(item) || cols.aliases(item); } ) const { return m.aliases(item) || rows.aliases(item) || cols.aliases(item); }
const ref_type& ref( const ref_type& ref(
...@@ -2282,12 +2295,12 @@ convergence: ...@@ -2282,12 +2295,12 @@ convergence:
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
template <typename T, long NR, long NC, typename mm> template <typename T, long NR, long NC, typename mm, typename l>
class assignable_sub_matrix class assignable_sub_matrix
{ {
public: public:
assignable_sub_matrix( assignable_sub_matrix(
matrix<T,NR,NC,mm>& m_, matrix<T,NR,NC,mm,l>& m_,
const rectangle& rect_ const rectangle& rect_
) : m(m_), rect(rect_) {} ) : m(m_), rect(rect_) {}
...@@ -2336,14 +2349,14 @@ convergence: ...@@ -2336,14 +2349,14 @@ convergence:
private: private:
matrix<T,NR,NC,mm>& m; matrix<T,NR,NC,mm,l>& m;
const rectangle rect; const rectangle rect;
}; };
template <typename T, long NR, long NC, typename mm> template <typename T, long NR, long NC, typename mm, typename l>
assignable_sub_matrix<T,NR,NC,mm> set_subm ( assignable_sub_matrix<T,NR,NC,mm,l> set_subm (
matrix<T,NR,NC,mm>& m, matrix<T,NR,NC,mm,l>& m,
const rectangle& rect const rectangle& rect
) )
{ {
...@@ -2359,13 +2372,13 @@ convergence: ...@@ -2359,13 +2372,13 @@ convergence:
); );
return assignable_sub_matrix<T,NR,NC,mm>(m,rect); return assignable_sub_matrix<T,NR,NC,mm,l>(m,rect);
} }
template <typename T, long NR, long NC, typename mm> template <typename T, long NR, long NC, typename mm, typename l>
assignable_sub_matrix<T,NR,NC,mm> set_subm ( assignable_sub_matrix<T,NR,NC,mm,l> set_subm (
matrix<T,NR,NC,mm>& m, matrix<T,NR,NC,mm,l>& m,
long r, long r,
long c, long c,
long nr, long nr,
...@@ -2383,17 +2396,17 @@ convergence: ...@@ -2383,17 +2396,17 @@ convergence:
<< "\n\tnc: " << nc << "\n\tnc: " << nc
); );
return assignable_sub_matrix<T,NR,NC,mm>(m,rectangle(c,r, c+nc-1, r+nr-1)); return assignable_sub_matrix<T,NR,NC,mm,l>(m,rectangle(c,r, c+nc-1, r+nr-1));
} }
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
template <typename T, long NR, long NC, typename mm, typename EXPr, typename EXPc> template <typename T, long NR, long NC, typename mm, typename l, typename EXPr, typename EXPc>
class assignable_sub_range_matrix class assignable_sub_range_matrix
{ {
public: public:
assignable_sub_range_matrix( assignable_sub_range_matrix(
matrix<T,NR,NC,mm>& m_, matrix<T,NR,NC,mm,l>& m_,
const EXPr& rows_, const EXPr& rows_,
const EXPc& cols_ const EXPc& cols_
) : m(m_), rows(rows_), cols(cols_) {} ) : m(m_), rows(rows_), cols(cols_) {}
...@@ -2449,14 +2462,14 @@ convergence: ...@@ -2449,14 +2462,14 @@ convergence:
private: private:
matrix<T,NR,NC,mm>& m; matrix<T,NR,NC,mm,l>& m;
const EXPr rows; const EXPr rows;
const EXPc cols; const EXPc cols;
}; };
template <typename T, long NR, long NC, typename mm, 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,matrix_exp<EXPr>,matrix_exp<EXPc> > set_subm ( assignable_sub_range_matrix<T,NR,NC,mm,l,matrix_exp<EXPr>,matrix_exp<EXPc> > set_subm (
matrix<T,NR,NC,mm>& 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
) )
...@@ -2477,17 +2490,17 @@ convergence: ...@@ -2477,17 +2490,17 @@ convergence:
<< "\n\tcols.nc(): " << cols.nc() << "\n\tcols.nc(): " << cols.nc()
); );
return assignable_sub_range_matrix<T,NR,NC,mm,matrix_exp<EXPr>,matrix_exp<EXPc> >(m,rows,cols); return assignable_sub_range_matrix<T,NR,NC,mm,l,matrix_exp<EXPr>,matrix_exp<EXPc> >(m,rows,cols);
} }
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
template <typename T, long NR, long NC, typename mm> template <typename T, long NR, long NC, typename mm, typename l>
class assignable_col_matrix class assignable_col_matrix
{ {
public: public:
assignable_col_matrix( assignable_col_matrix(
matrix<T,NR,NC,mm>& m_, matrix<T,NR,NC,mm,l>& m_,
const long col_ const long col_
) : m(m_), col(col_) {} ) : m(m_), col(col_) {}
...@@ -2532,14 +2545,14 @@ convergence: ...@@ -2532,14 +2545,14 @@ convergence:
private: private:
matrix<T,NR,NC,mm>& m; matrix<T,NR,NC,mm,l>& m;
const long col; const long col;
}; };
template <typename T, long NR, long NC, typename mm> template <typename T, long NR, long NC, typename mm, typename l>
assignable_col_matrix<T,NR,NC,mm> set_colm ( assignable_col_matrix<T,NR,NC,mm,l> set_colm (
matrix<T,NR,NC,mm>& m, matrix<T,NR,NC,mm,l>& m,
const long col const long col
) )
{ {
...@@ -2552,18 +2565,18 @@ convergence: ...@@ -2552,18 +2565,18 @@ convergence:
); );
return assignable_col_matrix<T,NR,NC,mm>(m,col); return assignable_col_matrix<T,NR,NC,mm,l>(m,col);
} }
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
template <typename T, long NR, long NC, typename mm> template <typename T, long NR, long NC, typename mm, typename l>
class assignable_row_matrix class assignable_row_matrix
{ {
public: public:
assignable_row_matrix( assignable_row_matrix(
matrix<T,NR,NC,mm>& m_, matrix<T,NR,NC,mm,l>& m_,
const long row_ const long row_
) : m(m_), row(row_) {} ) : m(m_), row(row_) {}
...@@ -2608,14 +2621,14 @@ convergence: ...@@ -2608,14 +2621,14 @@ convergence:
private: private:
matrix<T,NR,NC,mm>& m; matrix<T,NR,NC,mm,l>& m;
const long row; const long row;
}; };
template <typename T, long NR, long NC, typename mm> template <typename T, long NR, long NC, typename mm, typename l>
assignable_row_matrix<T,NR,NC,mm> set_rowm ( assignable_row_matrix<T,NR,NC,mm,l> set_rowm (
matrix<T,NR,NC,mm>& m, matrix<T,NR,NC,mm,l>& m,
const long row const long row
) )
{ {
...@@ -2628,7 +2641,7 @@ convergence: ...@@ -2628,7 +2641,7 @@ convergence:
); );
return assignable_row_matrix<T,NR,NC,mm>(m,row); return assignable_row_matrix<T,NR,NC,mm,l>(m,row);
} }
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
...@@ -3101,10 +3114,11 @@ convergence: ...@@ -3101,10 +3114,11 @@ convergence:
long NR, long NR,
long NC, long NC,
typename MM, typename MM,
typename U typename U,
typename L
> >
typename disable_if<is_matrix<U>,void>::type set_all_elements ( typename disable_if<is_matrix<U>,void>::type set_all_elements (
matrix<T,NR,NC,MM>& m, matrix<T,NR,NC,MM,L>& m,
const U& value const U& value
) )
{ {
...@@ -3128,10 +3142,11 @@ convergence: ...@@ -3128,10 +3142,11 @@ convergence:
long NR, long NR,
long NC, long NC,
typename MM, typename MM,
typename U typename U,
typename L
> >
typename enable_if<is_matrix<U>,void>::type set_all_elements ( typename enable_if<is_matrix<U>,void>::type set_all_elements (
matrix<T,NR,NC,MM>& m, matrix<T,NR,NC,MM,L>& m,
const U& value const U& value
) )
{ {
...@@ -3155,13 +3170,16 @@ convergence: ...@@ -3155,13 +3170,16 @@ convergence:
long wX, long wX,
typename MM1, typename MM1,
typename MM2, typename MM2,
typename MM3 typename MM3,
typename L1,
typename L2,
typename L3
> >
inline void svd3 ( inline void svd3 (
const matrix_exp<EXP>& m, const matrix_exp<EXP>& m,
matrix<typename matrix_exp<EXP>::type, uNR, uNC,MM1>& u, matrix<typename matrix_exp<EXP>::type, uNR, uNC,MM1,L1>& u,
matrix<typename matrix_exp<EXP>::type, wN, wX,MM2>& w, matrix<typename matrix_exp<EXP>::type, wN, wX,MM2,L2>& w,
matrix<typename matrix_exp<EXP>::type, vN, vN,MM3>& v matrix<typename matrix_exp<EXP>::type, vN, vN,MM3,L3>& v
) )
{ {
typedef typename matrix_exp<EXP>::type T; typedef typename matrix_exp<EXP>::type T;
...@@ -3195,13 +3213,16 @@ convergence: ...@@ -3195,13 +3213,16 @@ convergence:
long vN, long vN,
typename MM1, typename MM1,
typename MM2, typename MM2,
typename MM3 typename MM3,
typename L1,
typename L2,
typename L3
> >
inline void svd ( inline void svd (
const matrix_exp<EXP>& m, const matrix_exp<EXP>& m,
matrix<typename matrix_exp<EXP>::type, uNR, uNC,MM1>& u, matrix<typename matrix_exp<EXP>::type, uNR, uNC,MM1,L1>& u,
matrix<typename matrix_exp<EXP>::type, wN, wN,MM2>& w, matrix<typename matrix_exp<EXP>::type, wN, wN,MM2,L2>& w,
matrix<typename matrix_exp<EXP>::type, vN, vN,MM3>& v matrix<typename matrix_exp<EXP>::type, vN, vN,MM3,L3>& v
) )
{ {
typedef typename matrix_exp<EXP>::type T; typedef typename matrix_exp<EXP>::type T;
...@@ -4538,12 +4559,12 @@ convergence: ...@@ -4538,12 +4559,12 @@ convergence:
}; };
template < template <
typename T, long NR, long NC, typename mm, typename T, long NR, long NC, typename mm, typename l1,
long NR2, long NC2, typename mm2 long NR2, long NC2, typename mm2, typename l2
> >
void sort_columns ( void sort_columns (
matrix<T,NR,NC,mm>& m, matrix<T,NR,NC,mm,l1>& m,
matrix<T,NR2,NC2,mm2>& v matrix<T,NR2,NC2,mm2,l2>& v
) )
{ {
COMPILE_TIME_ASSERT(NC2 == 1 || NC2 == 0); COMPILE_TIME_ASSERT(NC2 == 1 || NC2 == 0);
...@@ -4585,12 +4606,12 @@ convergence: ...@@ -4585,12 +4606,12 @@ convergence:
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
template < template <
typename T, long NR, long NC, typename mm, typename T, long NR, long NC, typename mm, typename l1,
long NR2, long NC2, typename mm2 long NR2, long NC2, typename mm2, typename l2
> >
void rsort_columns ( void rsort_columns (
matrix<T,NR,NC,mm>& m, matrix<T,NR,NC,mm,l1>& m,
matrix<T,NR2,NC2,mm2>& v matrix<T,NR2,NC2,mm2,l2>& v
) )
{ {
COMPILE_TIME_ASSERT(NC2 == 1 || NC2 == 0); COMPILE_TIME_ASSERT(NC2 == 1 || NC2 == 0);
......
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