Commit d6a3b848 authored by Davis King's avatar Davis King

Updated the += and -= operators to be a little more flexible.

--HG--
extra : convert_revision : svn%3Afdd8eb12-d10e-0410-9acb-85c331704f74/trunk%403563
parent c2a83270
...@@ -1387,28 +1387,26 @@ namespace dlib ...@@ -1387,28 +1387,26 @@ namespace dlib
// m's dimensions don't match that of *this. // m's dimensions don't match that of *this.
COMPILE_TIME_ASSERT(EXP::NR == NR || NR == 0 || EXP::NR == 0); COMPILE_TIME_ASSERT(EXP::NR == NR || NR == 0 || EXP::NR == 0);
COMPILE_TIME_ASSERT(EXP::NC == NC || NC == 0 || EXP::NC == 0); COMPILE_TIME_ASSERT(EXP::NC == NC || NC == 0 || EXP::NC == 0);
DLIB_ASSERT(this->nr() == m.nr() && this->nc() == m.nc(),
"\tmatrix& matrix::operator+=(const matrix_exp& m)"
<< "\n\tYou are trying to add a dynamically sized matrix to a statically sized matrix with the wrong size"
<< "\n\tthis->nr(): " << nr()
<< "\n\tthis->nc(): " << nc()
<< "\n\tm.nr(): " << m.nr()
<< "\n\tm.nc(): " << m.nc()
<< "\n\tthis: " << this
);
COMPILE_TIME_ASSERT((is_same_type<typename EXP::type,type>::value == true)); COMPILE_TIME_ASSERT((is_same_type<typename EXP::type,type>::value == true));
if (m.destructively_aliases(*this) == false) if (nr() == m.nr() && nc() == m.nc())
{ {
matrix_assign(*this, *this + m); if (m.destructively_aliases(*this) == false)
{
matrix_assign(*this, *this + m);
}
else
{
// we have to use a temporary matrix object here because
// this->data is aliased inside the matrix_exp m somewhere.
matrix temp;
temp.set_size(m.nr(),m.nc());
matrix_assign(temp, *this + m);
temp.swap(*this);
}
} }
else else
{ {
// we have to use a temporary matrix object here because *this = m;
// this->data is aliased inside the matrix_exp m somewhere.
matrix temp;
temp.set_size(m.nr(),m.nc());
matrix_assign(temp, *this + m);
temp.swap(*this);
} }
return *this; return *this;
} }
...@@ -1423,28 +1421,26 @@ namespace dlib ...@@ -1423,28 +1421,26 @@ namespace dlib
// m's dimensions don't match that of *this. // m's dimensions don't match that of *this.
COMPILE_TIME_ASSERT(EXP::NR == NR || NR == 0 || EXP::NR == 0); COMPILE_TIME_ASSERT(EXP::NR == NR || NR == 0 || EXP::NR == 0);
COMPILE_TIME_ASSERT(EXP::NC == NC || NC == 0 || EXP::NC == 0); COMPILE_TIME_ASSERT(EXP::NC == NC || NC == 0 || EXP::NC == 0);
DLIB_ASSERT(this->nr() == m.nr() && this->nc() == m.nc(),
"\tmatrix& matrix::operator-=(const matrix_exp& m)"
<< "\n\tYou are trying to subtract a dynamically sized matrix from a statically sized matrix with the wrong size"
<< "\n\tthis->nr(): " << nr()
<< "\n\tthis->nc(): " << nc()
<< "\n\tm.nr(): " << m.nr()
<< "\n\tm.nc(): " << m.nc()
<< "\n\tthis: " << this
);
COMPILE_TIME_ASSERT((is_same_type<typename EXP::type,type>::value == true)); COMPILE_TIME_ASSERT((is_same_type<typename EXP::type,type>::value == true));
if (m.destructively_aliases(*this) == false) if (nr() == m.nr() && nc() == m.nc())
{ {
matrix_assign(*this, *this - m); if (m.destructively_aliases(*this) == false)
{
matrix_assign(*this, *this - m);
}
else
{
// we have to use a temporary matrix object here because
// this->data is aliased inside the matrix_exp m somewhere.
matrix temp;
temp.set_size(m.nr(),m.nc());
matrix_assign(temp, *this - m);
temp.swap(*this);
}
} }
else else
{ {
// we have to use a temporary matrix object here because *this = -m;
// this->data is aliased inside the matrix_exp m somewhere.
matrix temp;
temp.set_size(m.nr(),m.nc());
matrix_assign(temp, *this - m);
temp.swap(*this);
} }
return *this; return *this;
} }
...@@ -1454,8 +1450,17 @@ namespace dlib ...@@ -1454,8 +1450,17 @@ namespace dlib
) )
{ {
const long size = m.nr()*m.nc(); const long size = m.nr()*m.nc();
for (long i = 0; i < size; ++i) if (nr() == m.nr() && nc() == m.nc())
data(i) += m.data(i); {
for (long i = 0; i < size; ++i)
data(i) += m.data(i);
}
else
{
set_size(m.nr(), m.nc());
for (long i = 0; i < size; ++i)
data(i) = m.data(i);
}
return *this; return *this;
} }
...@@ -1464,8 +1469,17 @@ namespace dlib ...@@ -1464,8 +1469,17 @@ namespace dlib
) )
{ {
const long size = m.nr()*m.nc(); const long size = m.nr()*m.nc();
for (long i = 0; i < size; ++i) if (nr() == m.nr() && nc() == m.nc())
data(i) -= m.data(i); {
for (long i = 0; i < size; ++i)
data(i) -= m.data(i);
}
else
{
set_size(m.nr(), m.nc());
for (long i = 0; i < size; ++i)
data(i) = -m.data(i);
}
return *this; return *this;
} }
......
...@@ -611,10 +611,13 @@ namespace dlib ...@@ -611,10 +611,13 @@ namespace dlib
/*! /*!
requires requires
- matrix_exp<EXP>::type == T - matrix_exp<EXP>::type == T
- nr() == m.nr()
- nc() == m.nc()
ensures ensures
- #(*this) == *this + m - if (nr() == m.nr() && nc() == m.nc()) then
- #(*this) == *this + m
- else
- #(*this) == m
(i.e. if the dimensions don't match then this function performs a
normal assignment)
- returns *this - returns *this
!*/ !*/
...@@ -625,10 +628,11 @@ namespace dlib ...@@ -625,10 +628,11 @@ namespace dlib
/*! /*!
requires requires
- matrix_exp<EXP>::type == T - matrix_exp<EXP>::type == T
- nr() == m.nr()
- nc() == m.nc()
ensures ensures
- #(*this) == *this - m - if (nr() == m.nr() && nc() == m.nc()) then
- #(*this) == *this - m
- else
- #(*this) == -m
- returns *this - returns *this
!*/ !*/
...@@ -672,6 +676,9 @@ namespace dlib ...@@ -672,6 +676,9 @@ namespace dlib
exactly m.size() or 1 values so that the matrix is fully initialized. Supplying exactly m.size() or 1 values so that the matrix is fully initialized. Supplying
fewer or more than that is an error that will cause a dlib::fatal_error to be fewer or more than that is an error that will cause a dlib::fatal_error to be
thrown. thrown.
Note also that using an expression of the form m = scalar; when m.size() == 0
is legal but has no effect on m.
!*/ !*/
void swap ( void swap (
......
...@@ -776,6 +776,39 @@ namespace ...@@ -776,6 +776,39 @@ namespace
DLIB_TEST((1>=a) == b); DLIB_TEST((1>=a) == b);
} }
{
matrix<double> a, b, c;
a = randm(4,2);
b += a;
c -= a;
DLIB_TEST(equal(a, b));
DLIB_TEST(equal(-a, c));
b += a;
c -= a;
DLIB_TEST(equal(2*a, b));
DLIB_TEST(equal(-2*a, c));
b += a + a;
c -= a + a;
DLIB_TEST(equal(4*a, b));
DLIB_TEST(equal(-4*a, c));
b.set_size(0,0);
c.set_size(0,0);
b += a + a;
c -= a + a;
DLIB_TEST(equal(2*a, b));
DLIB_TEST(equal(-2*a, c));
}
} }
......
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