Cranberries Interval Library Ver. 3.0.0 Release Note
New Features
New functions
Summary
Add 10 functions.
See bellow.
New functions list
- rad
- rad is radian of interval. " (upper_bound - lower_bound) / 2 ".
- middle
- middle is middle point of interval. Same as mid. "(lower_bound + upper_bound)/2".
- mig
- mig returns minimum absolute value of interval.
- mag
- mag returns maximum absolute value of interval.
- norm
- Same as mag.
- in
- in(T x, interval <T> I) returns true if I includes x. Others return false.
- subset
- subset(interval<T> I, interval<T> J) returns true if J includes I. Others return false.
- proper_subset
- proper_subset(interval<T> I, interval\ J) returns true if I is proper subset of J. Others return false.
- overlap
- overlap(interval<T> I, interval<T> J) returns true if I ∩ J ≠ ∅. Others return false.
- intersect
- intersect(interval<T> I, interval<T> J) returns I ∩ J. Never use if I ∩ J = ∅.
Definition
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)
}
}
Constants
Summary
Add constants and interval_constants as constexpr functions
.
It includes Math Constants and Physics Constants.
Physics constants are defined The International System of Units.
Physics constants considered standard uncertainty.
It allows to compute with standard uncertainty using interval arithmetic.
Constants List
Math Constants
max
define as max<T>()
.
constants::max<T>()
returns std::numeric_limits<T>::max()
.
constants::max<interval<T>>()
returns interval<T>{ constants::max<T>(), constants::max<T>() }
zero
define as zero<T>()
.
constants::zero<T>()
returns static_cast<T>(0.0L)
.
constants::max<interval<T>>()
returns interval<T>{ constants::zero<T>(), constants::zero<T>() }
one
define as one<T>()
.
constants::one<T>()
returns static_cast<T>(1.0L)
.
constants::one<interval<T>>()
returns interval<T>{ constants::one<T>(), constants::one<T>() }
\pi
The ratio of the circumference of a circle to its diameter.
define as pi<T>()
.
constants::pi<T>()
returns static_cast<T>(3.141592653589793238462643383279L)
.
constants::pi<interval<T>>()
returns interval<T>{ constants::pi<T>(), constants::pi<T>() }
e
Base of natural logarithm.
define as e<T>()
.
constants::e<T>()
returns static_cast<T>(2.718281828459045235360287471352L)
.
constants::e<interval<T>>()
returns interval<T>{ constants::<T>(), constants::<T>() }
ln2(log_e 2)
define as ln2<T>()
.
constants::ln2<T>()
returns static_cast<T>(0.693147180559945309417232121458L)
.
constants::<interval<T>>()
returns interval<T>{ constants::e<T>(), constants::e<T>() }
ln10(log_e 10)
define as ln10<T>()
.
constants::ln10<T>()
returns static_cast<T>(2.302585092994045684017991454684L)
.
constants::ln10<interval<T>>()
returns interval<T>{ constants::ln10<T>(), constants::ln10<T>() }
\phi
Golden ratio.
define as golden<T>()
.
constants::golden<T>()
returns static_cast<T>(1.61803398874989484820458683436563811L)
.
constants::golden<interval<T>>()
returns interval<T>{ constants::golden<T>(), constants::golden<T>() }
Physics Constants
c_0 = 299792458 [m \cdot s^{-1}]
Velocity of light in vacuum.
define as c_0<T>()
.
constants::c_0<T>()
returns static_cast<T>(299792458L)
.
constants::c_0<interval<T>>()
returns interval<T>{ constants::c_0<T>(), constants::c_0<T>() }
\mu_0 = 12.566 370 614...×10^{−7} [N \cdot A^{−2}]
Permeability in vacuum.
define as mu_0<T>()
.
constants::mu_0<T>()
returns static_cast<T>(4.0L*pi<T>()*1E-7L)
.
constants::mu_0<interval<T>>()
returns interval<T>{ constants::mu_0<T>(), constants::mu_0<T>() }
\epsilon_0 = 8.854 187 817...×10^{−12} [F \cdot m^{−1}]
Permittivity of vacuum.
define as epsilon_0<T>()
.
constants::epsilon_0<T>()
returns static_cast<T>(8.854187817L)
.
constants::epsilon_0<interval<T>>()
returns interval<T>{ constants::epsilon_0<T>(), constants::epsilon_0<T>() }
Z_0 = \mu_0 \cdot c_0 = 376.730 313 461... [Ω]
Impedance of free space.
define as z_0<T>()
.
constants::z_0<T>()
returns static_cast<T>(376.730313461L)
.
constants::x_0<interval<T>>()
returns interval<T>{ constants::z_0<T>(), constants::z_0<T>() }
G = 6.67408(31)×10^{−11} [ N \cdot m^{2} \cdot kg^{−2} ]
Gravitational constant.
define as g<T>()
.
constants::g<T>()
returns static_cast<T>(6.67408E-11L)
.
constants::g<interval<T>>()
returns interval<T>{ static_cast<T>(6.67377E-11L), static_cast<T>(6.67439E-11L) }
h = 6.626070040(81)×10^{−34} [ J \cdot s ]
Planck constant.
define as planck<T>()
.
constants::planck<T>()
returns static_cast<T>(6.626070040E-34L)
.
constants::planck<interval<T>>()
returns interval<T>{ static_cast<T>(6.626069959E-34L), static_cast<T>(6.626070121E-34L) }
\hbar = 6.626070040(81)×10^{−34} [ J \cdot s ]
Dirac constants.
define as dirac<T>()
.
constants::dirac<T>()
returns static_cast<T>(1.054571800E-34L)
.
constants::dirac<interval<T>>()
returns interval<T>{ static_cast<T>(1.054571753E-34L), static_cast<T>(1.054571847E-34L) }
e = 1.6021766208(98)×10^{−19} [ C ]
Elementary charge.
define as <T>()
.
constants::<T>()
returns static_cast<T>(1.6021766208E-19L)
.
constants::<interval<T>>()
returns interval<T>{ static_cast<T>(1.6021766110E-19L), static_cast<T>(1.6021766306E-19L) }
\phi_0 = \frac{h}{2e} = 2.067833831(13)×10^{−15} [ Wb ]
Flux quantum.
define as phi_0<T>()
.
constants::phi_0<T>()
returns static_cast<T>(2.067833831E-15L)
.
constants::phi_0<interval<T>>()
returns interval<T>{ static_cast<T>(2.067833818E-15L), static_cast<T>(2.067833844E-15L) }
G_0 = \frac{2e^{2}}{h} = 7.7480917310(18)×10^{−5} [ S ]
Conductance quantum.
define as g_0<T>()
.
constants::g_0<T>()
returns static_cast<T>(7.7480917310E-5L)
.
constants::g_0<interval<T>>()
returns interval<T>{ static_cast<T>(7.7480917292E-5L), static_cast<T>(7.7480917328E-5L) }
R_0 = \frac{h}{2e^{2}} = 12906.4037278(29) [ Ω ]
Resistance quantum.
define as r_0<T>()
.
constants::r_0<T>()
returns static_cast<T>(12906.4037278L)
.
constants::r_0<interval<T>>()
returns interval<T>{ static_cast<T>(12906.4037249L), static_cast<T>(12906.4037307L) }
How to Use
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>>() ;
Definition
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>() };
}
}
Expression Template
Summary
It is feature for lazy evaluation.
Construct Expression and hold structure.
It allows to calculate before or not.
How to Use
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;
}
Definition
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)...));
}
}
Fixed Features
Fixed #2
Changed rounding control for math func to use fesetround instead of nextforward.
Four arithmetic operator and sqrt are perfectly work.
But other math functions work are undefined IEEE754.
Now writing polynomial approximation.
Fixed #5
Add resetters receiving value as const lvalue reference.
Fixed exception.hpp
Add exception check if-block MACRO.
Rename exception class.
Improvement exception check
Introducing exception check MACRO, exception having more information.
Exception has information; file, line, function name and reason why occurred it.
Fixed logical operator and four arithmetic operator
Fixed the problem that ADL failure occurred with policy if and only if arguments are const lvalue.