/*
**  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: cdot.inl,v 1.3 2001/08/09 11:37:52 cxsc Exp $ */

namespace cxsc {

// ---- Konstruktoren ----

inline cdotprecision::cdotprecision(const dotprecision &a,const dotprecision &b)
                        : re(a), im(b)
{
}

inline cdotprecision::cdotprecision(const real &a,const real &b)
                        : re(a), im(b)
{
}

inline cdotprecision::cdotprecision(const cdotprecision &a)
                        : re(a.re), im(a.im)
{
}

// ---- Typwandlungen ----

inline cdotprecision _cdotprecision(const dotprecision& a) 
{
  return cdotprecision (a);
}
inline cdotprecision _cdotprecision(const real& a) 
{
  return cdotprecision (a);
}
inline cdotprecision _cdotprecision(const complex& a) 
{
  return cdotprecision (a);
}

inline cdotprecision _cdotprecision(const dotprecision& a, const dotprecision& b) 
{
  return cdotprecision (a,b);
}
inline cdotprecision _cdotprecision(const real& a, const real& b) 
{
  return cdotprecision (a,b);
}

// ---- Standardfunkt ---- (arithmetische Operatoren)

inline cdotprecision operator-(const cdotprecision &a) throw() { return cdotprecision (-a.re, -a.im); }
inline cdotprecision operator+(const cdotprecision &a) throw() { return a; }

inline cdotprecision operator+(const cdotprecision &a,const cdotprecision &b) throw() { return cdotprecision(a.re+b.re,a.im+b.im); }
inline cdotprecision operator-(const cdotprecision &a,const cdotprecision &b) throw() { return cdotprecision(a.re-b.re,a.im-b.im); }

inline cdotprecision operator +(const cdotprecision &a,const complex &b) throw() { return cdotprecision(a.re+Re(b),a.im+Im(b)); }
inline cdotprecision operator +(const complex &b,const cdotprecision &a) throw() { return cdotprecision(a.re+Re(b),a.im+Im(b)); } 
inline cdotprecision operator -(const cdotprecision &a,const complex &b) throw() { return cdotprecision(a.re-Re(b),a.im-Im(b)); } 
inline cdotprecision operator -(const complex &a,const cdotprecision &b) throw() { return cdotprecision(Re(a)-b.re,Im(a)-b.im); }

inline cdotprecision operator +(const cdotprecision &a,const dotprecision &b) throw() { return cdotprecision(a.re+b,a.im); }
inline cdotprecision operator +(const dotprecision &b,const cdotprecision &a) throw() { return cdotprecision(a.re+b,a.im); } 
inline cdotprecision operator -(const cdotprecision &a,const dotprecision &b) throw() { return cdotprecision(a.re-b,a.im); } 
inline cdotprecision operator -(const dotprecision &a,const cdotprecision &b) throw() { return cdotprecision(a-b.re,-b.im); }

inline cdotprecision operator +(const cdotprecision &a,const real &b) throw() { return cdotprecision(a.re+b,a.im); }
inline cdotprecision operator +(const real &b,const cdotprecision &a) throw() { return cdotprecision(a.re+b,a.im); } 
inline cdotprecision operator -(const cdotprecision &a,const real &b) throw() { return cdotprecision(a.re-b,a.im); } 
inline cdotprecision operator -(const real &a,const cdotprecision &b) throw() { return cdotprecision(a-b.re,b.im); }

inline cdotprecision & operator +=(cdotprecision &a,const cdotprecision &b) throw() { a.re+=b.re;a.im+=b.im; return a;}
inline cdotprecision & operator +=(cdotprecision &a,const dotprecision &b) throw() { a.re+=b; return a;}
inline cdotprecision & operator -=(cdotprecision &a,const cdotprecision &b) throw() { a.re-=b.re;a.im-=b.im; return a;}
inline cdotprecision & operator -=(cdotprecision &a,const dotprecision &b) throw() { a.re-=b; return a;}
inline cdotprecision & operator +=(cdotprecision &a,const complex &b) throw() 
{
   a.re+=Re(b);
   a.im+=Im(b);
   return a;
}
inline cdotprecision & operator -=(cdotprecision &a,const complex &b) throw()
{
   a.re-=Re(b);
   a.im-=Im(b);
   return a;
}
inline cdotprecision & operator +=(cdotprecision &a,const real &b) throw()
{
   a.re+=b;
   return a;
}
inline cdotprecision & operator -=(cdotprecision &a,const real &b) throw()
{
   a.re-=b;
   return a;
}
      
// --- Vergleichsoperationen ----
inline bool operator ==(const cdotprecision &a,const cdotprecision &b) throw() {   return(a.re==b.re && a.im==b.im); }
inline bool operator !=(const cdotprecision &a,const cdotprecision &b) throw() {   return(a.re!=b.re || a.im!=b.im); }
inline bool operator ==(const dotprecision &r,const cdotprecision &a)     throw() {   return(r==a.re && !a.im); }
inline bool operator !=(const dotprecision &r,const cdotprecision &a)     throw() {   return(r!=a.re || !!a.im); }
inline bool operator ==(const cdotprecision &a,const dotprecision &r)     throw() {   return(r==a.re && !a.im); }
inline bool operator !=(const cdotprecision &a,const dotprecision &r)     throw() {   return(r!=a.re || !!a.im); }
inline bool operator ==(const complex &c,const cdotprecision &a)     throw() {   return(Re(c)==a.re && Im(c)==a.im); }
inline bool operator !=(const complex &c,const cdotprecision &a)     throw() {   return(Re(c)!=a.re || Im(c)!=a.im); }
inline bool operator ==(const cdotprecision &a,const complex &c)     throw() {   return(Re(c)==a.re && Im(c)==a.im); }
inline bool operator !=(const cdotprecision &a,const complex &c)     throw() {   return(Re(c)!=a.re || Im(c)!=a.im); }
inline bool operator ==(const real &c,const cdotprecision &a)     throw() {   return(c==a.re && !a.im); }
inline bool operator !=(const real &c,const cdotprecision &a)     throw() {   return(c!=a.re || !!a.im); }
inline bool operator ==(const cdotprecision &a,const real &c)     throw() {   return(c==a.re && !a.im); }
inline bool operator !=(const cdotprecision &a,const real &c)     throw() {   return(c!=a.re || !!a.im); }

// ----- Funktionen -----

inline cdotprecision& SetRe (cdotprecision& a, const dotprecision& b)  throw()
{ // ggf. exception
   a.re=b; 
   return a;
}

inline cdotprecision& SetIm (cdotprecision& a, const dotprecision& b) throw()
{
   a.im=b;
   return a;
}

inline cdotprecision conj(const cdotprecision& a) throw()
{
   return cdotprecision(a.re,-a.im);
}

inline bool operator !(const cdotprecision &a) throw() 
{ 
   return !a.re && !a.im;
}  

inline void accumulate  (cdotprecision & a, const complex & b, const real & c) throw() { accumulate(a,b,complex(c)); }
inline void accumulate  (cdotprecision & a, const real & b, const complex & c) throw() { accumulate(a,complex(b),c); }
inline void accumulate  (cdotprecision & a, const real & b, const real & c) throw() { accumulate(a,complex(b),complex(c)); }

} // namespace cxsc
