Commit 3fc0a290 authored by Davis King's avatar Davis King

Made the matrix rounding functions a little more general. They

are now able to be called on integral types and just do nothing
in that case.

--HG--
extra : convert_revision : svn%3Afdd8eb12-d10e-0410-9acb-85c331704f74/trunk%402726
parent 22770e29
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
#ifndef DLIB_MATRIx_MATH_FUNCTIONS #ifndef DLIB_MATRIx_MATH_FUNCTIONS
#define DLIB_MATRIx_MATH_FUNCTIONS #define DLIB_MATRIx_MATH_FUNCTIONS
#include "matrix_math_functions_abstract.h"
#include "matrix_utilities.h" #include "matrix_utilities.h"
#include "matrix.h" #include "matrix.h"
#include "../algs.h" #include "../algs.h"
...@@ -110,12 +111,8 @@ DLIB_MATRIX_SIMPLE_STD_FUNCTION(atan) ...@@ -110,12 +111,8 @@ DLIB_MATRIX_SIMPLE_STD_FUNCTION(atan)
const matrix_exp<EXP>& m const matrix_exp<EXP>& m
) )
{ {
// you can only round matrices that contain floats, doubles or long doubles. // you can only round matrices that contain built in scalar types like double, long, float, etc...
COMPILE_TIME_ASSERT(( COMPILE_TIME_ASSERT(is_built_in_scalar_type<typename EXP::type>::value);
is_same_type<typename EXP::type,float>::value == true ||
is_same_type<typename EXP::type,double>::value == true ||
is_same_type<typename EXP::type,long double>::value == true
));
typedef matrix_scalar_binary_exp<matrix_exp<EXP>,typename EXP::type, op_round_zeros> exp; typedef matrix_scalar_binary_exp<matrix_exp<EXP>,typename EXP::type, op_round_zeros> exp;
return matrix_exp<exp>(exp(m,10*std::numeric_limits<typename EXP::type>::epsilon())); return matrix_exp<exp>(exp(m,10*std::numeric_limits<typename EXP::type>::epsilon()));
} }
...@@ -128,12 +125,8 @@ DLIB_MATRIX_SIMPLE_STD_FUNCTION(atan) ...@@ -128,12 +125,8 @@ DLIB_MATRIX_SIMPLE_STD_FUNCTION(atan)
typename EXP::type eps typename EXP::type eps
) )
{ {
// you can only round matrices that contain floats, doubles or long doubles. // you can only round matrices that contain built in scalar types like double, long, float, etc...
COMPILE_TIME_ASSERT(( COMPILE_TIME_ASSERT(is_built_in_scalar_type<typename EXP::type>::value);
is_same_type<typename EXP::type,float>::value == true ||
is_same_type<typename EXP::type,double>::value == true ||
is_same_type<typename EXP::type,long double>::value == true
));
typedef matrix_scalar_binary_exp<matrix_exp<EXP>,typename EXP::type, op_round_zeros> exp; typedef matrix_scalar_binary_exp<matrix_exp<EXP>,typename EXP::type, op_round_zeros> exp;
return matrix_exp<exp>(exp(m,eps)); return matrix_exp<exp>(exp(m,eps));
} }
...@@ -306,7 +299,7 @@ DLIB_MATRIX_SIMPLE_STD_FUNCTION(atan) ...@@ -306,7 +299,7 @@ DLIB_MATRIX_SIMPLE_STD_FUNCTION(atan)
struct op_round struct op_round
{ {
template <typename EXP> template <typename EXP, typename enabled = void>
struct op : has_nondestructive_aliasing, preserves_dimensions<EXP> struct op : has_nondestructive_aliasing, preserves_dimensions<EXP>
{ {
typedef typename EXP::type type; typedef typename EXP::type type;
...@@ -316,6 +309,18 @@ DLIB_MATRIX_SIMPLE_STD_FUNCTION(atan) ...@@ -316,6 +309,18 @@ DLIB_MATRIX_SIMPLE_STD_FUNCTION(atan)
return static_cast<type>(std::floor(m(r,c)+0.5)); return static_cast<type>(std::floor(m(r,c)+0.5));
} }
}; };
template <typename EXP>
struct op<EXP,typename enable_if_c<std::numeric_limits<typename EXP::type>::is_integer>::type >
: has_nondestructive_aliasing, preserves_dimensions<EXP>
{
typedef typename EXP::type type;
template <typename M>
static type apply ( const M& m, long r, long c)
{
return m(r,c);
}
};
}; };
template < template <
...@@ -325,12 +330,8 @@ DLIB_MATRIX_SIMPLE_STD_FUNCTION(atan) ...@@ -325,12 +330,8 @@ DLIB_MATRIX_SIMPLE_STD_FUNCTION(atan)
const matrix_exp<EXP>& m const matrix_exp<EXP>& m
) )
{ {
// you can only round matrices that contain floats, doubles or long doubles. // you can only round matrices that contain built in scalar types like double, long, float, etc...
COMPILE_TIME_ASSERT(( COMPILE_TIME_ASSERT(is_built_in_scalar_type<typename EXP::type>::value);
is_same_type<typename EXP::type,float>::value == true ||
is_same_type<typename EXP::type,double>::value == true ||
is_same_type<typename EXP::type,long double>::value == true
));
typedef matrix_unary_exp<matrix_exp<EXP>,op_round> exp; typedef matrix_unary_exp<matrix_exp<EXP>,op_round> exp;
return matrix_exp<exp>(exp(m)); return matrix_exp<exp>(exp(m));
} }
......
...@@ -191,13 +191,17 @@ namespace dlib ...@@ -191,13 +191,17 @@ namespace dlib
); );
/*! /*!
requires requires
- matrix_exp::type == float, double, or long double - is_built_in_scalar_type<matrix_exp::type>::value == true
(i.e. m must contain a type like int, float, double, long, etc...)
ensures ensures
- returns a matrix R such that: - if (m contains integers) then
- R::type == the same type that was in m - returns m unmodified
- R has the same dimensions as m - else
- for all valid r and c: - returns a matrix R such that:
R(r,c) == m(r,c) rounded to the nearest integral value - R::type == the same type that was in m
- R has the same dimensions as m
- for all valid r and c:
R(r,c) == m(r,c) rounded to the nearest integral value
!*/ !*/
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
...@@ -206,8 +210,6 @@ namespace dlib ...@@ -206,8 +210,6 @@ namespace dlib
const matrix_exp& m const matrix_exp& m
); );
/*! /*!
requires
- matrix_exp::type == float, double, or long double
ensures ensures
- returns a matrix R such that: - returns a matrix R such that:
- R::type == the same type that was in m - R::type == the same type that was in m
...@@ -222,8 +224,6 @@ namespace dlib ...@@ -222,8 +224,6 @@ namespace dlib
const matrix_exp& m const matrix_exp& m
); );
/*! /*!
requires
- matrix_exp::type == float, double, or long double
ensures ensures
- returns a matrix R such that: - returns a matrix R such that:
- R::type == the same type that was in m - R::type == the same type that was in m
...@@ -239,17 +239,21 @@ namespace dlib ...@@ -239,17 +239,21 @@ namespace dlib
); );
/*! /*!
requires requires
- matrix_exp::type == float, double, or long double - is_built_in_scalar_type<matrix_exp::type>::value == true
(i.e. m must contain a type like int, float, double, long, etc...)
ensures ensures
- returns a matrix R such that: - if (m contains integers) then
- R::type == the same type that was in m - returns m unmodified
- R has the same dimensions as m - else
- let eps == 10*std::numeric_limits<matrix_exp::type>::epsilon() - returns a matrix R such that:
- for all valid r and c: - R::type == the same type that was in m
- if (abs(m(r,c)) >= eps) then - R has the same dimensions as m
- R(r,c) == m(r,c) - let eps == 10*std::numeric_limits<matrix_exp::type>::epsilon()
- else - for all valid r and c:
- R(r,c) == 0 - if (abs(m(r,c)) >= eps) then
- R(r,c) == m(r,c)
- else
- R(r,c) == 0
!*/ !*/
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
...@@ -260,7 +264,8 @@ namespace dlib ...@@ -260,7 +264,8 @@ namespace dlib
); );
/*! /*!
requires requires
- matrix_exp::type == float, double, or long double - is_built_in_scalar_type<matrix_exp::type>::value == true
(i.e. m must contain a type like int, float, double, long, etc...)
ensures ensures
- returns a matrix R such that: - returns a matrix R such that:
- R::type == the same type that was in m - R::type == the same type that was in m
......
...@@ -646,6 +646,23 @@ namespace ...@@ -646,6 +646,23 @@ namespace
} }
{
matrix<int> m(3,4), m2;
m = 1,2,3,4,
4,5,6,6,
6,1,8,0;
m2 = m;
DLIB_CASSERT(round(m) == m2,"");
DLIB_CASSERT(round_zeros(m) == m2,"");
m2 = 0,2,3,4,
4,5,6,6,
6,0,8,0;
DLIB_CASSERT(round_zeros(m,2) == m2,"");
}
{ {
matrix<double,6,6> m(identity_matrix<double>(6)*4.5); matrix<double,6,6> m(identity_matrix<double>(6)*4.5);
......
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