Cranberries Interval Library Ver. 3.0.0 Release Note

#Cranberries Interval Library Ver. 3.0.0 Release Note

#New Features

##New functions
###Summary
Add 10 functions.
See bellow.


###New functions list

<dl>
<dt>rad</dt>
<dd>rad is radian of interval. " (upper_bound - lower_bound) / 2 ".</dd>

<dt>middle</dt>
<dd>middle is middle point of interval. Same as mid. "(lower_bound + upper_bound)/2".</dd>

<dt>mig</dt>
<dd>mig returns minimum absolute value of interval.</dd>

<dt>mag</dt>
<dd>mag returns maximum absolute value of interval.</dd>

<dt>norm</dt>
<dd>Same as mag.</dd>

<dt>in</dt>
<dd>in(T x, interval &lt;T&gt; I) returns true if I includes x. Others return  false.</dd>

<dt>subset</dt>
<dd>subset(interval&lt;T&gt; I, interval&lt;T&gt; J) returns true if J includes I. Others return false.</dd>

<dt>proper_subset</dt>
<dd>proper_subset(interval&lt;T&gt; I, interval\<T\> J) returns  true if I is proper subset of J. Others return false.</dd>

<dt>overlap</dt>
<dd>overlap(interval&lt;T&gt; I, interval&lt;T&gt; J) returns true if I ∩ J ≠ ∅. Others return false.</dd>

<dt>intersect</dt>
<dd>intersect(interval&lt;T&gt; I, interval&lt;T&gt; J) returns I ∩ J. Never use if I ∩ J = ∅. </dd>

</dl>

###Definition


```cpp
	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)
		}
	}

```


</dl>

##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


```math
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>() }`

---


```math
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>() }`

---


```math
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>() }`

---


```math 
\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>() }`

---


```math
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>() }`

---


```math
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>() }`

---


```math
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>() }`

---


```math
\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
---


```math
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>() }`

---


```math
\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>() }`

---


```math
\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>() }`

---


```math
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>() }`

---


```math
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) }`

---


```math
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) }`

---


```math
\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) }`

---


```math
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) }`

---


```math
\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) }`

---


```math
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) }`

---

```math
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
---


```cpp
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
---

```cpp
	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

```cpp
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

```cpp
	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.