diff --git a/dlib/matrix/matrix_utilities.h b/dlib/matrix/matrix_utilities.h index f519f5021..7841168a8 100644 --- a/dlib/matrix/matrix_utilities.h +++ b/dlib/matrix/matrix_utilities.h @@ -314,6 +314,84 @@ namespace dlib return val; } +// ---------------------------------------------------------------------------------------- + + template + struct op_binary_min : basic_op_mm + { + op_binary_min( const M1& m1_, const M2& m2_) : basic_op_mm(m1_,m2_){} + + typedef typename M1::type type; + typedef const type const_ret_type; + const static long cost = M1::cost + M2::cost + 1; + + const_ret_type apply ( long r, long c) const + { return std::min(this->m1(r,c),this->m2(r,c)); } + }; + + template < + typename EXP1, + typename EXP2 + > + inline const matrix_op > min_pointwise ( + const matrix_exp& a, + const matrix_exp& b + ) + { + COMPILE_TIME_ASSERT((is_same_type::value == true)); + COMPILE_TIME_ASSERT(EXP1::NR == EXP2::NR || EXP1::NR == 0 || EXP2::NR == 0); + COMPILE_TIME_ASSERT(EXP1::NC == EXP2::NC || EXP1::NC == 0 || EXP2::NC == 0); + DLIB_ASSERT(a.nr() == b.nr() && + a.nc() == b.nc(), + "\t const matrix_exp min_pointwise(const matrix_exp& a, const matrix_exp& b)" + << "\n\ta.nr(): " << a.nr() + << "\n\ta.nc(): " << a.nc() + << "\n\tb.nr(): " << b.nr() + << "\n\tb.nc(): " << b.nc() + ); + typedef op_binary_min op; + return matrix_op(op(a.ref(),b.ref())); + } + +// ---------------------------------------------------------------------------------------- + + template + struct op_binary_max : basic_op_mm + { + op_binary_max( const M1& m1_, const M2& m2_) : basic_op_mm(m1_,m2_){} + + typedef typename M1::type type; + typedef const type const_ret_type; + const static long cost = M1::cost + M2::cost + 1; + + const_ret_type apply ( long r, long c) const + { return std::max(this->m1(r,c),this->m2(r,c)); } + }; + + template < + typename EXP1, + typename EXP2 + > + inline const matrix_op > max_pointwise ( + const matrix_exp& a, + const matrix_exp& b + ) + { + COMPILE_TIME_ASSERT((is_same_type::value == true)); + COMPILE_TIME_ASSERT(EXP1::NR == EXP2::NR || EXP1::NR == 0 || EXP2::NR == 0); + COMPILE_TIME_ASSERT(EXP1::NC == EXP2::NC || EXP1::NC == 0 || EXP2::NC == 0); + DLIB_ASSERT(a.nr() == b.nr() && + a.nc() == b.nc(), + "\t const matrix_exp max_pointwise(const matrix_exp& a, const matrix_exp& b)" + << "\n\ta.nr(): " << a.nr() + << "\n\ta.nc(): " << a.nc() + << "\n\tb.nr(): " << b.nr() + << "\n\tb.nc(): " << b.nc() + ); + typedef op_binary_max op; + return matrix_op(op(a.ref(),b.ref())); + } + // ---------------------------------------------------------------------------------------- template < diff --git a/dlib/matrix/matrix_utilities_abstract.h b/dlib/matrix/matrix_utilities_abstract.h index 26c060fdc..47dcebe88 100644 --- a/dlib/matrix/matrix_utilities_abstract.h +++ b/dlib/matrix/matrix_utilities_abstract.h @@ -1361,6 +1361,25 @@ namespace dlib according to std::norm(). !*/ +// ---------------------------------------------------------------------------------------- + + const matrix_exp min_pointwise ( + const matrix_exp& a, + const matrix_exp& b + ); + /*! + requires + - a.nr() == b.nr() + - a.nc() == b.nc() + - a and b both contain the same type of element + ensures + - returns a matrix R such that: + - R::type == the same type that was in a and b. + - R has the same dimensions as a and b. + - for all valid r and c: + R(r,c) == std::min(a(r,c), b(r,c)) + !*/ + // ---------------------------------------------------------------------------------------- const matrix_exp::type max ( @@ -1375,6 +1394,25 @@ namespace dlib according to std::norm(). !*/ +// ---------------------------------------------------------------------------------------- + + const matrix_exp max_pointwise ( + const matrix_exp& a, + const matrix_exp& b + ); + /*! + requires + - a.nr() == b.nr() + - a.nc() == b.nc() + - a and b both contain the same type of element + ensures + - returns a matrix R such that: + - R::type == the same type that was in a and b. + - R has the same dimensions as a and b. + - for all valid r and c: + R(r,c) == std::max(a(r,c), b(r,c)) + !*/ + // ---------------------------------------------------------------------------------------- void find_min_and_max ( diff --git a/dlib/test/matrix.cpp b/dlib/test/matrix.cpp index 2ba4c2427..7d95a8006 100644 --- a/dlib/test/matrix.cpp +++ b/dlib/test/matrix.cpp @@ -1063,6 +1063,28 @@ namespace } + { + matrix a = randm(3,4); + matrix b = randm(3,4); + + matrix m1, m2; + + m1 = max_pointwise(a,b); + m2 = min_pointwise(a,b); + DLIB_TEST(m1.nr() == a.nr()); + DLIB_TEST(m1.nc() == a.nc()); + DLIB_TEST(m2.nr() == a.nr()); + DLIB_TEST(m2.nc() == a.nc()); + for (long r = 0; r < a.nr(); ++r) + { + for (long c = 0; c < a.nc(); ++c) + { + DLIB_TEST_MSG(m1(r,c) == std::max(a(r,c), b(r,c)), m1(r,c) << " : " << a(r,c) << " " << b(r,c)); + DLIB_TEST(m2(r,c) == std::min(a(r,c), b(r,c))); + } + } + } + { matrix m; set_subm(m, range(0,3), range(0,4)) = 4;