mirror of https://github.com/davisking/dlib.git
Added unit tests and fixed a few issues.
This commit is contained in:
parent
4b6f44b866
commit
b9ce6dd0a7
|
@ -15,12 +15,22 @@ namespace dlib
|
|||
template <typename M1, typename M2, bool flip_m2 = false>
|
||||
struct op_conv
|
||||
{
|
||||
op_conv( const M1& m1_, const M2& m2_) : m1(m1_),m2(m2_)
|
||||
op_conv( const M1& m1_, const M2& m2_) :
|
||||
m1(m1_),
|
||||
m2(m2_),
|
||||
nr_(m1.nr()+m2.nr()-1),
|
||||
nc_(m1.nc()+m2.nc()-1)
|
||||
{
|
||||
if (nr_ < 0 || m1.size() == 0 || m2.size() == 0)
|
||||
nr_ = 0;
|
||||
if (nc_ < 0 || m1.size() == 0 || m2.size() == 0)
|
||||
nc_ = 0;
|
||||
}
|
||||
|
||||
const M1& m1;
|
||||
const M2& m2;
|
||||
long nr_;
|
||||
long nc_;
|
||||
|
||||
const static long cost = (M1::cost+M2::cost)*10;
|
||||
const static long NR = (M1::NR*M2::NR==0) ? (0) : (M1::NR+M2::NR-1);
|
||||
|
@ -54,8 +64,8 @@ namespace dlib
|
|||
return temp;
|
||||
}
|
||||
|
||||
long nr () const { return m1.nr()+m2.nr()-1; }
|
||||
long nc () const { return m1.nc()+m2.nc()-1; }
|
||||
long nr () const { return nr_; }
|
||||
long nc () const { return nc_; }
|
||||
|
||||
template <typename U> bool aliases ( const matrix_exp<U>& item) const { return m1.aliases(item) || m2.aliases(item); }
|
||||
template <typename U> bool destructively_aliases ( const matrix_exp<U>& item) const { return m1.aliases(item) || m2.aliases(item); }
|
||||
|
@ -70,17 +80,6 @@ namespace dlib
|
|||
const matrix_exp<M1>& m1,
|
||||
const matrix_exp<M2>& m2
|
||||
)
|
||||
/*!
|
||||
requires
|
||||
- m1 and m2 both contain elements of the same type
|
||||
ensures
|
||||
- returns a matrix R such that:
|
||||
- R is the convolution of m1 with m2. In particular, this function is
|
||||
equivalent to performing the following in matlab: R = conv2(m1,m2).
|
||||
- R::type == the same type that was in m1 and m2.
|
||||
- R.nr() == m1.nr()+m2.nr()-1
|
||||
- R.nc() == m1.nc()+m2.nc()-1
|
||||
!*/
|
||||
{
|
||||
COMPILE_TIME_ASSERT((is_same_type<typename M1::type,typename M2::type>::value == true));
|
||||
|
||||
|
@ -96,17 +95,6 @@ namespace dlib
|
|||
const matrix_exp<M1>& m1,
|
||||
const matrix_exp<M2>& m2
|
||||
)
|
||||
/*!
|
||||
requires
|
||||
- m1 and m2 both contain elements of the same type
|
||||
ensures
|
||||
- returns a matrix R such that:
|
||||
- R is the cross-correlation of m1 with m2. In particular, this
|
||||
function returns conv(m1,flip(m2)).
|
||||
- R::type == the same type that was in m1 and m2.
|
||||
- R.nr() == m1.nr()+m2.nr()-1
|
||||
- R.nc() == m1.nc()+m2.nc()-1
|
||||
!*/
|
||||
{
|
||||
COMPILE_TIME_ASSERT((is_same_type<typename M1::type,typename M2::type>::value == true));
|
||||
|
||||
|
@ -120,12 +108,18 @@ namespace dlib
|
|||
template <typename M1, typename M2, bool flip_m2 = false>
|
||||
struct op_conv_same
|
||||
{
|
||||
op_conv_same( const M1& m1_, const M2& m2_) : m1(m1_),m2(m2_)
|
||||
op_conv_same( const M1& m1_, const M2& m2_) : m1(m1_),m2(m2_),nr_(m1.nr()),nc_(m1.nc())
|
||||
{
|
||||
if (m1.size() == 0 || m2.size() == 0)
|
||||
nr_ = 0;
|
||||
if (m1.size() == 0 || m2.size() == 0)
|
||||
nc_ = 0;
|
||||
}
|
||||
|
||||
const M1& m1;
|
||||
const M2& m2;
|
||||
long nr_;
|
||||
long nc_;
|
||||
|
||||
const static long cost = (M1::cost+M2::cost)*10;
|
||||
const static long NR = M1::NR;
|
||||
|
@ -162,8 +156,8 @@ namespace dlib
|
|||
return temp;
|
||||
}
|
||||
|
||||
long nr () const { return m1.nr(); }
|
||||
long nc () const { return m1.nc(); }
|
||||
long nr () const { return nr_; }
|
||||
long nc () const { return nc_; }
|
||||
|
||||
template <typename U> bool aliases ( const matrix_exp<U>& item) const { return m1.aliases(item) || m2.aliases(item); }
|
||||
template <typename U> bool destructively_aliases ( const matrix_exp<U>& item) const { return m1.aliases(item) || m2.aliases(item); }
|
||||
|
@ -178,20 +172,6 @@ namespace dlib
|
|||
const matrix_exp<M1>& m1,
|
||||
const matrix_exp<M2>& m2
|
||||
)
|
||||
/*!
|
||||
requires
|
||||
- m1 and m2 both contain elements of the same type
|
||||
ensures
|
||||
- returns a matrix R such that:
|
||||
- R is the convolution of m1 with m2. In particular, this function is
|
||||
equivalent to performing the following in matlab: R = conv2(m1,m2,'same').
|
||||
In particular, this means the result will have the same dimensions as m1 and will
|
||||
contain the central part of the full convolution. This means conv_same(m1,m2) is
|
||||
equivalent to subm(conv(m1,m2), m2.nr()/2, m2.nc()/2, m1.nr(), m1.nc()).
|
||||
- R::type == the same type that was in m1 and m2.
|
||||
- R.nr() == m1.nr()
|
||||
- R.nc() == m1.nc()
|
||||
!*/
|
||||
{
|
||||
COMPILE_TIME_ASSERT((is_same_type<typename M1::type,typename M2::type>::value == true));
|
||||
|
||||
|
@ -207,17 +187,6 @@ namespace dlib
|
|||
const matrix_exp<M1>& m1,
|
||||
const matrix_exp<M2>& m2
|
||||
)
|
||||
/*!
|
||||
requires
|
||||
- m1 and m2 both contain elements of the same type
|
||||
ensures
|
||||
- returns a matrix R such that:
|
||||
- R is the cross-correlation of m1 with m2. In particular, this
|
||||
function returns conv_same(m1,flip(m2)).
|
||||
- R::type == the same type that was in m1 and m2.
|
||||
- R.nr() == m1.nr()
|
||||
- R.nc() == m1.nc()
|
||||
!*/
|
||||
{
|
||||
COMPILE_TIME_ASSERT((is_same_type<typename M1::type,typename M2::type>::value == true));
|
||||
|
||||
|
@ -236,9 +205,9 @@ namespace dlib
|
|||
nr_(m1.nr()-m2.nr()+1),
|
||||
nc_(m1.nc()-m2.nc()+1)
|
||||
{
|
||||
if (nr_ < 0)
|
||||
if (nr_ < 0 || nc_ <= 0 || m1.size() == 0 || m2.size() == 0)
|
||||
nr_ = 0;
|
||||
if (nc_ < 0)
|
||||
if (nc_ < 0 || nr_ <= 0 || m1.size() == 0 || m2.size() == 0)
|
||||
nc_ = 0;
|
||||
}
|
||||
|
||||
|
@ -298,23 +267,6 @@ namespace dlib
|
|||
const matrix_exp<M1>& m1,
|
||||
const matrix_exp<M2>& m2
|
||||
)
|
||||
/*!
|
||||
requires
|
||||
- m1 and m2 both contain elements of the same type
|
||||
ensures
|
||||
- returns a matrix R such that:
|
||||
- R is the convolution of m1 with m2. In particular, this function is
|
||||
equivalent to performing the following in matlab: R = conv2(m1,m2,'valid').
|
||||
In particular, this means only elements of the convolution which don't require
|
||||
zero padding are included in the result.
|
||||
- R::type == the same type that was in m1 and m2.
|
||||
- if (m1 has larger dimensions than m2) then
|
||||
- R.nr() == m1.nr()-m2.nr()+1
|
||||
- R.nc() == m1.nc()-m2.nc()+1
|
||||
- else
|
||||
- R.nr() == 0
|
||||
- R.nc() == 0
|
||||
!*/
|
||||
{
|
||||
COMPILE_TIME_ASSERT((is_same_type<typename M1::type,typename M2::type>::value == true));
|
||||
|
||||
|
@ -330,21 +282,6 @@ namespace dlib
|
|||
const matrix_exp<M1>& m1,
|
||||
const matrix_exp<M2>& m2
|
||||
)
|
||||
/*!
|
||||
requires
|
||||
- m1 and m2 both contain elements of the same type
|
||||
ensures
|
||||
- returns a matrix R such that:
|
||||
- R is the cross-correlation of m1 with m2. In particular, this
|
||||
function returns conv_valid(m1,flip(m2)).
|
||||
- R::type == the same type that was in m1 and m2.
|
||||
- if (m1 has larger dimensions than m2) then
|
||||
- R.nr() == m1.nr()-m2.nr()+1
|
||||
- R.nc() == m1.nc()-m2.nc()+1
|
||||
- else
|
||||
- R.nr() == 0
|
||||
- R.nc() == 0
|
||||
!*/
|
||||
{
|
||||
COMPILE_TIME_ASSERT((is_same_type<typename M1::type,typename M2::type>::value == true));
|
||||
|
||||
|
|
|
@ -611,6 +611,157 @@ namespace
|
|||
|
||||
|
||||
|
||||
template <
|
||||
long D1,
|
||||
long D2,
|
||||
long D3,
|
||||
long D4
|
||||
>
|
||||
void test_conv()
|
||||
{
|
||||
dlog << LINFO << D1 << " " << D2 << " " << D3 << " " << D4;
|
||||
matrix<int,D1,D1> a(1,1);
|
||||
matrix<int,D2,D2> b(2,2);
|
||||
matrix<int,D3,D3> c(3,3);
|
||||
matrix<int,D4,D1> d(4,1);
|
||||
|
||||
a = 4;
|
||||
|
||||
b = 1,2,
|
||||
3,4;
|
||||
|
||||
c = 1,2,3,
|
||||
4,5,6,
|
||||
7,8,9;
|
||||
|
||||
d = 1,
|
||||
2,
|
||||
3,
|
||||
4;
|
||||
|
||||
matrix<int> temp(4,4), temp2;
|
||||
temp = 1, 4, 7, 6,
|
||||
7, 23, 33, 24,
|
||||
19, 53, 63, 42,
|
||||
21, 52, 59, 36;
|
||||
|
||||
DLIB_TEST(conv(b,c) == temp);
|
||||
DLIB_TEST(conv(c,b) == temp);
|
||||
DLIB_TEST(xcorr(c,flip(b)) == temp);
|
||||
|
||||
temp.set_size(2,2);
|
||||
temp = 23, 33,
|
||||
53, 63;
|
||||
DLIB_TEST(conv_same(b,c) == temp);
|
||||
DLIB_TEST(xcorr_same(b,flip(c)) == temp);
|
||||
|
||||
temp2.set_size(2,2);
|
||||
temp2 = 63, 53,
|
||||
33, 23;
|
||||
DLIB_TEST(flip(temp) == temp2);
|
||||
DLIB_TEST(flip(temp) == fliplr(flipud(temp)));
|
||||
|
||||
DLIB_TEST(conv_valid(b,c).nr() == 0);
|
||||
DLIB_TEST(conv_valid(b,c).nc() == 0);
|
||||
|
||||
DLIB_TEST(conv_valid(c,b) == temp);
|
||||
DLIB_TEST(xcorr_valid(c,flip(b)) == temp);
|
||||
|
||||
temp.set_size(1,1);
|
||||
temp = 16;
|
||||
|
||||
DLIB_TEST(conv(a,a) == temp);
|
||||
DLIB_TEST(conv_same(a,a) == temp);
|
||||
DLIB_TEST(conv_valid(a,a) == temp);
|
||||
DLIB_TEST(xcorr(a,a) == temp);
|
||||
DLIB_TEST(xcorr_same(a,a) == temp);
|
||||
DLIB_TEST(xcorr_valid(a,a) == temp);
|
||||
|
||||
temp.set_size(0,0);
|
||||
DLIB_TEST(conv(temp,temp).nr() == 0);
|
||||
DLIB_TEST(conv(temp,temp).nc() == 0);
|
||||
DLIB_TEST(conv_same(temp,temp).nr() == 0);
|
||||
DLIB_TEST(conv_same(temp,temp).nc() == 0);
|
||||
DLIB_TEST_MSG(conv_valid(temp,temp).nr() == 0, conv_valid(temp,temp).nr());
|
||||
DLIB_TEST(conv_valid(temp,temp).nc() == 0);
|
||||
DLIB_TEST(conv(c,temp).nr() == 0);
|
||||
DLIB_TEST(conv(c,temp).nc() == 0);
|
||||
DLIB_TEST(conv_same(c,temp).nr() == 0);
|
||||
DLIB_TEST(conv_same(c,temp).nc() == 0);
|
||||
DLIB_TEST(conv_valid(c,temp).nr() == 0);
|
||||
DLIB_TEST(conv_valid(c,temp).nc() == 0);
|
||||
DLIB_TEST(conv(temp,c).nr() == 0);
|
||||
DLIB_TEST(conv(temp,c).nc() == 0);
|
||||
DLIB_TEST(conv_same(temp,c).nr() == 0);
|
||||
DLIB_TEST(conv_same(temp,c).nc() == 0);
|
||||
DLIB_TEST(conv_valid(temp,c).nr() == 0);
|
||||
DLIB_TEST(conv_valid(temp,c).nc() == 0);
|
||||
|
||||
temp.set_size(5,2);
|
||||
temp = 1, 2,
|
||||
5, 8,
|
||||
9, 14,
|
||||
13, 20,
|
||||
12, 16;
|
||||
DLIB_TEST(conv(b,d) == temp);
|
||||
DLIB_TEST(xcorr(b,flip(d)) == temp);
|
||||
|
||||
temp.set_size(2,2);
|
||||
temp = 9, 14,
|
||||
13, 20;
|
||||
DLIB_TEST(conv_same(b,d) == temp);
|
||||
DLIB_TEST(xcorr_same(b,flip(d)) == temp);
|
||||
|
||||
DLIB_TEST(conv_valid(b,d).nr() == 0);
|
||||
DLIB_TEST(xcorr_valid(b,flip(d)).nr() == 0);
|
||||
DLIB_TEST_MSG(conv_valid(b,d).nc() == 0, conv_valid(b,d).nc());
|
||||
DLIB_TEST(xcorr_valid(b,flip(d)).nc() == 0);
|
||||
|
||||
temp.set_size(5,5);
|
||||
temp = 1, 4, 10, 12, 9,
|
||||
8, 26, 56, 54, 36,
|
||||
30, 84, 165, 144, 90,
|
||||
56, 134, 236, 186, 108,
|
||||
49, 112, 190, 144, 81;
|
||||
|
||||
DLIB_TEST(conv(c,c) == temp);
|
||||
DLIB_TEST(xcorr(c,flip(c)) == temp);
|
||||
matrix<int> temp3 = c;
|
||||
temp3 = conv(temp3,c);
|
||||
DLIB_TEST(temp3 == temp);
|
||||
|
||||
temp3 = c;
|
||||
temp3 = conv(c,temp3);
|
||||
DLIB_TEST(temp3 == temp);
|
||||
|
||||
|
||||
temp.set_size(3,3);
|
||||
temp = 26, 56, 54,
|
||||
84, 165, 144,
|
||||
134, 236, 186;
|
||||
DLIB_TEST(conv_same(c,c) == temp);
|
||||
DLIB_TEST(xcorr_same(c,flip(c)) == temp);
|
||||
temp3 = c;
|
||||
temp3 = conv_same(c,temp3);
|
||||
DLIB_TEST(temp3 == temp);
|
||||
temp3 = c;
|
||||
temp3 = conv_same(temp3,c);
|
||||
DLIB_TEST(temp3 == temp);
|
||||
|
||||
temp.set_size(1,1);
|
||||
temp = 165;
|
||||
DLIB_TEST(conv_valid(c,c) == temp);
|
||||
DLIB_TEST(xcorr_valid(c,flip(c)) == temp);
|
||||
temp3 = c;
|
||||
temp3 = conv_valid(c,temp3);
|
||||
DLIB_TEST(temp3 == temp);
|
||||
temp3 = c;
|
||||
temp3 = conv_valid(temp3,c);
|
||||
DLIB_TEST(temp3 == temp);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
class matrix_tester : public tester
|
||||
|
@ -625,6 +776,9 @@ namespace
|
|||
void perform_test (
|
||||
)
|
||||
{
|
||||
test_conv<0,0,0,0>();
|
||||
test_conv<1,2,3,4>();
|
||||
|
||||
test_stuff();
|
||||
for (int i = 0; i < 10; ++i)
|
||||
matrix_test();
|
||||
|
|
Loading…
Reference in New Issue