1 // basic arithmetic objects
2 // Copyright (C) 2005, 2006, 2007, 2008 Tim Blechmann
4 // This program is free software; you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation; either version 2 of the License, or
7 // (at your option) any later version.
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
14 // You should have received a copy of the GNU General Public License
15 // along with this program; see the file COPYING. If not, write to
16 // the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 // Boston, MA 02111-1307, USA.
19 #ifndef TEMPLATE_FUNCTIONS_HPP
20 #define TEMPLATE_FUNCTIONS_HPP
23 #include <algorithm> // for std::min & std::max
25 #include <boost/math/special_functions/fpclassify.hpp>
27 #include "force_inline.hpp"
32 always_inline T
identity(T arg
)
38 always_inline T
plus(T lhs
, T rhs
)
44 always_inline T
minus(T lhs
, T rhs
)
50 always_inline F
inv_minus(F lhs
, F rhs
)
56 always_inline T
times(T lhs
, T rhs
)
62 always_inline T
over(T lhs
, T rhs
)
68 always_inline F
inv_over(F lhs
, F rhs
)
74 always_inline F
fmod(F lhs
, F rhs
)
76 return std::fmod(lhs
, rhs
);
81 always_inline F
less(F lhs
, F rhs
)
87 always_inline F
less_equal(F lhs
, F rhs
)
93 always_inline F
equal(F lhs
, F rhs
)
99 always_inline F
notequal(F lhs
, F rhs
)
101 return F(lhs
!= rhs
);
104 template <typename F
>
105 always_inline F
greater(F lhs
, F rhs
)
110 template <typename F
>
111 always_inline F
greater_equal(F lhs
, F rhs
)
113 return F(lhs
>= rhs
);
120 template <typename F
>
121 always_inline F
nova_max(F lhs
, F rhs
)
123 return max(lhs
, rhs
);
126 template <typename F
>
127 always_inline F
nova_min(F lhs
, F rhs
)
129 return min(lhs
, rhs
);
132 template <typename F
>
133 always_inline F
sign(F arg
)
142 template <typename F
>
143 always_inline F
and_bool(F lhs
, F rhs
)
145 return F(bool(lhs
) and bool(rhs
));
148 template <typename F
>
149 always_inline F
and_bitwise(F lhs
, F rhs
)
151 return F(long(lhs
) & long(rhs
));
154 template <typename F
>
155 always_inline F
or_bool(F lhs
, F rhs
)
157 return F(bool(lhs
) or bool(rhs
));
160 template <typename F
>
161 always_inline F
or_bitwise(F lhs
, F rhs
)
163 return F(long(lhs
) | long(rhs
));
166 template <typename F
>
167 always_inline F
shift_left(F lhs
, F rhs
)
169 return F(long(lhs
) << long(rhs
));
172 template <typename F
>
173 always_inline F
shift_right(F lhs
, F rhs
)
175 return F(long(lhs
) >> long(rhs
));
178 template <typename F
>
179 always_inline F
inv_pow(F lhs
, F rhs
)
181 return std::pow(rhs
, lhs
);
184 template <typename F
>
185 always_inline F
square(F arg
)
190 template <typename T
>
191 always_inline T
pow2(T
const & arg
)
196 template <typename T
>
197 always_inline T
cube(T arg
)
199 return arg
* arg
* arg
;
202 template <typename T
>
203 always_inline T
pow3(T
const & arg
)
210 template <typename F
>
211 always_inline F
rsqrt(F arg
)
213 return F(1) / std::sqrt(arg
);
216 template <typename F
>
217 always_inline F
rcp(F arg
)
225 template <typename F
>
226 always_inline F
isnormal(F arg
)
228 #ifdef __INTEL_COMPILER /* intel compiler workaround */
229 return boost::math::isnormal(arg
);
231 return std::isnormal(arg
);
236 template <typename F1
, typename F2
, typename F3
>
237 always_inline F1
clip(F1 t
, F2 low
, F3 hi
)
247 template <typename F
>
248 always_inline F
modulo(F lhs
, F rhs
)
250 F ret
= fmod(lhs
, rhs
);
256 template <typename I
>
257 always_inline I
wrap_optimistic(I val
, const I mod
)
259 if (unlikely(val
>= mod
))
262 while (unlikely(val
>= mod
));
264 while (unlikely(val
< I(0)))
270 template <typename I
>
271 always_inline I
scale_linear(I in
,
272 I
const & low_in
, I
const & high_in
,
273 I
const & low_out
, I
const & high_out
)
275 return (in
-low_in
) / (high_in
-low_in
) * (high_out
-low_out
) + low_out
;
278 template <typename I
>
279 always_inline I
scale_linear_clipped(I in
,
280 I
const & low_in
, I
const & high_in
,
281 I
const & low_out
, I
const & high_out
)
283 return (in
-low_in
) / (high_in
-low_in
) * (high_out
-low_out
) + low_out
;
287 } /* namespace nova */
289 #endif /* TEMPLATE_FUNCTIONS_HPP */