Commit 533b5beb authored by Davis King's avatar Davis King

Moved the matrix subexpression stuff into its own file.

--HG--
extra : convert_revision : svn%3Afdd8eb12-d10e-0410-9acb-85c331704f74/trunk%402750
parent 9d42e9fa
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#include "matrix/matrix.h" #include "matrix/matrix.h"
#include "matrix/matrix_utilities.h" #include "matrix/matrix_utilities.h"
#include "matrix/matrix_subexp.h"
#include "matrix/matrix_math_functions.h" #include "matrix/matrix_math_functions.h"
#include "matrix/matrix_assign.h" #include "matrix/matrix_assign.h"
......
...@@ -19,6 +19,188 @@ ...@@ -19,6 +19,188 @@
namespace dlib namespace dlib
{ {
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
// Helper templates for making operators used by expression objects
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
/*
templates for finding the max of two matrix expressions' dimensions
*/
template <typename EXP1, typename EXP2 = void, typename EXP3 = void, typename EXP4 = void>
struct max_nr;
template <typename EXP1>
struct max_nr<EXP1,void,void,void>
{
const static long val = EXP1::NR;
};
template <typename EXP1, typename EXP2>
struct max_nr<EXP1,EXP2,void,void>
{
const static long val = (EXP1::NR > EXP2::NR) ? (EXP1::NR) : (EXP2::NR);
};
template <typename EXP1, typename EXP2, typename EXP3>
struct max_nr<EXP1,EXP2,EXP3,void>
{
private:
const static long max12 = (EXP1::NR > EXP2::NR) ? (EXP1::NR) : (EXP2::NR);
public:
const static long val = (max12 > EXP3::NR) ? (max12) : (EXP3::NR);
};
template <typename EXP1, typename EXP2, typename EXP3, typename EXP4>
struct max_nr
{
private:
const static long max12 = (EXP1::NR > EXP2::NR) ? (EXP1::NR) : (EXP2::NR);
const static long max34 = (EXP3::NR > EXP4::NR) ? (EXP3::NR) : (EXP4::NR);
public:
const static long val = (max12 > max34) ? (max12) : (max34);
};
template <typename EXP1, typename EXP2 = void, typename EXP3 = void, typename EXP4 = void>
struct max_nc;
template <typename EXP1>
struct max_nc<EXP1,void,void,void>
{
const static long val = EXP1::NC;
};
template <typename EXP1, typename EXP2>
struct max_nc<EXP1,EXP2,void,void>
{
const static long val = (EXP1::NC > EXP2::NC) ? (EXP1::NC) : (EXP2::NC);
};
template <typename EXP1, typename EXP2, typename EXP3>
struct max_nc<EXP1,EXP2,EXP3,void>
{
private:
const static long max12 = (EXP1::NC > EXP2::NC) ? (EXP1::NC) : (EXP2::NC);
public:
const static long val = (max12 > EXP3::NC) ? (max12) : (EXP3::NC);
};
template <typename EXP1, typename EXP2, typename EXP3, typename EXP4>
struct max_nc
{
private:
const static long max12 = (EXP1::NC > EXP2::NC) ? (EXP1::NC) : (EXP2::NC);
const static long max34 = (EXP3::NC > EXP4::NC) ? (EXP3::NC) : (EXP4::NC);
public:
const static long val = (max12 > max34) ? (max12) : (max34);
};
// ----------------------------------------------------------------------------------------
struct has_destructive_aliasing
{
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,L>& item
) { return m.aliases(item); }
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,L>& item
) { return m1.aliases(item) || m2.aliases(item) ; }
template <typename M1, typename M2, typename M3, typename U, long iNR, long iNC, typename MM, typename L >
static bool destructively_aliases (
const M1& m1,
const M2& m2,
const M3& m3,
const matrix<U,iNR,iNC,MM,L>& item
) { return m1.aliases(item) || m2.aliases(item) || m3.aliases(item); }
template <typename M1, typename M2, typename M3, typename M4, typename U, long iNR, long iNC, typename MM, typename L >
static bool destructively_aliases (
const M1& m1,
const M2& m2,
const M3& m3,
const M4& m4,
const matrix<U,iNR,iNC,MM,L>& item
) { return m1.aliases(item) || m2.aliases(item) || m3.aliases(item) || m4.aliases(item); }
};
// ----------------------------------------------------------------------------------------
struct has_nondestructive_aliasing
{
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,L>& item
) { return m.destructively_aliases(item); }
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, L>& item
) { return m1.destructively_aliases(item) || m2.destructively_aliases(item) ; }
template <typename M1, typename M2, typename M3, typename U, long iNR, long iNC, typename MM, typename L >
static bool destructively_aliases (
const M1& m1,
const M2& m2,
const M3& m3,
const matrix<U,iNR,iNC, MM, L>& item
) { return m1.destructively_aliases(item) || m2.destructively_aliases(item) || m3.destructively_aliases(item) ; }
template <typename M1, typename M2, typename M3, typename M4, typename U, long iNR, long iNC, typename MM, typename L >
static bool destructively_aliases (
const M1& m1,
const M2& m2,
const M3& m3,
const M4& m4,
const matrix<U,iNR,iNC, MM, L>& item
) { return m1.destructively_aliases(item) ||
m2.destructively_aliases(item) ||
m3.destructively_aliases(item) ||
m4.destructively_aliases(item) ; }
};
// ----------------------------------------------------------------------------------------
template <typename EXP1, typename EXP2 = void, typename EXP3 = void, typename EXP4 = void>
struct preserves_dimensions
{
const static long NR = max_nr<EXP1,EXP2,EXP3,EXP4>::val;
const static long NC = max_nc<EXP1,EXP2,EXP3,EXP4>::val;
typedef typename EXP1::mem_manager_type mem_manager_type;
template <typename M>
static long nr (const M& m) { return m.nr(); }
template <typename M>
static long nc (const M& m) { return m.nc(); }
template <typename M1, typename M2>
static long nr (const M1& m1, const M2& ) { return m1.nr(); }
template <typename M1, typename M2>
static long nc (const M1& m1, const M2& ) { return m1.nc(); }
template <typename M1, typename M2, typename M3>
static long nr (const M1& m1, const M2&, const M3& ) { return m1.nr(); }
template <typename M1, typename M2, typename M3>
static long nc (const M1& m1, const M2&, const M3& ) { return m1.nc(); }
template <typename M1, typename M2, typename M3, typename M4>
static long nr (const M1& m1, const M2&, const M3&, const M4& ) { return m1.nr(); }
template <typename M1, typename M2, typename M3, typename M4>
static long nc (const M1& m1, const M2&, const M3&, const M4& ) { return m1.nc(); }
};
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
// General matrix expressions that take operator structs // General matrix expressions that take operator structs
......
// Copyright (C) 2006 Davis E. King (davisking@users.sourceforge.net)
// License: Boost Software License See LICENSE.txt for the full license.
#ifndef DLIB_MATRIx_SUBEXP_
#define DLIB_MATRIx_SUBEXP_
#include "matrix_subexp_abstract.h"
#include "matrix.h"
#include "../geometry/rectangle.h"
#include "matrix_expressions.h"
namespace dlib
{
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
template <long start, long inc, long end>
const matrix_range_static_exp<start,inc,end> range (
)
{
COMPILE_TIME_ASSERT(inc > 0);
return matrix_range_static_exp<start,inc,end>();
}
template <long start, long end>
const matrix_range_static_exp<start,1,end> range (
)
{
return matrix_range_static_exp<start,1,end>();
}
inline const matrix_range_exp range (
long start,
long end
)
{
return matrix_range_exp(start,end);
}
inline const matrix_range_exp range (
long start,
long inc,
long end
)
{
DLIB_ASSERT(inc > 0,
"\tconst matrix_exp range(start, inc, end)"
<< "\n\tstart can't be bigger than end"
<< "\n\tstart: " << start
<< "\n\tinc: " << inc
<< "\n\tend: " << end
);
return matrix_range_exp(start,inc,end);
}
// ----------------------------------------------------------------------------------------
template <
typename EXP
>
const rectangle get_rect (
const matrix_exp<EXP>& m
)
{
return rectangle(0, 0, m.nc()-1, m.nr()-1);
}
// ----------------------------------------------------------------------------------------
template <
typename EXP
>
const matrix_sub_exp<EXP> subm (
const matrix_exp<EXP>& m,
long r,
long c,
long nr,
long nc
)
{
DLIB_ASSERT(r >= 0 && c >= 0 && r+nr <= m.nr() && c+nc <= m.nc(),
"\tconst matrix_exp subm(const matrix_exp& m, r, c, nr, nc)"
<< "\n\tYou have specified invalid sub matrix dimensions"
<< "\n\tm.nr(): " << m.nr()
<< "\n\tm.nc(): " << m.nc()
<< "\n\tr: " << r
<< "\n\tc: " << c
<< "\n\tnr: " << nr
<< "\n\tnc: " << nc
);
typedef matrix_sub_exp<EXP> exp;
return exp(m.ref(),r,c,nr,nc);
}
// ----------------------------------------------------------------------------------------
template <
typename EXP
>
const matrix_sub_exp<EXP> subm (
const matrix_exp<EXP>& m,
const rectangle& rect
)
{
DLIB_ASSERT(get_rect(m).contains(rect) == true,
"\tconst matrix_exp subm(const matrix_exp& m, const rectangle& rect)"
<< "\n\tYou have specified invalid sub matrix dimensions"
<< "\n\tm.nr(): " << m.nr()
<< "\n\tm.nc(): " << m.nc()
<< "\n\trect.left(): " << rect.left()
<< "\n\trect.top(): " << rect.top()
<< "\n\trect.right(): " << rect.right()
<< "\n\trect.bottom(): " << rect.bottom()
);
typedef matrix_sub_exp<EXP> exp;
return exp(m.ref(),rect.top(),rect.left(),rect.height(),rect.width());
}
// ----------------------------------------------------------------------------------------
template <
typename EXP,
typename EXPr,
typename EXPc
>
const matrix_sub_range_exp<EXP,EXPr,EXPc> subm (
const matrix_exp<EXP>& m,
const matrix_exp<EXPr>& rows,
const matrix_exp<EXPc>& cols
)
{
// the rows and cols matrices must contain elements of type long
COMPILE_TIME_ASSERT((is_same_type<typename EXPr::type,long>::value == true));
COMPILE_TIME_ASSERT((is_same_type<typename EXPc::type,long>::value == true));
DLIB_ASSERT(0 <= min(rows) && max(rows) < m.nr() && 0 <= min(cols) && max(cols) < m.nc() &&
(rows.nr() == 1 || rows.nc() == 1) && (cols.nr() == 1 || cols.nc() == 1),
"\tconst matrix_exp subm(const matrix_exp& m, const matrix_exp& rows, const matrix_exp& cols)"
<< "\n\tYou have given invalid arguments to this function"
<< "\n\tm.nr(): " << m.nr()
<< "\n\tm.nc(): " << m.nc()
<< "\n\tmin(rows): " << min(rows)
<< "\n\tmax(rows): " << max(rows)
<< "\n\tmin(cols): " << min(cols)
<< "\n\tmax(cols): " << max(cols)
<< "\n\trows.nr(): " << rows.nr()
<< "\n\trows.nc(): " << rows.nc()
<< "\n\tcols.nr(): " << cols.nr()
<< "\n\tcols.nc(): " << cols.nc()
);
typedef matrix_sub_range_exp<EXP,EXPr,EXPc> exp;
return exp(m.ref(),rows.ref(),cols.ref());
}
// ----------------------------------------------------------------------------------------
struct op_rowm
{
template <typename EXP>
struct op : has_destructive_aliasing
{
const static long cost = EXP::cost;
const static long NR = 1;
const static long NC = EXP::NC;
typedef typename EXP::type type;
typedef typename EXP::mem_manager_type mem_manager_type;
template <typename M>
static type apply ( const M& m, long row, long, long c)
{ return m(row,c); }
template <typename M>
static long nr (const M& m) { return 1; }
template <typename M>
static long nc (const M& m) { return m.nc(); }
};
};
template <
typename EXP
>
const matrix_scalar_binary_exp<EXP,long,op_rowm> rowm (
const matrix_exp<EXP>& m,
long row
)
{
DLIB_ASSERT(row >= 0 && row < m.nr(),
"\tconst matrix_exp rowm(const matrix_exp& m, row)"
<< "\n\tYou have specified invalid sub matrix dimensions"
<< "\n\tm.nr(): " << m.nr()
<< "\n\tm.nc(): " << m.nc()
<< "\n\trow: " << row
);
typedef matrix_scalar_binary_exp<EXP,long,op_rowm> exp;
return exp(m.ref(),row);
}
// ----------------------------------------------------------------------------------------
struct op_rowm_range
{
template <typename EXP1, typename EXP2>
struct op : has_destructive_aliasing
{
const static long cost = EXP1::cost+EXP2::cost;
typedef typename EXP1::type type;
typedef typename EXP1::mem_manager_type mem_manager_type;
const static long NR = EXP2::NC*EXP2::NR;
const static long NC = EXP1::NC;
template <typename M1, typename M2>
static type apply ( const M1& m1, const M2& rows , long r, long c)
{ return m1(rows(r),c); }
template <typename M1, typename M2>
static long nr (const M1& m1, const M2& rows ) { return rows.size(); }
template <typename M1, typename M2>
static long nc (const M1& m1, const M2& ) { return m1.nc(); }
};
};
template <
typename EXP1,
typename EXP2
>
const matrix_binary_exp<EXP1,EXP2,op_rowm_range> rowm (
const matrix_exp<EXP1>& m,
const matrix_exp<EXP2>& rows
)
{
// the rows matrix must contain elements of type long
COMPILE_TIME_ASSERT((is_same_type<typename EXP2::type,long>::value == true));
DLIB_ASSERT(0 <= min(rows) && max(rows) < m.nr() && (rows.nr() == 1 || rows.nc() == 1),
"\tconst matrix_exp rowm(const matrix_exp& m, const matrix_exp& rows)"
<< "\n\tYou have given invalid arguments to this function"
<< "\n\tm.nr(): " << m.nr()
<< "\n\tm.nc(): " << m.nc()
<< "\n\tmin(rows): " << min(rows)
<< "\n\tmax(rows): " << max(rows)
<< "\n\trows.nr(): " << rows.nr()
<< "\n\trows.nc(): " << rows.nc()
);
typedef matrix_binary_exp<EXP1,EXP2,op_rowm_range> exp;
return exp(m.ref(),rows.ref());
}
// ----------------------------------------------------------------------------------------
struct op_colm
{
template <typename EXP>
struct op : has_destructive_aliasing
{
const static long cost = EXP::cost;
const static long NR = EXP::NR;
const static long NC = 1;
typedef typename EXP::type type;
typedef typename EXP::mem_manager_type mem_manager_type;
template <typename M>
static type apply ( const M& m, long col, long r, long)
{ return m(r,col); }
template <typename M>
static long nr (const M& m) { return m.nr(); }
template <typename M>
static long nc (const M& m) { return 1; }
};
};
template <
typename EXP
>
const matrix_scalar_binary_exp<EXP,long,op_colm> colm (
const matrix_exp<EXP>& m,
long col
)
{
DLIB_ASSERT(col >= 0 && col < m.nc(),
"\tconst matrix_exp colm(const matrix_exp& m, row)"
<< "\n\tYou have specified invalid sub matrix dimensions"
<< "\n\tm.nr(): " << m.nr()
<< "\n\tm.nc(): " << m.nc()
<< "\n\tcol: " << col
);
typedef matrix_scalar_binary_exp<EXP,long,op_colm> exp;
return exp(m.ref(),col);
}
// ----------------------------------------------------------------------------------------
struct op_colm_range
{
template <typename EXP1, typename EXP2>
struct op : has_destructive_aliasing
{
typedef typename EXP1::type type;
typedef typename EXP1::mem_manager_type mem_manager_type;
const static long NR = EXP1::NR;
const static long NC = EXP2::NC*EXP2::NR;
const static long cost = EXP1::cost+EXP2::cost;
template <typename M1, typename M2>
static type apply ( const M1& m1, const M2& cols , long r, long c)
{ return m1(r,cols(c)); }
template <typename M1, typename M2>
static long nr (const M1& m1, const M2& cols ) { return m1.nr(); }
template <typename M1, typename M2>
static long nc (const M1& m1, const M2& cols ) { return cols.size(); }
};
};
template <
typename EXP1,
typename EXP2
>
const matrix_binary_exp<EXP1,EXP2,op_colm_range> colm (
const matrix_exp<EXP1>& m,
const matrix_exp<EXP2>& cols
)
{
// the cols matrix must contain elements of type long
COMPILE_TIME_ASSERT((is_same_type<typename EXP2::type,long>::value == true));
DLIB_ASSERT(0 <= min(cols) && max(cols) < m.nc() && (cols.nr() == 1 || cols.nc() == 1),
"\tconst matrix_exp colm(const matrix_exp& m, const matrix_exp& cols)"
<< "\n\tYou have given invalid arguments to this function"
<< "\n\tm.nr(): " << m.nr()
<< "\n\tm.nc(): " << m.nc()
<< "\n\tmin(cols): " << min(cols)
<< "\n\tmax(cols): " << max(cols)
<< "\n\tcols.nr(): " << cols.nr()
<< "\n\tcols.nc(): " << cols.nc()
);
typedef matrix_binary_exp<EXP1,EXP2,op_colm_range> exp;
return exp(m.ref(),cols.ref());
}
// ----------------------------------------------------------------------------------------
template <typename T, long NR, long NC, typename mm, typename l>
class assignable_sub_matrix
{
public:
assignable_sub_matrix(
matrix<T,NR,NC,mm,l>& m_,
const rectangle& rect_
) : m(m_), rect(rect_) {}
T& operator() (
long r,
long c
)
{
return m(r+rect.top(),c+rect.left());
}
long nr() const { return rect.height(); }
long nc() const { return rect.width(); }
template <typename EXP>
assignable_sub_matrix& operator= (
const matrix_exp<EXP>& exp
)
{
DLIB_ASSERT( exp.nr() == (long)rect.height() && exp.nc() == (long)rect.width(),
"\tassignable_matrix_expression set_subm()"
<< "\n\tYou have tried to assign to this object using a matrix that isn't the right size"
<< "\n\texp.nr() (source matrix): " << exp.nr()
<< "\n\texp.nc() (source matrix): " << exp.nc()
<< "\n\trect.width() (target matrix): " << rect.width()
<< "\n\trect.height() (target matrix): " << rect.height()
);
if (exp.destructively_aliases(m) == false)
{
matrix_assign(*this, exp);
}
else
{
// make a temporary copy of the matrix we are going to assign to m to
// avoid aliasing issues during the copy
this->operator=(tmp(exp));
}
return *this;
}
assignable_sub_matrix& operator= (
const T& value
)
{
for (long r = rect.top(); r <= rect.bottom(); ++r)
{
for (long c = rect.left(); c <= rect.right(); ++c)
{
m(r,c) = value;
}
}
return *this;
}
private:
matrix<T,NR,NC,mm,l>& m;
const rectangle rect;
};
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
)
{
DLIB_ASSERT(get_rect(m).contains(rect) == true,
"\tassignable_matrix_expression set_subm(matrix& m, const rectangle& rect)"
<< "\n\tYou have specified invalid sub matrix dimensions"
<< "\n\tm.nr(): " << m.nr()
<< "\n\tm.nc(): " << m.nc()
<< "\n\trect.left(): " << rect.left()
<< "\n\trect.top(): " << rect.top()
<< "\n\trect.right(): " << rect.right()
<< "\n\trect.bottom(): " << rect.bottom()
);
return assignable_sub_matrix<T,NR,NC,mm,l>(m,rect);
}
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,
long nc
)
{
DLIB_ASSERT(r >= 0 && c >= 0 && r+nr <= m.nr() && c+nc <= m.nc(),
"\tassignable_matrix_expression set_subm(matrix& m, r, c, nr, nc)"
<< "\n\tYou have specified invalid sub matrix dimensions"
<< "\n\tm.nr(): " << m.nr()
<< "\n\tm.nc(): " << m.nc()
<< "\n\tr: " << r
<< "\n\tc: " << c
<< "\n\tnr: " << nr
<< "\n\tnc: " << nc
);
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 l, typename EXPr, typename EXPc>
class assignable_sub_range_matrix
{
public:
assignable_sub_range_matrix(
matrix<T,NR,NC,mm,l>& m_,
const EXPr& rows_,
const EXPc& cols_
) : m(m_), rows(rows_), cols(cols_) {}
T& operator() (
long r,
long c
)
{
return m(rows(r),cols(c));
}
long nr() const { return rows.size(); }
long nc() const { return cols.size(); }
template <typename EXP>
assignable_sub_range_matrix& operator= (
const matrix_exp<EXP>& exp
)
{
DLIB_ASSERT( exp.nr() == rows.size() && exp.nc() == cols.size(),
"\tassignable_matrix_expression set_subm(matrix& m, const matrix_exp rows, const matrix_exp cols)"
<< "\n\tYou have tried to assign to this object using a matrix that isn't the right size"
<< "\n\texp.nr() (source matrix): " << exp.nr()
<< "\n\texp.nc() (source matrix): " << exp.nc()
<< "\n\trows.size() (target matrix): " << rows.size()
<< "\n\tcols.size() (target matrix): " << cols.size()
);
if (exp.destructively_aliases(m) == false)
{
matrix_assign(*this, exp);
}
else
{
// make a temporary copy of the matrix we are going to assign to m to
// avoid aliasing issues during the copy
this->operator=(tmp(exp));
}
return *this;
}
assignable_sub_range_matrix& operator= (
const T& value
)
{
for (long r = 0; r < rows.size(); ++r)
{
for (long c = 0; c < cols.size(); ++c)
{
m(rows(r),cols(c)) = value;
}
}
return *this;
}
private:
matrix<T,NR,NC,mm,l>& m;
const EXPr rows;
const EXPc cols;
};
template <typename T, long NR, long NC, typename mm, typename l, typename EXPr, typename EXPc>
assignable_sub_range_matrix<T,NR,NC,mm,l,EXPr,EXPc > set_subm (
matrix<T,NR,NC,mm,l>& m,
const matrix_exp<EXPr>& rows,
const matrix_exp<EXPc>& cols
)
{
DLIB_ASSERT(0 <= min(rows) && max(rows) < m.nr() && 0 <= min(cols) && max(cols) < m.nc() &&
(rows.nr() == 1 || rows.nc() == 1) && (cols.nr() == 1 || cols.nc() == 1),
"\tassignable_matrix_expression set_subm(matrix& m, const matrix_exp& rows, const matrix_exp& cols)"
<< "\n\tYou have specified invalid sub matrix dimensions"
<< "\n\tm.nr(): " << m.nr()
<< "\n\tm.nc(): " << m.nc()
<< "\n\tmin(rows): " << min(rows)
<< "\n\tmax(rows): " << max(rows)
<< "\n\tmin(cols): " << min(cols)
<< "\n\tmax(cols): " << max(cols)
<< "\n\trows.nr(): " << rows.nr()
<< "\n\trows.nc(): " << rows.nc()
<< "\n\tcols.nr(): " << cols.nr()
<< "\n\tcols.nc(): " << cols.nc()
);
return assignable_sub_range_matrix<T,NR,NC,mm,l,EXPr,EXPc >(m,rows.ref(),cols.ref());
}
// ----------------------------------------------------------------------------------------
template <typename T, long NR, long NC, typename mm, typename l, typename EXPr>
assignable_sub_range_matrix<T,NR,NC,mm,l,EXPr,matrix_range_exp > set_rowm (
matrix<T,NR,NC,mm,l>& m,
const matrix_exp<EXPr>& rows
)
{
DLIB_ASSERT(0 <= min(rows) && max(rows) < m.nr() && (rows.nr() == 1 || rows.nc() == 1),
"\tassignable_matrix_expression set_rowm(matrix& m, const matrix_exp& rows)"
<< "\n\tYou have specified invalid sub matrix dimensions"
<< "\n\tm.nr(): " << m.nr()
<< "\n\tm.nc(): " << m.nc()
<< "\n\tmin(rows): " << min(rows)
<< "\n\tmax(rows): " << max(rows)
<< "\n\trows.nr(): " << rows.nr()
<< "\n\trows.nc(): " << rows.nc()
);
return assignable_sub_range_matrix<T,NR,NC,mm,l,EXPr,matrix_range_exp >(m,rows.ref(),range(0,m.nc()-1));
}
// ----------------------------------------------------------------------------------------
template <typename T, long NR, long NC, typename mm, typename l, typename EXPc>
assignable_sub_range_matrix<T,NR,NC,mm,l,matrix_range_exp,EXPc > set_colm (
matrix<T,NR,NC,mm,l>& m,
const matrix_exp<EXPc>& cols
)
{
DLIB_ASSERT(0 <= min(cols) && max(cols) < m.nc() && (cols.nr() == 1 || cols.nc() == 1),
"\tassignable_matrix_expression set_colm(matrix& m, const matrix_exp& cols)"
<< "\n\tYou have specified invalid sub matrix dimensions"
<< "\n\tm.nr(): " << m.nr()
<< "\n\tm.nc(): " << m.nc()
<< "\n\tmin(cols): " << min(cols)
<< "\n\tmax(cols): " << max(cols)
<< "\n\tcols.nr(): " << cols.nr()
<< "\n\tcols.nc(): " << cols.nc()
);
return assignable_sub_range_matrix<T,NR,NC,mm,l,matrix_range_exp,EXPc >(m,range(0,m.nr()-1),cols.ref());
}
// ----------------------------------------------------------------------------------------
template <typename T, long NR, long NC, typename mm, typename l>
class assignable_col_matrix
{
public:
assignable_col_matrix(
matrix<T,NR,NC,mm,l>& m_,
const long col_
) : m(m_), col(col_) {}
T& operator() (
long r,
long c
)
{
return m(r,col);
}
long nr() const { return m.nr(); }
long nc() const { return 1; }
template <typename EXP>
assignable_col_matrix& operator= (
const matrix_exp<EXP>& exp
)
{
DLIB_ASSERT( exp.nc() == 1 && exp.nr() == m.nr(),
"\tassignable_matrix_expression set_colm()"
<< "\n\tYou have tried to assign to this object using a matrix that isn't the right size"
<< "\n\texp.nr() (source matrix): " << exp.nr()
<< "\n\texp.nc() (source matrix): " << exp.nc()
<< "\n\tm.nr() (target matrix): " << m.nr()
);
if (exp.destructively_aliases(m) == false)
{
matrix_assign(*this, exp);
}
else
{
// make a temporary copy of the matrix we are going to assign to m to
// avoid aliasing issues during the copy
this->operator=(tmp(exp));
}
return *this;
}
assignable_col_matrix& operator= (
const T& value
)
{
for (long i = 0; i < m.nr(); ++i)
{
m(i,col) = value;
}
return *this;
}
private:
matrix<T,NR,NC,mm,l>& m;
const long col;
};
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
)
{
DLIB_ASSERT(col >= 0 && col < m.nc(),
"\tassignable_matrix_expression set_colm(matrix& m, col)"
<< "\n\tYou have specified invalid sub matrix dimensions"
<< "\n\tm.nr(): " << m.nr()
<< "\n\tm.nc(): " << m.nc()
<< "\n\tcol: " << col
);
return assignable_col_matrix<T,NR,NC,mm,l>(m,col);
}
// ----------------------------------------------------------------------------------------
template <typename T, long NR, long NC, typename mm, typename l>
class assignable_row_matrix
{
public:
assignable_row_matrix(
matrix<T,NR,NC,mm,l>& m_,
const long row_
) : m(m_), row(row_) {}
T& operator() (
long r,
long c
)
{
return m(row,c);
}
long nr() const { return 1; }
long nc() const { return m.nc(); }
template <typename EXP>
assignable_row_matrix& operator= (
const matrix_exp<EXP>& exp
)
{
DLIB_ASSERT( exp.nr() == 1 && exp.nc() == m.nc(),
"\tassignable_matrix_expression set_rowm()"
<< "\n\tYou have tried to assign to this object using a matrix that isn't the right size"
<< "\n\texp.nr() (source matrix): " << exp.nr()
<< "\n\texp.nc() (source matrix): " << exp.nc()
<< "\n\tm.nc() (target matrix): " << m.nc()
);
if (exp.destructively_aliases(m) == false)
{
matrix_assign(*this, exp);
}
else
{
// make a temporary copy of the matrix we are going to assign to m to
// avoid aliasing issues during the copy
this->operator=(tmp(exp));
}
return *this;
}
assignable_row_matrix& operator= (
const T& value
)
{
for (long i = 0; i < m.nc(); ++i)
{
m(row,i) = value;
}
return *this;
}
private:
matrix<T,NR,NC,mm,l>& m;
const long row;
};
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
)
{
DLIB_ASSERT(row >= 0 && row < m.nr(),
"\tassignable_matrix_expression set_rowm(matrix& m, row)"
<< "\n\tYou have specified invalid sub matrix dimensions"
<< "\n\tm.nr(): " << m.nr()
<< "\n\tm.nc(): " << m.nc()
<< "\n\trow: " << row
);
return assignable_row_matrix<T,NR,NC,mm,l>(m,row);
}
// ----------------------------------------------------------------------------------------
}
#endif // DLIB_MATRIx_SUBEXP_
// Copyright (C) 2006 Davis E. King (davisking@users.sourceforge.net)
// License: Boost Software License See LICENSE.txt for the full license.
#undef DLIB_MATRIx_SUBEXP_ABSTRACT_
#ifdef DLIB_MATRIx_SUBEXP_ABSTRACT_
#include "matrix_abstract.h"
#include "../geometry.h"
namespace dlib
{
// ----------------------------------------------------------------------------------------
const rectangle get_rect (
const matrix_exp& m
);
/*!
ensures
- returns rectangle(0, 0, m.nc()-1, m.nr()-1)
(i.e. returns a rectangle that has the same dimensions as
the matrix m)
!*/
// ----------------------------------------------------------------------------------------
template <long start, long inc, long end>
const matrix_exp range (
);
/*!
requires
- inc > 0
ensures
- returns a matrix R such that:
- R::type == long
- R.nr() == abs(end - start)/inc + 1
- R.nc() == 1
- if (start <= end) then
- R(i) == start + i*inc
- else
- R(i) == start - i*inc
!*/
template <long start, long end>
const matrix_exp range (
) { return range<start,1,end>(); }
const matrix_exp range (
long start,
long inc,
long end
);
/*!
requires
- inc > 0
ensures
- returns a matrix R such that:
- R::type == long
- R.nr() == abs(end - start)/inc + 1
- R.nc() == 1
- if (start <= end) then
- R(i) == start + i*inc
- else
- R(i) == start - i*inc
!*/
const matrix_exp range (
long start,
long end
) { return range(start,1,end); }
// ----------------------------------------------------------------------------------------
const matrix_exp subm (
const matrix_exp& m,
const matrix_exp& rows,
const matrix_exp& cols,
);
/*!
requires
- rows and cols contain elements of type long
- 0 <= min(rows) && max(rows) < m.nr()
- 0 <= min(cols) && max(cols) < m.nc()
- rows.nr() == 1 || rows.nc() == 1
- cols.nr() == 1 || cols.nc() == 1
(i.e. rows and cols must be vectors)
ensures
- returns a matrix R such that:
- R::type == the same type that was in m
- R.nr() == rows.size()
- R.nc() == cols.size()
- for all valid r and c:
R(r,c) == m(rows(r),cols(c))
!*/
// ----------------------------------------------------------------------------------------
const matrix_exp subm (
const matrix_exp& m,
long row,
long col,
long nr,
long nc
);
/*!
requires
- row >= 0
- row + nr <= m.nr()
- col >= 0
- col + nc <= m.nc()
ensures
- returns a matrix R such that:
- R.nr() == nr
- R.nc() == nc
- for all valid r and c:
R(r, c) == m(r+row,c+col)
!*/
// ----------------------------------------------------------------------------------------
const matrix_exp subm (
const matrix_exp& m,
const rectangle& rect
);
/*!
requires
- get_rect(m).contains(rect) == true
(i.e. rect is a region inside the matrix m)
ensures
- returns a matrix R such that:
- R.nr() == rect.height()
- R.nc() == rect.width()
- for all valid r and c:
R(r, c) == m(r+rect.top(), c+rect.left())
!*/
// ----------------------------------------------------------------------------------------
const matrix_exp rowm (
const matrix_exp& m,
long row
);
/*!
requires
- 0 <= row < m.nr()
ensures
- returns a matrix R such that:
- R.nr() == 1
- R.nc() == m.nc()
- for all valid i:
R(i) == m(row,i)
!*/
// ----------------------------------------------------------------------------------------
const matrix_exp rowm (
const matrix_exp& m,
const matrix_exp& rows
);
/*!
requires
- rows contains elements of type long
- 0 <= min(rows) && max(rows) < m.nr()
- rows.nr() == 1 || rows.nc() == 1
(i.e. rows must be a vector)
ensures
- returns a matrix R such that:
- R::type == the same type that was in m
- R.nr() == rows.size()
- R.nc() == m.nc()
- for all valid r and c:
R(r,c) == m(rows(r),c)
!*/
// ----------------------------------------------------------------------------------------
const matrix_exp colm (
const matrix_exp& m,
long col
);
/*!
requires
- 0 <= col < m.nr()
ensures
- returns a matrix R such that:
- R.nr() == m.nr()
- R.nc() == 1
- for all valid i:
R(i) == m(i,col)
!*/
// ----------------------------------------------------------------------------------------
const matrix_exp colm (
const matrix_exp& m,
const matrix_exp& cols
);
/*!
requires
- cols contains elements of type long
- 0 <= min(cols) && max(cols) < m.nc()
- cols.nr() == 1 || cols.nc() == 1
(i.e. cols must be a vector)
ensures
- returns a matrix R such that:
- R::type == the same type that was in m
- R.nr() == m.nr()
- R.nc() == cols.size()
- for all valid r and c:
R(r,c) == m(r,cols(c))
!*/
// ----------------------------------------------------------------------------------------
assignable_matrix_expression set_subm (
matrix& m,
long row,
long col,
long nr,
long nc
);
/*!
requires
- row >= 0
- row + nr <= m.nr()
- col >= 0
- col + nc <= m.nc()
ensures
- statements of the following form:
- set_subm(m,row,col,nr,nc) = some_matrix;
result in it being the case that:
- subm(m,row,col,nr,nc) == some_matrix.
- statements of the following form:
- set_subm(m,row,col,nr,nc) = scalar_value;
result in it being the case that:
- subm(m,row,col,nr,nc) == uniform_matrix<matrix::type>(nr,nc,scalar_value).
!*/
// ----------------------------------------------------------------------------------------
assignable_matrix_expression set_subm (
matrix& m,
const rectangle& rect
);
/*!
requires
- get_rect(m).contains(rect) == true
(i.e. rect is a region inside the matrix m)
ensures
- statements of the following form:
- set_subm(m,rect) = some_matrix;
result in it being the case that:
- subm(m,rect) == some_matrix.
- statements of the following form:
- set_subm(m,rect) = scalar_value;
result in it being the case that:
- subm(m,rect) == uniform_matrix<matrix::type>(nr,nc,scalar_value).
!*/
// ----------------------------------------------------------------------------------------
assignable_matrix_expression set_subm (
matrix& m,
const matrix_exp& rows,
const matrix_exp& cols
);
/*!
requires
- rows and cols contain elements of type long
- 0 <= min(rows) && max(rows) < m.nr()
- 0 <= min(cols) && max(cols) < m.nc()
- rows.nr() == 1 || rows.nc() == 1
- cols.nr() == 1 || cols.nc() == 1
(i.e. rows and cols must be vectors)
ensures
- statements of the following form:
- set_subm(m,rows,cols) = some_matrix;
result in it being the case that:
- subm(m,rows,cols) == some_matrix.
- statements of the following form:
- set_subm(m,rows,cols) = scalar_value;
result in it being the case that:
- subm(m,rows,cols) == uniform_matrix<matrix::type>(nr,nc,scalar_value).
!*/
// ----------------------------------------------------------------------------------------
assignable_matrix_expression set_rowm (
matrix& m,
long row
);
/*!
requires
- 0 <= row < m.nr()
ensures
- statements of the following form:
- set_rowm(m,row) = some_matrix;
result in it being the case that:
- rowm(m,row) == some_matrix.
- statements of the following form:
- set_rowm(m,row) = scalar_value;
result in it being the case that:
- rowm(m,row) == uniform_matrix<matrix::type>(1,nc,scalar_value).
!*/
// ----------------------------------------------------------------------------------------
assignable_matrix_expression set_rowm (
matrix& m,
const matrix_exp& rows
);
/*!
requires
- rows contains elements of type long
- 0 <= min(rows) && max(rows) < m.nr()
- rows.nr() == 1 || rows.nc() == 1
(i.e. rows must be a vector)
ensures
- statements of the following form:
- set_rowm(m,rows) = some_matrix;
result in it being the case that:
- rowm(m,rows) == some_matrix.
- statements of the following form:
- set_rowm(m,rows) = scalar_value;
result in it being the case that:
- rowm(m,rows) == uniform_matrix<matrix::type>(nr,nc,scalar_value).
!*/
// ----------------------------------------------------------------------------------------
assignable_matrix_expression set_colm (
matrix& m,
long col
);
/*!
requires
- 0 <= col < m.nr()
ensures
- statements of the following form:
- set_colm(m,col) = some_matrix;
result in it being the case that:
- colm(m,col) == some_matrix.
- statements of the following form:
- set_colm(m,col) = scalar_value;
result in it being the case that:
- colm(m,col) == uniform_matrix<matrix::type>(nr,1,scalar_value).
!*/
// ----------------------------------------------------------------------------------------
assignable_matrix_expression set_colm (
matrix& m,
const matrix_exp& cols
);
/*!
requires
- cols contains elements of type long
- 0 <= min(cols) && max(cols) < m.nc()
- cols.nr() == 1 || cols.nc() == 1
(i.e. cols must be a vector)
ensures
- statements of the following form:
- set_colm(m,cols) = some_matrix;
result in it being the case that:
- colm(m,cols) == some_matrix.
- statements of the following form:
- set_colm(m,cols) = scalar_value;
result in it being the case that:
- colm(m,cols) == uniform_matrix<matrix::type>(nr,nc,scalar_value).
!*/
// ----------------------------------------------------------------------------------------
}
#endif // DLIB_MATRIx_SUBEXP_ABSTRACT_
...@@ -9,7 +9,6 @@ ...@@ -9,7 +9,6 @@
#include <complex> #include <complex>
#include <limits> #include <limits>
#include "../pixel.h" #include "../pixel.h"
#include "../geometry/rectangle.h"
#include "../stl_checked.h" #include "../stl_checked.h"
#include <vector> #include <vector>
#include <algorithm> #include <algorithm>
...@@ -21,180 +20,6 @@ ...@@ -21,180 +20,6 @@
namespace dlib namespace dlib
{ {
// ----------------------------------------------------------------------------------------
/*
templates for finding the max of two matrix expressions' dimensions
*/
template <typename EXP1, typename EXP2 = void, typename EXP3 = void, typename EXP4 = void>
struct max_nr;
template <typename EXP1>
struct max_nr<EXP1,void,void,void>
{
const static long val = EXP1::NR;
};
template <typename EXP1, typename EXP2>
struct max_nr<EXP1,EXP2,void,void>
{
const static long val = (EXP1::NR > EXP2::NR) ? (EXP1::NR) : (EXP2::NR);
};
template <typename EXP1, typename EXP2, typename EXP3>
struct max_nr<EXP1,EXP2,EXP3,void>
{
private:
const static long max12 = (EXP1::NR > EXP2::NR) ? (EXP1::NR) : (EXP2::NR);
public:
const static long val = (max12 > EXP3::NR) ? (max12) : (EXP3::NR);
};
template <typename EXP1, typename EXP2, typename EXP3, typename EXP4>
struct max_nr
{
private:
const static long max12 = (EXP1::NR > EXP2::NR) ? (EXP1::NR) : (EXP2::NR);
const static long max34 = (EXP3::NR > EXP4::NR) ? (EXP3::NR) : (EXP4::NR);
public:
const static long val = (max12 > max34) ? (max12) : (max34);
};
template <typename EXP1, typename EXP2 = void, typename EXP3 = void, typename EXP4 = void>
struct max_nc;
template <typename EXP1>
struct max_nc<EXP1,void,void,void>
{
const static long val = EXP1::NC;
};
template <typename EXP1, typename EXP2>
struct max_nc<EXP1,EXP2,void,void>
{
const static long val = (EXP1::NC > EXP2::NC) ? (EXP1::NC) : (EXP2::NC);
};
template <typename EXP1, typename EXP2, typename EXP3>
struct max_nc<EXP1,EXP2,EXP3,void>
{
private:
const static long max12 = (EXP1::NC > EXP2::NC) ? (EXP1::NC) : (EXP2::NC);
public:
const static long val = (max12 > EXP3::NC) ? (max12) : (EXP3::NC);
};
template <typename EXP1, typename EXP2, typename EXP3, typename EXP4>
struct max_nc
{
private:
const static long max12 = (EXP1::NC > EXP2::NC) ? (EXP1::NC) : (EXP2::NC);
const static long max34 = (EXP3::NC > EXP4::NC) ? (EXP3::NC) : (EXP4::NC);
public:
const static long val = (max12 > max34) ? (max12) : (max34);
};
// ----------------------------------------------------------------------------------------
struct has_destructive_aliasing
{
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,L>& item
) { return m.aliases(item); }
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,L>& item
) { return m1.aliases(item) || m2.aliases(item) ; }
template <typename M1, typename M2, typename M3, typename U, long iNR, long iNC, typename MM, typename L >
static bool destructively_aliases (
const M1& m1,
const M2& m2,
const M3& m3,
const matrix<U,iNR,iNC,MM,L>& item
) { return m1.aliases(item) || m2.aliases(item) || m3.aliases(item); }
template <typename M1, typename M2, typename M3, typename M4, typename U, long iNR, long iNC, typename MM, typename L >
static bool destructively_aliases (
const M1& m1,
const M2& m2,
const M3& m3,
const M4& m4,
const matrix<U,iNR,iNC,MM,L>& item
) { return m1.aliases(item) || m2.aliases(item) || m3.aliases(item) || m4.aliases(item); }
};
struct has_nondestructive_aliasing
{
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,L>& item
) { return m.destructively_aliases(item); }
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, L>& item
) { return m1.destructively_aliases(item) || m2.destructively_aliases(item) ; }
template <typename M1, typename M2, typename M3, typename U, long iNR, long iNC, typename MM, typename L >
static bool destructively_aliases (
const M1& m1,
const M2& m2,
const M3& m3,
const matrix<U,iNR,iNC, MM, L>& item
) { return m1.destructively_aliases(item) || m2.destructively_aliases(item) || m3.destructively_aliases(item) ; }
template <typename M1, typename M2, typename M3, typename M4, typename U, long iNR, long iNC, typename MM, typename L >
static bool destructively_aliases (
const M1& m1,
const M2& m2,
const M3& m3,
const M4& m4,
const matrix<U,iNR,iNC, MM, L>& item
) { return m1.destructively_aliases(item) ||
m2.destructively_aliases(item) ||
m3.destructively_aliases(item) ||
m4.destructively_aliases(item) ; }
};
template <typename EXP1, typename EXP2 = void, typename EXP3 = void, typename EXP4 = void>
struct preserves_dimensions
{
const static long NR = max_nr<EXP1,EXP2,EXP3,EXP4>::val;
const static long NC = max_nc<EXP1,EXP2,EXP3,EXP4>::val;
typedef typename EXP1::mem_manager_type mem_manager_type;
template <typename M>
static long nr (const M& m) { return m.nr(); }
template <typename M>
static long nc (const M& m) { return m.nc(); }
template <typename M1, typename M2>
static long nr (const M1& m1, const M2& ) { return m1.nr(); }
template <typename M1, typename M2>
static long nc (const M1& m1, const M2& ) { return m1.nc(); }
template <typename M1, typename M2, typename M3>
static long nr (const M1& m1, const M2&, const M3& ) { return m1.nr(); }
template <typename M1, typename M2, typename M3>
static long nc (const M1& m1, const M2&, const M3& ) { return m1.nc(); }
template <typename M1, typename M2, typename M3, typename M4>
static long nr (const M1& m1, const M2&, const M3&, const M4& ) { return m1.nr(); }
template <typename M1, typename M2, typename M3, typename M4>
static long nc (const M1& m1, const M2&, const M3&, const M4& ) { return m1.nc(); }
};
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
template < template <
...@@ -1212,48 +1037,6 @@ convergence: ...@@ -1212,48 +1037,6 @@ convergence:
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
template <long start, long inc, long end>
const matrix_range_static_exp<start,inc,end> range (
)
{
COMPILE_TIME_ASSERT(inc > 0);
return matrix_range_static_exp<start,inc,end>();
}
template <long start, long end>
const matrix_range_static_exp<start,1,end> range (
)
{
return matrix_range_static_exp<start,1,end>();
}
inline const matrix_range_exp range (
long start,
long end
)
{
return matrix_range_exp(start,end);
}
inline const matrix_range_exp range (
long start,
long inc,
long end
)
{
DLIB_ASSERT(inc > 0,
"\tconst matrix_exp range(start, inc, end)"
<< "\n\tstart can't be bigger than end"
<< "\n\tstart: " << start
<< "\n\tinc: " << inc
<< "\n\tend: " << end
);
return matrix_range_exp(start,inc,end);
}
// ----------------------------------------------------------------------------------------
template < template <
typename array_type typename array_type
> >
...@@ -1336,733 +1119,6 @@ convergence: ...@@ -1336,733 +1119,6 @@ convergence:
return exp(vector); return exp(vector);
} }
// ----------------------------------------------------------------------------------------
template <
typename EXP
>
const rectangle get_rect (
const matrix_exp<EXP>& m
)
{
return rectangle(0, 0, m.nc()-1, m.nr()-1);
}
// ----------------------------------------------------------------------------------------
template <
typename EXP
>
const matrix_sub_exp<EXP> subm (
const matrix_exp<EXP>& m,
long r,
long c,
long nr,
long nc
)
{
DLIB_ASSERT(r >= 0 && c >= 0 && r+nr <= m.nr() && c+nc <= m.nc(),
"\tconst matrix_exp subm(const matrix_exp& m, r, c, nr, nc)"
<< "\n\tYou have specified invalid sub matrix dimensions"
<< "\n\tm.nr(): " << m.nr()
<< "\n\tm.nc(): " << m.nc()
<< "\n\tr: " << r
<< "\n\tc: " << c
<< "\n\tnr: " << nr
<< "\n\tnc: " << nc
);
typedef matrix_sub_exp<EXP> exp;
return exp(m.ref(),r,c,nr,nc);
}
// ----------------------------------------------------------------------------------------
template <
typename EXP
>
const matrix_sub_exp<EXP> subm (
const matrix_exp<EXP>& m,
const rectangle& rect
)
{
DLIB_ASSERT(get_rect(m).contains(rect) == true,
"\tconst matrix_exp subm(const matrix_exp& m, const rectangle& rect)"
<< "\n\tYou have specified invalid sub matrix dimensions"
<< "\n\tm.nr(): " << m.nr()
<< "\n\tm.nc(): " << m.nc()
<< "\n\trect.left(): " << rect.left()
<< "\n\trect.top(): " << rect.top()
<< "\n\trect.right(): " << rect.right()
<< "\n\trect.bottom(): " << rect.bottom()
);
typedef matrix_sub_exp<EXP> exp;
return exp(m.ref(),rect.top(),rect.left(),rect.height(),rect.width());
}
// ----------------------------------------------------------------------------------------
template <
typename EXP,
typename EXPr,
typename EXPc
>
const matrix_sub_range_exp<EXP,EXPr,EXPc> subm (
const matrix_exp<EXP>& m,
const matrix_exp<EXPr>& rows,
const matrix_exp<EXPc>& cols
)
{
// the rows and cols matrices must contain elements of type long
COMPILE_TIME_ASSERT((is_same_type<typename EXPr::type,long>::value == true));
COMPILE_TIME_ASSERT((is_same_type<typename EXPc::type,long>::value == true));
DLIB_ASSERT(0 <= min(rows) && max(rows) < m.nr() && 0 <= min(cols) && max(cols) < m.nc() &&
(rows.nr() == 1 || rows.nc() == 1) && (cols.nr() == 1 || cols.nc() == 1),
"\tconst matrix_exp subm(const matrix_exp& m, const matrix_exp& rows, const matrix_exp& cols)"
<< "\n\tYou have given invalid arguments to this function"
<< "\n\tm.nr(): " << m.nr()
<< "\n\tm.nc(): " << m.nc()
<< "\n\tmin(rows): " << min(rows)
<< "\n\tmax(rows): " << max(rows)
<< "\n\tmin(cols): " << min(cols)
<< "\n\tmax(cols): " << max(cols)
<< "\n\trows.nr(): " << rows.nr()
<< "\n\trows.nc(): " << rows.nc()
<< "\n\tcols.nr(): " << cols.nr()
<< "\n\tcols.nc(): " << cols.nc()
);
typedef matrix_sub_range_exp<EXP,EXPr,EXPc> exp;
return exp(m.ref(),rows.ref(),cols.ref());
}
// ----------------------------------------------------------------------------------------
struct op_rowm
{
template <typename EXP>
struct op : has_destructive_aliasing
{
const static long cost = EXP::cost;
const static long NR = 1;
const static long NC = EXP::NC;
typedef typename EXP::type type;
typedef typename EXP::mem_manager_type mem_manager_type;
template <typename M>
static type apply ( const M& m, long row, long, long c)
{ return m(row,c); }
template <typename M>
static long nr (const M& m) { return 1; }
template <typename M>
static long nc (const M& m) { return m.nc(); }
};
};
template <
typename EXP
>
const matrix_scalar_binary_exp<EXP,long,op_rowm> rowm (
const matrix_exp<EXP>& m,
long row
)
{
DLIB_ASSERT(row >= 0 && row < m.nr(),
"\tconst matrix_exp rowm(const matrix_exp& m, row)"
<< "\n\tYou have specified invalid sub matrix dimensions"
<< "\n\tm.nr(): " << m.nr()
<< "\n\tm.nc(): " << m.nc()
<< "\n\trow: " << row
);
typedef matrix_scalar_binary_exp<EXP,long,op_rowm> exp;
return exp(m.ref(),row);
}
// ----------------------------------------------------------------------------------------
struct op_rowm_range
{
template <typename EXP1, typename EXP2>
struct op : has_destructive_aliasing
{
const static long cost = EXP1::cost+EXP2::cost;
typedef typename EXP1::type type;
typedef typename EXP1::mem_manager_type mem_manager_type;
const static long NR = EXP2::NC*EXP2::NR;
const static long NC = EXP1::NC;
template <typename M1, typename M2>
static type apply ( const M1& m1, const M2& rows , long r, long c)
{ return m1(rows(r),c); }
template <typename M1, typename M2>
static long nr (const M1& m1, const M2& rows ) { return rows.size(); }
template <typename M1, typename M2>
static long nc (const M1& m1, const M2& ) { return m1.nc(); }
};
};
template <
typename EXP1,
typename EXP2
>
const matrix_binary_exp<EXP1,EXP2,op_rowm_range> rowm (
const matrix_exp<EXP1>& m,
const matrix_exp<EXP2>& rows
)
{
// the rows matrix must contain elements of type long
COMPILE_TIME_ASSERT((is_same_type<typename EXP2::type,long>::value == true));
DLIB_ASSERT(0 <= min(rows) && max(rows) < m.nr() && (rows.nr() == 1 || rows.nc() == 1),
"\tconst matrix_exp rowm(const matrix_exp& m, const matrix_exp& rows)"
<< "\n\tYou have given invalid arguments to this function"
<< "\n\tm.nr(): " << m.nr()
<< "\n\tm.nc(): " << m.nc()
<< "\n\tmin(rows): " << min(rows)
<< "\n\tmax(rows): " << max(rows)
<< "\n\trows.nr(): " << rows.nr()
<< "\n\trows.nc(): " << rows.nc()
);
typedef matrix_binary_exp<EXP1,EXP2,op_rowm_range> exp;
return exp(m.ref(),rows.ref());
}
// ----------------------------------------------------------------------------------------
struct op_colm
{
template <typename EXP>
struct op : has_destructive_aliasing
{
const static long cost = EXP::cost;
const static long NR = EXP::NR;
const static long NC = 1;
typedef typename EXP::type type;
typedef typename EXP::mem_manager_type mem_manager_type;
template <typename M>
static type apply ( const M& m, long col, long r, long)
{ return m(r,col); }
template <typename M>
static long nr (const M& m) { return m.nr(); }
template <typename M>
static long nc (const M& m) { return 1; }
};
};
template <
typename EXP
>
const matrix_scalar_binary_exp<EXP,long,op_colm> colm (
const matrix_exp<EXP>& m,
long col
)
{
DLIB_ASSERT(col >= 0 && col < m.nc(),
"\tconst matrix_exp colm(const matrix_exp& m, row)"
<< "\n\tYou have specified invalid sub matrix dimensions"
<< "\n\tm.nr(): " << m.nr()
<< "\n\tm.nc(): " << m.nc()
<< "\n\tcol: " << col
);
typedef matrix_scalar_binary_exp<EXP,long,op_colm> exp;
return exp(m.ref(),col);
}
// ----------------------------------------------------------------------------------------
struct op_colm_range
{
template <typename EXP1, typename EXP2>
struct op : has_destructive_aliasing
{
typedef typename EXP1::type type;
typedef typename EXP1::mem_manager_type mem_manager_type;
const static long NR = EXP1::NR;
const static long NC = EXP2::NC*EXP2::NR;
const static long cost = EXP1::cost+EXP2::cost;
template <typename M1, typename M2>
static type apply ( const M1& m1, const M2& cols , long r, long c)
{ return m1(r,cols(c)); }
template <typename M1, typename M2>
static long nr (const M1& m1, const M2& cols ) { return m1.nr(); }
template <typename M1, typename M2>
static long nc (const M1& m1, const M2& cols ) { return cols.size(); }
};
};
template <
typename EXP1,
typename EXP2
>
const matrix_binary_exp<EXP1,EXP2,op_colm_range> colm (
const matrix_exp<EXP1>& m,
const matrix_exp<EXP2>& cols
)
{
// the cols matrix must contain elements of type long
COMPILE_TIME_ASSERT((is_same_type<typename EXP2::type,long>::value == true));
DLIB_ASSERT(0 <= min(cols) && max(cols) < m.nc() && (cols.nr() == 1 || cols.nc() == 1),
"\tconst matrix_exp colm(const matrix_exp& m, const matrix_exp& cols)"
<< "\n\tYou have given invalid arguments to this function"
<< "\n\tm.nr(): " << m.nr()
<< "\n\tm.nc(): " << m.nc()
<< "\n\tmin(cols): " << min(cols)
<< "\n\tmax(cols): " << max(cols)
<< "\n\tcols.nr(): " << cols.nr()
<< "\n\tcols.nc(): " << cols.nc()
);
typedef matrix_binary_exp<EXP1,EXP2,op_colm_range> exp;
return exp(m.ref(),cols.ref());
}
// ----------------------------------------------------------------------------------------
template <typename T, long NR, long NC, typename mm, typename l>
class assignable_sub_matrix
{
public:
assignable_sub_matrix(
matrix<T,NR,NC,mm,l>& m_,
const rectangle& rect_
) : m(m_), rect(rect_) {}
T& operator() (
long r,
long c
)
{
return m(r+rect.top(),c+rect.left());
}
long nr() const { return rect.height(); }
long nc() const { return rect.width(); }
template <typename EXP>
assignable_sub_matrix& operator= (
const matrix_exp<EXP>& exp
)
{
DLIB_ASSERT( exp.nr() == (long)rect.height() && exp.nc() == (long)rect.width(),
"\tassignable_matrix_expression set_subm()"
<< "\n\tYou have tried to assign to this object using a matrix that isn't the right size"
<< "\n\texp.nr() (source matrix): " << exp.nr()
<< "\n\texp.nc() (source matrix): " << exp.nc()
<< "\n\trect.width() (target matrix): " << rect.width()
<< "\n\trect.height() (target matrix): " << rect.height()
);
if (exp.destructively_aliases(m) == false)
{
matrix_assign(*this, exp);
}
else
{
// make a temporary copy of the matrix we are going to assign to m to
// avoid aliasing issues during the copy
this->operator=(tmp(exp));
}
return *this;
}
assignable_sub_matrix& operator= (
const T& value
)
{
for (long r = rect.top(); r <= rect.bottom(); ++r)
{
for (long c = rect.left(); c <= rect.right(); ++c)
{
m(r,c) = value;
}
}
return *this;
}
private:
matrix<T,NR,NC,mm,l>& m;
const rectangle rect;
};
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
)
{
DLIB_ASSERT(get_rect(m).contains(rect) == true,
"\tassignable_matrix_expression set_subm(matrix& m, const rectangle& rect)"
<< "\n\tYou have specified invalid sub matrix dimensions"
<< "\n\tm.nr(): " << m.nr()
<< "\n\tm.nc(): " << m.nc()
<< "\n\trect.left(): " << rect.left()
<< "\n\trect.top(): " << rect.top()
<< "\n\trect.right(): " << rect.right()
<< "\n\trect.bottom(): " << rect.bottom()
);
return assignable_sub_matrix<T,NR,NC,mm,l>(m,rect);
}
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,
long nc
)
{
DLIB_ASSERT(r >= 0 && c >= 0 && r+nr <= m.nr() && c+nc <= m.nc(),
"\tassignable_matrix_expression set_subm(matrix& m, r, c, nr, nc)"
<< "\n\tYou have specified invalid sub matrix dimensions"
<< "\n\tm.nr(): " << m.nr()
<< "\n\tm.nc(): " << m.nc()
<< "\n\tr: " << r
<< "\n\tc: " << c
<< "\n\tnr: " << nr
<< "\n\tnc: " << nc
);
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 l, typename EXPr, typename EXPc>
class assignable_sub_range_matrix
{
public:
assignable_sub_range_matrix(
matrix<T,NR,NC,mm,l>& m_,
const EXPr& rows_,
const EXPc& cols_
) : m(m_), rows(rows_), cols(cols_) {}
T& operator() (
long r,
long c
)
{
return m(rows(r),cols(c));
}
long nr() const { return rows.size(); }
long nc() const { return cols.size(); }
template <typename EXP>
assignable_sub_range_matrix& operator= (
const matrix_exp<EXP>& exp
)
{
DLIB_ASSERT( exp.nr() == rows.size() && exp.nc() == cols.size(),
"\tassignable_matrix_expression set_subm(matrix& m, const matrix_exp rows, const matrix_exp cols)"
<< "\n\tYou have tried to assign to this object using a matrix that isn't the right size"
<< "\n\texp.nr() (source matrix): " << exp.nr()
<< "\n\texp.nc() (source matrix): " << exp.nc()
<< "\n\trows.size() (target matrix): " << rows.size()
<< "\n\tcols.size() (target matrix): " << cols.size()
);
if (exp.destructively_aliases(m) == false)
{
matrix_assign(*this, exp);
}
else
{
// make a temporary copy of the matrix we are going to assign to m to
// avoid aliasing issues during the copy
this->operator=(tmp(exp));
}
return *this;
}
assignable_sub_range_matrix& operator= (
const T& value
)
{
for (long r = 0; r < rows.size(); ++r)
{
for (long c = 0; c < cols.size(); ++c)
{
m(rows(r),cols(c)) = value;
}
}
return *this;
}
private:
matrix<T,NR,NC,mm,l>& m;
const EXPr rows;
const EXPc cols;
};
template <typename T, long NR, long NC, typename mm, typename l, typename EXPr, typename EXPc>
assignable_sub_range_matrix<T,NR,NC,mm,l,EXPr,EXPc > set_subm (
matrix<T,NR,NC,mm,l>& m,
const matrix_exp<EXPr>& rows,
const matrix_exp<EXPc>& cols
)
{
DLIB_ASSERT(0 <= min(rows) && max(rows) < m.nr() && 0 <= min(cols) && max(cols) < m.nc() &&
(rows.nr() == 1 || rows.nc() == 1) && (cols.nr() == 1 || cols.nc() == 1),
"\tassignable_matrix_expression set_subm(matrix& m, const matrix_exp& rows, const matrix_exp& cols)"
<< "\n\tYou have specified invalid sub matrix dimensions"
<< "\n\tm.nr(): " << m.nr()
<< "\n\tm.nc(): " << m.nc()
<< "\n\tmin(rows): " << min(rows)
<< "\n\tmax(rows): " << max(rows)
<< "\n\tmin(cols): " << min(cols)
<< "\n\tmax(cols): " << max(cols)
<< "\n\trows.nr(): " << rows.nr()
<< "\n\trows.nc(): " << rows.nc()
<< "\n\tcols.nr(): " << cols.nr()
<< "\n\tcols.nc(): " << cols.nc()
);
return assignable_sub_range_matrix<T,NR,NC,mm,l,EXPr,EXPc >(m,rows.ref(),cols.ref());
}
// ----------------------------------------------------------------------------------------
template <typename T, long NR, long NC, typename mm, typename l, typename EXPr>
assignable_sub_range_matrix<T,NR,NC,mm,l,EXPr,matrix_range_exp > set_rowm (
matrix<T,NR,NC,mm,l>& m,
const matrix_exp<EXPr>& rows
)
{
DLIB_ASSERT(0 <= min(rows) && max(rows) < m.nr() && (rows.nr() == 1 || rows.nc() == 1),
"\tassignable_matrix_expression set_rowm(matrix& m, const matrix_exp& rows)"
<< "\n\tYou have specified invalid sub matrix dimensions"
<< "\n\tm.nr(): " << m.nr()
<< "\n\tm.nc(): " << m.nc()
<< "\n\tmin(rows): " << min(rows)
<< "\n\tmax(rows): " << max(rows)
<< "\n\trows.nr(): " << rows.nr()
<< "\n\trows.nc(): " << rows.nc()
);
return assignable_sub_range_matrix<T,NR,NC,mm,l,EXPr,matrix_range_exp >(m,rows.ref(),range(0,m.nc()-1));
}
// ----------------------------------------------------------------------------------------
template <typename T, long NR, long NC, typename mm, typename l, typename EXPc>
assignable_sub_range_matrix<T,NR,NC,mm,l,matrix_range_exp,EXPc > set_colm (
matrix<T,NR,NC,mm,l>& m,
const matrix_exp<EXPc>& cols
)
{
DLIB_ASSERT(0 <= min(cols) && max(cols) < m.nc() && (cols.nr() == 1 || cols.nc() == 1),
"\tassignable_matrix_expression set_colm(matrix& m, const matrix_exp& cols)"
<< "\n\tYou have specified invalid sub matrix dimensions"
<< "\n\tm.nr(): " << m.nr()
<< "\n\tm.nc(): " << m.nc()
<< "\n\tmin(cols): " << min(cols)
<< "\n\tmax(cols): " << max(cols)
<< "\n\tcols.nr(): " << cols.nr()
<< "\n\tcols.nc(): " << cols.nc()
);
return assignable_sub_range_matrix<T,NR,NC,mm,l,matrix_range_exp,EXPc >(m,range(0,m.nr()-1),cols.ref());
}
// ----------------------------------------------------------------------------------------
template <typename T, long NR, long NC, typename mm, typename l>
class assignable_col_matrix
{
public:
assignable_col_matrix(
matrix<T,NR,NC,mm,l>& m_,
const long col_
) : m(m_), col(col_) {}
T& operator() (
long r,
long c
)
{
return m(r,col);
}
long nr() const { return m.nr(); }
long nc() const { return 1; }
template <typename EXP>
assignable_col_matrix& operator= (
const matrix_exp<EXP>& exp
)
{
DLIB_ASSERT( exp.nc() == 1 && exp.nr() == m.nr(),
"\tassignable_matrix_expression set_colm()"
<< "\n\tYou have tried to assign to this object using a matrix that isn't the right size"
<< "\n\texp.nr() (source matrix): " << exp.nr()
<< "\n\texp.nc() (source matrix): " << exp.nc()
<< "\n\tm.nr() (target matrix): " << m.nr()
);
if (exp.destructively_aliases(m) == false)
{
matrix_assign(*this, exp);
}
else
{
// make a temporary copy of the matrix we are going to assign to m to
// avoid aliasing issues during the copy
this->operator=(tmp(exp));
}
return *this;
}
assignable_col_matrix& operator= (
const T& value
)
{
for (long i = 0; i < m.nr(); ++i)
{
m(i,col) = value;
}
return *this;
}
private:
matrix<T,NR,NC,mm,l>& m;
const long col;
};
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
)
{
DLIB_ASSERT(col >= 0 && col < m.nc(),
"\tassignable_matrix_expression set_colm(matrix& m, col)"
<< "\n\tYou have specified invalid sub matrix dimensions"
<< "\n\tm.nr(): " << m.nr()
<< "\n\tm.nc(): " << m.nc()
<< "\n\tcol: " << col
);
return assignable_col_matrix<T,NR,NC,mm,l>(m,col);
}
// ----------------------------------------------------------------------------------------
template <typename T, long NR, long NC, typename mm, typename l>
class assignable_row_matrix
{
public:
assignable_row_matrix(
matrix<T,NR,NC,mm,l>& m_,
const long row_
) : m(m_), row(row_) {}
T& operator() (
long r,
long c
)
{
return m(row,c);
}
long nr() const { return 1; }
long nc() const { return m.nc(); }
template <typename EXP>
assignable_row_matrix& operator= (
const matrix_exp<EXP>& exp
)
{
DLIB_ASSERT( exp.nr() == 1 && exp.nc() == m.nc(),
"\tassignable_matrix_expression set_rowm()"
<< "\n\tYou have tried to assign to this object using a matrix that isn't the right size"
<< "\n\texp.nr() (source matrix): " << exp.nr()
<< "\n\texp.nc() (source matrix): " << exp.nc()
<< "\n\tm.nc() (target matrix): " << m.nc()
);
if (exp.destructively_aliases(m) == false)
{
matrix_assign(*this, exp);
}
else
{
// make a temporary copy of the matrix we are going to assign to m to
// avoid aliasing issues during the copy
this->operator=(tmp(exp));
}
return *this;
}
assignable_row_matrix& operator= (
const T& value
)
{
for (long i = 0; i < m.nc(); ++i)
{
m(row,i) = value;
}
return *this;
}
private:
matrix<T,NR,NC,mm,l>& m;
const long row;
};
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
)
{
DLIB_ASSERT(row >= 0 && row < m.nr(),
"\tassignable_matrix_expression set_rowm(matrix& m, row)"
<< "\n\tYou have specified invalid sub matrix dimensions"
<< "\n\tm.nr(): " << m.nr()
<< "\n\tm.nc(): " << m.nc()
<< "\n\trow: " << row
);
return assignable_row_matrix<T,NR,NC,mm,l>(m,row);
}
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
struct op_trans struct op_trans
......
...@@ -14,7 +14,7 @@ namespace dlib ...@@ -14,7 +14,7 @@ namespace dlib
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
// Elementary matrix operations // Simple matrix utilities
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
...@@ -199,372 +199,6 @@ namespace dlib ...@@ -199,372 +199,6 @@ namespace dlib
R(r, c) == array[r][c] R(r, c) == array[r][c]
!*/ !*/
// ----------------------------------------------------------------------------------------
const rectangle get_rect (
const matrix_exp& m
);
/*!
ensures
- returns rectangle(0, 0, m.nc()-1, m.nr()-1)
(i.e. returns a rectangle that has the same dimensions as
the matrix m)
!*/
// ----------------------------------------------------------------------------------------
template <long start, long inc, long end>
const matrix_exp range (
);
/*!
requires
- inc > 0
ensures
- returns a matrix R such that:
- R::type == long
- R.nr() == abs(end - start)/inc + 1
- R.nc() == 1
- if (start <= end) then
- R(i) == start + i*inc
- else
- R(i) == start - i*inc
!*/
template <long start, long end>
const matrix_exp range (
) { return range<start,1,end>(); }
const matrix_exp range (
long start,
long inc,
long end
);
/*!
requires
- inc > 0
ensures
- returns a matrix R such that:
- R::type == long
- R.nr() == abs(end - start)/inc + 1
- R.nc() == 1
- if (start <= end) then
- R(i) == start + i*inc
- else
- R(i) == start - i*inc
!*/
const matrix_exp range (
long start,
long end
) { return range(start,1,end); }
// ----------------------------------------------------------------------------------------
const matrix_exp subm (
const matrix_exp& m,
const matrix_exp& rows,
const matrix_exp& cols,
);
/*!
requires
- rows and cols contain elements of type long
- 0 <= min(rows) && max(rows) < m.nr()
- 0 <= min(cols) && max(cols) < m.nc()
- rows.nr() == 1 || rows.nc() == 1
- cols.nr() == 1 || cols.nc() == 1
(i.e. rows and cols must be vectors)
ensures
- returns a matrix R such that:
- R::type == the same type that was in m
- R.nr() == rows.size()
- R.nc() == cols.size()
- for all valid r and c:
R(r,c) == m(rows(r),cols(c))
!*/
// ----------------------------------------------------------------------------------------
const matrix_exp subm (
const matrix_exp& m,
long row,
long col,
long nr,
long nc
);
/*!
requires
- row >= 0
- row + nr <= m.nr()
- col >= 0
- col + nc <= m.nc()
ensures
- returns a matrix R such that:
- R.nr() == nr
- R.nc() == nc
- for all valid r and c:
R(r, c) == m(r+row,c+col)
!*/
// ----------------------------------------------------------------------------------------
const matrix_exp subm (
const matrix_exp& m,
const rectangle& rect
);
/*!
requires
- get_rect(m).contains(rect) == true
(i.e. rect is a region inside the matrix m)
ensures
- returns a matrix R such that:
- R.nr() == rect.height()
- R.nc() == rect.width()
- for all valid r and c:
R(r, c) == m(r+rect.top(), c+rect.left())
!*/
// ----------------------------------------------------------------------------------------
const matrix_exp rowm (
const matrix_exp& m,
long row
);
/*!
requires
- 0 <= row < m.nr()
ensures
- returns a matrix R such that:
- R.nr() == 1
- R.nc() == m.nc()
- for all valid i:
R(i) == m(row,i)
!*/
// ----------------------------------------------------------------------------------------
const matrix_exp rowm (
const matrix_exp& m,
const matrix_exp& rows
);
/*!
requires
- rows contains elements of type long
- 0 <= min(rows) && max(rows) < m.nr()
- rows.nr() == 1 || rows.nc() == 1
(i.e. rows must be a vector)
ensures
- returns a matrix R such that:
- R::type == the same type that was in m
- R.nr() == rows.size()
- R.nc() == m.nc()
- for all valid r and c:
R(r,c) == m(rows(r),c)
!*/
// ----------------------------------------------------------------------------------------
const matrix_exp colm (
const matrix_exp& m,
long col
);
/*!
requires
- 0 <= col < m.nr()
ensures
- returns a matrix R such that:
- R.nr() == m.nr()
- R.nc() == 1
- for all valid i:
R(i) == m(i,col)
!*/
// ----------------------------------------------------------------------------------------
const matrix_exp colm (
const matrix_exp& m,
const matrix_exp& cols
);
/*!
requires
- cols contains elements of type long
- 0 <= min(cols) && max(cols) < m.nc()
- cols.nr() == 1 || cols.nc() == 1
(i.e. cols must be a vector)
ensures
- returns a matrix R such that:
- R::type == the same type that was in m
- R.nr() == m.nr()
- R.nc() == cols.size()
- for all valid r and c:
R(r,c) == m(r,cols(c))
!*/
// ----------------------------------------------------------------------------------------
assignable_matrix_expression set_subm (
matrix& m,
long row,
long col,
long nr,
long nc
);
/*!
requires
- row >= 0
- row + nr <= m.nr()
- col >= 0
- col + nc <= m.nc()
ensures
- statements of the following form:
- set_subm(m,row,col,nr,nc) = some_matrix;
result in it being the case that:
- subm(m,row,col,nr,nc) == some_matrix.
- statements of the following form:
- set_subm(m,row,col,nr,nc) = scalar_value;
result in it being the case that:
- subm(m,row,col,nr,nc) == uniform_matrix<matrix::type>(nr,nc,scalar_value).
!*/
// ----------------------------------------------------------------------------------------
assignable_matrix_expression set_subm (
matrix& m,
const rectangle& rect
);
/*!
requires
- get_rect(m).contains(rect) == true
(i.e. rect is a region inside the matrix m)
ensures
- statements of the following form:
- set_subm(m,rect) = some_matrix;
result in it being the case that:
- subm(m,rect) == some_matrix.
- statements of the following form:
- set_subm(m,rect) = scalar_value;
result in it being the case that:
- subm(m,rect) == uniform_matrix<matrix::type>(nr,nc,scalar_value).
!*/
// ----------------------------------------------------------------------------------------
assignable_matrix_expression set_subm (
matrix& m,
const matrix_exp& rows,
const matrix_exp& cols
);
/*!
requires
- rows and cols contain elements of type long
- 0 <= min(rows) && max(rows) < m.nr()
- 0 <= min(cols) && max(cols) < m.nc()
- rows.nr() == 1 || rows.nc() == 1
- cols.nr() == 1 || cols.nc() == 1
(i.e. rows and cols must be vectors)
ensures
- statements of the following form:
- set_subm(m,rows,cols) = some_matrix;
result in it being the case that:
- subm(m,rows,cols) == some_matrix.
- statements of the following form:
- set_subm(m,rows,cols) = scalar_value;
result in it being the case that:
- subm(m,rows,cols) == uniform_matrix<matrix::type>(nr,nc,scalar_value).
!*/
// ----------------------------------------------------------------------------------------
assignable_matrix_expression set_rowm (
matrix& m,
long row
);
/*!
requires
- 0 <= row < m.nr()
ensures
- statements of the following form:
- set_rowm(m,row) = some_matrix;
result in it being the case that:
- rowm(m,row) == some_matrix.
- statements of the following form:
- set_rowm(m,row) = scalar_value;
result in it being the case that:
- rowm(m,row) == uniform_matrix<matrix::type>(1,nc,scalar_value).
!*/
// ----------------------------------------------------------------------------------------
assignable_matrix_expression set_rowm (
matrix& m,
const matrix_exp& rows
);
/*!
requires
- rows contains elements of type long
- 0 <= min(rows) && max(rows) < m.nr()
- rows.nr() == 1 || rows.nc() == 1
(i.e. rows must be a vector)
ensures
- statements of the following form:
- set_rowm(m,rows) = some_matrix;
result in it being the case that:
- rowm(m,rows) == some_matrix.
- statements of the following form:
- set_rowm(m,rows) = scalar_value;
result in it being the case that:
- rowm(m,rows) == uniform_matrix<matrix::type>(nr,nc,scalar_value).
!*/
// ----------------------------------------------------------------------------------------
assignable_matrix_expression set_colm (
matrix& m,
long col
);
/*!
requires
- 0 <= col < m.nr()
ensures
- statements of the following form:
- set_colm(m,col) = some_matrix;
result in it being the case that:
- colm(m,col) == some_matrix.
- statements of the following form:
- set_colm(m,col) = scalar_value;
result in it being the case that:
- colm(m,col) == uniform_matrix<matrix::type>(nr,1,scalar_value).
!*/
// ----------------------------------------------------------------------------------------
assignable_matrix_expression set_colm (
matrix& m,
const matrix_exp& cols
);
/*!
requires
- cols contains elements of type long
- 0 <= min(cols) && max(cols) < m.nc()
- cols.nr() == 1 || cols.nc() == 1
(i.e. cols must be a vector)
ensures
- statements of the following form:
- set_colm(m,cols) = some_matrix;
result in it being the case that:
- colm(m,cols) == some_matrix.
- statements of the following form:
- set_colm(m,cols) = scalar_value;
result in it being the case that:
- colm(m,cols) == uniform_matrix<matrix::type>(nr,nc,scalar_value).
!*/
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
template < template <
......
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