Skip to content

Instantly share code, notes, and snippets.

@loliGothicK
Created December 29, 2015 09:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save loliGothicK/98cd66dad9688f858976 to your computer and use it in GitHub Desktop.
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
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)
}
}
\mu_0 = 12.566 370 614...×10^{−7} [N \cdot A^{−2}]
\epsilon_0 = 8.854 187 817...×10^{−12} [F \cdot m^{−1}]
Z_0 = \mu_0 \cdot c_0 = 376.730 313 461... [Ω]
G = 6.67408(31)×10^{−11} [ N \cdot m^{2} \cdot kg^{−2} ]
h = 6.626070040(81)×10^{−34} [ J \cdot s ]
\hbar = 6.626070040(81)×10^{−34} [ J \cdot s ]
e = 1.6021766208(98)×10^{−19} [ C ]
\phi_0 = \frac{h}{2e} = 2.067833831(13)×10^{−15} [ Wb ]
G_0 = \frac{2e^{2}}{h} = 7.7480917310(18)×10^{−5} [ S ]
R_0 = \frac{h}{2e^{2}} = 12906.4037278(29) [ Ω ]
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>>() ;
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>() };
}
}
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;
}
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)...));
}
}
ln2(log_e 2)
ln10(log_e 10)
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