diff --git a/src/mlpack/core/arma_extend/CMakeLists.txt b/src/mlpack/core/arma_extend/CMakeLists.txt index 017369c414..14323f80eb 100644 --- a/src/mlpack/core/arma_extend/CMakeLists.txt +++ b/src/mlpack/core/arma_extend/CMakeLists.txt @@ -9,6 +9,9 @@ set(SOURCES glue_ccov_proto.hpp op_ccov_meat.hpp op_ccov_proto.hpp + promote_type.hpp + traits.hpp + typedef.hpp ) # add directory name to sources diff --git a/src/mlpack/core/arma_extend/arma_extend.hpp b/src/mlpack/core/arma_extend/arma_extend.hpp index ff11255408..e22ab109da 100644 --- a/src/mlpack/core/arma_extend/arma_extend.hpp +++ b/src/mlpack/core/arma_extend/arma_extend.hpp @@ -71,6 +71,11 @@ namespace arma { #endif namespace arma { + // u64 + #include "typedef.hpp" + #include "traits.hpp" + #include "promote_type.hpp" + // ccov() #include "op_ccov_proto.hpp" #include "op_ccov_meat.hpp" diff --git a/src/mlpack/core/arma_extend/promote_type.hpp b/src/mlpack/core/arma_extend/promote_type.hpp new file mode 100644 index 0000000000..34131a8287 --- /dev/null +++ b/src/mlpack/core/arma_extend/promote_type.hpp @@ -0,0 +1,109 @@ +// Extra promote_type definitions until 64-bit index support is added to +// Armadillo. The syntax was changed for 2.1.91, so we need to be careful about +// how we do that. +#if ((ARMA_VERSION_MAJOR > 2)) || \ + ((ARMA_VERSION_MAJOR == 2) && (ARMA_VERSION_MINOR > 1)) || \ + ((ARMA_VERSION_MAJOR == 2) && (ARMA_VERSION_MINOR == 1) && \ + (ARMA_VERSION_PATCH >= 91)) +// The new syntax changed the name of 'promote_type' to 'is_promotable'. We +// have to update accordingly... +template struct is_promotable, s64> : public is_promotable_ok { typedef std::complex result; }; +template struct is_promotable, u64> : public is_promotable_ok { typedef std::complex result; }; + +template<> struct is_promotable : public is_promotable_ok { typedef double result; }; +template<> struct is_promotable : public is_promotable_ok { typedef double result; }; + +template<> struct is_promotable : public is_promotable_ok { typedef float result; }; +template<> struct is_promotable : public is_promotable_ok { typedef float result; }; + +template<> struct is_promotable : public is_promotable_ok { typedef s64 result; }; +template<> struct is_promotable : public is_promotable_ok { typedef s64 result; }; +template<> struct is_promotable : public is_promotable_ok { typedef s64 result; }; // float ? +template<> struct is_promotable : public is_promotable_ok { typedef s64 result; }; +template<> struct is_promotable : public is_promotable_ok { typedef s64 result; }; +template<> struct is_promotable : public is_promotable_ok { typedef s64 result; }; +template<> struct is_promotable : public is_promotable_ok { typedef s64 result; }; + +template<> struct is_promotable : public is_promotable_ok { typedef s64 result; }; // float ? +template<> struct is_promotable : public is_promotable_ok { typedef u64 result; }; +template<> struct is_promotable : public is_promotable_ok { typedef s64 result; }; // float ? +template<> struct is_promotable : public is_promotable_ok { typedef u64 result; }; +template<> struct is_promotable : public is_promotable_ok { typedef s64 result; }; // float ? +template<> struct is_promotable : public is_promotable_ok { typedef u64 result; }; + +template struct is_promotable > : public is_promotable_ok { typedef std::complex result; }; +template struct is_promotable > : public is_promotable_ok { typedef std::complex result; }; + +template<> struct is_promotable : public is_promotable_ok { typedef double result; }; +template<> struct is_promotable : public is_promotable_ok { typedef double result; }; + +template<> struct is_promotable : public is_promotable_ok { typedef float result; }; +template<> struct is_promotable : public is_promotable_ok { typedef float result; }; + +template<> struct is_promotable : public is_promotable_ok { typedef s64 result; }; // float ? +template<> struct is_promotable : public is_promotable_ok { typedef s64 result; }; +template<> struct is_promotable : public is_promotable_ok { typedef s64 result; }; // float ? +template<> struct is_promotable : public is_promotable_ok { typedef s64 result; }; +template<> struct is_promotable : public is_promotable_ok { typedef s64 result; }; +template<> struct is_promotable : public is_promotable_ok { typedef s64 result; }; +template<> struct is_promotable : public is_promotable_ok { typedef s64 result; }; + +template<> struct is_promotable : public is_promotable_ok { typedef s64 result; }; // float ? +template<> struct is_promotable : public is_promotable_ok { typedef u64 result; }; +template<> struct is_promotable : public is_promotable_ok { typedef s64 result; }; // float ? +template<> struct is_promotable : public is_promotable_ok { typedef u64 result; }; +template<> struct is_promotable : public is_promotable_ok { typedef s64 result; }; // float ? +template<> struct is_promotable : public is_promotable_ok { typedef u64 result; }; + +#else +// The old syntax used the 'promote_type' struct. We just define all of these +// for u64 and s64. +template struct promote_type, s64> : public promote_type_ok { typedef std::complex result; }; +template struct promote_type, u64> : public promote_type_ok { typedef std::complex result; }; + +template<> struct promote_type : public promote_type_ok { typedef double result; }; +template<> struct promote_type : public promote_type_ok { typedef double result; }; + +template<> struct promote_type : public promote_type_ok { typedef float result; }; +template<> struct promote_type : public promote_type_ok { typedef float result; }; + +template<> struct promote_type : public promote_type_ok { typedef s64 result; }; +template<> struct promote_type : public promote_type_ok { typedef s64 result; }; +template<> struct promote_type : public promote_type_ok { typedef s64 result; }; // float ? +template<> struct promote_type : public promote_type_ok { typedef s64 result; }; +template<> struct promote_type : public promote_type_ok { typedef s64 result; }; +template<> struct promote_type : public promote_type_ok { typedef s64 result; }; +template<> struct promote_type : public promote_type_ok { typedef s64 result; }; + +template<> struct promote_type : public promote_type_ok { typedef s64 result; }; // float ? +template<> struct promote_type : public promote_type_ok { typedef u64 result; }; +template<> struct promote_type : public promote_type_ok { typedef s64 result; }; // float ? +template<> struct promote_type : public promote_type_ok { typedef u64 result; }; +template<> struct promote_type : public promote_type_ok { typedef s64 result; }; // float ? +template<> struct promote_type : public promote_type_ok { typedef u64 result; }; + +template struct promote_type > : public promote_type_ok { typedef std::complex result; }; +template struct promote_type > : public promote_type_ok { typedef std::complex result; }; + +template<> struct promote_type : public promote_type_ok { typedef double result; }; +template<> struct promote_type : public promote_type_ok { typedef double result; }; + +template<> struct promote_type : public promote_type_ok { typedef float result; }; +template<> struct promote_type : public promote_type_ok { typedef float result; }; + +template<> struct promote_type : public promote_type_ok { typedef s64 result; }; // float ? +template<> struct promote_type : public promote_type_ok { typedef s64 result; }; +template<> struct promote_type : public promote_type_ok { typedef s64 result; }; // float ? +template<> struct promote_type : public promote_type_ok { typedef s64 result; }; +template<> struct promote_type : public promote_type_ok { typedef s64 result; }; +template<> struct promote_type : public promote_type_ok { typedef s64 result; }; +template<> struct promote_type : public promote_type_ok { typedef s64 result; }; + +template<> struct promote_type : public promote_type_ok { typedef s64 result; }; // float ? +template<> struct promote_type : public promote_type_ok { typedef u64 result; }; +template<> struct promote_type : public promote_type_ok { typedef s64 result; }; // float ? +template<> struct promote_type : public promote_type_ok { typedef u64 result; }; +template<> struct promote_type : public promote_type_ok { typedef s64 result; }; // float ? +template<> struct promote_type : public promote_type_ok { typedef u64 result; }; + +#endif diff --git a/src/mlpack/core/arma_extend/traits.hpp b/src/mlpack/core/arma_extend/traits.hpp new file mode 100644 index 0000000000..ddf1261b27 --- /dev/null +++ b/src/mlpack/core/arma_extend/traits.hpp @@ -0,0 +1,26 @@ +// Extra traits to support u64 and s64 until that patch is applied to the +// Armadillo sources. + +#if ARMA_VERSION_MAJOR < 1 || \ + (ARMA_VERSION_MAJOR == 1 && ARMA_VERSION_MINOR <= 2) +// For old Armadillo versions ( <= 1.2.0 ), all we have to do is define these +// two structs which say these element types are supported. +template<> struct isnt_supported_elem_type< u64 > : public isnt_supported_elem_type_false {}; +template<> struct isnt_supported_elem_type< s64 > : public isnt_supported_elem_type_false {}; + +#else +// For new Armadillo versions ( > 1.2.0 ) we have to get a little bit more +// tricky. We will overload the values for the is_supported_elem_type +// structure, allowing us to redefine it to report success for u64s and s64s. +template<> +struct is_supported_elem_type + { + static const bool value = true; + }; + +template<> +struct is_supported_elem_type + { + static const bool value = true; + }; +#endif diff --git a/src/mlpack/core/arma_extend/typedef.hpp b/src/mlpack/core/arma_extend/typedef.hpp new file mode 100644 index 0000000000..72b1b7f98e --- /dev/null +++ b/src/mlpack/core/arma_extend/typedef.hpp @@ -0,0 +1,69 @@ +// Extensions to typedef u64 and s64 until that support is added into +// Armadillo. We only need to typedef s64 on Armadillo > 1.2.0. + +#if ((ARMA_VERSION_MAJOR > 1)) || \ + ((ARMA_VERSION_MAJOR == 1) && (ARMA_VERSION_MINOR > 2)) || \ + ((ARMA_VERSION_MAJOR == 1) && (ARMA_VERSION_MINOR == 2) && \ + (ARMA_VERSION_PATCH > 0)) +#ifndef ARMA_64BIT_WORD + // An unincluded header file typedefs u64 for us. + template + struct deduce_u64 + { + }; + + template<> + struct deduce_u64 + { + typedef std::size_t u64; + + static const u64 max = (sizeof(u64) >= 8) ? 0xFFFFFFFFFFFFFFFF : 0xFFFFFFFF; // check required for silly compilers + static const bool trunc = false; + }; + + template<> + struct deduce_u64 + { + #if (ULONG_MAX >= 0xFFFFFFFFFFFFFFFF) + typedef unsigned long u64; + static const u64 max = 0xFFFFFFFFFFFFFFFF; + static const bool trunc = false; + #elif defined(ULLONG_MAX) + typedef unsigned long long u64; + static const u64 max = 0xFFFFFFFFFFFFFFFF; + static const bool trunc = false; + #elif (_MSC_VER >= 1200) + //#elif (_MSC_VER >= 1310) && defined(_MSC_EXTENSIONS) + typedef unsigned __int64 u64; + static const u64 max = 0xFFFFFFFFFFFFFFFF; + static const bool trunc = false; + #else + #error "don't know how to typedef 'u64' on this system" + #endif + }; + + typedef deduce_u64<(sizeof(std::size_t) >= 8)>::u64 u64; +#endif + + // We only need to typedef s64. + #if ULONG_MAX >= 0xffffffffffffffff + typedef long s64; + #elif ULLONG_MAX >= 0xffffffffffffffff + typedef long s64; + #else + #error "don't know how to typedef 's64' on this system" + #endif +#else + + // We must typedef both u64 and s64. + #if ULONG_MAX >= 0xffffffffffffffff + typedef unsigned long u64; + typedef long s64; + #elif ULLONG_MAX >= 0xffffffffffffffff + typedef unsigned long long u64; + typedef long long s64; + #else + #error "don't know how to typedef 'u64' on this system" + #endif + +#endif