- Fixed some issues with the requires clause of the removerc function.

- Added the remove_row and remove_col functions.  Also made all
    three of the above functions capable of taking arguments at
    run time as well as compile time.

--HG--
extra : convert_revision : svn%3Afdd8eb12-d10e-0410-9acb-85c331704f74/trunk%402307
This commit is contained in:
Davis King 2008-06-13 12:58:37 +00:00
parent 881c2b090f
commit ad06153a0b
3 changed files with 456 additions and 13 deletions

View File

@ -1177,7 +1177,6 @@ namespace dlib
// ----------------------------------------------------------------------------------------
template <
typename M,
typename S,
@ -1239,6 +1238,72 @@ namespace dlib
const S s;
};
// ----------------------------------------------------------------------------------------
template <
typename M,
typename S,
typename OP_
>
class matrix_scalar_trinary_exp
{
/*!
REQUIREMENTS ON M
- must be a matrix_exp or matrix_ref object (or
an object with a compatible interface).
!*/
typedef typename OP_::template op<M> OP;
public:
typedef typename OP::type type;
typedef matrix_scalar_trinary_exp ref_type;
typedef typename OP::mem_manager_type mem_manager_type;
const static long NR = OP::NR;
const static long NC = OP::NC;
matrix_scalar_trinary_exp (
const M& m_,
const S& s1_,
const S& s2_
) :
m(m_),
s1(s1_),
s2(s2_)
{
COMPILE_TIME_ASSERT(is_matrix<S>::value == false);
}
const typename OP::type operator() (
long r,
long c
) const { return OP::apply(m,s1,s2,r,c); }
template <typename U, long iNR, long iNC, typename MM >
bool aliases (
const matrix<U,iNR,iNC,MM>& item
) const { return m.aliases(item); }
template <typename U, long iNR, long iNC , typename MM>
bool destructively_aliases (
const matrix<U,iNR,iNC,MM>& item
) const { return OP::destructively_aliases(m,item); }
const ref_type& ref(
) const { return *this; }
long nr (
) const { return OP::nr(m); }
long nc (
) const { return OP::nc(m); }
private:
const M m;
const S s1;
const S s2;
};
// ----------------------------------------------------------------------------------------
template <
@ -1821,8 +1886,8 @@ namespace dlib
template <typename EXP>
struct op : has_destructive_aliasing
{
const static long NR = EXP::NR - 1;
const static long NC = EXP::NC - 1;
const static long NR = (EXP::NR==0) ? 0 : (EXP::NR - 1);
const static long NC = (EXP::NC==0) ? 0 : (EXP::NC - 1);
typedef typename EXP::type type;
typedef typename EXP::mem_manager_type mem_manager_type;
template <typename M>
@ -1851,6 +1916,41 @@ namespace dlib
};
};
struct op_removerc2
{
template <typename EXP>
struct op : has_destructive_aliasing
{
const static long NR = (EXP::NR==0) ? 0 : (EXP::NR - 1);
const static long NC = (EXP::NC==0) ? 0 : (EXP::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 R, long C, long r, long c)
{
if (r < R)
{
if (c < C)
return m(r,c);
else
return m(r,c+1);
}
else
{
if (c < C)
return m(r+1,c);
else
return m(r+1,c+1);
}
}
template <typename M>
static long nr (const M& m) { return m.nr() - 1; }
template <typename M>
static long nc (const M& m) { return m.nc() - 1; }
};
};
template <
long R,
long C,
@ -1861,12 +1961,12 @@ namespace dlib
)
{
// you can't remove a row from a matrix with only one row
COMPILE_TIME_ASSERT(EXP::NR > 1 || EXP::NR == 0);
COMPILE_TIME_ASSERT(EXP::NR > R || EXP::NR == 0);
// you can't remove a column from a matrix with only one column
COMPILE_TIME_ASSERT(EXP::NC > 1 || EXP::NR == 0);
DLIB_ASSERT(m.nr() > 1 && m.nc() > 1,
COMPILE_TIME_ASSERT(EXP::NC > C || EXP::NR == 0);
DLIB_ASSERT(m.nr() > R && m.nc() > C,
"\tconst matrix_exp removerc<R,C>(const matrix_exp& m)"
<< "\n\tYou can't remove a row/column from a matrix with only one row/column"
<< "\n\tYou can't remove a row/column from a matrix if it doesn't have that row/column"
<< "\n\tm.nr(): " << m.nr()
<< "\n\tm.nc(): " << m.nc()
<< "\n\tR: " << R
@ -1876,6 +1976,231 @@ namespace dlib
return matrix_exp<exp>(exp(m));
}
template <
typename EXP
>
const matrix_exp<matrix_scalar_trinary_exp<matrix_exp<EXP>,long,op_removerc2> > removerc (
const matrix_exp<EXP>& m,
long R,
long C
)
{
DLIB_ASSERT(m.nr() > R && m.nc() > C,
"\tconst matrix_exp removerc(const matrix_exp& m,R,C)"
<< "\n\tYou can't remove a row/column from a matrix if it doesn't have that row/column"
<< "\n\tm.nr(): " << m.nr()
<< "\n\tm.nc(): " << m.nc()
<< "\n\tR: " << R
<< "\n\tC: " << C
);
typedef matrix_scalar_trinary_exp<matrix_exp<EXP>,long,op_removerc2 > exp;
return matrix_exp<exp>(exp(m,R,C));
}
// ----------------------------------------------------------------------------------------
template <long C>
struct op_remove_col
{
template <typename EXP>
struct op : has_destructive_aliasing
{
const static long NR = EXP::NR;
const static long NC = (EXP::NC==0) ? 0 : (EXP::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 r, long c)
{
if (c < C)
{
return m(r,c);
}
else
{
return m(r,c+1);
}
}
template <typename M>
static long nr (const M& m) { return m.nr(); }
template <typename M>
static long nc (const M& m) { return m.nc() - 1; }
};
};
struct op_remove_col2
{
template <typename EXP>
struct op : has_destructive_aliasing
{
const static long NR = EXP::NR;
const static long NC = (EXP::NC==0) ? 0 : (EXP::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 C, long r, long c)
{
if (c < C)
{
return m(r,c);
}
else
{
return m(r,c+1);
}
}
template <typename M>
static long nr (const M& m) { return m.nr(); }
template <typename M>
static long nc (const M& m) { return m.nc() - 1; }
};
};
template <
long C,
typename EXP
>
const matrix_exp<matrix_unary_exp<matrix_exp<EXP>,op_remove_col<C> > > remove_col (
const matrix_exp<EXP>& m
)
{
// You can't remove the given column from the matrix because the matrix doesn't
// have a column with that index.
COMPILE_TIME_ASSERT(EXP::NC > C || EXP::NC == 0);
DLIB_ASSERT(m.nc() > C ,
"\tconst matrix_exp remove_col<C>(const matrix_exp& m)"
<< "\n\tYou can't remove a col from a matrix if it doesn't have it"
<< "\n\tm.nr(): " << m.nr()
<< "\n\tm.nc(): " << m.nc()
<< "\n\tC: " << C
);
typedef matrix_unary_exp<matrix_exp<EXP>,op_remove_col<C> > exp;
return matrix_exp<exp>(exp(m));
}
template <
typename EXP
>
const matrix_exp<matrix_scalar_binary_exp<matrix_exp<EXP>,long,op_remove_col2 > > remove_col (
const matrix_exp<EXP>& m,
long C
)
{
DLIB_ASSERT(m.nc() > C ,
"\tconst matrix_exp remove_col(const matrix_exp& m,C)"
<< "\n\tYou can't remove a col from a matrix if it doesn't have it"
<< "\n\tm.nr(): " << m.nr()
<< "\n\tm.nc(): " << m.nc()
<< "\n\tC: " << C
);
typedef matrix_scalar_binary_exp<matrix_exp<EXP>,long,op_remove_col2 > exp;
return matrix_exp<exp>(exp(m,C));
}
// ----------------------------------------------------------------------------------------
template <long R>
struct op_remove_row
{
template <typename EXP>
struct op : has_destructive_aliasing
{
const static long NR = (EXP::NR==0) ? 0 : (EXP::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 r, long c)
{
if (r < R)
{
return m(r,c);
}
else
{
return m(r+1,c);
}
}
template <typename M>
static long nr (const M& m) { return m.nr() - 1; }
template <typename M>
static long nc (const M& m) { return m.nc(); }
};
};
struct op_remove_row2
{
template <typename EXP>
struct op : has_destructive_aliasing
{
const static long NR = (EXP::NR==0) ? 0 : (EXP::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 R, long r, long c)
{
if (r < R)
{
return m(r,c);
}
else
{
return m(r+1,c);
}
}
template <typename M>
static long nr (const M& m) { return m.nr() - 1; }
template <typename M>
static long nc (const M& m) { return m.nc(); }
};
};
template <
long R,
typename EXP
>
const matrix_exp<matrix_unary_exp<matrix_exp<EXP>,op_remove_row<R> > > remove_row (
const matrix_exp<EXP>& m
)
{
// You can't remove the given row from the matrix because the matrix doesn't
// have a row with that index.
COMPILE_TIME_ASSERT(EXP::NR > R || EXP::NR == 0);
DLIB_ASSERT(m.nr() > R ,
"\tconst matrix_exp remove_row<R>(const matrix_exp& m)"
<< "\n\tYou can't remove a row from a matrix if it doesn't have it"
<< "\n\tm.nr(): " << m.nr()
<< "\n\tm.nc(): " << m.nc()
<< "\n\tR: " << R
);
typedef matrix_unary_exp<matrix_exp<EXP>,op_remove_row<R> > exp;
return matrix_exp<exp>(exp(m));
}
template <
typename EXP
>
const matrix_exp<matrix_scalar_binary_exp<matrix_exp<EXP>,long,op_remove_row2> > remove_row (
const matrix_exp<EXP>& m,
long R
)
{
DLIB_ASSERT(m.nr() > R ,
"\tconst matrix_exp remove_row(const matrix_exp& m, long R)"
<< "\n\tYou can't remove a row from a matrix if it doesn't have it"
<< "\n\tm.nr(): " << m.nr()
<< "\n\tm.nc(): " << m.nc()
<< "\n\tR: " << R
);
typedef matrix_scalar_binary_exp<matrix_exp<EXP>,long,op_remove_row2 > exp;
return matrix_exp<exp>(exp(m,R));
}
// ----------------------------------------------------------------------------------------
struct op_diag

View File

@ -369,13 +369,99 @@ namespace dlib
);
/*!
requires
- m.nr() > 1
- m.nc() > 1
- m.nr() > R
- m.nc() > C
ensures
- returns a matrix R such that:
- R.nr() == m.nr() - 1
- R.nc() == m.nc() - 1
- R == m with its R row and C column removed
- returns a matrix M such that:
- M.nr() == m.nr() - 1
- M.nc() == m.nc() - 1
- M == m with its R row and C column removed
!*/
// ----------------------------------------------------------------------------------------
const matrix_exp removerc (
const matrix_exp& m,
long R,
long C
);
/*!
requires
- m.nr() > R
- m.nc() > C
ensures
- returns a matrix M such that:
- M.nr() == m.nr() - 1
- M.nc() == m.nc() - 1
- M == m with its R row and C column removed
!*/
// ----------------------------------------------------------------------------------------
template <
long R
>
const matrix_exp remove_row (
const matrix_exp& m
);
/*!
requires
- m.nr() > R
ensures
- returns a matrix M such that:
- M.nr() == m.nr() - 1
- M.nc() == m.nc()
- M == m with its R row removed
!*/
// ----------------------------------------------------------------------------------------
const matrix_exp remove_row (
const matrix_exp& m,
long R
);
/*!
requires
- m.nr() > R
ensures
- returns a matrix M such that:
- M.nr() == m.nr() - 1
- M.nc() == m.nc()
- M == m with its R row removed
!*/
// ----------------------------------------------------------------------------------------
template <
long C
>
const matrix_exp remove_col (
const matrix_exp& m
);
/*!
requires
- m.nc() > C
ensures
- returns a matrix M such that:
- M.nr() == m.nr()
- M.nc() == m.nc() - 1
- M == m with its C column removed
!*/
// ----------------------------------------------------------------------------------------
const matrix_exp remove_col (
const matrix_exp& m,
long C
);
/*!
requires
- m.nc() > C
ensures
- returns a matrix M such that:
- M.nr() == m.nr()
- M.nc() == m.nc() - 1
- M == m with its C column removed
!*/
// ----------------------------------------------------------------------------------------

View File

@ -122,6 +122,7 @@ namespace
matrix<double,2,3> mrc2;
set_all_elements(mrc2,1);
DLIB_CASSERT((removerc<1,1>(mrc) == mrc2),"");
DLIB_CASSERT((removerc(mrc,1,1) == mrc2),"");
matrix<int,3,3> m4, m5, m6;
set_all_elements(m4, 4);
@ -1240,9 +1241,40 @@ namespace
4, 4, 4, 4, 4,
9, 0, 3, 3, 0
};
long res_vals_c3[] = {
9, 0, 3, 0,
9, 2, 2, 0,
9, 2, 2, 0,
4, 4, 4, 4,
9, 0, 3, 0
};
long res_vals_r2[] = {
9, 0, 3, 3, 0,
9, 2, 2, 2, 0,
4, 4, 4, 4, 4,
9, 0, 3, 3, 0
};
matrix<long> temp;
res = res_vals;
temp = matrix<long,4,5>(res_vals_r2);
DLIB_CASSERT(remove_row<2>(res) == temp,"");
DLIB_CASSERT(remove_row<2>(res)(3,3) == 3,"");
DLIB_CASSERT(remove_row<2>(res).nr() == 4,"");
DLIB_CASSERT(remove_row<2>(res).nc() == 5,"");
DLIB_CASSERT(remove_row(res,2) == temp,"");
DLIB_CASSERT(remove_row(res,2)(3,3) == 3,"");
DLIB_CASSERT(remove_row(res,2).nr() == 4,"");
DLIB_CASSERT(remove_row(res,2).nc() == 5,"");
temp = matrix<long,5,4>(res_vals_c3);
DLIB_CASSERT(remove_col(res,3) == temp,"");
DLIB_CASSERT(remove_col(res,3)(2,3) == 0,"");
DLIB_CASSERT(remove_col(res,3).nr() == 5,"");
DLIB_CASSERT(remove_col(res,3).nc() == 4,"");
set_all_elements(m2, 1);
set_subm(m1, rectangle(1,1,3,2)) = 2;
set_all_elements(m2, 2);