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 @@
#ifndef DLIB_MATRIx_
#define DLIB_MATRIx_
#include "matrix_fwd.h"
#include "matrix_abstract.h"
#include "../algs.h"
#include "../serialize.h"
......@@ -11,6 +12,7 @@
#include <algorithm>
#include "../memory_manager.h"
#include "../is_kind.h"
#include "matrix_data_layout.h"
#ifdef _MSC_VER
// Disable the following warnings for Visual Studio
......@@ -26,16 +28,6 @@
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
typename T,
long num_rows,
long num_cols,
typename mem_manager
typename mem_manager,
typename layout
>
class matrix_ref
{
......@@ -51,11 +44,12 @@ namespace dlib
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>& m_
const matrix<T,num_rows,num_cols,mem_manager,layout>& m_
) : m(m_) {}
matrix_ref (
......@@ -76,18 +70,18 @@ namespace dlib
long 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 (
const matrix<U,iNR,iNC,mm>& item
const matrix<U,iNR,iNC,mm,l>& item
) 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 (
const matrix<U,iNR,iNC,mm>& item
const matrix<U,iNR,iNC,mm,l>& item
) const { return false; }
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 matrix_ref ref(
......@@ -97,412 +91,7 @@ namespace dlib
// no assignment operator
matrix_ref& operator=(const matrix_ref&);
const matrix<T,num_rows,num_cols,mem_manager>& 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;
const matrix<T,num_rows,num_cols,mem_manager,layout>& m; // This is the item contained by this expression.
};
// ----------------------------------------------------------------------------------------
......@@ -608,14 +197,14 @@ namespace dlib
long nc (
) 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 (
const matrix<U,iNR,iNC,mm>& item
const matrix<U,iNR,iNC,mm,l>& 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 (
const matrix<U,iNR,iNC,mm>& item
const matrix<U,iNR,iNC,mm,l>& item
) const { return ref_.destructively_aliases(item); }
const ref_type& ref (
......@@ -647,10 +236,10 @@ namespace dlib
template <typename T>
struct is_matrix<matrix_exp<T> > { static const bool value = true; };
template <typename T, long NR, long NC, typename mm>
struct is_matrix<matrix_ref<T,NR,NC,mm> > { static const bool value = true; };
template <typename T, long NR, long NC, typename mm>
struct is_matrix<matrix<T,NR,NC,mm> > { static const bool value = true; };
template <typename T, long NR, long NC, typename mm, typename l>
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>
......@@ -776,14 +365,14 @@ namespace dlib
long 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 (
const matrix<U,iNR,iNC,mm>& item
const matrix<U,iNR,iNC,mm,l>& 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 (
const matrix<U,iNR,iNC,mm>& item
const matrix<U,iNR,iNC,mm,l>& item
) const { return aliases(item); }
const ref_type& ref(
......@@ -799,16 +388,17 @@ namespace dlib
long NC,
typename EXP1,
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<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
// 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;
return matrix_exp<exp_outer>(exp_outer(m1.ref().lhs,exp_inner(m1.ref().rhs,m2)));
}
......@@ -831,14 +421,15 @@ namespace dlib
long NR,
long NC,
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* (
const matrix<T,NR,NC,MM>& m1,
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>::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));
}
......@@ -847,14 +438,15 @@ namespace dlib
long NR,
long NC,
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<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));
}
......@@ -865,14 +457,16 @@ namespace dlib
long NR2,
long NC2,
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* (
const matrix<T,NR1,NC1,MM1>& m1,
const matrix<T,NR2,NC2,MM2>& m2
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>::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));
}
......@@ -931,14 +525,14 @@ namespace dlib
long 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 (
const matrix<U,iNR,iNC,mm>& item
const matrix<U,iNR,iNC,mm,l>& 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 (
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 ref_type& ref(
......@@ -1018,14 +612,14 @@ namespace dlib
long 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 (
const matrix<U,iNR,iNC, mm>& item
const matrix<U,iNR,iNC, mm,l>& 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 (
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 ref_type& ref(
......@@ -1090,14 +684,14 @@ namespace dlib
long c
) 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 (
const matrix<U,iNR,iNC,mm>& item
const matrix<U,iNR,iNC,mm,l>& 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 (
const matrix<U,iNR,iNC,mm>& item
const matrix<U,iNR,iNC,mm,l>& item
) const { return m.destructively_aliases(item); }
const ref_type& ref(
......@@ -1162,14 +756,14 @@ namespace dlib
long c
) 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 (
const matrix<U,iNR,iNC,mm>& item
const matrix<U,iNR,iNC,mm,l>& 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 (
const matrix<U,iNR,iNC,mm>& item
const matrix<U,iNR,iNC,mm,l>& item
) const { return m.destructively_aliases(item); }
const ref_type& ref(
......@@ -1295,34 +889,34 @@ namespace dlib
// ----------------------------------------------------------------------------------------
template <
typename matrix_dest_type,
typename src_exp
>
void matrix_assign (
matrix_dest_type& dest,
const matrix_exp<src_exp>& src,
const long row_offset = 0,
const long col_offset = 0
)
/*!
requires
- src.destructively_aliases(dest) == false
- dest.nr() == src.nr()-row_offset
- dest.nc() == src.nc()-col_offset
ensures
- #subm(dest, row_offset, col_offset, src.nr(), src.nc()) == src
- the part of dest outside the above sub matrix remains unchanged
!*/
template <
typename matrix_dest_type,
typename src_exp
>
void matrix_assign (
matrix_dest_type& dest,
const matrix_exp<src_exp>& src,
const long row_offset = 0,
const long col_offset = 0
)
/*!
requires
- src.destructively_aliases(dest) == false
- dest.nr() == src.nr()-row_offset
- dest.nc() == src.nc()-col_offset
ensures
- #subm(dest, row_offset, col_offset, src.nr(), src.nc()) == src
- the part of dest outside the above sub matrix remains unchanged
!*/
{
for (long r = 0; r < src.nr(); ++r)
{
for (long r = 0; r < src.nr(); ++r)
for (long c = 0; c < src.nc(); ++c)
{
for (long c = 0; c < src.nc(); ++c)
{
dest(r+row_offset,c+col_offset) = src(r,c);
}
dest(r+row_offset,c+col_offset) = src(r,c);
}
}
}
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
......@@ -1332,27 +926,29 @@ namespace dlib
typename T,
long num_rows,
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);
public:
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 layout layout_type;
const static long NR = num_rows;
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 (
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
// row vector.
......@@ -1397,7 +993,7 @@ namespace dlib
matrix (
long rows,
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) &&
rows >= 0 && cols >= 0,
......@@ -1414,7 +1010,7 @@ namespace dlib
template <typename EXP>
matrix (
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
// the same as the type contained in the target matrix.
......@@ -1442,7 +1038,7 @@ namespace dlib
matrix (
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());
matrix_assign(*this, m);
......@@ -1451,7 +1047,7 @@ namespace dlib
template <typename U, size_t len>
matrix (
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);
size_t idx = 0;
......@@ -1726,7 +1322,7 @@ namespace dlib
}
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.
matrix temp;
temp.set_size(m.nr(),m.nc());
......@@ -1762,7 +1358,7 @@ namespace dlib
}
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.
matrix temp;
temp.set_size(m.nr(),m.nc());
......@@ -1834,33 +1430,34 @@ namespace dlib
}
private:
matrix_data<T,NR,NC, mem_manager> data;
typename layout::template layout<T,NR,NC,mem_manager> data;
};
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
template <
typename T,
long NR,
long NC,
typename mm
typename mm,
typename l
>
void swap(
matrix<T,NR,NC,mm>& a,
matrix<T,NR,NC,mm>& b
matrix<T,NR,NC,mm,l>& a,
matrix<T,NR,NC,mm,l>& b
) { a.swap(b); }
template <
typename T,
long NR,
long NC,
typename mm
typename mm,
typename l
>
void serialize (
const matrix<T,NR,NC,mm>& item,
const matrix<T,NR,NC,mm,l>& item,
std::ostream& out
)
{
......@@ -1886,10 +1483,11 @@ namespace dlib
typename T,
long NR,
long NC,
typename mm
typename mm,
typename l
>
void deserialize (
matrix<T,NR,NC,mm>& item,
matrix<T,NR,NC,mm,l>& item,
std::istream& in
)
{
......
......@@ -5,6 +5,7 @@
#include "../serialize.h"
#include "../memory_manager.h"
#include "matrix_data_layout_abstract.h"
namespace dlib
{
......@@ -15,7 +16,8 @@ namespace dlib
typename T,
long num_rows,
long num_cols,
typename mem_manager
typename mem_manager,
typename layout
>
class matrix;
......@@ -25,7 +27,8 @@ namespace dlib
typename T,
long num_rows,
long num_cols,
typename mem_manager
typename mem_manager,
typename layout
>
class matrix_ref
{
......@@ -38,11 +41,12 @@ namespace dlib
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>& m
const matrix<T,num_rows,num_cols,mem_manager,layout>& m
);
/*!
ensures
......@@ -92,18 +96,18 @@ namespace dlib
- 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 (
const matrix<U,iNR,iNC,mm>& item
const matrix<U,iNR,iNC,mm,l>& item
) const;
/*!
ensures
- returns false
!*/
template <typename U, long iNR, long iNC, typename mm>
template <typename U, long iNR, long iNC, typename mm, typename l>
bool aliases (
const matrix<U,iNR,iNC,mm>& item
const matrix<U,iNR,iNC,mm,l>& item
) const;
/*!
ensures
......@@ -234,9 +238,9 @@ namespace dlib
- 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 (
const matrix<U,iNR,iNC,mm>& item
const matrix<U,iNR,iNC,mm,l>& item
) const;
/*!
ensures
......@@ -247,9 +251,9 @@ namespace dlib
- 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 (
const matrix<U,iNR,iNC,mm>& item
const matrix<U,iNR,iNC,mm,l>& item
) const;
/*!
ensures
......@@ -404,9 +408,10 @@ namespace dlib
typename T,
long num_rows = 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
......@@ -418,6 +423,10 @@ namespace dlib
must be an implementation of memory_manager_stateless/memory_manager_stateless_kernel_abstract.h
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
- if (num_rows > 0) then
- nr() == num_rows
......@@ -445,16 +454,18 @@ namespace dlib
be detected at compile time. It also allows the compiler to perform loop
unrolling which can result in substantially faster code.
Also note that the elements of this matrix are contiguous in memory and
stored in row major order. Additionally, all memory allocations are
performed using the memory manager object supplied as a template argument
to this class.
Also note that the elements of this matrix are laid out in memory by the layout
object supplied as a template argument to this class. The default_matrix_layout
sets elements down contiguously in memory and in row major order. Additionally,
all memory allocations are performed using the memory manager object supplied as
a template argument to this class.
!*/
public:
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 layout layout_type;
const static long NR = num_rows;
const static long NC = num_cols;
......@@ -754,11 +765,12 @@ namespace dlib
typename T,
long NR,
long NC,
typename mm
typename mm,
typename l
>
void swap(
matrix<T,NR,NC,mm>& a,
matrix<T,NR,NC,mm>& b
matrix<T,NR,NC,mm,l>& a,
matrix<T,NR,NC,mm,l>& b
) { a.swap(b); }
/*!
Provides a global swap function
......@@ -768,10 +780,11 @@ namespace dlib
typename T,
long NR,
long NC,
typename mm
typename mm,
typename l
>
void serialize (
const matrix<T,NR,NC,mm>& item,
const matrix<T,NR,NC,mm,l>& item,
std::ostream& out
);
/*!
......@@ -782,10 +795,11 @@ namespace dlib
typename T,
long NR,
long NC,
typename mm
typename mm,
typename l
>
void deserialize (
matrix<T,NR,NC,mm>& item,
matrix<T,NR,NC,mm,l>& item,
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
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 (
const M& m,
const matrix<U,iNR,iNC,MM>& item
const matrix<U,iNR,iNC,MM,L>& 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 (
const M1& m1,
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) ; }
};
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 (
const M& m,
const matrix<U,iNR,iNC,MM>& item
const matrix<U,iNR,iNC,MM,L>& 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 (
const M1& m1,
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) ; }
};
......@@ -317,13 +317,17 @@ namespace dlib
typename MM1,
typename MM2,
typename MM3,
typename MM4
typename MM4,
typename L1,
typename L2,
typename L3,
typename L4
>
bool svdcmp(
matrix<T,M,N,MM1>& a,
matrix<T,wN,wX,MM2>& w,
matrix<T,vN,vN,MM3>& v,
matrix<T,rN,rX,MM4>& rv1
matrix<T,M,N,MM1,L1>& a,
matrix<T,wN,wX,MM2,L2>& w,
matrix<T,vN,vN,MM3,L3>& v,
matrix<T,rN,rX,MM4,L4>& rv1
)
/*! ( this function is derived from the one in numerical recipes in C chapter 2.6)
requires
......@@ -632,13 +636,16 @@ namespace dlib
long NX,
typename MM1,
typename MM2,
typename MM3
typename MM3,
typename L1,
typename L2,
typename L3
>
bool ludcmp (
matrix<T,N,N,MM1>& a,
matrix<long,N,NX,MM2>& indx,
matrix<T,N,N,MM1,L1>& a,
matrix<long,N,NX,MM2,L2>& indx,
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)
......@@ -728,12 +735,15 @@ namespace dlib
long NX,
typename MM1,
typename MM2,
typename MM3
typename MM3,
typename L1,
typename L2,
typename L3
>
void lubksb (
const matrix<T,N,N,MM1>& a,
const matrix<long,N,NX,MM2>& indx,
matrix<T,N,NX,MM3>& b
const matrix<T,N,N,MM1,L1>& a,
const matrix<long,N,NX,MM2,L2>& indx,
matrix<T,N,NX,MM3,L3>& b
)
/*!
( this function is derived from the one in numerical recipes in C chapter 2.3)
......@@ -788,15 +798,18 @@ namespace dlib
long vN,
typename MM1,
typename MM2,
typename MM3
typename MM3,
typename L1,
typename L2,
typename L3
>
long svd2 (
bool withu,
bool withv,
const matrix_exp<EXP>& a,
matrix<typename EXP::type,uM,uM,MM1>& u,
matrix<typename EXP::type,qN,qX,MM2>& q,
matrix<typename EXP::type,vN,vN,MM3>& v
matrix<typename EXP::type,uM,uM,MM1,L1>& u,
matrix<typename EXP::type,qN,qX,MM2,L2>& q,
matrix<typename EXP::type,vN,vN,MM3,L3>& v
)
{
/*
......@@ -1186,14 +1199,14 @@ convergence:
long 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 (
const matrix<U,iNR,iNC,MM>& item
const matrix<U,iNR,iNC,MM,L>& item
) 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 (
const matrix<U,iNR,iNC,MM>& item
const matrix<U,iNR,iNC,MM,L>& item
) const { return false; }
long nr (
......@@ -1244,14 +1257,14 @@ convergence:
long 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 (
const matrix<U,iNR,iNC,MM>& item
const matrix<U,iNR,iNC,MM,L>& item
) 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 (
const matrix<U,iNR,iNC,MM>& item
const matrix<U,iNR,iNC,MM,L>& item
) const { return false; }
const ref_type& ref(
......@@ -1303,14 +1316,14 @@ convergence:
long 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 (
const matrix<U,iNR,iNC,MM>& item
const matrix<U,iNR,iNC,MM,L>& item
) 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 (
const matrix<U,iNR,iNC,MM>& item
const matrix<U,iNR,iNC,MM,L>& item
) const { return false; }
const ref_type& ref(
......@@ -1360,14 +1373,14 @@ convergence:
long 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 (
const matrix<U,iNR,iNC,MM>& item
const matrix<U,iNR,iNC,MM,L>& 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 (
const matrix<U,iNR,iNC,MM>& item
const matrix<U,iNR,iNC,MM,L>& item
) const { return OP::destructively_aliases(m,item); }
const ref_type& ref(
......@@ -1415,14 +1428,14 @@ convergence:
long
) 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 (
const matrix<U,iNR,iNC,MM>& item
const matrix<U,iNR,iNC,MM,L>& item
) 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 (
const matrix<U,iNR,iNC,MM>& item
const matrix<U,iNR,iNC,MM,L>& item
) const { return false; }
const ref_type& ref(
......@@ -1470,14 +1483,14 @@ convergence:
long
) 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 (
const matrix<U,iNR,iNC,MM>& item
const matrix<U,iNR,iNC,MM,L>& item
) 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 (
const matrix<U,iNR,iNC,MM>& item
const matrix<U,iNR,iNC,MM,L>& item
) const { return false; }
const ref_type& ref(
......@@ -1524,14 +1537,14 @@ convergence:
long 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 (
const matrix<U,iNR,iNC,MM>& item
const matrix<U,iNR,iNC,MM,L>& item
) 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 (
const matrix<U,iNR,iNC,MM>& item
const matrix<U,iNR,iNC,MM,L>& item
) const { return false; }
const ref_type& ref(
......@@ -1586,14 +1599,14 @@ convergence:
long 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 (
const matrix<U,iNR,iNC,MM>& item
const matrix<U,iNR,iNC,MM,L>& 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 (
const matrix<U,iNR,iNC,MM>& item
const matrix<U,iNR,iNC,MM,L>& item
) const { return m.aliases(item); }
const ref_type& ref(
......@@ -1649,14 +1662,14 @@ convergence:
long 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 (
const matrix<U,iNR,iNC,MM>& item
const matrix<U,iNR,iNC,MM,L>& 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 (
const matrix<U,iNR,iNC,MM>& item
const matrix<U,iNR,iNC,MM,L>& item
) const { return OP::destructively_aliases(m,item); }
const ref_type& ref(
......@@ -1714,14 +1727,14 @@ convergence:
long 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 (
const matrix<U,iNR,iNC,MM>& item
const matrix<U,iNR,iNC,MM,L>& 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 (
const matrix<U,iNR,iNC,MM>& item
const matrix<U,iNR,iNC,MM,L>& item
) const { return OP::destructively_aliases(m,item); }
const ref_type& ref(
......@@ -1776,14 +1789,14 @@ convergence:
long 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 (
const matrix<U,iNR,iNC,MM>& item
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 >
template <typename U, long iNR, long iNC, typename MM, typename L >
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 ref_type& ref(
......@@ -1839,14 +1852,14 @@ convergence:
long c
) 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 (
const matrix<U,iNR,iNC,MM>& item
const matrix<U,iNR,iNC,MM,L>& item
) 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 (
const matrix<U,iNR,iNC,MM>& item
const matrix<U,iNR,iNC,MM,L>& item
) const { return false; }
long nr (
......@@ -1881,14 +1894,14 @@ convergence:
long c
) 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 (
const matrix<U,iNR,iNC,MM>& item
const matrix<U,iNR,iNC,MM,L>& item
) 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 (
const matrix<U,iNR,iNC,MM>& item
const matrix<U,iNR,iNC,MM,L>& item
) const { return false; }
long nr (
......@@ -2134,14 +2147,14 @@ convergence:
long 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 (
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); }
template <typename U, long iNR, long iNC , typename MM>
template <typename U, long iNR, long iNC , typename MM, typename L>
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 ref_type& ref(
......@@ -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
{
public:
assignable_sub_matrix(
matrix<T,NR,NC,mm>& m_,
matrix<T,NR,NC,mm,l>& m_,
const rectangle& rect_
) : m(m_), rect(rect_) {}
......@@ -2336,14 +2349,14 @@ convergence:
private:
matrix<T,NR,NC,mm>& m;
matrix<T,NR,NC,mm,l>& m;
const rectangle rect;
};
template <typename T, long NR, long NC, typename mm>
assignable_sub_matrix<T,NR,NC,mm> set_subm (
matrix<T,NR,NC,mm>& m,
template <typename T, long NR, long NC, typename mm, typename l>
assignable_sub_matrix<T,NR,NC,mm,l> set_subm (
matrix<T,NR,NC,mm,l>& m,
const rectangle& rect
)
{
......@@ -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>
assignable_sub_matrix<T,NR,NC,mm> set_subm (
matrix<T,NR,NC,mm>& m,
template <typename T, long NR, long NC, typename mm, typename l>
assignable_sub_matrix<T,NR,NC,mm,l> set_subm (
matrix<T,NR,NC,mm,l>& m,
long r,
long c,
long nr,
......@@ -2383,17 +2396,17 @@ convergence:
<< "\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
{
public:
assignable_sub_range_matrix(
matrix<T,NR,NC,mm>& m_,
matrix<T,NR,NC,mm,l>& m_,
const EXPr& rows_,
const EXPc& cols_
) : m(m_), rows(rows_), cols(cols_) {}
......@@ -2449,14 +2462,14 @@ convergence:
private:
matrix<T,NR,NC,mm>& m;
matrix<T,NR,NC,mm,l>& m;
const EXPr rows;
const EXPc cols;
};
template <typename T, long NR, long NC, typename mm, typename EXPr, typename EXPc>
assignable_sub_range_matrix<T,NR,NC,mm,matrix_exp<EXPr>,matrix_exp<EXPc> > set_subm (
matrix<T,NR,NC,mm>& m,
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 (
matrix<T,NR,NC,mm,l>& m,
const matrix_exp<EXPr>& rows,
const matrix_exp<EXPc>& cols
)
......@@ -2477,17 +2490,17 @@ convergence:
<< "\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
{
public:
assignable_col_matrix(
matrix<T,NR,NC,mm>& m_,
matrix<T,NR,NC,mm,l>& m_,
const long col_
) : m(m_), col(col_) {}
......@@ -2532,14 +2545,14 @@ convergence:
private:
matrix<T,NR,NC,mm>& m;
matrix<T,NR,NC,mm,l>& m;
const long col;
};
template <typename T, long NR, long NC, typename mm>
assignable_col_matrix<T,NR,NC,mm> set_colm (
matrix<T,NR,NC,mm>& m,
template <typename T, long NR, long NC, typename mm, typename l>
assignable_col_matrix<T,NR,NC,mm,l> set_colm (
matrix<T,NR,NC,mm,l>& m,
const long col
)
{
......@@ -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
{
public:
assignable_row_matrix(
matrix<T,NR,NC,mm>& m_,
matrix<T,NR,NC,mm,l>& m_,
const long row_
) : m(m_), row(row_) {}
......@@ -2608,14 +2621,14 @@ convergence:
private:
matrix<T,NR,NC,mm>& m;
matrix<T,NR,NC,mm,l>& m;
const long row;
};
template <typename T, long NR, long NC, typename mm>
assignable_row_matrix<T,NR,NC,mm> set_rowm (
matrix<T,NR,NC,mm>& m,
template <typename T, long NR, long NC, typename mm, typename l>
assignable_row_matrix<T,NR,NC,mm,l> set_rowm (
matrix<T,NR,NC,mm,l>& m,
const long row
)
{
......@@ -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:
long NR,
long NC,
typename MM,
typename U
typename U,
typename L
>
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
)
{
......@@ -3128,10 +3142,11 @@ convergence:
long NR,
long NC,
typename MM,
typename U
typename U,
typename L
>
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
)
{
......@@ -3155,13 +3170,16 @@ convergence:
long wX,
typename MM1,
typename MM2,
typename MM3
typename MM3,
typename L1,
typename L2,
typename L3
>
inline void svd3 (
const matrix_exp<EXP>& m,
matrix<typename matrix_exp<EXP>::type, uNR, uNC,MM1>& u,
matrix<typename matrix_exp<EXP>::type, wN, wX,MM2>& w,
matrix<typename matrix_exp<EXP>::type, vN, vN,MM3>& v
matrix<typename matrix_exp<EXP>::type, uNR, uNC,MM1,L1>& u,
matrix<typename matrix_exp<EXP>::type, wN, wX,MM2,L2>& w,
matrix<typename matrix_exp<EXP>::type, vN, vN,MM3,L3>& v
)
{
typedef typename matrix_exp<EXP>::type T;
......@@ -3195,13 +3213,16 @@ convergence:
long vN,
typename MM1,
typename MM2,
typename MM3
typename MM3,
typename L1,
typename L2,
typename L3
>
inline void svd (
const matrix_exp<EXP>& m,
matrix<typename matrix_exp<EXP>::type, uNR, uNC,MM1>& u,
matrix<typename matrix_exp<EXP>::type, wN, wN,MM2>& w,
matrix<typename matrix_exp<EXP>::type, vN, vN,MM3>& v
matrix<typename matrix_exp<EXP>::type, uNR, uNC,MM1,L1>& u,
matrix<typename matrix_exp<EXP>::type, wN, wN,MM2,L2>& w,
matrix<typename matrix_exp<EXP>::type, vN, vN,MM3,L3>& v
)
{
typedef typename matrix_exp<EXP>::type T;
......@@ -4538,12 +4559,12 @@ convergence:
};
template <
typename T, long NR, long NC, typename mm,
long NR2, long NC2, typename mm2
typename T, long NR, long NC, typename mm, typename l1,
long NR2, long NC2, typename mm2, typename l2
>
void sort_columns (
matrix<T,NR,NC,mm>& m,
matrix<T,NR2,NC2,mm2>& v
matrix<T,NR,NC,mm,l1>& m,
matrix<T,NR2,NC2,mm2,l2>& v
)
{
COMPILE_TIME_ASSERT(NC2 == 1 || NC2 == 0);
......@@ -4585,12 +4606,12 @@ convergence:
// ----------------------------------------------------------------------------------------
template <
typename T, long NR, long NC, typename mm,
long NR2, long NC2, typename mm2
typename T, long NR, long NC, typename mm, typename l1,
long NR2, long NC2, typename mm2, typename l2
>
void rsort_columns (
matrix<T,NR,NC,mm>& m,
matrix<T,NR2,NC2,mm2>& v
matrix<T,NR,NC,mm,l1>& m,
matrix<T,NR2,NC2,mm2,l2>& v
)
{
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