C-XSC - A C++ Class Library for Extended Scientific Computing  2.5.4
l_cinterval.cpp
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 
00024 /* CVS $Id: l_cinterval.cpp,v 1.18 2014/01/30 17:23:46 cxsc Exp $ */
00025 
00026 #include "l_cinterval.hpp"
00027 #include "cidot.hpp"
00028 #include "dot.hpp"
00029 #include "l_rmath.hpp"
00030 #include "l_imath.hpp"
00031 
00032 namespace cxsc {
00033 
00034 
00035 #define CXSC_Zero 0.0
00036 
00037 cinterval::cinterval(const l_cinterval & a) throw()
00038 {
00039     interval u,v;
00040     u = a.re;
00041     v = a.im;
00042     *this = cinterval(u,v);
00043 }
00044 
00045 cinterval & cinterval::operator = (const l_cinterval & a) throw()
00046 {
00047     interval u,v;
00048     u = a.re;
00049     v = a.im;
00050 return *this = cinterval(u,v);
00051 }
00052 
00053 l_cinterval::l_cinterval(const dotprecision  &a) throw() : re(a),im(0) {}
00054 l_cinterval::l_cinterval(const idotprecision &a) throw() : re(a),im(0) {}
00055 l_cinterval::l_cinterval(const cdotprecision &a) 
00056                                          throw() : re(Re(a)),im(Im(a)) {}
00057 l_cinterval::l_cinterval(const cidotprecision &a) throw() : 
00058                          re( l_interval(Re(a))),im(l_interval(Im(a)) ) {}
00059 
00060 l_cinterval operator * (const l_cinterval & a, const l_cinterval & b) throw()
00061 {
00062     idotprecision akku;
00063     l_cinterval res;
00064     l_interval u,v;
00065     akku = 0.0;
00066     accumulate(akku,a.re,b.re);
00067     accumulate(akku,-a.im,b.im);
00068     u = akku;
00069     if (Inf(u)>Sup(u)) 
00070     {   std::cerr << "Error in l_cinterval * l_cinterval" << std::endl;
00071         exit(1);
00072     }
00073     akku = 0.0;
00074     accumulate(akku,a.im,b.re);
00075     accumulate(akku,a.re,b.im);
00076     v = akku; // v: Imaginaerteil
00077     if (Inf(v)>Sup(v)) 
00078     {   std::cerr << "Error in l_cinterval * l_cinterval" << std::endl;
00079         exit(1);
00080     }
00081     res = l_cinterval(u,v);
00082     return res;
00083 }
00084 
00085 
00086 // *********************************************************************
00087 // In l_complex.cpp implemented: (In l_complex.hpp not declared!)
00088 void product(const l_real& a, const l_real& b, const l_real& c, 
00089              const l_real& d, int& ex, l_interval& res);
00090 void product(const l_real& c, const l_real& d, int& ex, l_interval& res);
00091 l_real quotient(const l_interval& z, const l_interval& n, int round, 
00092                 int ex_z, int ex_n);
00093 //void Times2pown(l_interval& a, int n) throw();
00094 
00095 // *********************************************************************
00096 
00097 static const int max_expo  = 1020, max_expo1 = 1023;
00098 
00099 // optimale komplexe Intervalldivision
00100 
00101 bool cxsc_l_complex_division_p[5];
00102 
00103 l_real cxsc_complex_division_f(l_real a, l_real b, l_real c, l_real d, 
00104                                int round)
00105 {
00106    int ex1, ex2;
00107    l_interval z,n;
00108 
00109    //  f:=(a*c+b*d)/(SQR(c)+SQR(d))
00110 
00111    product(a, c, b, d, ex1, z);
00112    product(c, d, ex2, n);
00113    return quotient(z, n, round, ex1, ex2);
00114 }
00115 
00116 // *************************************************************************
00117 // *************************************************************************
00118 
00119 static l_real minmax(int minimum, l_real a, l_real b, l_real y0,
00120                      l_interval x, int i, int j)
00121 // Calculates the inner minimum or maximum of f = (ac+bd)/(cc+dd)
00122 // on the interval x = [c.inf,c.sup] ( a,b,d=y0 fixated ).
00123 // If minimum = true the minimum will be calculated, otherwise the maximum.
00124 
00125 {
00126    l_real ay0, minmax;
00127    l_interval t,q,x0,two_Da;
00128 
00129    int Da(0);
00130 
00131    a += 0.0;   b += 0.0;  y0 += 0.0; 
00132 
00133    if (minimum) 
00134       minmax = MaxReal;
00135    else         
00136       minmax = -MaxReal;
00137 
00138    if (Inf(x) == Sup(x)) 
00139    {
00140       if (cxsc_l_complex_division_p[i] && cxsc_l_complex_division_p[j])
00141          minmax = cxsc_complex_division_f( a, b, Inf(x), y0, 1-2*minimum );
00142       
00143       cxsc_l_complex_division_p[i] = false;
00144       cxsc_l_complex_division_p[j] = false;
00145   } else 
00146   if (a == 0.0) 
00147   {
00148       if ( b == CXSC_Zero  ||  y0 == CXSC_Zero ) 
00149       {
00150          minmax = 0.0;
00151          cxsc_l_complex_division_p[i]   = false;
00152          cxsc_l_complex_division_p[j]   = false;
00153       } else 
00154       { // b*y0 <> 0:
00155          if (0.0 < x) {
00156             if (minimum  && sign(b) != sign(y0) ) 
00157             {
00158                 // minmax = divd(b, y0);
00159                 minmax = Inf(l_interval(b)/y0);
00160                 cxsc_l_complex_division_p[i]   = false;
00161                 cxsc_l_complex_division_p[j]   = false;
00162             } else 
00163             if (!minimum  &&  sign(b) == sign(y0) ) 
00164             {
00165                 // minmax =  divu(b, y0);
00166                 minmax = Sup(l_interval(b)/y0);
00167                 cxsc_l_complex_division_p[i]   = false;
00168                 cxsc_l_complex_division_p[j]   = false;
00169             }
00170          }
00171       }
00172   } else 
00173   { 
00174       //  a != 0.0
00175       if (y0 == 0.0) 
00176       {
00177          if (minimum) 
00178          {
00179             if (a > 0.0) 
00180                 // minmax = divd(a, Sup(x));
00181                 minmax = Inf(l_interval(a)/l_interval(Sup(x)));
00182             else         
00183                 // minmax = divd(a, Inf(x));
00184                 minmax = Inf(l_interval(a)/l_interval(Inf(x)));
00185          } else 
00186          {
00187             if (a > 0.0) 
00188                 // minmax = divu(a, Inf(x));
00189                 minmax = Sup(l_interval(a)/l_interval(Inf(x)));
00190             else         
00191                 // minmax = divu(a, Sup(x));
00192                 minmax = Sup(l_interval(a)/l_interval(Sup(x)));
00193          }
00194          cxsc_l_complex_division_p[i] = false;
00195          cxsc_l_complex_division_p[j] = false;
00196       } else 
00197       {  // a  != 0.0 and
00198          // y0 != 0.0, Calculation of extrema points and minimum|maximum
00199          // values: 
00200          //  Calculation of: t = sign(a) * ( |b/a| + sqrt( 1+|b/a|^2 ) )
00201 
00202          l_real invf2(1.0), a_skal;
00203          // int exf1=0,  exf2=0,  exinf1=0,  exinf2=0; // unused variable
00204 
00205          // We first calculate:   t = |b/a| + sqrt( 1+|b/a|^2 );
00206 
00207          if (sign(b)==0) t = 1.0;
00208          else
00209          {   // a != 0.0  and  b != 0;
00210              // To avoid overflow by calculating |b/a| + sqrt( 1+|b/a|^2 )
00211              // we must multiply a with 2^Da:
00212              int expo_diff = expo(b[1]) - expo(a[1]), ex;
00213              a_skal = a;
00214              if (expo_diff > max_expo) 
00215              {
00216                  Da = expo_diff-max_expo; // Da > 0;
00217                  // a must be multiplied with 2^Da to avoid overflow 
00218                  // by calculating |b/a| + sqrt( 1+|b/a|^2 ) :
00219                  if (Da>max_expo1)
00220                  {
00221                      times2pown(a_skal,max_expo1);
00222                      ex = Da - max_expo1;
00223                      times2pown(a_skal,ex);
00224                  }
00225                  else times2pown(a_skal,Da);
00226 
00227                  // Now calculating an inclusion t of 2^(-Da):
00228                  if (Da>1022)
00229                  {
00230                      two_Da = l_interval( comp(0.5,-1021) ); 
00231                      times2pown(two_Da,1022-Da);     
00232                  }
00233                  else two_Da = l_interval( comp(0.5,1-Da) ); 
00234                  // Now two_Da is am inclusion of 2^(-Da);
00235              }
00236              q = l_interval(b)/a_skal;
00237              if (sign(q[1])<0) q = -q;
00238              // q: Inclusion of |b/(a*2^Da)|;
00239 
00240              t = (Da > 0)? q + sqrtx2y2(two_Da,q) : q + sqrt1px2(q);
00241          }
00242 
00243          if (a<0.0)  t = -t;
00244 
00245 // if (Da > 0) the value t from the last line must additionally be 
00246 // multiplied with 2^Da, to get an inclusion of the expression:    
00247 //               sign(a) * ( |b/a| + sqrt( 1+|b/a|^2 ) );
00248 
00249 // Now to a fall differentiation for min-,max- calculation:
00250 // First we will calculate an inclusion x0 of the point of the
00251 // relative minimum or maximum:
00252 
00253          ay0 = abs(y0);
00254 
00255          if ( (sign(b) == sign(y0)) == minimum ) 
00256          {   // Calculation of x0 = |y0| * t :
00257              if (expo(ay0[1]) + expo(t[1]) + Da > max_expo1) goto Ende;
00258              else x0 = ay0 * t;
00259              if (Da>0) Times2pown(x0,Da);
00260          } 
00261          else  //  Calculation of x0 = |y0| / t :
00262          {   
00263              if (expo(ay0[1]) - expo(t[1]) - Da > max_expo1) goto Ende;
00264              else x0 = ay0 / t;             
00265              if (Da>0) Times2pown(x0,-Da); 
00266          }
00267 
00268          if (minimum) x0 = -x0;
00269 
00270          if (x0 < x) // The minimum or maximum point lies in 
00271          {           // the interior of x.
00272              //  Calculation of:  a / ( 2*x0 )
00273              q = a/x0;
00274              times2pown(q,-1); // q: inclusion of a / ( 2*x0 );
00275 
00276              if (minimum) minmax = Inf(q);
00277              else minmax = Sup(q);
00278 
00279              cxsc_l_complex_division_p[i] = false;
00280              cxsc_l_complex_division_p[j] = false;
00281          }
00282       Ende:;
00283       }  // y0 != 0.0
00284   }
00285    return minmax;
00286 } // *** minmax ***
00287 
00288 l_real max(const l_real& u, const l_real& v)
00289 {
00290     l_real res(u);
00291     if (v>u) res = v;
00292     return res;
00293 }
00294 
00295 l_real min(const l_real& u, const l_real& v)
00296 {
00297     l_real res(u);
00298     if (v<u) res = v;
00299     return res;
00300 }
00301 
00302 l_cinterval cidiv(const l_cinterval& A, const l_cinterval& B)
00303 {
00304    l_real   realteilINF, realteilSUP,
00305             imagteilINF, imagteilSUP;
00306    // da sonst eventuell zwischendurch illegale Intervalle entstehen
00307    l_real     a0,b0;
00308    bool     a_repeat,b_repeat; 
00309    int      i, rep, j;
00310    l_real   AREINF, ARESUP, AIMINF, AIMSUP,
00311             BREINF, BRESUP, BIMINF, BIMSUP;
00312    l_interval ARE, AIM, BRE, BIM;
00313 
00314    // keine Fehlerabfrage -> ist schon in CINTVAL.CPP
00315    //  IF ( 0.0 IN B.RE ) AND ( 0.0 IN B.IM ) THEN
00316    //   CIDIVISION:= COMPL( 1.0 / INTVAL(-1.0,1.0), INTVAL(0.0) );
00317    //   Fehlerabbruch erzwingen: Intervall enthaelt 0
00318 
00319    //  *** Berechnung des Realteils ***
00320 
00321    AREINF = Inf(Re(A));    AREINF += 0.0;
00322    ARESUP = Sup(Re(A));    ARESUP += 0.0;
00323    AIMINF = Inf(Im(A));    AIMINF += 0.0;
00324    AIMSUP = Sup(Im(A));    AIMSUP += 0.0;
00325    BREINF = Inf(Re(B));    BREINF += 0.0;
00326    BRESUP = Sup(Re(B));    BRESUP += 0.0;
00327    BIMINF = Inf(Im(B));    BIMINF += 0.0;
00328    BIMSUP = Sup(Im(B));    BIMSUP += 0.0;
00329    ARE    = Re(A);
00330    AIM    = Im(A);
00331    BRE    = Re(B);
00332    BIM    = Im(B);
00333 
00334    a_repeat = ( BREINF < CXSC_Zero ) && ( CXSC_Zero < BRESUP );
00335    b_repeat = ( BIMINF < CXSC_Zero ) && ( CXSC_Zero < BIMSUP );
00336 
00337    if (a_repeat || b_repeat) 
00338       rep = 2;
00339    else                      
00340       rep = 1;
00341 
00342    if (BREINF >= 0.0) 
00343       a0 = ARESUP;
00344    else               
00345       a0 = AREINF;
00346   
00347    if (BIMINF >= 0.0) 
00348       b0 = AIMSUP;
00349    else               
00350       b0 = AIMINF;
00351 
00352    realteilSUP = -MaxReal;
00353 
00354    for (j=1; j<=rep; j++) 
00355    {
00356       for (i=1; i<=4; cxsc_l_complex_division_p[i++] = true);
00357     
00358       realteilSUP =
00359              max( realteilSUP,
00360                    max( max( minmax( false, a0, b0, BIMINF, BRE, 1,2 ),
00361                              minmax( false, a0, b0, BIMSUP, BRE, 3,4 ) ),
00362                         max( minmax( false, b0, a0, BREINF, BIM, 1,3 ),
00363                              minmax( false, b0, a0, BRESUP, BIM, 2,4 ) ) )
00364 
00365                 );
00366 
00367       if (cxsc_l_complex_division_p[1])
00368          realteilSUP = max( realteilSUP, cxsc_complex_division_f( a0, b0, BREINF, BIMINF, +1 ) );
00369       if (cxsc_l_complex_division_p[2])
00370          realteilSUP = max( realteilSUP, cxsc_complex_division_f( a0, b0, BRESUP, BIMINF, +1 ) );
00371       if (cxsc_l_complex_division_p[3])
00372          realteilSUP = max( realteilSUP, cxsc_complex_division_f( a0, b0, BREINF, BIMSUP, +1 ) );
00373       if (cxsc_l_complex_division_p[4])
00374          realteilSUP = max( realteilSUP, cxsc_complex_division_f( a0, b0, BRESUP, BIMSUP, +1 ) );
00375 
00376       if (a_repeat) 
00377          a0 = ARESUP; 
00378       else if (b_repeat) 
00379          b0 = AIMSUP;
00380    }
00381 
00382    if (BREINF >= 0.0) 
00383       a0 = AREINF;
00384    else               
00385       a0 = ARESUP;
00386    if (BIMINF >= 0.0) 
00387       b0 = AIMINF;
00388    else               
00389       b0 = AIMSUP;
00390 
00391    realteilINF = MaxReal;
00392 
00393    for (j=1; j<=rep; j++) 
00394    {
00395       for (i=1; i<=4; cxsc_l_complex_division_p[i++] = true);
00396       
00397       realteilINF =
00398               min( realteilINF,
00399                    min( min( minmax( true, a0, b0, BIMINF, BRE, 1,2 ),
00400                              minmax( true, a0, b0, BIMSUP, BRE, 3,4 ) ),
00401                         min( minmax( true, b0, a0, BREINF, BIM, 1,3 ),
00402                              minmax( true, b0, a0, BRESUP, BIM, 2,4 ) ) )
00403                  );
00404 
00405       if (cxsc_l_complex_division_p[1])
00406          realteilINF = min( realteilINF, cxsc_complex_division_f( a0, b0, BREINF, BIMINF, -1 ) );
00407       if (cxsc_l_complex_division_p[2])
00408          realteilINF = min( realteilINF, cxsc_complex_division_f( a0, b0, BRESUP, BIMINF, -1 ) );
00409       if (cxsc_l_complex_division_p[3])
00410          realteilINF = min( realteilINF, cxsc_complex_division_f( a0, b0, BREINF, BIMSUP, -1 ) );
00411       if (cxsc_l_complex_division_p[4])
00412          realteilINF = min( realteilINF, cxsc_complex_division_f( a0, b0, BRESUP, BIMSUP, -1 ) );
00413 
00414       if (a_repeat) 
00415          a0 = AREINF; 
00416       else if (b_repeat) 
00417          b0 = AIMINF;
00418    }
00419 
00420 
00421    //  Calculation of the img. part: 
00422    //  g(a, b, c, d) = cxsc_complex_division_f(b, -a, c, d) 
00423 
00424    a_repeat = ( BIMINF < CXSC_Zero ) && ( CXSC_Zero < BIMSUP );
00425    b_repeat = ( BREINF < CXSC_Zero ) && ( CXSC_Zero < BRESUP );
00426 
00427    //  IF a_repeat OR b_repeat THEN rep:= 2 ELSE rep:= 1;  
00428 
00429    if (BREINF >= 0.0) 
00430       b0 = AIMSUP;
00431    else 
00432       b0 = AIMINF;
00433    
00434    if (BIMINF >= 0.0) 
00435       a0 = AREINF;
00436    else 
00437       a0 = ARESUP;
00438 
00439    imagteilSUP = -MaxReal;
00440 
00441    for (j=1; j<=rep; j++) 
00442    {
00443       for (i=1; i<=4; cxsc_l_complex_division_p[i++] = true) ;
00444     
00445       imagteilSUP =
00446               max( imagteilSUP,
00447                    max( max( minmax( false,  b0, -a0, BIMINF, BRE, 1,2 ),
00448                              minmax( false,  b0, -a0, BIMSUP, BRE, 3,4 ) ),
00449                         max( minmax( false, -a0,  b0, BREINF, BIM, 1,3 ),
00450                              minmax( false, -a0,  b0, BRESUP, BIM, 2,4 ) ) )
00451                  );
00452     
00453       if (cxsc_l_complex_division_p[1])
00454          imagteilSUP = max( imagteilSUP, cxsc_complex_division_f( b0, -a0, BREINF, BIMINF, +1 ) );
00455       if (cxsc_l_complex_division_p[2])
00456          imagteilSUP = max( imagteilSUP, cxsc_complex_division_f( b0, -a0, BRESUP, BIMINF, +1 ) );
00457       if (cxsc_l_complex_division_p[3])
00458          imagteilSUP = max( imagteilSUP, cxsc_complex_division_f( b0, -a0, BREINF, BIMSUP, +1 ) );
00459       if (cxsc_l_complex_division_p[4])
00460          imagteilSUP = max( imagteilSUP, cxsc_complex_division_f( b0, -a0, BRESUP, BIMSUP, +1 ) );
00461 
00462       if (b_repeat) 
00463          b0 = AIMSUP;  
00464       else if (a_repeat) 
00465          a0 = AREINF  ;
00466    }
00467 
00468    if (BREINF >= 0.0) 
00469       b0 = AIMINF;
00470    else 
00471       b0 = AIMSUP;
00472   
00473    if (BIMINF >= 0.0) 
00474       a0 = ARESUP;
00475    else 
00476       a0 = AREINF;
00477 
00478    imagteilINF = MaxReal;
00479 
00480    for (j=1; j<=rep; j++) 
00481    {
00482       for (i=1; i<=4; cxsc_l_complex_division_p[i++] = true) ;
00483     
00484       imagteilINF =
00485               min( imagteilINF,
00486                    min( min( minmax( true,  b0, -a0, BIMINF, BRE, 1,2 ),
00487                              minmax( true,  b0, -a0, BIMSUP, BRE, 3,4 ) ),
00488                         min( minmax( true, -a0,  b0, BREINF, BIM, 1,3 ),
00489                              minmax( true, -a0,  b0, BRESUP, BIM, 2,4 ) ) )
00490                  );
00491     
00492       if (cxsc_l_complex_division_p[1])
00493          imagteilINF = min( imagteilINF, cxsc_complex_division_f( b0, -a0, BREINF, BIMINF, -1 ) );
00494       if (cxsc_l_complex_division_p[2])
00495          imagteilINF = min( imagteilINF, cxsc_complex_division_f( b0, -a0, BRESUP, BIMINF, -1 ) );
00496       if (cxsc_l_complex_division_p[3])
00497          imagteilINF = min( imagteilINF, cxsc_complex_division_f( b0, -a0, BREINF, BIMSUP, -1 ) );
00498       if (cxsc_l_complex_division_p[4])
00499          imagteilINF = min( imagteilINF, cxsc_complex_division_f( b0, -a0, BRESUP, BIMSUP, -1 ) );
00500 
00501       if (b_repeat) 
00502          b0 = AIMINF;  
00503       else if (a_repeat) 
00504          a0 = ARESUP;
00505    }
00506 
00507    return l_cinterval(l_interval(realteilINF, realteilSUP),
00508                       l_interval(imagteilINF, imagteilSUP));
00509 }  // cidiv
00510 
00511 l_cinterval C_point_div(const l_cinterval& z, const l_cinterval& n)
00512 // Division of complex point intervals; 
00513 // z,n must be point intervals!!  Blomquist, 07,11.02
00514 // This function only for internal use!
00515 {
00516     l_complex a,b,q1,q2;
00517     a = l_complex(InfRe(z),InfIm(z));
00518     b = l_complex(InfRe(n),InfIm(n));
00519     q1 = divd(a,b);
00520     q2 = divu(a,b);
00521 
00522     l_interval re, im;
00523     re = l_interval( Re(q1),Re(q2) );
00524     im = l_interval( Im(q1),Im(q2) );
00525 
00526     return l_cinterval(re,im);
00527 }  // C_point_div
00528 
00529 
00530 l_cinterval operator / (const l_cinterval & a, const l_cinterval & b) 
00531                                                       throw(DIV_BY_ZERO)
00532 {
00533     if (0.0 <= b.re && 0.0 <= b.im ) {
00534 //    if (0.0 <= (sqr(b.re) + sqr(b.im))) {
00535       cxscthrow(DIV_BY_ZERO("l_cinterval operator / (const l_cinterval&, const l_cinterval&)"));
00536       return a; // dummy result
00537     }      
00538     bool a_point, b_point;
00539     a_point = InfRe(a)==SupRe(a) && InfIm(a)==SupIm(a);
00540     b_point = InfRe(b)==SupRe(b) && InfIm(b)==SupIm(b);
00541     if(a_point && b_point) return C_point_div(a,b); // a,b are point intervals
00542     else return cidiv(a,b);
00543 }
00544 
00545 l_interval abs(const l_cinterval &a) throw()
00546 {
00547     return sqrtx2y2(a.re,a.im);
00548 }
00549 
00550 
00551 // ---- Ausgabefunkt. ---------------------------------------
00552 
00553 std::ostream & operator << (std::ostream &s, const l_cinterval& a) throw()
00554 {
00555     s << '('          
00556       << a.re << ','  
00557       << a.im       
00558       << ')';
00559     return s;
00560 }
00561 
00562 std::string & operator << (std::string &s, const l_cinterval& a) throw()
00563 {
00564 // string s; l_cinterval a;
00565 // s << a; s delivers the string of the value a in the form:
00566 // ([Inf(real-part(a)),Sup(real-part(a))],[Inf(img-part(a)),Sup(img-part(a))])
00567     s+='(';
00568     s << a.re;
00569     s+=',';
00570     s << a.im; 
00571     s+=')';
00572     return s;
00573 }
00574 
00575 std::string & operator >> (std::string &s, l_cinterval &a) 
00576                                      throw(EMPTY_INTERVAL)
00577 // With: 
00578 //       l_cinterval a;
00579 //       string("([1.234,1.234],[2.567,2.567])") >> a;
00580 // the value a will be an inclusion of the above string.
00581 // The actual precisions of the staggered intervals a.re and a.im 
00582 // will not be affected by the operator >> !
00583 // The above braces, brackets and commas must not be used in the 
00584 // string, however the four numbers must then be seperated by spaces!
00585 // Thus, the following string will produce the same inclusion a:
00586 //       string("1.234 1.234 2.567 2.567 ") >> a;
00587 // Blomquist, 15.11.2006;
00588 {
00589     l_real Iar,Sar,Iai,Sai;
00590     l_interval lr,li;
00591     int stagprec_old(stagprec);
00592     dotprecision dot;
00593 
00594     s = skipwhitespacessinglechar (s, '(');
00595     s = skipwhitespacessinglechar (s, '[');
00596     s = s >> dot;
00597     stagprec = StagPrec(a.re);
00598     lr = l_interval(dot);
00599     Iar = Inf(lr);
00600     s = skipwhitespacessinglechar (s, ',');
00601     s = s >> dot; 
00602     lr = l_interval(dot);
00603     Sar = Sup(lr);
00604     lr = l_interval(Iar,Sar);
00605 
00606     stagprec = StagPrec(a.im);
00607     s = skipwhitespacessinglechar (s, ']');
00608     s = skipwhitespacessinglechar (s, ',');
00609     s = skipwhitespacessinglechar (s, '[');
00610     s = s >> dot; 
00611 
00612     li = l_interval(dot);
00613     Iai = Inf(li);
00614     s = skipwhitespacessinglechar (s, ',');
00615     s = s >> dot; 
00616     li = l_interval(dot);
00617     Sai = Sup(li);
00618     li = l_interval(Iai,Sai);
00619 
00620     a = l_cinterval(lr,li );
00621     s = skipwhitespaces (s);
00622     if (s[0] == ']') 
00623         s.erase(0,1);
00624     s = skipwhitespaces (s);
00625     if (s[0] == ')') 
00626         s.erase(0,1);
00627     stagprec = stagprec_old;
00628     if (Inf(a.re) > Sup(a.re) || Inf(a.im) > Sup(a.im)) 
00629         cxscthrow(EMPTY_INTERVAL
00630         ("std::string & operator >> (std::string &s, cinterval &a)"));
00631 
00632    return s;
00633 }
00634 
00635 std::istream & operator >> (std::istream & s, l_cinterval& a) 
00636                                                  throw(EMPTY_INTERVAL)
00637 // With: 
00638 //       l_cinterval lc;
00639 //       cout << "([a,b],[c,d]) = ?" << endl;
00640 //       cin >> lc;
00641 // the input string ([1.23,1.23],[3.45,3.45]) will be included by lc.
00642 // The actual precisions of the staggered intervals  lc.re  and  lc.im 
00643 // will not be affected by the operator >> !
00644 // The above braces, brackets and commas must not be used in the 
00645 // string, however the four numbers a,b,c,d must then be seperated by 
00646 // spaces! Thus, the following input string   1.23 1.23 3.45 3.45
00647 // will produce the same inclusion lc:
00648 // Blomquist, 15.11.2006;
00649 { 
00650     l_real Iar,Sar,Iai,Sai;
00651     l_interval lr,li;
00652     dotprecision dot;
00653     // int stagprec_old(stagprec); // unused variable
00654 
00655     char c;
00656     skipeolnflag = inpdotflag = true;
00657     stagprec = StagPrec(a.re);
00658     c = skipwhitespacessinglechar (s, '(');
00659     if (inpdotflag) s.putback(c);
00660     c = skipwhitespacessinglechar (s, '[');
00661     if (inpdotflag) s.putback(c);
00662     s >> dot;
00663     lr = l_interval(dot);
00664     Iar = Inf(lr);
00665     skipeolnflag = inpdotflag = true; 
00666     c = skipwhitespacessinglechar (s, ','); 
00667     if (inpdotflag) s.putback(c);
00668     s >> dot;
00669     lr = l_interval(dot);
00670     Sar = Sup(lr);
00671     lr = l_interval(Iar,Sar);
00672     c = skipwhitespacessinglechar (s, ']');
00673     if (inpdotflag) s.putback(c);
00674     c = skipwhitespacessinglechar (s, ',');
00675     if (inpdotflag) s.putback(c);
00676     
00677     c = skipwhitespacessinglechar (s, '[');
00678     if (inpdotflag) s.putback(c);
00679 //    s >> RndDown >> Inf(a.im);
00680     stagprec = StagPrec(a.im);
00681     s >> dot;
00682     li = l_interval(dot);
00683     Iai = Inf(li);
00684     skipeolnflag = inpdotflag = true; 
00685     c = skipwhitespacessinglechar (s, ','); 
00686     if (inpdotflag) s.putback(c);
00687     s >> dot;
00688     li = l_interval(dot);
00689     Sai = Sup(li);
00690     li = l_interval(Iai,Sai);
00691 
00692     a = l_cinterval(lr,li);
00693 
00694    if (!waseolnflag) 
00695    {
00696       skipeolnflag = false, inpdotflag = true;
00697       c = skipwhitespaces (s);
00698       if (inpdotflag && c != ']') 
00699          s.putback(c);
00700    }
00701    if (!waseolnflag) 
00702    {
00703       skipeolnflag = false, inpdotflag = true;
00704       c = skipwhitespaces (s);
00705       if (inpdotflag && c != ')') 
00706          s.putback(c);
00707          }
00708    if (Inf(a.re) > Sup(a.re) || Inf(a.im) > Sup(a.im)) 
00709    cxscthrow(EMPTY_INTERVAL
00710         ("std::istream & operator >> (std::istream &s, cinterval &a)"));
00711       
00712    return s;
00713 }
00714 
00715 void operator >> (const std::string &s, l_cinterval &a) throw(EMPTY_INTERVAL)
00716 {
00717    std::string r(s);
00718    r >> a;
00719 }
00720 
00721 void operator >> (const char *s, l_cinterval &a) throw(EMPTY_INTERVAL)
00722 {
00723    std::string r(s);
00724    r >> a;
00725 }
00726 
00727 } // namespace cxsc
00728 
00729 
00730 
00731 
00732 
00733 
00734 
00735 
00736 
00737 
00738 
00739 
00740 
00741 
00742 
00743 
00744 
00745 
00746 
00747 
00748 
00749 
00750 
00751 
00752 
00753