Created
December 29, 2015 09:50
-
-
Save loliGothicK/98cd66dad9688f858976 to your computer and use it in GitHub Desktop.
Cranberries Interval Library Ver. 3.0.0 Release Note ref: http://qiita.com/_EnumHack/items/821c4bc9031a1e9a82b3
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
template < typename T > | |
constexpr T interval<T>::rad() const | |
{ | |
return pimpl->upper() - pimpl->lower() / static_cast<T>(2.0L); | |
} | |
template < typename T > | |
constexpr T interval<T>::norm() const | |
{ | |
using std::abs; | |
auto&& l = abs(pimpl->lower()); | |
auto&& r = abs(pimpl->upper()); | |
return l < r ? r : l; | |
} | |
template < typename T > | |
constexpr T interval<T>::mag() const | |
{ | |
using std::abs; | |
auto&& l = abs(pimpl->lower()); | |
auto&& r = abs(pimpl->upper()); | |
return l < r ? r : l; | |
} | |
template < typename T > | |
constexpr T interval<T>::mig() const | |
{ | |
using std::abs; | |
auto&& l = abs(pimpl->lower()); | |
auto&& r = abs(pimpl->upper()); | |
return l < r ? l : r; | |
} | |
template < typename T > | |
constexpr bool in(T&& x, interval<T> const& y) | |
{ | |
return y.lower() < x && x < y.upper() ? true : false; | |
} | |
template < typename T > | |
constexpr bool subset(interval<T> const& x, interval<T> const& y) | |
{ | |
return y.lower() <= x.lower() && x.lower() <= y.upper() ? true : false; | |
} | |
template < typename T > | |
constexpr bool proper_subset(interval<T> const& x, interval<T> const& y) | |
{ | |
return y.lower() < x.lower() && x.lower() < y.upper() ? true : false; | |
} | |
template < typename T > | |
constexpr bool overlap(interval<T> const& x, interval<T> const& y) | |
{ | |
return x.lower() < y.upper() || y.lower() < x.upper() ? true : false; | |
} | |
template < typename T > | |
constexpr interval<T> intersect(interval<T> const& x, interval<T> const& y) | |
{ | |
if (x.lower() < y.lower() && y.upper() < x.upper()) { | |
return interval<T>(y); | |
} | |
else if (y.lower() < x.lower() && x.upper() < y.upper()) { | |
return interval<T>(x); | |
} | |
else if (x.lower() < y.upper()) { | |
interval<T>{ x.lower(), y.upper() }; | |
} | |
else if (y.lower() < x.upper()) { | |
interval<T>{ y.lower(), x.upper() }; | |
} | |
else { | |
CRANBERRIES_THROW_INVALID_ARGUMENT_ERROR(x and y do not overlap each other) | |
} | |
} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
max |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
\mu_0 = 12.566 370 614...×10^{−7} [N \cdot A^{−2}] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
\epsilon_0 = 8.854 187 817...×10^{−12} [F \cdot m^{−1}] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Z_0 = \mu_0 \cdot c_0 = 376.730 313 461... [Ω] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
G = 6.67408(31)×10^{−11} [ N \cdot m^{2} \cdot kg^{−2} ] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
h = 6.626070040(81)×10^{−34} [ J \cdot s ] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
\hbar = 6.626070040(81)×10^{−34} [ J \cdot s ] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
e = 1.6021766208(98)×10^{−19} [ C ] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
\phi_0 = \frac{h}{2e} = 2.067833831(13)×10^{−15} [ Wb ] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
G_0 = \frac{2e^{2}}{h} = 7.7480917310(18)×10^{−5} [ S ] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
R_0 = \frac{h}{2e^{2}} = 12906.4037278(29) [ Ω ] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
zero |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
namespace c = Cranberries::constants ; | |
// Normal double arithmetic | |
auto a = 3.0 * c::g<double>() ; | |
// Considering standard uncertainty | |
auto b = 3.0 * c::g<interval<double>>() ; | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
namespace constants { | |
template < typename T > | |
constexpr auto pi() -> decltype(static_cast<T>(3.141592653589793238462643383279L)) | |
{ | |
return static_cast<T>(3.141592653589793238462643383279L); | |
} | |
template < typename T > | |
constexpr auto e() -> decltype(static_cast<T>(2.718281828459045235360287471352L)) | |
{ | |
return static_cast<T>(2.718281828459045235360287471352L); | |
} | |
template < typename T > | |
constexpr auto ln2() -> decltype(static_cast<T>(0.693147180559945309417232121458L)) | |
{ | |
return static_cast<T>(0.693147180559945309417232121458L); | |
} | |
template < typename T > | |
constexpr auto ln10() -> decltype(static_cast<T>(2.302585092994045684017991454684L)) | |
{ | |
return static_cast<T>(2.302585092994045684017991454684L); | |
} | |
template < typename T > | |
constexpr auto golden() -> decltype(static_cast<T>(1.61803398874989484820458683436563811L)) | |
{ | |
return static_cast<T>(1.61803398874989484820458683436563811L); | |
} | |
template < typename T > | |
constexpr auto c_0() -> decltype(static_cast<T>(299792458L)) | |
{ | |
return static_cast<T>(299792458L); | |
} | |
template < typename T > | |
constexpr auto mu_0() -> decltype(static_cast<T>(4.0L*pi<T>()*1E-7L)) | |
{ | |
return static_cast<T>(4.0L*pi<T>()*1E-7L); | |
} | |
template < typename T > | |
constexpr auto epsilon_0() -> decltype(static_cast<T>(8.854187817L)) | |
{ | |
return static_cast<T>(8.854187817L); | |
} | |
template < typename T > | |
constexpr auto z_0() -> decltype(static_cast<T>(376.730313461L)) | |
{ | |
return static_cast<T>(376.730313461L); | |
} | |
template < typename T > | |
constexpr auto g() -> decltype(static_cast<T>(6.67408E-11L)) | |
{ | |
return static_cast<T>(6.67408E-11L); | |
} | |
template < typename T > | |
constexpr auto planck() -> decltype(static_cast<T>(6.626070040E-34L)) | |
{ | |
return static_cast<T>(6.626070040E-34L); | |
} | |
template < typename T > | |
constexpr auto dirac() -> decltype(static_cast<T>(1.054571800E-34L)) | |
{ | |
return static_cast<T>(1.054571800E-34L); | |
} | |
template < typename T > | |
constexpr auto electron() -> decltype(static_cast<T>(1.6021766208E-19L)) | |
{ | |
return static_cast<T>(1.6021766208E-19L); | |
} | |
template < typename T > | |
constexpr auto phi_0() -> decltype(static_cast<T>(2.067833831E-15L)) | |
{ | |
return static_cast<T>(2.067833831E-15L); | |
} | |
template < typename T > | |
constexpr auto g_0() -> decltype(static_cast<T>(7.7480917310E-5L)) | |
{ | |
return static_cast<T>(7.7480917310E-5L); | |
} | |
template < typename T > | |
constexpr auto r_0() -> decltype(static_cast<T>(12906.4037278L)) | |
{ | |
return static_cast<T>(12906.4037278L); | |
} | |
template < typename T > | |
constexpr auto max() -> decltype(std::numeric_limits<T>::max()) | |
{ | |
return std::numeric_limits<T>::max(); | |
} | |
template < typename T > | |
constexpr auto zero() -> decltype(static_cast<T>(0.0L)) | |
{ | |
return static_cast<T>(0.0L); | |
} | |
template < typename T > | |
constexpr auto one() -> decltype(static_cast<T>(1.0L)) | |
{ | |
return static_cast<T>(1.0L); | |
} | |
template < typename T, typename U = typename T::value_type > | |
constexpr T pi() | |
{ | |
return interval<U>{ constants::pi<U>(), constants::pi<U>() }; | |
} | |
template < typename T, typename U = typename T::value_type > | |
constexpr T e() | |
{ | |
return interval<U>{ constants::e<U>(), constants::e<U>() }; | |
} | |
template < typename T, typename U = typename T::value_type > | |
constexpr T ln2() | |
{ | |
return interval<U>{ constants::ln2<U>(), constants::ln2<U>() }; | |
} | |
template < typename T, typename U = typename T::value_type > | |
constexpr T ln10() | |
{ | |
return interval<U>{ constants::ln10<U>(), constants::ln10<U>() }; | |
} | |
template < typename T, typename U = typename T::value_type > | |
constexpr T golden() | |
{ | |
return interval<U>{ constants::golden<U>(), constants::golden<U>() }; | |
} | |
template < typename T, typename U = typename T::value_type > | |
constexpr T c_0() | |
{ | |
return interval<U>{ constants::c_0<U>(), constants::c_0<U>() }; | |
} | |
template < typename T, typename U = typename T::value_type > | |
constexpr T mu_0() | |
{ | |
return interval<U>{ constants::mu_0<U>(), constants::mu_0<U>() }; | |
} | |
template < typename T, typename U = typename T::value_type > | |
constexpr T epsilon_0() | |
{ | |
return interval<U>{ constants::epsilon_0<U>(), constants::epsilon_0<U>() }; | |
} | |
template < typename T, typename U = typename T::value_type > | |
constexpr T z_0() | |
{ | |
return interval<U>{ constants::z_0<U>(), constants::z_0<U>() }; | |
} | |
template < typename T, typename U = typename T::value_type > | |
constexpr T g() | |
{ | |
return interval<U>{ static_cast<U>(6.67377E-11L), static_cast<U>(6.67439E-11L) }; | |
} | |
template < typename T, typename U = typename T::value_type > | |
constexpr T planck() | |
{ | |
return interval<U>{ static_cast<U>(6.626069959E-34L), static_cast<U>(6.626070121E-34L) }; | |
} | |
template < typename T, typename U = typename T::value_type > | |
constexpr T dirac() | |
{ | |
return interval<U>{ static_cast<U>(1.054571753E-34L), static_cast<U>(1.054571847E-34L) }; | |
} | |
template < typename T, typename U = typename T::value_type > | |
constexpr T electron() | |
{ | |
return interval<U>{ static_cast<U>(1.6021766110E-19L), static_cast<U>(1.6021766306E-19L) }; | |
} | |
template < typename T, typename U = typename T::value_type > | |
constexpr T phi_0() | |
{ | |
return interval<U>{ static_cast<U>(2.067833818E-15L), static_cast<U>(2.067833844E-15L) }; | |
} | |
template < typename T, typename U = typename T::value_type > | |
constexpr T g_0() | |
{ | |
return interval<U>{ static_cast<U>(7.7480917292E-5L), static_cast<U>(7.7480917328E-5L) }; | |
} | |
template < typename T, typename U = typename T::value_type > | |
constexpr T r_0() | |
{ | |
return interval<U>{ static_cast<U>(12906.4037249L), static_cast<U>(12906.4037307L) }; | |
} | |
template < typename T, typename U = typename T::value_type > | |
constexpr T max() | |
{ | |
return interval<U>{ constants::max<U>(), constants::max<U>() }; | |
} | |
template < typename T, typename U = typename T::value_type > | |
constexpr T zero() | |
{ | |
return interval<U>{ constants::zero<U>(), constants::zero<U>() }; | |
} | |
template < typename T, typename U = typename T::value_type > | |
constexpr T one() | |
{ | |
return interval<U>{ constants::one<U>(), constants::one<U>() }; | |
} | |
} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
interval a{1,2},b{2,3},c{3,4},d{4,5}; | |
{ | |
// Introducing Expression Template | |
using namespace Expression; | |
interval<> hoge{}; | |
// Construction Expression | |
// Use auto | |
auto expr = sub_(add_(max_(sin_(a), b), multi_(a, max_(a, b, c, sin_(a)))), min_(pow_(c, 2), div_(erf_(d), a))); | |
hoge = expr ; // Able to assign to interval | |
// Also available compound assign operator | |
hoge += expr ; | |
hoge -= expr ; | |
hoge *= expr ; | |
hoge /= expr ; | |
// Or can call member func eval() to get result of Expression. | |
cout << expr.eval() << endl; | |
cout << hoge << endl; | |
} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
template< typename T > | |
class is_expr | |
{ | |
private: | |
template< typename U > | |
static auto check(U v) -> decltype(v.is_expr(), std::true_type()); | |
static auto check(...) -> decltype(std::false_type()); | |
public: | |
typedef decltype(check(std::declval<T>())) type; | |
static bool const value = type::value; | |
}; | |
template< typename T > | |
class is_interval | |
{ | |
private: | |
template< typename U > | |
static auto check(U v) -> decltype(v.is_interval(), std::true_type()); | |
static auto check(...) -> decltype(std::false_type()); | |
public: | |
typedef decltype(check(std::declval<T>())) type; | |
static bool const value = type::value; | |
}; | |
template < typename T > | |
struct Val | |
{ | |
T value; | |
public: | |
void is_expr() {}; | |
typedef T type; | |
Val() | |
:value(T()) {} | |
Val(T&& v) | |
: value(std::forward<T>(v)) {} | |
T operator[](int) | |
{ | |
return value; | |
} | |
}; | |
template < typename T > | |
Val<T> val(T&& x) | |
{ | |
return Val<T>(std::forward<T>(x)); | |
} | |
template <typename T, int F = std::is_class<T>::value > | |
struct Expr | |
{ | |
typedef Val<T> Ref; | |
}; | |
template <typename T> | |
struct Expr<T, true> | |
{ | |
typedef T Ref; | |
}; | |
struct Add; | |
struct Sub; | |
struct Multi; | |
struct Div; | |
struct Max; | |
struct Min; | |
struct Pow; | |
template < typename T1, typename T2, typename Op, int F = is_expr<T1>::value + (is_expr<T2>::value << 1) > | |
struct promotion; | |
template < typename T1, typename T2 > | |
struct promotion<T1, T2, Add, 0> | |
{ | |
typedef decltype(std::declval<T1>() + std::declval<T2>()) type; | |
}; | |
template < typename T1, typename T2 > | |
struct promotion<T1, T2, Add, 1> | |
{ | |
typedef decltype(std::declval<typename T1::type>() + std::declval<T2>()) type; | |
}; | |
template < typename T1, typename T2 > | |
struct promotion<T1, T2, Add, 2> | |
{ | |
typedef decltype(std::declval<T1>() + std::declval<typename T2::type>()) type; | |
}; | |
template < typename T1, typename T2 > | |
struct promotion<T1, T2, Add, 3> | |
{ | |
typedef decltype(std::declval<typename T1::type>() + std::declval<typename T2::type>()) type; | |
}; | |
template < typename T1, typename T2 > | |
struct promotion<T1, T2, Sub, 0> | |
{ | |
typedef decltype(std::declval<T1>() - std::declval<T2>()) type; | |
}; | |
template < typename T1, typename T2 > | |
struct promotion<T1, T2, Sub, 1> | |
{ | |
typedef decltype(std::declval<typename T1::type>() - std::declval<T2>()) type; | |
}; | |
template < typename T1, typename T2 > | |
struct promotion<T1, T2, Sub, 2> | |
{ | |
typedef decltype(std::declval<T1>() - std::declval<typename T2::type>()) type; | |
}; | |
template < typename T1, typename T2 > | |
struct promotion<T1, T2, Sub, 3> | |
{ | |
typedef decltype(std::declval<typename T1::type>() - std::declval<typename T2::type>()) type; | |
}; | |
template < typename T1, typename T2 > | |
struct promotion<T1, T2, Multi, 0> | |
{ | |
typedef decltype(std::declval<T1>() * std::declval<T2>()) type; | |
}; | |
template < typename T1, typename T2 > | |
struct promotion<T1, T2, Multi, 1> | |
{ | |
typedef decltype(std::declval<typename T1::type>() * std::declval<T2>()) type; | |
}; | |
template < typename T1, typename T2 > | |
struct promotion<T1, T2, Multi, 2> | |
{ | |
typedef decltype(std::declval<T1>() * std::declval<typename T2::type>()) type; | |
}; | |
template < typename T1, typename T2 > | |
struct promotion<T1, T2, Multi, 3> | |
{ | |
typedef decltype(std::declval<typename T1::type>() * std::declval<typename T2::type>()) type; | |
}; | |
template < typename T1, typename T2 > | |
struct promotion<T1, T2, Div, 0> | |
{ | |
typedef decltype(std::declval<T1>() / std::declval<T2>()) type; | |
}; | |
template < typename T1, typename T2 > | |
struct promotion<T1, T2, Div, 1> | |
{ | |
typedef decltype(std::declval<typename T1::type>() / std::declval<T2>()) type; | |
}; | |
template < typename T1, typename T2 > | |
struct promotion<T1, T2, Div, 2> | |
{ | |
typedef decltype(std::declval<T1>() / std::declval<typename T2::type>()) type; | |
}; | |
template < typename T1, typename T2 > | |
struct promotion<T1, T2, Div, 3> | |
{ | |
typedef decltype(std::declval<typename T1::type>() / std::declval<typename T2::type>()) type; | |
}; | |
template < typename T1, typename T2 > | |
struct promotion<T1, T2, Max, 0> | |
{ | |
typedef decltype(max(std::declval<T1>(), std::declval<T2>())) type; | |
}; | |
template < typename T1, typename T2 > | |
struct promotion<T1, T2, Max, 1> | |
{ | |
typedef decltype(max(std::declval<typename T1::type>(), std::declval<T2>())) type; | |
}; | |
template < typename T1, typename T2 > | |
struct promotion<T1, T2, Max, 2> | |
{ | |
typedef decltype(max(std::declval<T1>(), std::declval<typename T2::type>())) type; | |
}; | |
template < typename T1, typename T2 > | |
struct promotion<T1, T2, Max, 3> | |
{ | |
typedef decltype(max(std::declval<typename T1::type>(), std::declval<typename T2::type>())) type; | |
}; | |
template < typename T1, typename T2 > | |
struct promotion<T1, T2, Min, 0> | |
{ | |
typedef decltype(min(std::declval<T1>(), std::declval<T2>())) type; | |
}; | |
template < typename T1, typename T2 > | |
struct promotion<T1, T2, Min, 1> | |
{ | |
typedef decltype(min(std::declval<typename T1::type>(), std::declval<T2>())) type; | |
}; | |
template < typename T1, typename T2 > | |
struct promotion<T1, T2, Min, 2> | |
{ | |
typedef decltype(min(std::declval<T1>(), std::declval<typename T2::type>())) type; | |
}; | |
template < typename T1, typename T2 > | |
struct promotion<T1, T2, Min, 3> | |
{ | |
typedef decltype(min(std::declval<typename T1::type>(), std::declval<typename T2::type>())) type; | |
}; | |
template < typename T1, typename T2 > | |
struct promotion<T1, T2, Pow, 0> | |
{ | |
typedef decltype(pow(std::declval<T1>(), std::declval<T2>())) type; | |
}; | |
template < typename T1, typename T2 > | |
struct promotion<T1, T2, Pow, 1> | |
{ | |
typedef decltype(pow(std::declval<typename T1::type>(), std::declval<T2>())) type; | |
}; | |
template < typename T1, typename T2 > | |
struct promotion<T1, T2, Pow, 2> | |
{ | |
typedef decltype(pow(std::declval<T1>(), std::declval<typename T2::type>())) type; | |
}; | |
template < typename T1, typename T2 > | |
struct promotion<T1, T2, Pow, 3> | |
{ | |
typedef decltype(pow(std::declval<typename T1::type>(), std::declval<typename T2::type>())) type; | |
}; | |
template < typename T1, typename T2, typename Op > | |
using promotion_t = typename promotion<T1, T2, Op>::type; | |
#ifdef _MSC_VER | |
template < typename T1, typename T2, typename T3 | |
, int F = is_expr<T1>::value + (is_expr<T2>::value << 1) + (is_expr<T3>::value << 2) > | |
struct fma_promotion | |
{ | |
typedef decltype(std::fma(std::decay_t<T1>(), std::decay_t<T2>(), std::decay_t<T3>())) type; | |
}; | |
template < typename T1, typename T2, typename T3 > | |
struct fma_promotion<T1, T2, T3, 1> | |
{ | |
typedef decltype(std::fma(typename std::decay_t<T1>::type(), std::decay_t<T2>(), std::decay_t<T3>())) type; | |
}; | |
template < typename T1, typename T2, typename T3 > | |
struct fma_promotion<T1, T2, T3, 2> | |
{ | |
typedef decltype(std::fma(std::decay_t<T1>(), std::decay_t<typename T2::type>(), std::decay_t<T3>())) type; | |
}; | |
template < typename T1, typename T2, typename T3 > | |
struct fma_promotion<T1, T2, T3, 3> | |
{ | |
typedef decltype(std::fma(std::decay_t<typename T1::type>(), std::decay_t<typename T2::type>(), std::decay_t<T3>())) type; | |
}; | |
template < typename T1, typename T2, typename T3 > | |
struct fma_promotion<T1, T2, T3, 4> | |
{ | |
typedef decltype(std::fma(std::decay_t<T1>(), std::decay_t<T2>(), std::decay_t<typename T3::type>())) type; | |
}; | |
template < typename T1, typename T2, typename T3 > | |
struct fma_promotion<T1, T2, T3, 5> | |
{ | |
typedef decltype(std::fma(std::decay_t<typename T1::type>(), std::decay_t<T2>(), std::decay_t<typename T3::type>())) type; | |
}; | |
template < typename T1, typename T2, typename T3 > | |
struct fma_promotion<T1, T2, T3, 6> | |
{ | |
typedef decltype(std::fma(std::decay_t<T1>(), std::decay_t<typename T2::type>(), std::decay_t<typename T3::type>())) type; | |
}; | |
template < typename T1, typename T2, typename T3 > | |
struct fma_promotion<T1, T2, T3, 7> | |
{ | |
typedef decltype(std::fma(std::decay_t<typename T1::type>(), std::decay_t<typename T2::type>(), std::decay_t<typename T3::type>())) type; | |
}; | |
#else | |
template < typename T1, typename T2, typename T3 | |
, int F = is_expr<T1>::value + (is_expr<T2>::value << 1) + (is_expr<T3>::value << 2) > | |
struct fma_promotion | |
{ | |
typedef decltype(fma(std::decay_t<T1>(), std::decay_t<T2>(), std::decay_t<T3>())) type; | |
}; | |
template < typename T1, typename T2, typename T3 > | |
struct fma_promotion<T1, T2, T3, 1> | |
{ | |
typedef decltype(fma(typename std::decay_t<T1>::type(), std::decay_t<T2>(), std::decay_t<T3>())) type; | |
}; | |
template < typename T1, typename T2, typename T3 > | |
struct fma_promotion<T1, T2, T3, 2> | |
{ | |
typedef decltype(fma(std::decay_t<T1>(), std::decay_t<typename T2::type>(), std::decay_t<T3>())) type; | |
}; | |
template < typename T1, typename T2, typename T3 > | |
struct fma_promotion<T1, T2, T3, 3> | |
{ | |
typedef decltype(fma(std::decay_t<typename T1::type>(), std::decay_t<typename T2::type>(), std::decay_t<T3>())) type; | |
}; | |
template < typename T1, typename T2, typename T3 > | |
struct fma_promotion<T1, T2, T3, 4> | |
{ | |
typedef decltype(fma(std::decay_t<T1>(), std::decay_t<T2>(), std::decay_t<typename T3::type>())) type; | |
}; | |
template < typename T1, typename T2, typename T3 > | |
struct fma_promotion<T1, T2, T3, 5> | |
{ | |
typedef decltype(fma(std::decay_t<typename T1::type>(), std::decay_t<T2>(), std::decay_t<typename T3::type>())) type; | |
}; | |
template < typename T1, typename T2, typename T3 > | |
struct fma_promotion<T1, T2, T3, 6> | |
{ | |
typedef decltype(fma(std::decay_t<T1>(), std::decay_t<typename T2::type>(), std::decay_t<typename T3::type>())) type; | |
}; | |
template < typename T1, typename T2, typename T3 > | |
struct fma_promotion<T1, T2, T3, 7> | |
{ | |
typedef decltype(fma(std::decay_t<typename T1::type>(), std::decay_t<typename T2::type>(), std::decay_t<typename T3::type>())) type; | |
}; | |
#endif | |
template < typename T1, typename T2, typename T3 > | |
using fma_promotion_t = typename fma_promotion<T1, T2, T3>::type; | |
template < class A, class Func > | |
class Expr1 | |
{ | |
std::decay_t<typename Expr<A>::Ref> arg; | |
public: | |
void is_expr() {}; | |
typedef decltype(Func::Apply(arg[0])) type; | |
Expr1(A&& a) | |
:arg(std::forward<A>(a)) {} | |
auto operator[](const long long)->decltype(Func::Apply(arg[0])) const | |
{ | |
return Func::Apply(arg[0]); | |
} | |
auto eval()->decltype(Func::Apply(arg[0])) const | |
{ | |
return Func::Apply(arg[0]); | |
} | |
}; | |
template <class L, class Op, class R> | |
class Expr2 { | |
std::decay_t<typename Expr<L>::Ref> l_; | |
std::decay_t<typename Expr<R>::Ref> r_; | |
public: | |
void is_expr() {}; | |
typedef promotion_t<L, R, Op> type; | |
Expr2(L&& l, R&& r) | |
: l_(std::forward<L>(l)), r_(std::forward<R>(r)) {} | |
auto operator[](const long long)->decltype(Op::Apply(l_[0], r_[0])) const | |
{ | |
return Op::Apply(l_[0], r_[0]); | |
} | |
auto eval()->decltype(Op::Apply(l_[0], r_[0])) const | |
{ | |
return Op::Apply(l_[0], r_[0]); | |
} | |
}; | |
template <class T1, class T2, class T3, class Func> | |
class Expr3 { | |
std::decay_t<typename Expr<T1>::Ref> v1_; | |
std::decay_t<typename Expr<T2>::Ref> v2_; | |
std::decay_t<typename Expr<T3>::Ref> v3_; | |
public: | |
void is_expr() {}; | |
typedef fma_promotion_t<T1, T2, T3> type; | |
Expr3(T1&& v1, T2&& v2, T3&& v3) | |
: v1_(std::forward<T1>(v1)), v2_(std::forward<T2>(v2)), v3_(std::forward<T3>(v3)) {} | |
auto operator[](const long long)->decltype(Func::Apply(v1_[0], v2_[0], v3_[0])) const | |
{ | |
return Func::Apply(v1_[0], v2_[0], v3_[0]); | |
} | |
auto eval()->decltype(Func::Apply(v1_[0], v2_[0], v3_[0])) const | |
{ | |
return Func::Apply(v1_[0], v2_[0], v3_[0]); | |
} | |
}; | |
struct Add { | |
template <typename L, typename R> | |
using promotion_t = promotion_add_t<L, R>; | |
template < typename T, typename U > | |
static auto Apply(interval<T> const& l, interval<U> const& r) | |
{ | |
return add(l, r); | |
} | |
template < typename T, typename U > | |
static auto Apply(interval<T> const& l, U const& r) | |
{ | |
return add(l, r); | |
} | |
template < typename T, typename U > | |
static auto Apply(U&& l, interval<T> const& r) | |
{ | |
return add(std::forward<U>(l), r); | |
} | |
}; | |
struct Sub { | |
template <typename L, typename R> | |
using promotion_t = promotion_sub_t<L, R>; | |
template < typename T, typename U > | |
static interval<promotion_t<T, U>> Apply(interval<T> const& l, interval<U> const& r) | |
{ | |
return sub(l, r); | |
} | |
template < typename T, typename U > | |
static interval<promotion_t<T, U>> Apply(interval<T> const& l, U const& r) | |
{ | |
return sub(l, r); | |
} | |
template < typename T, typename U > | |
static interval<promotion_t<T, U>> Apply(U const& l, interval<T> const& r) | |
{ | |
return sub(l, r); | |
} | |
}; | |
struct Multi { | |
template <typename L, typename R> | |
using promotion_t = promotion_multi_t<L, R>; | |
template < typename T, typename U > | |
static interval<promotion_t<T, U>> Apply(interval<T> const& l, interval<U> const& r) | |
{ | |
return multi(l, r); | |
} | |
template < typename T, typename U > | |
static auto Apply(interval<T> const& l, U const& r) | |
{ | |
return multi(l, r); | |
} | |
template < typename T, typename U > | |
static interval<promotion_t<T, U>> Apply(U const& l, interval<T> const& r) | |
{ | |
return multi(l, r); | |
} | |
}; | |
struct Div { | |
template <typename L, typename R> | |
using promotion_t = promotion_div_t<L, R>; | |
template < typename T, typename U > | |
static interval<promotion_t<T, U>> Apply(interval<T> const& l, interval<U> const& r) | |
{ | |
return div(l, r); | |
} | |
template < typename T, typename U > | |
static interval<promotion_t<T, U>> Apply(interval<T> const& l, U const& r) | |
{ | |
return div(l, r); | |
} | |
template < typename T, typename U > | |
static interval<promotion_t<T, U>> Apply(U const& l, interval<T> const& r) | |
{ | |
return div(l, r); | |
} | |
}; | |
struct Sin | |
{ | |
template < typename T > | |
static interval<T> Apply(interval<T> const& x) | |
{ | |
return sin(x); | |
} | |
template < typename T > | |
static auto Apply(T const& x)->decltype(std::sin(x)) | |
{ | |
return std::sin(x); | |
} | |
}; | |
struct Cos | |
{ | |
template < typename T > | |
static interval<T> Apply(interval<T> const& x) | |
{ | |
return cos(x); | |
} | |
template < typename T > | |
static auto Apply(T const& x)->decltype(std::cos(x)) | |
{ | |
return std::cos(x); | |
} | |
}; | |
struct Tan | |
{ | |
template < typename T > | |
static interval<T> Apply(interval<T> const& x) | |
{ | |
return tan(x); | |
} | |
template < typename T > | |
static auto Apply(T const& x)->decltype(std::tan(x)) | |
{ | |
return std::tan(x); | |
} | |
}; | |
struct Asin | |
{ | |
template < typename T > | |
static interval<T> Apply(interval<T> const& x) | |
{ | |
return asin(x); | |
} | |
template < typename T > | |
static auto Apply(T const& x)->decltype(std::asin(x)) | |
{ | |
return std::asin(x); | |
} | |
}; | |
struct Acos | |
{ | |
template < typename T > | |
static interval<T> Apply(interval<T> const& x) | |
{ | |
return acos(x); | |
} | |
template < typename T > | |
static auto Apply(T const& x)->decltype(std::acos(x)) | |
{ | |
return std::acos(x); | |
} | |
}; | |
struct Atan | |
{ | |
template < typename T > | |
static interval<T> Apply(interval<T> const& x) | |
{ | |
return atan(x); | |
} | |
template < typename T > | |
static auto Apply(T const& x)->decltype(std::atan(x)) | |
{ | |
return std::atan(x); | |
} | |
}; | |
struct Sinh | |
{ | |
template < typename T > | |
static interval<T> Apply(interval<T> const& x) | |
{ | |
return sinh(x); | |
} | |
template < typename T > | |
static auto Apply(T const& x)->decltype(std::sinh(x)) | |
{ | |
return std::sinh(x); | |
} | |
}; | |
struct Cosh | |
{ | |
template < typename T > | |
static interval<T> Apply(interval<T> const& x) | |
{ | |
return cosh(x); | |
} | |
template < typename T > | |
static auto Apply(T const& x)->decltype(std::cosh(x)) | |
{ | |
return std::cosh(x); | |
} | |
}; | |
struct Tanh | |
{ | |
template < typename T > | |
static interval<T> Apply(interval<T> const& x) | |
{ | |
return tanh(x); | |
} | |
template < typename T > | |
static auto Apply(T const& x)->decltype(std::tanh(x)) | |
{ | |
return std::tanh(x); | |
} | |
}; | |
struct Asinh | |
{ | |
template < typename T > | |
static interval<T> Apply(interval<T> const& x) | |
{ | |
return asinh(x); | |
} | |
template < typename T > | |
static auto Apply(T const& x)->decltype(std::asinh(x)) | |
{ | |
return std::asinh(x); | |
} | |
}; | |
struct Acosh | |
{ | |
template < typename T > | |
static interval<T> Apply(interval<T> const& x) | |
{ | |
return acosh(x); | |
} | |
template < typename T > | |
static auto Apply(T const& x)->decltype(std::acosh(x)) | |
{ | |
return std::acosh(x); | |
} | |
}; | |
struct Atanh | |
{ | |
template < typename T > | |
static interval<T> Apply(interval<T> const& x) | |
{ | |
return atanh(x); | |
} | |
template < typename T > | |
static auto Apply(T const& x)->decltype(std::atanh(x)) | |
{ | |
return std::atanh(x); | |
} | |
}; | |
struct Sqrt | |
{ | |
template < typename T > | |
static interval<T> Apply(interval<T> const& x) | |
{ | |
return sqrt(x); | |
} | |
template < typename T > | |
static auto Apply(T const& x)->decltype(std::sqrt(x)) | |
{ | |
return std::sqrt(x); | |
} | |
}; | |
struct Cbrt | |
{ | |
template < typename T > | |
static interval<T> Apply(interval<T> const& x) | |
{ | |
return cbrt(x); | |
} | |
template < typename T > | |
static auto Apply(T const& x)->decltype(std::cbrt(x)) | |
{ | |
return std::cbrt(x); | |
} | |
}; | |
struct Pow | |
{ | |
template < typename T > | |
static interval<T> Apply(interval<T> x, int const& n) | |
{ | |
return pow(x, n); | |
} | |
template < typename T > | |
static auto Apply(T const& x, int const& n)->decltype(std::pow(x, n)) | |
{ | |
return std::pow(x, n); | |
} | |
}; | |
struct Exp | |
{ | |
template < typename T > | |
static interval<T> Apply(interval<T> x) | |
{ | |
return exp(x); | |
} | |
template < typename T > | |
static auto Apply(T const& x)->decltype(std::exp(x)) | |
{ | |
return std::exp(x); | |
} | |
}; | |
struct Exp2 | |
{ | |
template < typename T > | |
static interval<T> Apply(interval<T> x) | |
{ | |
return exp2(x); | |
} | |
template < typename T > | |
static auto Apply(T const& x)->decltype(std::exp2(x)) | |
{ | |
return std::exp2(x); | |
} | |
}; | |
struct Expm1 | |
{ | |
template < typename T > | |
static interval<T> Apply(interval<T> x) | |
{ | |
return expm1(x); | |
} | |
template < typename T > | |
static auto Apply(T const& x)->decltype(std::expm1(x)) | |
{ | |
return std::expm1(x); | |
} | |
}; | |
struct Abs | |
{ | |
template < typename T > | |
static interval<T> Apply(interval<T> x) | |
{ | |
return abs(x); | |
} | |
template < typename T > | |
static auto Apply(T const& x)->decltype(std::abs(x)) | |
{ | |
return std::abs(x); | |
} | |
}; | |
struct Log | |
{ | |
template < typename T > | |
static interval<T> Apply(interval<T> x) | |
{ | |
return log(x); | |
} | |
template < typename T > | |
static auto Apply(T const& x)->decltype(std::log(x)) | |
{ | |
return std::log(x); | |
} | |
}; | |
struct Log10 | |
{ | |
template < typename T > | |
static interval<T> Apply(interval<T> x) | |
{ | |
return log10(x); | |
} | |
template < typename T > | |
static auto Apply(T const& x)->decltype(std::log10(x)) | |
{ | |
return std::log10(x); | |
} | |
}; | |
struct Log2 | |
{ | |
template < typename T > | |
static interval<T> Apply(interval<T> x) | |
{ | |
return log2(x); | |
} | |
template < typename T > | |
static auto Apply(T const& x)->decltype(std::log2(x)) | |
{ | |
return std::log2(x); | |
} | |
}; | |
struct Log1p | |
{ | |
template < typename T > | |
static interval<T> Apply(interval<T> x) | |
{ | |
return log1p(x); | |
} | |
template < typename T > | |
static auto Apply(T const& x)->decltype(std::log1p(x)) | |
{ | |
return std::log1p(x); | |
} | |
}; | |
struct Erf | |
{ | |
template < typename T > | |
static interval<T> Apply(interval<T> x) | |
{ | |
return erf(x); | |
} | |
template < typename T > | |
static auto Apply(T const& x)->decltype(std::erf(x)) | |
{ | |
return std::erf(x); | |
} | |
}; | |
struct Erfc | |
{ | |
template < typename T > | |
static interval<T> Apply(interval<T> x) | |
{ | |
return erfc(x); | |
} | |
template < typename T > | |
static auto Apply(T const& x)->decltype(std::erfc(x)) | |
{ | |
return std::erfc(x); | |
} | |
}; | |
struct Fma | |
{ | |
template < typename T1, typename T2, typename T3 > | |
static auto Apply(T1&& v1, T2&& v2, T3&& v3)->decltype(fma(v1, v2, v3)) | |
{ | |
return fma(std::forward<T1>(v1), std::forward<T2>(v2), std::forward<T3>(v3)); | |
} | |
}; | |
struct Max | |
{ | |
template < typename L, typename R > | |
static auto Apply(L&& v1, R&& v2) | |
{ | |
return max(std::forward<L>(v1), std::forward<R>(v2)); | |
} | |
}; | |
struct Min | |
{ | |
template < typename L, typename R > | |
static auto Apply(L&& v1, R&& v2) | |
{ | |
return min(std::forward<L>(v1), std::forward<R>(v2)); | |
} | |
}; | |
namespace Expression { | |
template <class L, class R> | |
inline constexpr Expr2<L, Add, R> add_(L&& lhs, R&& rhs) | |
{ | |
return Expr2<L, Add, R>(std::forward<L>(lhs), std::forward<R>(rhs)); | |
} | |
template <class L, class R> | |
inline constexpr Expr2<L, Sub, R> sub_(L&& lhs, R&& rhs) | |
{ | |
return Expr2<L, Sub, R>(std::forward<L>(lhs), std::forward<R>(rhs)); | |
} | |
template <class L, class R> | |
inline constexpr Expr2<L, Multi, R> multi_(L&& lhs, R&& rhs) | |
{ | |
return Expr2<L, Multi, R>(std::forward<L>(lhs), std::forward<R>(rhs)); | |
} | |
template <class L, class R> | |
inline constexpr Expr2<L, Div, R> div_(L&& lhs, R&& rhs) | |
{ | |
return Expr2<L, Div, R>(std::forward<L>(lhs), std::forward<R>(rhs)); | |
} | |
template< class A > | |
inline constexpr Expr1<A, Sin> sin_(A&& a) | |
{ | |
return Expr1<A, Sin>(std::forward<A>(a)); | |
} | |
template< class A > | |
inline constexpr Expr1<A, Cos> cos_(A&& a) | |
{ | |
return Expr1<A, Cos>(std::forward<A>(a)); | |
} | |
template< class A > | |
inline constexpr Expr1<A, Tan> tan_(A&& a) | |
{ | |
return Expr1<A, Tan>(std::forward<A>(a)); | |
} | |
template < class A > | |
inline constexpr Expr1<A, Asin> asin_(A&& a) | |
{ | |
return Expr1<A, Asin>(std::forward<A>(a)); | |
} | |
template < class A > | |
inline constexpr Expr1<A, Acos> acos_(A&& a) | |
{ | |
return Expr1<A, Acos>(std::forward<A>(a)); | |
} | |
template < class A > | |
inline constexpr Expr1<A, Atan> atan_(A&& a) | |
{ | |
return Expr1<A, Atan>(std::forward<A>(a)); | |
} | |
template < class A > | |
inline constexpr Expr1<A, Sinh> sinh_(A&& a) | |
{ | |
return Expr1<A, Sinh>(std::forward<A>(a)); | |
} | |
template < class A > | |
inline constexpr Expr1<A, Cosh> cosh_(A&& a) | |
{ | |
return Expr1<A, Cosh>(std::forward<A>(a)); | |
} | |
template < class A > | |
inline constexpr Expr1<A, Tanh> tanh_(A&& a) | |
{ | |
return Expr1<A, Tanh>(std::forward<A>(a)); | |
} | |
template < class A > | |
inline constexpr Expr1<A, Asinh> asinh_(A&& a) | |
{ | |
return Expr1<A, Asinh>(std::forward<A>(a)); | |
} | |
template < class A > | |
inline constexpr Expr1<A, Acosh> acosh_(A&& a) | |
{ | |
return Expr1<A, Acosh>(std::forward<A>(a)); | |
} | |
template < class A > | |
inline constexpr Expr1<A, Atanh> atanh_(A&& a) | |
{ | |
return Expr1<A, Atanh>(std::forward<A>(a)); | |
} | |
template < class A > | |
inline constexpr Expr1<A, Exp> exp_(A&& a) | |
{ | |
return Expr1<A, Exp>(std::forward<A>(a)); | |
} | |
template < class A > | |
inline constexpr Expr1<A, Exp2> exp2_(A&& a) | |
{ | |
return Expr1<A, Exp2>(std::forward<A>(a)); | |
} | |
template < class A > | |
inline constexpr Expr1<A, Expm1> expm1_(A&& a) | |
{ | |
return Expr1<A, Expm1>(std::forward<A>(a)); | |
} | |
template < class A > | |
inline constexpr Expr1<A, Log> log_(A&& a) | |
{ | |
return Expr1<A, Log>(std::forward<A>(a)); | |
} | |
template < class A > | |
inline constexpr Expr1<A, Log10> log10_(A&& a) | |
{ | |
return Expr1<A, Log10>(std::forward<A>(a)); | |
} | |
template < class A > | |
inline constexpr Expr1<A, Log2> log2_(A&& a) | |
{ | |
return Expr1<A, Log2>(std::forward<A>(a)); | |
} | |
template < class A > | |
inline constexpr Expr1<A, Log1p> log1p_(A&& a) | |
{ | |
return Expr1<A, Log1p>(std::forward<A>(a)); | |
} | |
template < class A > | |
inline constexpr Expr1<A, Abs> abs_(A&& a) | |
{ | |
return Expr1<A, Abs>(std::forward<A>(a)); | |
} | |
template < class A > | |
inline constexpr Expr1<A, Erf> erf_(A&& a) | |
{ | |
return Expr1<A, Erf>(std::forward<A>(a)); | |
} | |
template < class A > | |
inline constexpr Expr1<A, Erfc> erfc_(A&& a) | |
{ | |
return Expr1<A, Erfc>(std::forward<A>(a)); | |
} | |
template< class L, class R > | |
inline constexpr Expr2<L, Pow, R> pow_(L&& a, R&& n) | |
{ | |
return Expr2<L, Pow, R>(std::forward<L>(a), std::forward<R>(n)); | |
} | |
template< class T1, class T2, class T3 > | |
inline constexpr auto fma_(T1&& v1, T2&& v2, T3&& v3) | |
{ | |
return Expr3<T1, T2, T3, Fma>(std::forward<T1>(v1), std::forward<T2>(v2), std::forward<T3>(v3)); | |
} | |
template < typename L, typename R > | |
inline constexpr auto max_(L&& v1, R&& v2) | |
{ | |
return Expr2<L, Max, R>(std::forward<L>(v1), std::forward<R>(v2)); | |
} | |
template < typename L, typename R > | |
inline constexpr auto min_(L&& v1, R&& v2) | |
{ | |
return Expr2<L, Min, R>(std::forward<L>(v1), std::forward<R>(v2)); | |
} | |
template < typename T, typename ... Args > | |
inline constexpr auto max_(T&& head, Args&&... args) | |
{ | |
return max_(std::forward<T>(head), max_(std::forward<Args>(args)...)); | |
} | |
template < typename T, typename ... Args > | |
inline constexpr auto min_(T&& head, Args&&... args) | |
{ | |
return min_(std::forward<T>(head), min_(std::forward<Args>(args)...)); | |
} | |
} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
one |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
\pi |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
e |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
ln2(log_e 2) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
ln10(log_e 10) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
\phi |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
c_0 = 299792458 [m \cdot s^{-1}] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment