C-XSC - A C++ Class Library for Extended Scientific Computing  2.5.4
l_complex.hpp
00001 /*
00002 **  CXSC is a C++ library for eXtended Scientific Computing (V 2.5.4)
00003 **
00004 **  Copyright (C) 1990-2000 Institut fuer Angewandte Mathematik,
00005 **                          Universitaet Karlsruhe, Germany
00006 **            (C) 2000-2014 Wiss. Rechnen/Softwaretechnologie
00007 **                          Universitaet Wuppertal, Germany   
00008 **
00009 **  This library is free software; you can redistribute it and/or
00010 **  modify it under the terms of the GNU Library General Public
00011 **  License as published by the Free Software Foundation; either
00012 **  version 2 of the License, or (at your option) any later version.
00013 **
00014 **  This library is distributed in the hope that it will be useful,
00015 **  but WITHOUT ANY WARRANTY; without even the implied warranty of
00016 **  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00017 **  Library General Public License for more details.
00018 **
00019 **  You should have received a copy of the GNU Library General Public
00020 **  License along with this library; if not, write to the Free
00021 **  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00022 */
00023 /* CVS $Id: l_complex.hpp,v 1.19 2014/01/30 17:23:46 cxsc Exp $ */
00024 
00025 #ifndef _CXSC_L_COMPLEX_HPP_INCLUDED
00026 #define _CXSC_L_COMPLEX_HPP_INCLUDED
00027 
00028 #include <iostream>
00029 #include <string>
00030 
00031 #include "except.hpp"
00032 #include "complex.hpp"
00033 #include "l_real.hpp"
00034 #include "l_rmath.hpp"
00035 #include "cdot.hpp"
00036 
00037 namespace cxsc {
00038 
00040 
00045 class l_complex
00046 {
00047    private:
00048     // ------------- Datenelemente -------------------------------------------
00049     l_real re, im;
00050 
00051    public:
00053     l_complex _l_complex(const cdotprecision &);
00054     // ------------- Constructors --------------------------------------------
00056     l_complex(void)  throw() {}
00058     l_complex(const l_real& a, const l_real& b) throw() : re(a), im(b) { }
00060     l_complex(const real& a, const real& b) throw() : re(a), im(b) { }
00061 
00063     l_complex & operator = (const l_real & lr) throw() 
00064         { re = lr; im = 0; return *this; }
00066     l_complex & operator = (const real & r) throw() 
00067       { re = r; im = 0; return *this; } 
00069     l_complex & operator = (const complex & c) throw() 
00070         { re = Re(c); im = Im(c); return *this; } 
00072     l_complex & operator = (const dotprecision & d) throw() 
00073         { re = d; im = 0.0; return *this; }
00075     l_complex & operator = (const cdotprecision & cd) throw() 
00076         { re = Re(_l_complex(cd)); im = Im(_l_complex(cd)); return *this; }
00077          
00079          l_complex & operator = (const lx_complex &) throw();
00080 
00081     // ------------- Type-Casts ----------------------------------------------
00083     explicit inline l_complex(const l_real  &r) throw() : re(r), im(0.0) { }
00085     explicit inline l_complex(const   real  &r) throw() : re(r), im(0.0) { }
00087     explicit inline l_complex(const complex &r) throw() : re(Re(r)), im(Im(r))
00088                                                                          { }
00090     explicit inline l_complex(const dotprecision &d) throw()
00091                   : re(d), im(0.0) { }
00093     explicit inline l_complex(const cdotprecision &cd) throw()
00094                   : re(Re(_l_complex(cd))), im(Im(_l_complex(cd))) { }
00095 
00096 //    friend inline l_complex _l_complex(const l_real &a) throw()
00097 //      { return l_complex(a); }
00098 //    friend inline l_complex _l_complex(const l_real &a, const l_real &b)
00099 //        throw()   { return l_complex(a,b); }
00100 //    friend inline l_complex _l_complex(const real &a) throw()
00101 //      { return l_complex(a); }
00102 //    friend inline l_complex _l_complex(const real &a, const real &b)
00103 //        throw()   { return l_complex(a,b); }
00104 //    friend inline l_complex _l_complex(const complex &c)
00105 //        throw()   { return l_complex(c); }
00106 //    friend inline l_complex _l_complex(const dotprecision &d)
00107 //        throw()   { return l_complex(d); }
00113     friend inline l_complex _l_complex(const cdotprecision &cd)
00114         throw()   { return l_complex(cd); }
00115 
00116     // ----------------------------------------------------------------------
00118     friend int StagPrec(const l_complex&) throw();
00119 
00120 // ------------- Arithmetic Operators ---------------------------------------
00121     // ----------------------------------------------------------------------
00122     // ------------- Unary Operators ----------------------------------------
00123 
00125     friend l_complex operator-(const l_complex&);
00127     friend l_complex operator+(const l_complex&);
00128 
00129     // ------------- Binary Operators ---------------------------------------
00130     // ----------------- l_complex +/- l_complex ----------------------------
00132     friend inline l_complex operator +
00133                    (const l_complex &, const l_complex &) throw();
00134 
00136     friend inline l_complex operator -
00137                    (const l_complex &, const l_complex &) throw();
00138     
00139     // ----------------- l_complex + complex --------------------------------
00141     inline l_complex operator + (const complex &) const throw();
00142 
00144     friend inline l_complex operator +
00145                    (const complex &, const l_complex &) throw();
00146 
00147     // ---------------- l_complex + real ------------------------------------
00149     inline l_complex operator + (const real &) const throw();
00150 
00152     friend inline l_complex operator +
00153                    (const real &, const l_complex &) throw();
00154 
00155     // ---------------- l_complex + l_real ----------------------------------
00157     inline l_complex operator + (const l_real &) const throw();
00158 
00160     friend inline l_complex operator +
00161                    (const l_real &, const l_complex &) throw();
00162 
00163     // ---------------- l_complex - l_real ----------------------------------
00165     inline l_complex operator - (const l_real &) const throw();
00166 
00168     friend inline l_complex operator -
00169                    (const l_real &, const l_complex &) throw();
00170 
00171     // ----------------- l_complex - complex -------------------------------
00173     inline l_complex operator - (const complex &) const throw();
00174 
00176     friend inline l_complex operator -
00177                    (const complex &, const l_complex &) throw();
00178 
00179     // ---------------- l_complex - real ------------------------------------
00181     inline l_complex operator - (const real &) const throw();
00182 
00184     friend inline l_complex operator -
00185                    (const real &, const l_complex &) throw();
00186 
00187     // ---------------- l_complex + cdotprecision ---------------------------
00189     friend cdotprecision operator+
00190            (const l_complex &, const cdotprecision &) throw();
00191 
00193     friend cdotprecision operator+ 
00194       (const cdotprecision &, const l_complex &) throw();
00195 
00196     // ---------------- l_complex - cdotprecision ---------------------------
00198     friend cdotprecision operator- 
00199       (const l_complex &, const cdotprecision &) throw();
00200 
00202     friend cdotprecision operator- 
00203       (const cdotprecision &, const l_complex &) throw(); 
00204 
00205     // ---------------- l_complex + dotprecision ----------------------------
00207     friend cdotprecision operator+ 
00208       (const l_complex &, const dotprecision &) throw();
00209 
00211     friend cdotprecision operator+ 
00212       (const dotprecision &, const l_complex &) throw();
00213 
00214     // ---------------- l_complex - dotprecision ----------------------------
00216     friend cdotprecision operator- 
00217       (const l_complex &, const dotprecision &) throw();
00218 
00220     friend cdotprecision operator- 
00221       (const dotprecision &, const l_complex &) throw();
00222 
00223 
00224 // ------------- Multiplication ---------------------------------------------
00225 // ------------------ l_complex * l_complex ---------------------------------
00226 
00228 friend l_complex operator * (const l_complex& a, const l_complex& b)
00229     throw();
00230 
00231 // ------------------ l_complex * complex -----------------------------------
00233 friend l_complex operator * (const l_complex& a, const complex& b)
00234     throw();
00235 
00237 friend l_complex operator * ( const complex& b, const l_complex& a )
00238     throw();
00239 
00240 // ------------------ l_complex * real ---------------------------------------
00242     inline l_complex operator * (const real &) const throw();
00243 
00245     friend inline l_complex operator *
00246                    (const real &, const l_complex &) throw();
00247 
00248 // ------------------ l_complex * l_real -------------------------------------
00250     inline l_complex operator * (const l_real &) const throw();
00251 
00253     friend inline l_complex operator *
00254                    (const l_real &, const l_complex &) throw();
00255 
00256 
00257 // ----------------- Others --------------------------------------------------
00259     friend l_real & Re(l_complex& a); // { return a.re; }
00261     friend l_real   Re(const l_complex& a); // { return a.re; }
00263     friend l_real & Im(l_complex& a); // { return a.im; }
00265     friend l_real   Im(const l_complex& a); // { return a.im; }
00266 
00268     friend inline l_complex conj(const l_complex&) throw(); // conjugated value
00270     friend l_complex & SetRe(l_complex & a,const l_real & b); 
00271         // { a.re=b; return a; } // The real part of a is substituted by b.
00272     // SetRe(lc,lr); --> Re(lc)=lr;
00273     // lc1 = SetRe(lc,lr); --> Re(lc)=lr; and lc1 = lc;
00275     friend l_complex & SetIm(l_complex & a,const l_real & b); 
00276         // { a.im=b; return a; } // See SetRe(...);
00277 
00278 
00279 // ----- accumulate(cdotprecision,l_complex,l_complex|complex|real|l_real ----
00281     friend void accumulate(cdotprecision&, const l_complex&, 
00282                                            const l_complex&) throw();
00283 
00285     friend void accumulate(cdotprecision&, const l_complex&, 
00286                                            const complex&) throw();
00287 
00289     friend void accumulate(cdotprecision&, const l_complex&, 
00290                                            const real&) throw();
00291 
00293     friend void accumulate(cdotprecision&, const l_complex&, 
00294                                            const l_real&) throw();
00295 
00296 // ---------------- cdotprecision +(-)= l_complex ---------------------------- 
00298 friend inline cdotprecision & operator += (cdotprecision &cd, 
00299                                            const l_complex &lc) throw(); 
00301 friend inline cdotprecision & operator -= (cdotprecision &cd, 
00302                                            const l_complex &lc) throw(); 
00303 
00304 // ---------------- l_complex +(-)= l_complex|complex|real|l_real ------------
00306 friend inline l_complex & operator += (l_complex &,const l_complex &) throw(); 
00308 friend inline l_complex & operator -= (l_complex &,const l_complex &) throw(); 
00310 friend inline l_complex & operator += (l_complex &,const complex &) throw(); 
00312 friend inline l_complex & operator -= (l_complex &,const complex &) throw();
00314 friend inline l_complex & operator += (l_complex &,const real &) throw();
00316 friend inline l_complex & operator -= (l_complex &,const real &) throw();
00318 friend inline l_complex & operator += (l_complex &,const l_real &) throw();
00320 friend inline l_complex & operator -= (l_complex &,const l_real &) throw(); 
00321 
00322 // ---------------- l_complex *= l_complex|complex|real|l_real ---------------
00324 friend inline l_complex & operator *= (l_complex &,const l_complex &) throw();
00326 friend inline l_complex & operator *= (l_complex &,const complex &) throw();
00328 friend inline l_complex & operator *= (l_complex &,const real &) throw();
00330 friend inline l_complex & operator *= (l_complex &,const l_real &) throw();
00331 
00332 // ---------------- Compare Operators ----------------------------------------
00333 friend inline bool operator! (const l_complex &) throw();
00335 friend inline bool operator== (const l_complex &, const l_complex &) throw();
00337 friend inline bool operator!= (const l_complex &, const l_complex &) throw();
00339 friend inline bool operator== (const l_complex &, const complex &) throw();
00341 friend inline bool operator== (const complex &, const l_complex &) throw();
00343 friend inline bool operator!= (const l_complex &, const complex &) throw();
00345 friend inline bool operator!= (const complex &, const l_complex &) throw();
00347 friend inline bool operator== (const l_complex &, const real &) throw();
00349 friend inline bool operator== (const real &, const l_complex &) throw();
00351 friend inline bool operator!= (const l_complex &, const real &) throw();
00353 friend inline bool operator!= (const real &, const l_complex &) throw();
00355 friend inline bool operator== (const l_complex &, const l_real &) throw();
00357 friend inline bool operator== (const l_real &, const l_complex &) throw();
00359 friend inline bool operator!= (const l_complex &, const l_real &) throw();
00361 friend inline bool operator!= (const l_real &, const l_complex &) throw();
00363 friend inline bool operator== (const l_complex &, const dotprecision &)
00364                                                                   throw();
00366 friend inline bool operator== (const dotprecision &, const l_complex &)
00367                                                                   throw();
00369 friend inline bool operator!= (const l_complex &, const dotprecision &)
00370                                                                   throw();
00372 friend inline bool operator!= (const dotprecision &, const l_complex &)
00373                                                                   throw();
00374 
00376 friend inline bool operator ==(const cdotprecision &, const l_complex &)
00377     throw(); // {l_complex.inl}
00379 friend inline bool operator ==(const l_complex &, const cdotprecision &)
00380     throw(); // {l_complex.inl}
00382 friend inline bool operator !=(const cdotprecision &, const l_complex &)
00383     throw(); // {l_complex.inl}
00385 friend inline bool operator !=(const l_complex &, const cdotprecision &)
00386     throw(); // {l_complex.inl}
00387 
00388 // -------------- Division: Directed rounding, Blomquist 28.11.02 ------------
00389 
00391     friend l_complex divn (const l_complex &, const l_complex &);
00393     friend l_complex divd (const l_complex &, const l_complex &);
00395     friend l_complex divu (const l_complex &, const l_complex &);
00396 
00397 // -------------- Division:  Blomquist 28.11.02 ------------------------------
00399     friend l_complex operator / (const l_complex &,const l_complex &) throw();
00400 
00402     friend inline l_complex operator / (const l_complex & a,
00403                                         const complex & b) throw();
00405     friend inline l_complex operator / (const l_complex & a,
00406                                         const l_real & b) throw();
00408     friend inline l_complex operator / (const l_complex & a,
00409                                         const real & b) throw();
00410 
00412     friend inline l_complex operator / (const complex& a,
00413                                         const l_complex& b) throw();
00415     friend inline l_complex operator / (const real& a,
00416                                         const l_complex& b) throw();
00418     friend inline l_complex operator / (const l_real& a,
00419                                         const l_complex& b) throw();
00420 
00422     friend inline l_complex& operator /=(l_complex&,const l_complex&) throw();
00424     friend inline l_complex& operator /=(l_complex&,const complex&) throw();
00426     friend inline l_complex& operator /=(l_complex&,const real&) throw();
00428     friend inline l_complex& operator /=(l_complex&,const l_real&) throw();
00429 
00431 friend l_real abs2(const l_complex &a) throw(); // a.re*a.re + a.im*a.im;
00433 friend l_real abs (const l_complex &z) throw(); 
00434 
00435 // ----------------------- Output --------------------------------------------
00436 
00438 friend std::ostream& operator << (std::ostream& s,const l_complex& z ) throw()
00439 // A complex number z of type l_complex is written to the output channel.
00440 {     
00441     s << '('          
00442     << z.re << ", "   
00443     << z.im       
00444     << ')';
00445     return s;
00446 }
00447 
00449 friend std::string & operator << (std::string &s, const l_complex& a) throw()
00450 // The value of a variable a of type l_complex is copied to a string s.
00451 // s has the form:  (Re(a),Im(a))
00452 {  
00453     s+='(';
00454     s << a.re;
00455     s+=", ";
00456     s << a.im; 
00457     s+=')';
00458     return s;
00459 }
00460 
00461 // ----------------------- Input ---------------------------------------------
00462 
00464 friend std::istream & operator >> (std::istream &s, l_complex &a) throw()
00465 // An input of a complex number z of the form (Re(z),Im(z)) is copied to
00466 // the variable a of type l_complex.
00467 {  
00468    char c;
00469 
00470    skipeolnflag = inpdotflag = true;
00471    c = skipwhitespacessinglechar (s, '(');
00472    if (inpdotflag) 
00473       s.putback(c);
00474 
00475    s >> a.re;
00476 
00477    skipeolnflag = inpdotflag = true;
00478    c = skipwhitespacessinglechar (s, ',');
00479    if (inpdotflag) s.putback(c);
00480 
00481    s >> a.im >> RestoreOpt;
00482 
00483    if (!waseolnflag) 
00484    {
00485       skipeolnflag = false, inpdotflag = true;
00486       c = skipwhitespaces (s);
00487       if (inpdotflag && c != ')') 
00488          s.putback(c);
00489    }
00490    return s;
00491 }
00492 
00494 friend std::string & operator >> (std::string &s, l_complex &a) throw()
00495 // A complex number z of the form (Re(z),Im(z)), represented in a string s
00496 // is copied to a of type l_complex.
00497 {   
00498    s = skipwhitespacessinglechar (s, '(');
00499    s >> SaveOpt >> a.re;
00500    s = skipwhitespacessinglechar (s, ',');
00501    s >> a.im >> RestoreOpt;
00502    s = skipwhitespaces (s);
00503 
00504    if (s[0] == ')') 
00505       s.erase(0,1);
00506    return s;
00507 }
00508 
00509 }; // end of class l_complex
00510 
00511 inline l_complex _l_complex(const l_real &a) throw()
00512         { return l_complex(a); }
00513 inline l_complex _l_complex(const l_real &a, const l_real &b)
00514         throw()   { return l_complex(a,b); }
00515 inline l_complex _l_complex(const real &a) throw()
00516         { return l_complex(a); }
00517 inline l_complex _l_complex(const real &a, const real &b)
00518         throw()   { return l_complex(a,b); }
00519 inline l_complex _l_complex(const complex &c)
00520         throw()   { return l_complex(c); }
00521 inline l_complex _l_complex(const dotprecision &d)
00522         throw()   { return l_complex(d); }
00523 inline l_complex conj(const l_complex&) throw();
00524 //inline l_complex _l_complex(const cdotprecision &cd)
00525 //        throw()   { return l_complex(cd); }
00526 
00527 l_real & Re(l_complex& a);
00528 l_real   Re(const l_complex& a);
00529 l_real & Im(l_complex& a);
00530 l_real   Im(const l_complex& a);
00531 
00532 l_complex & SetRe(l_complex & a,const l_real & b);
00533         //{ a.re=b; return a; } // The real part of a is substituted by b.
00534     // SetRe(lc,lr); --> Re(lc)=lr;
00535     // lc1 = SetRe(lc,lr); --> Re(lc)=lr; and lc1 = lc;
00536 l_complex & SetIm(l_complex & a,const l_real & b); 
00537 //        { a.im=b; return a; } // See SetRe(...);
00538 
00539 l_complex _l_complex(const cdotprecision &) throw();
00540 
00541 }  // end namespace cxsc
00542 
00543 #include "l_complex.inl"
00544 
00545 #endif // _CXSC_L_COMPLEX_HPP_INCLUDED