00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
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;
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
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
00094
00095
00096
00097 static const int max_expo = 1020, max_expo1 = 1023;
00098
00099
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
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
00122
00123
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 {
00155 if (0.0 < x) {
00156 if (minimum && sign(b) != sign(y0) )
00157 {
00158
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
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
00175 if (y0 == 0.0)
00176 {
00177 if (minimum)
00178 {
00179 if (a > 0.0)
00180
00181 minmax = Inf(l_interval(a)/l_interval(Sup(x)));
00182 else
00183
00184 minmax = Inf(l_interval(a)/l_interval(Inf(x)));
00185 } else
00186 {
00187 if (a > 0.0)
00188
00189 minmax = Sup(l_interval(a)/l_interval(Inf(x)));
00190 else
00191
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 {
00198
00199
00200
00201
00202 l_real invf2(1.0), a_skal;
00203
00204
00205
00206
00207 if (sign(b)==0) t = 1.0;
00208 else
00209 {
00210
00211
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;
00217
00218
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
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
00235 }
00236 q = l_interval(b)/a_skal;
00237 if (sign(q[1])<0) q = -q;
00238
00239
00240 t = (Da > 0)? q + sqrtx2y2(two_Da,q) : q + sqrt1px2(q);
00241 }
00242
00243 if (a<0.0) t = -t;
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253 ay0 = abs(y0);
00254
00255 if ( (sign(b) == sign(y0)) == minimum )
00256 {
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
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)
00271 {
00272
00273 q = a/x0;
00274 times2pown(q,-1);
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 }
00284 }
00285 return minmax;
00286 }
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
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
00315
00316
00317
00318
00319
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
00422
00423
00424 a_repeat = ( BIMINF < CXSC_Zero ) && ( CXSC_Zero < BIMSUP );
00425 b_repeat = ( BREINF < CXSC_Zero ) && ( CXSC_Zero < BRESUP );
00426
00427
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 }
00510
00511 l_cinterval C_point_div(const l_cinterval& z, const l_cinterval& n)
00512
00513
00514
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 }
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
00535 cxscthrow(DIV_BY_ZERO("l_cinterval operator / (const l_cinterval&, const l_cinterval&)"));
00536 return a;
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);
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
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
00565
00566
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
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
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
00638
00639
00640
00641
00642
00643
00644
00645
00646
00647
00648
00649 {
00650 l_real Iar,Sar,Iai,Sai;
00651 l_interval lr,li;
00652 dotprecision dot;
00653
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
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 }
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