32 #ifndef PLANCK_MATH_UTILS_H 33 #define PLANCK_MATH_UTILS_H 44 template<
typename F>
inline bool approx (F a, F b, F epsilon=1e-5)
47 return abs(a-b) <= (epsilon*abs(b));
51 template<
typename F>
inline bool abs_approx (F a, F b, F epsilon=1e-5)
54 return abs(a-b) <= epsilon;
58 template<
typename I,
typename F>
inline I
ifloor (F arg)
65 template<
typename I,
typename F>
inline I
nearest (F arg)
66 {
return ifloor<I>(arg+0.5); }
71 inline double fmodulo (
double v1,
double v2)
75 return (v1<v2) ? v1 : fmod(v1,v2);
76 double tmp=fmod(v1,v2)+v2;
77 return (tmp==v2) ? 0. : tmp;
84 template<
typename I>
inline I
imodulo (I v1, I v2)
85 { I v=v1%v2;
return (v>=0) ? v : v+v2; }
88 template<
typename T>
inline T
sign (
const T& signvalue)
89 {
return (signvalue>=0) ? 1 : -1; }
92 template<
typename T,
typename I>
inline T
xpow (I m, T val)
93 {
return (m&1) ? -val : val; }
95 template<
typename I,
bool g4>
struct isqrt_helper__
97 template<
typename I>
struct isqrt_helper__ <I, false>
99 static uint32
isqrt (I arg)
102 return uint32 (sqrt(arg+0.5));
105 template<
typename I>
struct isqrt_helper__ <I, true>
107 static uint32
isqrt (I arg)
110 I res = sqrt(
double(arg)+0.5);
111 if (arg<(int64(1)<<50))
return uint32(res);
114 else if ((res+1)*(res+1)<=arg)
121 template<
typename I>
inline uint32
isqrt (I arg)
122 {
return isqrt_helper__<I,(sizeof(I)>4)>::
isqrt(arg); }
125 template<
typename I>
inline int ilog2 (I arg)
128 if (arg==0)
return 0;
129 if (
sizeof(I)==
sizeof(
int))
130 return 8*
sizeof(int)-1-__builtin_clz(arg);
131 if (
sizeof(I)==
sizeof(long))
132 return 8*
sizeof(long)-1-__builtin_clzl(arg);
133 if (
sizeof(I)==
sizeof(
long long))
134 return 8*
sizeof(
long long)-1-__builtin_clzll(arg);
137 while (arg > 0xFFFF) { res+=16; arg>>=16; }
138 if (arg > 0x00FF) { res|=8; arg>>=8; }
139 if (arg > 0x000F) { res|=4; arg>>=4; }
140 if (arg > 0x0003) { res|=2; arg>>=2; }
141 if (arg > 0x0001) { res|=1; }
145 template<
typename I>
inline int ilog2_nonnull (I arg)
148 if (
sizeof(I)<=
sizeof(
int))
149 return 8*
sizeof(int)-1-__builtin_clz(arg);
150 if (
sizeof(I)==
sizeof(long))
151 return 8*
sizeof(long)-1-__builtin_clzl(arg);
152 if (
sizeof(I)==
sizeof(
long long))
153 return 8*
sizeof(
long long)-1-__builtin_clzll(arg);
158 template<
typename I>
inline int trailingZeros(I arg)
160 if (arg==0)
return sizeof(I)<<3;
162 if (
sizeof(I)<=
sizeof(int))
163 return __builtin_ctz(arg);
164 if (
sizeof(I)==
sizeof(
long))
165 return __builtin_ctzl(arg);
166 if (
sizeof(I)==
sizeof(
long long))
167 return __builtin_ctzll(arg);
170 while ((arg&0xFFFF)==0) { res+=16; arg>>=16; }
171 if ((arg&0x00FF)==0) { res|=8; arg>>=8; }
172 if ((arg&0x000F)==0) { res|=4; arg>>=4; }
173 if ((arg&0x0003)==0) { res|=2; arg>>=2; }
174 if ((arg&0x0001)==0) { res|=1; }
182 return ((x==0.) && (y==0.)) ? 0.0 : atan2(y,x);
187 template<
typename T,
typename Iter,
typename Comp>
inline void interpol_helper 188 (
const Iter &begin,
const Iter &end,
const T &val, Comp comp,
tsize &idx,
192 planck_assert((end-begin)>1,
"sequence too small for interpolation");
193 idx = lower_bound(begin,end,val,comp)-begin;
195 idx = min(
tsize(end-begin-2),idx);
196 frac = (val-begin[idx])/(begin[idx+1]-begin[idx]);
202 (
const Iter &begin,
const Iter &end,
const T &val,
tsize &idx, T &frac)
207 #if (__cplusplus>=201103L) 209 template<
typename T1,
typename T2>
210 inline bool multiequal (
const T1 &a,
const T2 &b)
213 template<
typename T1,
typename T2,
typename... Args>
214 inline bool multiequal (
const T1 &a,
const T2 &b, Args... args)
215 {
return (a==b) && multiequal (a, args...); }
219 template<
typename T>
inline bool multiequal (
const T &a,
const T &b)
222 template<
typename T>
inline bool multiequal (
const T &a,
const T &b,
const T &c)
223 {
return (a==b) && (a==c); }
225 template<
typename T>
inline bool multiequal (
const T &a,
const T &b,
const T &c,
227 {
return (a==b) && (a==c) && (a==d); }
229 template<
typename T>
inline bool multiequal (
const T &a,
const T &b,
const T &c,
230 const T &d,
const T &e)
231 {
return (a==b) && (a==c) && (a==d) && (a==e); }
233 template<
typename T>
inline bool multiequal (
const T &a,
const T &b,
const T &c,
234 const T &d,
const T &e,
const T &f)
235 {
return (a==b) && (a==c) && (a==d) && (a==e) && (a==f); }
239 template<
typename T>
class kahan_adder
244 kahan_adder(): sum(0), c(0) {}
246 void add (
const T &val)
255 T result()
const {
return sum; }
258 template<
typename T>
class tree_adder
261 std::vector<T> state;
265 tree_adder(): state(1,T(0)), n(0) {}
267 void add (
const T &val)
270 if (n>(
tsize(1)<<(state.size()-1)))
271 state.push_back(T(0));
273 while (((n>>shift)&1)==0)
275 state[shift+1]+=state[shift];
283 for (
tsize i=0; i<state.size(); ++i)
289 template<
typename Iter>
bool checkNan (Iter begin, Iter end)
293 if (*begin != *begin)
return true;
double safe_atan2(double y, double x)
bool approx(F a, F b, F epsilon=1e-5)
#define planck_assert(testval, msg)
void interpol_helper(const Iter &begin, const Iter &end, const T &val, Comp comp, tsize &idx, T &frac)
double fmodulo(double v1, double v2)
bool abs_approx(F a, F b, F epsilon=1e-5)
T sign(const T &signvalue)