Commit 9ab53f01 authored by Davis King's avatar Davis King

Added the += and -= operators to the set_subm(), set_rowm(), and set_colm()

functions.
parent b5b061f9
...@@ -583,6 +583,62 @@ namespace dlib ...@@ -583,6 +583,62 @@ namespace dlib
return *this; return *this;
} }
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, subm(m,rect)+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;
}
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, subm(m,rect)-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= ( assignable_sub_matrix& operator= (
const T& value const T& value
) )
...@@ -598,6 +654,36 @@ namespace dlib ...@@ -598,6 +654,36 @@ namespace dlib
return *this; 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;
}
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;
}
matrix<T,NR,NC,mm,l>& m; matrix<T,NR,NC,mm,l>& m;
const rectangle rect; const rectangle rect;
...@@ -705,6 +791,62 @@ namespace dlib ...@@ -705,6 +791,62 @@ namespace dlib
return *this; return *this;
} }
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, subm(m,rows,cols)+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;
}
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, subm(m,rows,cols)-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= ( assignable_sub_range_matrix& operator= (
const T& value const T& value
) )
...@@ -720,6 +862,36 @@ namespace dlib ...@@ -720,6 +862,36 @@ namespace dlib
return *this; 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;
}
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: private:
matrix<T,NR,NC,mm,l>& m; matrix<T,NR,NC,mm,l>& m;
...@@ -858,6 +1030,60 @@ namespace dlib ...@@ -858,6 +1030,60 @@ namespace dlib
return *this; return *this;
} }
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, colm(m,col)+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;
}
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, colm(m,col)-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= ( assignable_col_matrix& operator= (
const T& value const T& value
) )
...@@ -870,6 +1096,30 @@ namespace dlib ...@@ -870,6 +1096,30 @@ namespace dlib
return *this; return *this;
} }
assignable_col_matrix& operator+= (
const T& value
)
{
for (long i = 0; i < m.nr(); ++i)
{
m(i,col) += value;
}
return *this;
}
assignable_col_matrix& operator-= (
const T& value
)
{
for (long i = 0; i < m.nr(); ++i)
{
m(i,col) -= value;
}
return *this;
}
matrix<T,NR,NC,mm,l>& m; matrix<T,NR,NC,mm,l>& m;
const long col; const long col;
...@@ -958,6 +1208,60 @@ namespace dlib ...@@ -958,6 +1208,60 @@ namespace dlib
return *this; return *this;
} }
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, rowm(m,row)+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;
}
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, rowm(m,row)-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= ( assignable_row_matrix& operator= (
const T& value const T& value
) )
...@@ -970,6 +1274,30 @@ namespace dlib ...@@ -970,6 +1274,30 @@ namespace dlib
return *this; return *this;
} }
assignable_row_matrix& operator+= (
const T& value
)
{
for (long i = 0; i < m.nc(); ++i)
{
m(row,i) += value;
}
return *this;
}
assignable_row_matrix& operator-= (
const T& value
)
{
for (long i = 0; i < m.nc(); ++i)
{
m(row,i) -= value;
}
return *this;
}
matrix<T,NR,NC,mm,l>& m; matrix<T,NR,NC,mm,l>& m;
const long row; const long row;
......
...@@ -324,6 +324,10 @@ namespace dlib ...@@ -324,6 +324,10 @@ namespace dlib
- set_subm(m,row,col,nr,nc) = scalar_value; - set_subm(m,row,col,nr,nc) = scalar_value;
result in it being the case that: result in it being the case that:
- subm(m,row,col,nr,nc) == uniform_matrix<matrix::type>(nr,nc,scalar_value). - subm(m,row,col,nr,nc) == uniform_matrix<matrix::type>(nr,nc,scalar_value).
- In addition to the normal assignment statements using the = symbol, you may
also use the usual += and -= versions of the assignment operator. In these
cases, they have their usual effect.
!*/ !*/
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
...@@ -346,6 +350,10 @@ namespace dlib ...@@ -346,6 +350,10 @@ namespace dlib
- set_subm(m,rect) = scalar_value; - set_subm(m,rect) = scalar_value;
result in it being the case that: result in it being the case that:
- subm(m,rect) == uniform_matrix<matrix::type>(nr,nc,scalar_value). - subm(m,rect) == uniform_matrix<matrix::type>(nr,nc,scalar_value).
- In addition to the normal assignment statements using the = symbol, you may
also use the usual += and -= versions of the assignment operator. In these
cases, they have their usual effect.
!*/ !*/
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
...@@ -373,6 +381,10 @@ namespace dlib ...@@ -373,6 +381,10 @@ namespace dlib
- set_subm(m,rows,cols) = scalar_value; - set_subm(m,rows,cols) = scalar_value;
result in it being the case that: result in it being the case that:
- subm(m,rows,cols) == uniform_matrix<matrix::type>(nr,nc,scalar_value). - subm(m,rows,cols) == uniform_matrix<matrix::type>(nr,nc,scalar_value).
- In addition to the normal assignment statements using the = symbol, you may
also use the usual += and -= versions of the assignment operator. In these
cases, they have their usual effect.
!*/ !*/
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
...@@ -394,6 +406,10 @@ namespace dlib ...@@ -394,6 +406,10 @@ namespace dlib
- set_rowm(m,row) = scalar_value; - set_rowm(m,row) = scalar_value;
result in it being the case that: result in it being the case that:
- rowm(m,row) == uniform_matrix<matrix::type>(1,nc,scalar_value). - rowm(m,row) == uniform_matrix<matrix::type>(1,nc,scalar_value).
- In addition to the normal assignment statements using the = symbol, you may
also use the usual += and -= versions of the assignment operator. In these
cases, they have their usual effect.
!*/ !*/
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
...@@ -418,6 +434,10 @@ namespace dlib ...@@ -418,6 +434,10 @@ namespace dlib
- set_rowm(m,rows) = scalar_value; - set_rowm(m,rows) = scalar_value;
result in it being the case that: result in it being the case that:
- rowm(m,rows) == uniform_matrix<matrix::type>(nr,nc,scalar_value). - rowm(m,rows) == uniform_matrix<matrix::type>(nr,nc,scalar_value).
- In addition to the normal assignment statements using the = symbol, you may
also use the usual += and -= versions of the assignment operator. In these
cases, they have their usual effect.
!*/ !*/
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
...@@ -439,6 +459,10 @@ namespace dlib ...@@ -439,6 +459,10 @@ namespace dlib
- set_colm(m,col) = scalar_value; - set_colm(m,col) = scalar_value;
result in it being the case that: result in it being the case that:
- colm(m,col) == uniform_matrix<matrix::type>(nr,1,scalar_value). - colm(m,col) == uniform_matrix<matrix::type>(nr,1,scalar_value).
- In addition to the normal assignment statements using the = symbol, you may
also use the usual += and -= versions of the assignment operator. In these
cases, they have their usual effect.
!*/ !*/
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
...@@ -463,6 +487,10 @@ namespace dlib ...@@ -463,6 +487,10 @@ namespace dlib
- set_colm(m,cols) = scalar_value; - set_colm(m,cols) = scalar_value;
result in it being the case that: result in it being the case that:
- colm(m,cols) == uniform_matrix<matrix::type>(nr,nc,scalar_value). - colm(m,cols) == uniform_matrix<matrix::type>(nr,nc,scalar_value).
- In addition to the normal assignment statements using the = symbol, you may
also use the usual += and -= versions of the assignment operator. In these
cases, they have their usual effect.
!*/ !*/
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
......
...@@ -810,6 +810,106 @@ namespace ...@@ -810,6 +810,106 @@ namespace
DLIB_TEST(mean(a) == complex<double>(4, 5)); DLIB_TEST(mean(a) == complex<double>(4, 5));
} }
void test_setsubs()
{
{
matrix<double> m(3,3);
m = 0;
set_colm(m,0) += 1;
set_rowm(m,0) += 1;
set_subm(m,1,1,2,2) += 5;
matrix<double> m2(3,3);
m2 = 2, 1, 1,
1, 5, 5,
1, 5, 5;
DLIB_TEST(m == m2);
set_colm(m,0) -= 1;
set_rowm(m,0) -= 1;
set_subm(m,1,1,2,2) -= 5;
m2 = 0;
DLIB_TEST(m == m2);
matrix<double,1,3> r;
matrix<double,3,1> c;
matrix<double,2,2> b;
r = 1,2,3;
c = 2,
3,
4;
b = 2,3,
4,5;
set_colm(m,1) += c;
set_rowm(m,1) += r;
set_subm(m,1,1,2,2) += b;
m2 = 0, 2, 0,
1, 7, 6,
0, 8, 5;
DLIB_TEST(m2 == m);
set_colm(m,1) -= c;
set_rowm(m,1) -= r;
set_subm(m,1,1,2,2) -= b;
m2 = 0;
DLIB_TEST(m2 == m);
// check that the code path for destructive aliasing works right.
m = 2*identity_matrix<double>(3);
set_colm(m,1) += m*c;
m2 = 2, 4, 0,
0, 8, 0,
0, 8, 2;
DLIB_TEST(m == m2);
m = 2*identity_matrix<double>(3);
set_colm(m,1) -= m*c;
m2 = 2, -4, 0,
0, -4, 0,
0, -8, 2;
DLIB_TEST(m == m2);
m = 2*identity_matrix<double>(3);
set_rowm(m,1) += r*m;
m2 = 2, 0, 0,
2, 6, 6,
0, 0, 2;
DLIB_TEST(m == m2);
m = 2*identity_matrix<double>(3);
set_rowm(m,1) -= r*m;
m2 = 2, 0, 0,
-2, -2, -6,
0, 0, 2;
DLIB_TEST(m == m2);
m = identity_matrix<double>(3);
const rectangle rect(0,0,1,1);
set_subm(m,rect) += subm(m,rect)*b;
m2 = 3, 3, 0,
4, 6, 0,
0, 0, 1;
DLIB_TEST(m == m2);
m = identity_matrix<double>(3);
set_subm(m,rect) -= subm(m,rect)*b;
m2 = -1, -3, 0,
-4, -4, 0,
0, 0, 1;
DLIB_TEST(m == m2);
}
}
class matrix_tester : public tester class matrix_tester : public tester
{ {
...@@ -823,6 +923,8 @@ namespace ...@@ -823,6 +923,8 @@ namespace
void perform_test ( void perform_test (
) )
{ {
test_setsubs();
test_conv<0,0,0,0>(); test_conv<0,0,0,0>();
test_conv<1,2,3,4>(); test_conv<1,2,3,4>();
......
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