mcpele
1.0.0
The Monte Carlo Python Energy Landscape Explorer
|
00001 #ifndef _PELE_META_POW_H 00002 #define _PELE_META_POW_H 00003 00004 /* 00005 *Usage: For integer (negative integer powers), one obtains x ^ N. 00006 *For half-integer (negative half-integer powers), one obtains sqrt(x ^ N). 00007 *Example: pos_int_pow<2>(x) is x ^ 2; neg_half_int_pow<5>(x) is x ^ (-2.5). 00008 *References: 00009 *Used here: general reference on template meta-programming and recursive template functions: 00010 *http://www.itp.phys.ethz.ch/education/hs12/programming_techniques 00011 *Also used here: reference on template meta-programming power function: 00012 *http://stackoverflow.com/questions/16443682/c-power-of-integer-template-meta-programming 00013 **/ 00014 00015 #include <cmath> //for sqrt in half powers 00016 #include <type_traits> //for static asserts 00017 00018 namespace pele{ 00019 00020 template<class T, int N> 00021 struct meta_pow{ 00022 static T f(const T x) 00023 { 00024 return meta_pow<T, N - 1>::f(x) * x; 00025 } 00026 }; 00027 00028 template<class T> 00029 struct meta_pow<T, 0>{ 00030 static T f(const T x) 00031 { 00032 return T(1); 00033 } 00034 }; 00035 00040 template<int N, class T> 00041 inline T pos_int_pow(const T x) 00042 { 00043 static_assert(N >= 0, "illegal exponent input"); 00044 return meta_pow<T, N>::f(x); 00045 } 00046 00051 template<int N, class T> 00052 inline T neg_int_pow(const T x) 00053 { 00054 static_assert(N <= 0, "illegal exponent input"); 00055 return T(1) / meta_pow<T, -N>::f(x); 00056 } 00057 00062 template<int N, class T> 00063 inline T pos_half_int_pow(const T x) 00064 { 00065 static_assert(N >= 0, "illegal exponent input"); 00066 return std::sqrt(meta_pow<T, N>::f(x)); 00067 } 00068 00073 template<int N, class T> 00074 inline T neg_half_int_pow(const T x) 00075 { 00076 static_assert(N <= 0, "illegal exponent input"); 00077 return T(1) / std::sqrt(meta_pow<T, -N>::f(x)); 00078 } 00079 00080 }//namespace pele 00081 00082 #endif //#ifndef _PELE_META_POW_H