/*
**  CXSC is a C++ library for eXtended Scientific Computing
**
**  Copyright (C) 1990-2000 Institut fuer Angewandte Mathematik,
**                          Universitaet Karlsruhe, Germany
**            (C) 2000-2001 Wiss. Rechnen/Softwaretechnologie
**                          Universitaet Wuppertal, Germany   
**
**  This library is free software; you can redistribute it and/or
**  modify it under the terms of the GNU Library General Public
**  License as published by the Free Software Foundation; either
**  version 2 of the License, or (at your option) any later version.
**
**  This library is distributed in the hope that it will be useful,
**  but WITHOUT ANY WARRANTY; without even the implied warranty of
**  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
**  Library General Public License for more details.
**
**  You should have received a copy of the GNU Library General Public
**  License along with this library; if not, write to the Free
**  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/

/* CVS $Id: cinterva.hpp,v 1.3 2001/08/09 11:37:53 cxsc Exp $ */

#ifndef CINTERVA_HPP_INCLUDED
#define CINTERVA_HPP_INCLUDED

#include <iostream>
#include <string>

// Headerfile for cinterval.

#include "except.hpp"
#include "real.hpp"
#include "complex.hpp"
#include "interval.hpp"

namespace cxsc {

class civector;
class cimatrix;
class civector_slice;
class cimatrix_slice;

class cinterval
{
   private:
      // ---- private data ----------------------------------------
      interval  re;
      interval  im;

   public:
      // ---- implicit constructors  ------------------------------
      inline cinterval(void)  throw ()           {}
      inline cinterval(const interval & a,const interval &b) throw(); 
      inline cinterval(const complex & a,const complex & b)  throw(ERROR_CINTERVAL_EMPTY_INTERVAL); 

      // The following are defined in the specific vector, matrix-files
#if(IndCheck) 
		INLINE cinterval(const civector &)       throw (ERROR_CIVECTOR_TYPE_CAST_OF_THICK_OBJ,ERROR_CIVECTOR_USE_OF_UNINITIALIZED_OBJ);
      INLINE cinterval(const civector_slice &) throw (ERROR_CIVECTOR_TYPE_CAST_OF_THICK_OBJ,ERROR_CIVECTOR_USE_OF_UNINITIALIZED_OBJ);
      INLINE cinterval(const cimatrix &)       throw (ERROR_CIMATRIX_TYPE_CAST_OF_THICK_OBJ,ERROR_CIMATRIX_USE_OF_UNINITIALIZED_OBJ);
      INLINE cinterval(const cimatrix_slice &) throw (ERROR_CIMATRIX_TYPE_CAST_OF_THICK_OBJ,ERROR_CIMATRIX_USE_OF_UNINITIALIZED_OBJ);
#else
		INLINE cinterval(const civector &)       throw ();
      INLINE cinterval(const civector_slice &) throw ();
      INLINE cinterval(const cimatrix &)       throw ();
      INLINE cinterval(const cimatrix_slice &) throw ();
#endif
      // ---- explicit constructors -------------------------------

      explicit inline cinterval(const real     & a)  throw();
      explicit inline cinterval(const interval & a)  throw();
      explicit inline cinterval(const complex  & a)  throw(); 
      explicit        cinterval(const dotprecision &)  throw();
      explicit        cinterval(const cdotprecision &) throw();
      explicit        cinterval(const idotprecision &) throw();
      explicit        cinterval(const cidotprecision &) throw();

      // ---- assignments -----------------------------------------

      inline cinterval & operator =(const real &) throw();
      inline cinterval & operator =(const interval &) throw();
      inline cinterval & operator =(const complex &) throw();
      inline cinterval & operator =(const cinterval &) throw();
      
      inline cinterval & operator =(const dotprecision &) throw();
      inline cinterval & operator =(const idotprecision &) throw();
      inline cinterval & operator =(const cdotprecision &) throw();
      inline cinterval & operator =(const cidotprecision &) throw();
      
      // ---- compatiblility typecasts ----------------------------

      friend inline cinterval _cinterval(const real &) throw ();
      friend inline cinterval _cinterval(const interval &) throw();
      friend inline cinterval _cinterval(const complex &) throw ();
      friend inline cinterval _cinterval(const dotprecision &) throw();
      friend inline cinterval _cinterval(const idotprecision &) throw();
      friend inline cinterval _cinterval(const cdotprecision &) throw();
      friend inline cinterval _cinterval(const cidotprecision &) throw();
      
      friend inline cinterval _cinterval(const interval &,const interval &) throw();
      friend inline cinterval _cinterval(const real &,const interval &) throw();
      friend inline cinterval _cinterval(const interval &,const real &) throw();
      friend inline cinterval _cinterval(const complex &,const complex &) throw();
      friend inline cinterval _cinterval(const real &,const complex &) throw();
      friend inline cinterval _cinterval(const complex &,const real &) throw();
      friend inline cinterval _unchecked_cinterval(const complex &,const complex &) throw();
      friend inline cinterval _unchecked_cinterval(const real &,const complex &) throw();
      friend inline cinterval _unchecked_cinterval(const complex &,const real &) throw();

      // ---- Input/Output  ---------------------------------------

      friend std::ostream & operator <<(std::ostream &,const cinterval &) throw();
      friend std::istream & operator >>(std::istream &,cinterval &)       throw(ERROR_CINTERVAL_EMPTY_INTERVAL);
      friend std::string &  operator <<(std::string &,const cinterval &)  throw();
      friend std::string &  operator >>(std::string &,cinterval &)        throw(ERROR_CINTERVAL_EMPTY_INTERVAL);
      friend void           operator >>(const char *,cinterval &)         throw(ERROR_CINTERVAL_EMPTY_INTERVAL);
      friend void           operator >>(const std::string &,cinterval &)  throw(ERROR_CINTERVAL_EMPTY_INTERVAL);

      // ---- Std.Operators ---------------------------------------

      friend inline cinterval operator -(const cinterval &) throw ();
      friend inline cinterval operator +(const cinterval &) throw ();
      friend inline bool operator!  (const cinterval & a)                    throw();

      // CI-CI

      friend inline cinterval operator +(const cinterval &,const cinterval &) throw();
      friend inline cinterval operator -(const cinterval &,const cinterval &) throw();
      friend        cinterval operator *(const cinterval &,const cinterval &) throw();
      friend        cinterval operator /(const cinterval &,const cinterval &) throw();
      friend inline cinterval operator |(const cinterval &,const cinterval &) throw();
      friend inline cinterval operator &(const cinterval &,const cinterval &) throw(ERROR_CINTERVAL_EMPTY_INTERVAL);
      
      friend inline cinterval & operator +=(cinterval &, const cinterval &) throw();
      friend inline cinterval & operator -=(cinterval &, const cinterval &) throw();
      friend inline cinterval & operator *=(cinterval &, const cinterval &) throw();
      friend inline cinterval & operator /=(cinterval &, const cinterval &) throw();
      friend inline cinterval & operator |=(cinterval &, const cinterval &) throw();
      friend inline cinterval & operator &=(cinterval &, const cinterval &) throw(ERROR_CINTERVAL_EMPTY_INTERVAL);
      
      // CI-R
      
      friend inline cinterval operator +(const cinterval &,const real &) throw();
      friend inline cinterval operator +(const real &,const cinterval &) throw();
      friend inline cinterval operator -(const cinterval &,const real &) throw();
      friend inline cinterval operator -(const real &,const cinterval &) throw();
      friend inline cinterval operator *(const cinterval &,const real &) throw();
      friend inline cinterval operator *(const real &,const cinterval &) throw();
      friend inline cinterval operator /(const cinterval &,const real &) throw();
      friend inline cinterval operator /(const real &,const cinterval &) throw();
      friend inline cinterval operator |(const cinterval &,const real &) throw();
      friend inline cinterval operator |(const real &,const cinterval &) throw();
      friend inline cinterval operator &(const cinterval &,const real &) throw();
      friend inline cinterval operator &(const real &,const cinterval &) throw();
      
      friend inline cinterval & operator +=(cinterval &, const real &) throw();
      friend inline cinterval & operator -=(cinterval &, const real &) throw();
      friend inline cinterval & operator *=(cinterval &, const real &) throw();
      friend inline cinterval & operator /=(cinterval &, const real &) throw();
      friend inline cinterval & operator |=(cinterval &, const real &) throw();
      friend inline cinterval & operator &=(cinterval &, const real &) throw();
      
      // CI-I

      friend inline cinterval operator +(const cinterval &,const interval &) throw();
      friend inline cinterval operator +(const interval &,const cinterval &) throw();
      friend inline cinterval operator -(const cinterval &,const interval &) throw();
      friend inline cinterval operator -(const interval &,const cinterval &) throw();
      friend inline cinterval operator *(const cinterval &,const interval &) throw();
      friend inline cinterval operator *(const interval &,const cinterval &) throw();
      friend inline cinterval operator /(const cinterval &,const interval &) throw();
      friend inline cinterval operator /(const interval &,const cinterval &) throw();
      friend inline cinterval operator |(const cinterval &,const interval &) throw();
      friend inline cinterval operator |(const interval &,const cinterval &) throw();
      friend inline cinterval operator &(const cinterval &,const interval &) throw();
      friend inline cinterval operator &(const interval &,const cinterval &) throw();
      
      friend inline cinterval & operator +=(cinterval &, const interval &) throw();
      friend inline cinterval & operator -=(cinterval &, const interval &) throw();
      friend inline cinterval & operator *=(cinterval &, const interval &) throw();
      friend inline cinterval & operator /=(cinterval &, const interval &) throw();
      friend inline cinterval & operator |=(cinterval &, const interval &) throw();
      friend inline cinterval & operator &=(cinterval &, const interval &) throw();

      // CI-C

      friend inline cinterval operator +(const cinterval &,const complex &) throw();
      friend inline cinterval operator +(const complex &,const cinterval &) throw();
      friend inline cinterval operator -(const cinterval &,const complex &) throw();
      friend inline cinterval operator -(const complex &,const cinterval &) throw();
      friend inline cinterval operator *(const cinterval &,const complex &) throw();
      friend inline cinterval operator *(const complex &,const cinterval &) throw();
      friend inline cinterval operator /(const cinterval &,const complex &) throw();
      friend inline cinterval operator /(const complex &,const cinterval &) throw();
      friend inline cinterval operator |(const cinterval &,const complex &) throw();
      friend inline cinterval operator |(const complex &,const cinterval &) throw();
      friend inline cinterval operator &(const cinterval &,const complex &) throw();
      friend inline cinterval operator &(const complex &,const cinterval &) throw();
      

      friend inline cinterval & operator +=(cinterval &, const complex &) throw();
      friend inline cinterval & operator -=(cinterval &, const complex &) throw();
      friend inline cinterval & operator *=(cinterval &, const complex &) throw();
      friend inline cinterval & operator /=(cinterval &, const complex &) throw();
      friend inline cinterval & operator |=(cinterval &, const complex &) throw();
      friend inline cinterval & operator &=(cinterval &, const complex &) throw();
      
      // C-R

      friend inline cinterval operator |(const complex &,const real &) throw();
      friend inline cinterval operator |(const real &,const complex &) throw();

      // C-I

      friend inline cinterval operator +(const complex &,const interval &) throw();
      friend inline cinterval operator +(const interval &,const complex &) throw();
      friend inline cinterval operator -(const complex &,const interval &) throw();
      friend inline cinterval operator -(const interval &,const complex &) throw();
      friend inline cinterval operator *(const complex &,const interval &) throw();
      friend inline cinterval operator *(const interval &,const complex &) throw();
      friend inline cinterval operator /(const complex &,const interval &) throw();
      friend inline cinterval operator /(const interval &,const complex &) throw();
      friend inline cinterval operator |(const complex &,const interval &) throw();
      friend inline cinterval operator |(const interval &,const complex &) throw();
      friend inline cinterval operator &(const complex &,const interval &) throw();
      friend inline cinterval operator &(const interval &,const complex &) throw();
      

      // C-C

      friend inline cinterval operator |(const complex &,const complex &) throw();

      // ---- Comp.Operat.  ---------------------------------------
      
      friend inline bool operator== (const cinterval & a, const cinterval & b) throw();
      friend inline bool operator!= (const cinterval & a, const cinterval & b) throw();
      
      // CI-R
      
      friend inline bool operator== (const cinterval & a, const real & b)    throw();
      friend inline bool operator== (const real & a, const cinterval & b)    throw();
      friend inline bool operator!= (const cinterval & a, const real & b)    throw();
      friend inline bool operator!= (const real & a, const cinterval & b)    throw();

      // CI-I
      
      friend inline bool operator== (const cinterval & a, const interval & b)    throw();
      friend inline bool operator== (const interval & a, const cinterval & b)    throw();
      friend inline bool operator!= (const cinterval & a, const interval & b)    throw();
      friend inline bool operator!= (const interval & a, const cinterval & b)    throw();

      // CI-C
      
      friend inline bool operator== (const cinterval & a, const complex & b)    throw();
      friend inline bool operator== (const complex & a, const cinterval & b)    throw();
      friend inline bool operator!= (const cinterval & a, const complex & b)    throw();
      friend inline bool operator!= (const complex & a, const cinterval & b)    throw();

      // ---- Set Operators ----
      
      friend inline bool operator  <(const cinterval &,const cinterval &) throw();
      friend inline bool operator  >(const cinterval &,const cinterval &) throw();
      friend inline bool operator <=(const cinterval &,const cinterval &) throw();
      friend inline bool operator >=(const cinterval &,const cinterval &) throw();

      // CI-R

      friend inline bool operator  <(const real &,const cinterval &) throw();
      friend inline bool operator  >(const real &,const cinterval &) throw();
      friend inline bool operator <=(const real &,const cinterval &) throw();
      friend inline bool operator >=(const real &,const cinterval &) throw();

      friend inline bool operator  <(const cinterval &,const real &) throw();
      friend inline bool operator  >(const cinterval &,const real &) throw();
      friend inline bool operator <=(const cinterval &,const real &) throw();
      friend inline bool operator >=(const cinterval &,const real &) throw();

      // CI-I

      friend inline bool operator  <(const interval &,const cinterval &) throw();
      friend inline bool operator  >(const interval &,const cinterval &) throw();
      friend inline bool operator <=(const interval &,const cinterval &) throw();
      friend inline bool operator >=(const interval &,const cinterval &) throw();

      friend inline bool operator  <(const cinterval &,const interval &) throw();
      friend inline bool operator  >(const cinterval &,const interval &) throw();
      friend inline bool operator <=(const cinterval &,const interval &) throw();
      friend inline bool operator >=(const cinterval &,const interval &) throw();

      // CI-C

      friend inline bool operator  <(const complex &,const cinterval &) throw();
      friend inline bool operator  >(const complex &,const cinterval &) throw();
      friend inline bool operator <=(const complex &,const cinterval &) throw();
      friend inline bool operator >=(const complex &,const cinterval &) throw();

      friend inline bool operator  <(const cinterval &,const complex &) throw();
      friend inline bool operator  >(const cinterval &,const complex &) throw();
      friend inline bool operator <=(const cinterval &,const complex &) throw();
      friend inline bool operator >=(const cinterval &,const complex &) throw();

      // ---- Others   -------------------------------------------
      friend inline complex    Inf(const cinterval &) throw();
      friend inline complex    Sup(const cinterval &) throw();
      
      friend inline cinterval & SetInf(cinterval &,const complex &) throw(ERROR_CINTERVAL_EMPTY_INTERVAL);
      friend inline cinterval & SetInf(cinterval &,const real &) throw(ERROR_CINTERVAL_EMPTY_INTERVAL);
      friend inline cinterval & SetSup(cinterval &,const complex &) throw(ERROR_CINTERVAL_EMPTY_INTERVAL);
      friend inline cinterval & SetSup(cinterval &,const real &) throw(ERROR_CINTERVAL_EMPTY_INTERVAL);
      friend inline cinterval & UncheckedSetInf(cinterval &,const complex &) throw();
      friend inline cinterval & UncheckedSetInf(cinterval &,const real &)    throw();
      friend inline cinterval & UncheckedSetSup(cinterval &,const complex &) throw();
      friend inline cinterval & UncheckedSetSup(cinterval &,const real &)    throw();
      
      friend interval & Re(cinterval & a)       throw() { return a.re; }
      friend interval   Re(const cinterval & a) throw() { return a.re; }
      friend interval & Im(cinterval & a)       throw() { return a.im; }
      friend interval   Im(const cinterval & a) throw() { return a.im; }
      
      friend cinterval & SetRe(cinterval & a,const interval & b) { a.re=b; return a; }
      friend cinterval & SetIm(cinterval & a,const interval & b) { a.im=b; return a; } 
      friend cinterval & SetRe(cinterval & a,const real     & b) { a.re=b; return a; }
      friend cinterval & SetIm(cinterval & a,const real     & b) { a.im=b; return a; } 

      friend inline real InfRe(const cinterval &a) throw() { return Inf(a.re); }
      friend inline real InfIm(const cinterval &a) throw() { return Inf(a.im); }
      friend inline real SupRe(const cinterval &a) throw() { return Sup(a.re); }
      friend inline real SupIm(const cinterval &a) throw() { return Sup(a.im); }
      
      friend inline real & InfRe(cinterval &a) throw() { return Inf(a.re); }
      friend inline real & InfIm(cinterval &a) throw() { return Inf(a.im); }
      friend inline real & SupRe(cinterval &a) throw() { return Sup(a.re); }
      friend inline real & SupIm(cinterval &a) throw() { return Sup(a.im); }
      
      friend        interval  abs(const cinterval &) throw();
      friend inline cinterval conj(const cinterval &) throw();
      friend inline   complex mid(const cinterval &) throw();
      friend inline   complex diam(const cinterval &) throw();
};


} // namespace cxsc 

#include "cinterva.inl"

#endif



