//--------------------------------------------------------------------------
// Author: Thomas Nowotny
//
// Institute: Institut fuer Theoretische Physik
// Augustusplatz 10-11
// 04109 Leipzig
//
// email to: nowotny@itp.uni-leipzig.de
//
// initial version: 8/99
// last change: 8/99
//--------------------------------------------------------------------------
#include "eld.h"
template <class type>
eld<type>::eld()
{
}
template <class type>
eld<type>::eld(type xi)
{
xm= xi;
x= xi;
xp= xi;
assert(xm <= xp);
}
template <class type>
eld<type>::eld(type xmi, type xi, type xpi)
{
xm= xmi;
x= xi;
xp= xpi;
assert(xm <= xp);
}
template <class type>
eld<type>::eld(const eld<type> &ei)
{
xm= ei.xm;
x= ei.x;
xp= ei.xp;
assert(xm <= xp);
}
template <class type>
inline eld<type>& eld<type>::operator=(const eld<type> ei)
{
xm= ei.xm;
x= ei.x;
xp= ei.xp;
assert(xm <= xp);
return *this;
}
template <class type>
inline eld<type>& eld<type>::operator=(const type li)
{
xm= li;
x= li;
xp= li;
assert(xm <= xp);
return *this;
}
template <class type>
inline eld<type>& eld<type>::operator+=(const eld<type> e2)
{
xm+= e2.xm;
xm-= abs(xm*__eld_eps);
x+= e2.x;
xp+= e2.xp;
xp+= abs(xp*__eld_eps);
assert(xm <= xp);
return *this;
}
template <class type>
inline eld<type>& eld<type>::operator-=(const eld<type> e2)
{
xm-= e2.xp;
x-= e2.x;
xp-= e2.xm;
xm-= abs(xm*__eld_eps);
xp+= abs(xp*__eld_eps);
assert(xm <= xp);
return *this;
}
template <class type>
inline eld<type>& eld<type>::operator*=(const eld<type> e2)
{
type h1= xm*e2.xm;
type h2= xm*e2.xp;
type h3= xp*e2.xm;
type h4= xp*e2.xp;
xm= min(min(h1,h2),min(h3,h4));
xm-= abs(xm*__eld_eps);
x*= e2.x;
xp= max(max(h1,h2),max(h3,h4));
xp+= abs(xp*__eld_eps);
assert(xm <= xp);
return *this;
}
template <class type>
inline eld<type> eld<type>::inv()
{
eld<type> ei;
if ((xm <= 0) && (xp >= 0))
{
ei.xm= -__eld_max;
ei.x= one;
ei.xp= __eld_max;
}
else
{
ei.xm= one/xp;
ei.xm-= abs(ei.xm*__eld_eps);
ei.x= one/x;
ei.xp= one/xm;
ei.xp+= abs(ei.xp*__eld_eps);
}
assert(ei.xm <= ei.xp);
return ei;
}
template <class type>
inline eld<type>& eld<type>::operator/=(const eld<type> e2)
{
eld<type> en(e2);
*this*= en.inv();
assert(xm <= xp);
return *this;
}
template <class type>
inline eld<type>& eld<type>::operator+=(const type l)
{
xm+= l;
xm-= abs(xm*__eld_eps);
x+= l;
xp+= l;
xp+= abs(xp*__eld_eps);
assert(xm <= xp);
return *this;
}
template <class type>
inline eld<type>& eld<type>::operator-=(const type l)
{
xm-= l;
xm-= abs(xm*__eld_eps);
x-= l;
xp-= l;
xp+= abs(xp*__eld_eps);
assert(xm <= xp);
return *this;
}
template <class type>
inline eld<type>& eld<type>::operator*=(const type l)
{
if (l < 0)
{
type tmp= xm;
xm= xp*l;
xp= tmp*l;
}
else
{
xm*= l;
xp*= l;
}
x*= l;
xm-= abs(xm*__eld_eps);
xp+= abs(xp*__eld_eps);
assert(xm <= xp);
return *this;
}
template <class type>
inline eld<type>& eld<type>::operator/=(const type l)
{
if (l < 0)
{
type tmp= xm;
xm= xp/l;
xp= tmp/l;
}
else
{
xm/= l;
xp/= l;
}
x/= l;
xm-= abs(xm*__eld_eps);
xp+= abs(xp*__eld_eps);
assert(xm <= xp);
return *this;
}
template <class type>
inline eld<type> operator-(const eld<type> e)
{
eld<type> en;
en.xm= -e.xp;
en.x= -e.x;
en.xp= -e.xm;
assert(en.xm <= en.xp);
return en;
}
template <class type>
inline eld<type> operator+(const eld<type> e1, const eld<type> e2)
{
eld<type> en(e1);
en+= e2;
assert(en.xm <= en.xp);
return en;
}
template <class type>
inline eld<type> operator-(const eld<type> e1, const eld<type> e2)
{
eld<type> en(e1);
en-= e2;
assert(en.xm <= en.xp);
return en;
}
template <class type>
inline eld<type> operator*(const eld<type> e1, const eld<type> e2)
{
eld<type> en(e1);
en*= e2;
assert(en.xm <= en.xp);
return en;
}
template <class type>
inline eld<type> operator/(const eld<type> e1, const eld<type> e2)
{
eld<type> en(e1);
en/= e2;
assert(en.xm <= en.xp);
return en;
}
template <class type>
inline eld<type> operator+(const type l, const eld<type> e)
{
eld<type> en(l);
en+= e;
assert(en.xm <= en.xp);
return en;
}
template <class type>
inline eld<type> operator-(const type l, const eld<type> e)
{
eld<type> en(l);
en-= e;
assert(en.xm <= en.xp);
return en;
}
template <class type>
inline eld<type> operator*(const type l, const eld<type> e)
{
eld<type> en(l);
en*= e;
assert(en.xm <= en.xp);
return en;
}
template <class type>
inline eld<type> operator/(const type l, const eld<type> e)
{
eld<type> en(l);
en/= e;
assert(en.xm <= en.xp);
return en;
}
template <class type>
inline eld<type> operator+(const eld<type> e, const type l)
{
eld<type> en(e);
en+= l;
assert(en.xm <= en.xp);
return en;
}
template <class type>
inline eld<type> operator-(const eld<type> e, const type l)
{
eld<type> en(e);
en-= l;
assert(en.xm <= en.xp);
return en;
}
template <class type>
inline eld<type> operator*(const eld<type> e, const type l)
{
eld<type> en(l);
en*= e;
assert(en.xm <= en.xp);
return en;
}
template <class type>
inline eld<type> operator/(const eld<type> e, const type l)
{
eld<type> en(one/l);
en*= e;
assert(en.xm <= en.xp);
return en;
}
template <class type>
ostream& operator<<(ostream& os, const eld<type> e)
{
os << "(" << e.xm << " " << e.x << " " << e.xp << ")";
return os;
}
template <class type>
istream& operator>>(istream& is, eld<type>& e)
{
char buf= ' ';
while(buf != '(')
{
is >> buf;
}
is >> e.xm;
is >> e.x;
is >> e.xp;
is >> buf;
assert(e.xm <= e.xp);
return is;
}
template <class type>
inline int operator==(const eld<type> e1, const eld<type> e2)
{
return e1.x == e2.x;
}
template <class type>
inline int operator!=(const eld<type> e1, const eld<type> e2)
{
return !(e1 == e2);
}
template <class type>
inline int operator<(const eld<type> e1, const eld<type> e2)
{
return e1.x < e2.x;
}
template <class type>
inline int operator<=(const eld<type> e1, const eld<type> e2)
{
return e1.x <= e2.x;
}
template <class type>
inline int operator>(const eld<type> e1, const eld<type> e2)
{
return e1.x > e2.x;
}
template <class type>
inline int operator>=(const eld<type> e1, const eld<type> e2)
{
return e1.x >= e2.x;
}
template <class type>
inline int operator==(const eld<type> e, const type l)
{
return e.x == l;
}
template <class type>
inline int operator!=(const eld<type> e, const type l)
{
return !(e == l);
}
template <class type>
inline int operator<(const eld<type> e, const type l)
{
return e.x < l;
}
template <class type>
inline int operator<=(const eld<type> e, const type l)
{
return e.x <= l;
}
template <class type>
inline int operator>(const eld<type> e, const type l)
{
return e.x > l;
}
template <class type>
inline int operator>=(const eld<type> e, const type l)
{
return e.x >= l;
}
template <class type>
inline int operator==(const type l, const eld<type> e)
{
return e.x == l;
}
template <class type>
inline int operator!=(const type l, const eld<type> e)
{
return !(e == l);
}
template <class type>
inline int operator<(const type l, const eld<type> e)
{
return l < e.x;
}
template <class type>
inline int operator<=(const type l, const eld<type> e)
{
return l <= e.x;
}
template <class type>
inline int operator>(const type l, const eld<type> e)
{
return l > e.x;
}
template <class type>
inline int operator>=(const type l, const eld<type> e)
{
return l >= e.x;
}
template <class type>
inline eld<type> min(const eld<type> e, const type l)
{
if (e < l) return e;
else
{
eld<type> en(l);
return en;
}
}
template <class type>
inline eld<type> min(const type l, const eld<type> e)
{
if (l < e)
{
eld<type> en(l);
return en;
}
else return e;
}
template <class type>
inline eld<type> max(const eld<type> e, const type l)
{
if (e > l) return e;
else
{
eld<type> en(l);
return en;
}
}
template <class type>
inline eld<type> max(const type l, const eld<type> e)
{
if (l > e)
{
eld<type> en(l);
return en;
}
else return e;
}
template <class type>
inline eld<type> sqrt(const eld<type> e)
{
eld<type> en;
assert(en.x >= null);
if (e.xm < null) en.xm= null;
else en.xm= sqrt(e.xm);
en.x= sqrt(e.x);
en.xp= sqrt(e.xp);
en.xm-= abs(en.xm*__eld_eps);
en.xp+= abs(en.xp*__eld_eps);
assert(en.xm <= en.xp);
return en;
}
template <class type>
inline eld<type> sinh(const eld<type> e)
{
eld<type> en;
en.xm= sinh(e.xm);
en.x= sinh(e.x);
en.xp= sinh(e.xp);
en.xm-= abs(en.xm*__eld_eps);
en.xp+= abs(en.xp*__eld_eps);
assert(en.xm <= en.xp);
return en;
}
template <class type>
inline eld<type> cosh(const eld<type> e)
{
eld<type> en;
type h1, h2;
h1= cosh(e.xm);
h2= cosh(e.xp);
if ((e.xm < 0) && (e.xp > 0)) en.xm= null;
else en.xm= min(h1, h2);
en.xp= max(h1, h2);
en.x= cosh(e.x);
en.xm-= abs(en.xm*__eld_eps);
en.xp+= abs(en.xp*__eld_eps);
assert(en.xm <= en.xp);
return en;
}
template <class type>
inline eld<type> tanh(const eld<type> e)
{
eld<type> en;
en.xm= tanh(e.xm);
en.x= tanh(e.x);
en.xp= tanh(e.xp);
en.xm-= abs(en.xm*__eld_eps);
en.xp+= abs(en.xp*__eld_eps);
assert(en.xm <= en.xp);
return en;
}
template <class type>
inline eld<type> log(const eld<type> e)
{
eld<type> en;
en.xm= log(e.xm);
en.x= log(e.x);
en.xp= log(e.xp);
en.xm-= abs(en.xm*__eld_eps);
en.xp+= abs(en.xp*__eld_eps);
assert(en.xm <= en.xp);
return en;
}
template <class type>
inline eld<type> exp(const eld<type> e)
{
eld<type> en;
en.xm= exp(e.xm);
en.x= exp(e.x);
en.xp= exp(e.xp);
en.xm-= abs(en.xm*__eld_eps);
en.xp+= abs(en.xp*__eld_eps);
assert(en.xm <= en.xp);
return en;
}
template <class type>
inline eld<type> atan(const eld<type> e)
{
eld<type> en;
en.xm= atan(e.xm);
en.x= atan(e.x);
en.xp= atan(e.xp);
en.xm-= abs(en.xm*__eld_eps);
en.xp+= abs(en.xp*__eld_eps);
assert(en.xm <= en.xp);
return en;
}
/*
template <class type>
inline eld<type> cos(const eld<type> e)
{
eld<type> en;
int xmi= (int) floor(e.xm/__eld_pi);
int xpi= (int) floor(e.xp/__eld_pi);
if (xmi != xpi)
{
if (xpi%2 == 0)
{
en.xm= min(cos(e.xm), cos(e.xp));
en.xp= one;
}
else
{
en.xm= -one;
en.xp= max(cos(e.xm), cos(e.xp));
}
}
else
{
en.xm= min(cos(e.xm), cos(e.xp));
en.xp= max(cos(e.xm), cos(e.xp));
}
en.x= cos(e.x);
en.xm-= abs(en.xm*__eld_eps);
en.xp+= abs(en.xp*__eld_eps);
return en;
}
template <class type>
inline eld<type> sin(const eld<type> e)
{
eld<type> en;
int xmi= (int) floor((e.xm-__eld_pi/2)/__eld_pi);
int xpi= (int) floor((e.xp-__eld_pi/2)/__eld_pi);
if (xmi != xpi)
{
if (xpi%2 == 0)
{
en.xm= min(sin(e.xm), sin(e.xp));
en.xp= one;
}
else
{
en.xm= -one;
en.xp= max(sin(e.xm), sin(e.xp));
}
}
else
{
en.xm= min(sin(e.xm), sin(e.xp));
en.xp= max(sin(e.xm), sin(e.xp));
}
en.x= sin(e.x);
en.xm-= abs(en.xm*__eld_eps);
en.xp+= abs(en.xp*__eld_eps);
return en;
}
*/
template <class type>
inline eld<type> tan(const eld<type> e)
{
eld<type> en;
en.xm= tan(e.xm);
en.x= tan(e.x);
en.xp= tan(e.xp);
en.xm-= abs(en.xm*__eld_eps);
en.xp+= abs(en.xp*__eld_eps);
assert(en.xm <= en.xp);
return en;
}
template <class type>
inline eld<type> abs(const eld<type> e)
{
eld<type> en;
en.xm= abs(e.xm);
en.x= abs(e.x);
en.xp= abs(e.xp);
if (en.xm > en.xp)
{
type zws= en.xm;
en.xm= en.xp;
en.xp= zws;
}
assert(en.xm <= en.xp);
return en;
}
template <class type>
inline eld<type> pow(const eld<type> e, const eld<type> ee)
{
assert(e > null);
return exp(ee*log(e));
}
template <class type>
inline eld<type> pow(const eld<type> e, const type ee)
{
assert(e > null);
return exp(ee*log(e));
}
template <class type>
inline eld<type> pow(const eld<type> e, const int ee)
{
assert(e > null);
eet= (type) ee;
return exp(eet*log(e));
}
template <class type>
inline eld<type> pow(const type e, const eld<type> ee)
{
assert(e > null);
return exp(ee*log(e));
}
template <class type>
inline eld<type> atanh(const eld<type> e)
{
eld<type> en;
assert(e > -one);
assert(e < one);
en.xm= atanh(e.xm);
en.x= atanh(e.x);
en.xp= atanh(e.xp);
en.xm-= abs(en.xm*__eld_eps);
en.xp+= abs(en.xp*__eld_eps);
assert(en.xm <= en.xp);
return en;
}
template <class type>
inline eld<type> floor(const eld<type> e)
{
eld<type> en;
en.xm= floor(e.xm);
en.x= floor(e.x);
en.xp= floor(e.xp);
assert(en.xm <= en.xp);
return en;
}
template <class type>
inline eld<type> trunc(const eld<type> e)
{
eld<type> en;
en.xm= (type)((long)(e.xm));
en.x= (type)((long)(e.x));
en.xp= (type)((long)(e.xp));
assert(en.xm <= en.xp);
return en;
}
template <class type>
inline long conv_to_long(const eld<type> e)
{
return (long) e.x;
}
template <class type>
inline int conv_to_int(const eld<type> e)
{
return (int) e.x;
}
template <class type>
inline short conv_to_short(const eld<type> e)
{
return (short) e.x;
}