pele
Python energy landscape explorer
/home/js850/projects/pele/source/pele/meta_pow.h
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
 All Classes Namespaces Functions Variables Typedefs