Add asin, acos, atan, sinh, cosh, tanh to interval

This commit is contained in:
Soonho Kong 2013-08-14 12:08:24 -07:00
parent 56f4050932
commit 49b8bde67c
2 changed files with 140 additions and 9 deletions

View file

@ -3,6 +3,7 @@ Copyright (c) 2013 Microsoft Corporation. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE. Released under Apache 2.0 license as described in the file LICENSE.
Author: Leonardo de Moura Author: Leonardo de Moura
Soonho Kong
*/ */
#pragma once #pragma once
#include "numeric_traits.h" #include "numeric_traits.h"

View file

@ -3,6 +3,7 @@ Copyright (c) 2013 Microsoft Corporation. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE. Released under Apache 2.0 license as described in the file LICENSE.
Author: Leonardo de Moura Author: Leonardo de Moura
Soonho Kong
*/ */
#pragma once #pragma once
#include <gmp.h> #include <gmp.h>
@ -12,7 +13,6 @@ Author: Leonardo de Moura
#include "trace.h" #include "trace.h"
#include "mpz.h" #include "mpz.h"
namespace lean { namespace lean {
template<typename T> template<typename T>
@ -398,7 +398,7 @@ interval<T> & interval<T>::operator*=(interval<T> const & o) {
mul(new_u_val, new_u_kind, b, b_k, d, d_k); mul(new_u_val, new_u_kind, b, b_k, d, d_k);
} else { } else {
lean_assert(i2.is_P()); lean_assert(i2.is_P());
// 0 <= a <= x, 0 <= c <= y --> a*c <= x*y // 0 n<= a <= x, 0 <= c <= y --> a*c <= x*y
// x <= b, y <= d --> x*y <= b*d (uses the fact that x is pos (a is not negative) or y is pos (c is not negative)) // x <= b, y <= d --> x*y <= b*d (uses the fact that x is pos (a is not negative) or y is pos (c is not negative))
set_is_lower_open((i1.is_P0() || i2.is_P0()) ? false : a_o || c_o); set_is_lower_open((i1.is_P0() || i2.is_P0()) ? false : a_o || c_o);
@ -1105,14 +1105,144 @@ template<typename T> void interval<T>::tan() {
template<typename T> void interval<T>::sec () { /* TODO */ lean_unreachable(); return; } template<typename T> void interval<T>::sec () { /* TODO */ lean_unreachable(); return; }
template<typename T> void interval<T>::csc () { /* TODO */ lean_unreachable(); return; } template<typename T> void interval<T>::csc () { /* TODO */ lean_unreachable(); return; }
template<typename T> void interval<T>::cot () { /* TODO */ lean_unreachable(); return; } template<typename T> void interval<T>::cot () { /* TODO */ lean_unreachable(); return; }
template<typename T> void interval<T>::asin () { /* TODO */ lean_unreachable(); return; } template<typename T> void interval<T>::asin () {
template<typename T> void interval<T>::acos () { /* TODO */ lean_unreachable(); return; } lean_assert(lower_kind() == XN_NUMERAL && upper_kind() == XN_NUMERAL);
template<typename T> void interval<T>::atan () { /* TODO */ lean_unreachable(); return; } lean_assert(-1.0 <= m_lower && m_upper <= 1.0);
template<typename T> void interval<T>::sinh () { /* TODO */ lean_unreachable(); return; } numeric_traits<T>::set_rounding(false);
template<typename T> void interval<T>::cosh () { /* TODO */ lean_unreachable(); return; } numeric_traits<T>::asin(m_lower);
template<typename T> void interval<T>::tanh () { /* TODO */ lean_unreachable(); return; } numeric_traits<T>::set_rounding(true);
numeric_traits<T>::asin(m_upper);
lean_assert(check_invariant());
return;
}
template<typename T> void interval<T>::acos () {
lean_assert(lower_kind() == XN_NUMERAL && upper_kind() == XN_NUMERAL);
lean_assert(-1.0 <= m_lower && m_upper <= 1.0);
numeric_traits<T>::set_rounding(true);
numeric_traits<T>::acos(m_lower);
numeric_traits<T>::set_rounding(false);
numeric_traits<T>::acos(m_upper);
std::swap(m_lower, m_upper);
lean_assert(check_invariant());
return;
}
template<typename T> void interval<T>::atan () {
if(lower_kind() == XN_MINUS_INFINITY) {
m_lower = -1.0;
m_lower_open = false;
m_lower_inf = false;
} else {
numeric_traits<T>::set_rounding(false);
numeric_traits<T>::atan(m_lower);
}
if(upper_kind() == XN_MINUS_INFINITY) {
m_upper = 1.0;
m_upper_open = false;
m_upper_inf = false;
} else {
numeric_traits<T>::set_rounding(true);
numeric_traits<T>::atan(m_upper);
}
lean_assert(check_invariant());
return;
}
template<typename T> void interval<T>::sinh () {
if(lower_kind() == XN_NUMERAL) {
numeric_traits<T>::set_rounding(false);
numeric_traits<T>::sinh(m_lower);
}
if(upper_kind() == XN_NUMERAL) {
numeric_traits<T>::set_rounding(true);
numeric_traits<T>::sinh(m_upper);
}
lean_assert(check_invariant());
return;
}
template<typename T> void interval<T>::cosh () {
if(lower_kind() == XN_NUMERAL && upper_kind() == XN_NUMERAL) {
if(numeric_traits<T>::is_pos(m_lower) || numeric_traits<T>::is_zero(m_lower)) {
// [a, b] where 0 <= a <= b
numeric_traits<T>::set_rounding(false);
numeric_traits<T>::cosh(m_lower);
numeric_traits<T>::set_rounding(true);
numeric_traits<T>::cosh(m_lower);
lean_assert(check_invariant());
return;
}
if(numeric_traits<T>::is_neg(m_upper) || numeric_traits<T>::is_zero(m_upper)) {
// [a, b] where a <= b < 0
numeric_traits<T>::set_rounding(true);
numeric_traits<T>::cosh(m_lower);
numeric_traits<T>::set_rounding(false);
numeric_traits<T>::cosh(m_lower);
std::swap(m_lower, m_upper);
lean_assert(check_invariant());
return;
}
// [a,b] where a < 0 < b
m_lower = 0.0;
m_lower_open = false;
m_upper = m_upper > m_lower ? m_upper : m_lower;
numeric_traits<T>::set_rounding(true);
numeric_traits<T>::cosh(m_upper);
lean_assert(check_invariant());
return;
}
if(lower_kind() == XN_NUMERAL) {
m_upper_open = false;
m_upper_inf = true;
// [-oo, c]
if(numeric_traits<T>::is_neg(m_upper)) {
m_lower = m_upper;
numeric_traits<T>::set_rounding(false);
numeric_traits<T>::cosh(m_lower);
lean_assert(check_invariant());
return;
} else {
m_lower = 0.0;
m_lower_open = false;
lean_assert(check_invariant());
return;
}
}
if(upper_kind() == XN_NUMERAL) {
// [c,+oo]
if(numeric_traits<T>::is_neg(m_upper)) {
m_lower = 0.0;
m_lower_open = false;
lean_assert(check_invariant());
return;
} else {
numeric_traits<T>::set_rounding(false);
numeric_traits<T>::cosh(m_lower);
lean_assert(check_invariant());
return;
}
}
lean_assert(lower_kind() == XN_MINUS_INFINITY && upper_kind() == XN_PLUS_INFINITY);
// cosh((-oo, +oo)) = [0, +oo)
m_upper_open = true;
m_upper_inf = true;
m_lower = 0.0;
m_lower_open = false;
m_lower_inf = false;
lean_assert(check_invariant());
return;
}
template<typename T> void interval<T>::tanh () {
if(lower_kind() == XN_NUMERAL) {
numeric_traits<T>::set_rounding(false);
numeric_traits<T>::tanh(m_lower);
}
if(upper_kind() == XN_NUMERAL) {
numeric_traits<T>::set_rounding(true);
numeric_traits<T>::tanh(m_upper);
}
lean_assert(check_invariant());
return;
}
template<typename T> void interval<T>::asinh() { /* TODO */ lean_unreachable(); return; } template<typename T> void interval<T>::asinh() { /* TODO */ lean_unreachable(); return; }
template<typename T> void interval<T>::acosh() { /* TODO */ lean_unreachable(); return; } template<typename T> void interval<T>::acosh() { /* TODO */ lean_unreachable(); return; }
template<typename T> void interval<T>::atanh() { /* TODO */ lean_unreachable(); return; } template<typename T> void interval<T>::atanh() { /* TODO */ lean_unreachable(); return; }
} }