Commit abce1689 authored by Edwin Carlinet's avatar Edwin Carlinet
Browse files

Add some vec related functionalities.

	*  mln/core/math_ops.hpp,
	*  mln/core/vec/vec_math_ops.hpp: l2dist, l2dist_sqr
	*  mln/core/vec_base.hpp: explicit conversion from other tags.
parent aa842f61
......@@ -7,6 +7,7 @@
*
*/
# include <utility>
# include <cmath>
namespace mln
......@@ -118,6 +119,17 @@ namespace mln
double l2norm(double x);
long double l2norm(long double x);
int l2dist(int x, int y);
long l2dist(long x, long y);
long long l2dist(long long x, long long y);
unsigned int l2dist(unsigned int x, unsigned int y);
unsigned long l2dist(unsigned long x, unsigned long y);
unsigned long long l2dist(unsigned long long x, unsigned long long y);
float l2dist(float x, float y);
double l2dist(double x, double y);
long double l2dist(long double x, long double y);
int l2norm_sqr(int x);
long l2norm_sqr(long n);
long long l2norm_sqr(long long n);
......@@ -128,6 +140,16 @@ namespace mln
double l2norm_sqr(double x);
long double l2norm_sqr(long double x);
int l2dist_sqr(int x, int y);
long l2dist_sqr(long x, long y);
long long l2dist_sqr(long long x, long long y);
unsigned int l2dist_sqr(unsigned int x, unsigned int y);
unsigned long l2dist_sqr(unsigned long x, unsigned long y);
unsigned long long l2dist_sqr(unsigned long long x, unsigned long long y);
float l2dist_sqr(float x, float y);
double l2dist_sqr(double x, double y);
long double l2dist_sqr(long double x, long double y);
int linfnorm(int x);
long linfnorm(long n);
long long linfnorm(long long n);
......@@ -157,6 +179,7 @@ namespace mln
template <typename T = void> struct l0norm_t;
template <typename T = void> struct l1norm_t;
template <typename T = void> struct l2norm_t;
template <typename T = void> struct l2norm_sqr_t;
template <typename T = void> struct linfnorm_t;
template <unsigned p, typename T = void> struct lpnorm_t;
};
......@@ -169,6 +192,9 @@ namespace mln
# define MLN_GEN_CODE(FUN, TYPE, OP) \
inline TYPE FUN(TYPE x) { return OP; }
# define MLN_GEN_BINARY_CODE(FUN, TYPE, OP) \
inline TYPE FUN(TYPE x, TYPE y) { return OP; }
# define MLN_GEN_CODE_2(TEMPLATE, FUN, TYPE, OP) \
TEMPLATE inline TYPE FUN(TYPE x) { return OP; }
......@@ -189,6 +215,23 @@ namespace mln
}; \
}
# define MLN_FUNCTIONAL_GEN_BINARY_CODE(FUN) \
namespace functional { \
using mln::FUN; \
template <typename T> \
struct FUN##_t { \
typedef decltype(FUN(std::declval<T>(), std::declval<T>())) result_type; \
auto operator() (const T& x, const T& y) const -> decltype(FUN(x,y)) \
{ return FUN(x,y); } \
}; \
template <> \
struct FUN##_t<void> { \
template <typename T> \
auto operator() (const T& x, const T& y) const -> decltype(FUN(x,y)) \
{ return FUN(x,y); } \
}; \
}
# define MLN_FUNCTIONAL_GEN_CODE_2(TTYPE, TNAME, FUN) \
namespace functional { \
template <TTYPE TNAME, typename T> \
......@@ -264,6 +307,17 @@ namespace mln
MLN_GEN_CODE(l2norm, long double, std::abs(x));
MLN_FUNCTIONAL_GEN_CODE(l2norm);
MLN_GEN_BINARY_CODE(l2dist, int, abs(x - y));
MLN_GEN_BINARY_CODE(l2dist, long, abs(x - y));
MLN_GEN_BINARY_CODE(l2dist, long long, abs(x - y));
MLN_GEN_BINARY_CODE(l2dist, unsigned int, abs(x - y));
MLN_GEN_BINARY_CODE(l2dist, unsigned long, abs(x - y));
MLN_GEN_BINARY_CODE(l2dist, unsigned long long, abs(x - y));
MLN_GEN_BINARY_CODE(l2dist, float, abs(x - y));
MLN_GEN_BINARY_CODE(l2dist, double, abs(x - y));
MLN_GEN_BINARY_CODE(l2dist, long double, abs(x - y));
MLN_FUNCTIONAL_GEN_BINARY_CODE(l2dist);
MLN_GEN_CODE(l2norm_sqr, int, sqr(x));
MLN_GEN_CODE(l2norm_sqr, long, sqr(x));
MLN_GEN_CODE(l2norm_sqr, long long, sqr(x));
......@@ -275,6 +329,17 @@ namespace mln
MLN_GEN_CODE(l2norm_sqr, long double, sqr(x));
MLN_FUNCTIONAL_GEN_CODE(l2norm_sqr);
MLN_GEN_BINARY_CODE(l2dist_sqr, int, sqr(x - y));
MLN_GEN_BINARY_CODE(l2dist_sqr, long, sqr(x - y));
MLN_GEN_BINARY_CODE(l2dist_sqr, long long, sqr(x - y));
MLN_GEN_BINARY_CODE(l2dist_sqr, unsigned int, sqr(x - y));
MLN_GEN_BINARY_CODE(l2dist_sqr, unsigned long, sqr(x - y));
MLN_GEN_BINARY_CODE(l2dist_sqr, unsigned long long, sqr(x - y));
MLN_GEN_BINARY_CODE(l2dist_sqr, float, sqr(x - y));
MLN_GEN_BINARY_CODE(l2dist_sqr, double, sqr(x - y));
MLN_GEN_BINARY_CODE(l2dist_sqr, long double, sqr(x - y));
MLN_FUNCTIONAL_GEN_BINARY_CODE(l2dist_sqr);
MLN_GEN_CODE(linfnorm, int, std::abs(x));
MLN_GEN_CODE(linfnorm, long, std::abs(x));
MLN_GEN_CODE(linfnorm, long long, std::abs(x));
......@@ -342,8 +407,10 @@ namespace mln
MLN_FUNCTIONAL_GEN_CODE(prod);
# undef MLN_GEN_CODE
# undef MLN_GEN_BINARY_CODE
# undef MLN_GEN_CODE_2
# undef MLN_FUNCTIONAL_GEN_CODE
# undef MLN_FUNCTIONAL_GEN_BINARY_CODE
# undef MLN_FUNCTIONAL_GEN_CODE_2
}
......
......@@ -93,7 +93,12 @@ namespace mln
MLN_PROMOTE_FUNCOMP(T, pow, abs)
lpnorm(const internal::vec_base<T, dim, tag>& x);
template <typename T, unsigned dim, class tag>
inline
auto
l2dist(const internal::vec_base<T, dim, tag>& x,
const internal::vec_base<T, dim, tag>& y)
-> decltype(l2norm(x-y));
/*****************************/
......@@ -112,13 +117,26 @@ namespace mln
return res; \
}
#define MLN_GEN_BINARY_CODE(FUN, FUNBASE, EXPR) \
template <class T, unsigned dim, class tag> \
inline \
auto \
FUN(const internal::vec_base<T, dim, tag>& x, \
const internal::vec_base<T, dim, tag>& y) \
-> decltype(FUNBASE(EXPR)) \
{ \
return FUNBASE(EXPR); \
}
MLN_GEN_CODE(sqr);
MLN_GEN_CODE(sqrt);
MLN_GEN_CODE(abs);
MLN_GEN_CODE(cbrt);
MLN_GEN_BINARY_CODE(l2dist, l2norm, x-y);
# undef MLN_GEN_CODE
template <class U, class V, unsigned dim, class tag>
internal::vec_base< decltype( pow(std::declval<U>(), std::declval<V>()) ),
......@@ -262,6 +280,8 @@ namespace mln
}
# undef MLN_GEN_CODE
# undef MLN_GEN_BINARY_CODE
# undef MLN_VEC_PROMOTE_FUN
# undef MLN_VEC_PROMOTE
# undef MLN_PROMOTE_FUNCOMP
......
......@@ -227,6 +227,16 @@ namespace mln
vec_base() = default;
vec_base(const vec_base&) = default;
template <class OtherTag>
explicit
vec_base(const vec_base<T, dim, OtherTag>& other)
{
for (unsigned i = 0; i < dim; ++i)
v_[i] = other.v_[i];
}
constexpr
vec_base(const literal::zero_t&)
......@@ -565,6 +575,13 @@ namespace std
typedef mln::internal::vec_base< typename make_unsigned<T>::type, dim, tag > type;
};
template <typename T1, typename T2, unsigned dim, typename Tag>
struct common_type< mln::internal::vec_base<T1,dim,Tag>,
mln::internal::vec_base<T2,dim,Tag> >
{
typedef mln::internal::vec_base<typename std::common_type<T1,T2>::type, dim, Tag> type;
};
}
namespace boost
......
Supports Markdown
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