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
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045 template<typename C>
00046 interval<C>::interval(typename util::CallTraits<baseType>::TParam iValue)
00047 {
00048 v[0] = v[1] = iValue;
00049 }
00050
00051
00052 template<typename C>
00053 interval<C>::interval(typename util::CallTraits<baseType>::TParam iInf,typename util::CallTraits<baseType>::TParam iSup)
00054 {
00055 v[0] = iInf;
00056 v[1] = iSup;
00057 }
00058
00059 template<typename C>
00060 interval<C>& interval<C>::operator=(const interval<C>& i)
00061 {
00062 v[0] = i.v[0];
00063 v[1] = i.v[1];
00064 return *this;
00065 }
00066
00067 template<typename C>
00068 const interval<C>& interval<C>::operator+() const
00069 {
00070 return *this;
00071 }
00072
00073 template<typename C>
00074 void interval<C>::set(typename util::CallTraits<C>::TParam iInf,typename util::CallTraits<C>::TParam iSup)
00075 {
00076 v[0] = iInf;
00077 v[1] = iSup;
00078 }
00079
00080 template<typename C>
00081 bool interval<C>::isEmpty() const
00082 {
00083 return v[0]>v[1];
00084 }
00085
00086
00087 template<typename C>
00088 bool interval<C>::isSingleton() const
00089 {
00090 return v[0]==v[1];
00091 }
00092
00093
00094 template<typename C>
00095 bool interval<C>::contains(typename util::CallTraits<baseType>::TParam ix) const
00096 {
00097 return (ix>=v[0]) && (ix<=v[1]);
00098 }
00099
00100 template<typename C>
00101 C& interval<C>::operator[](int i)
00102 {
00103 return v[i];
00104 }
00105
00106 template<typename C>
00107 C interval<C>::operator[](int i) const
00108 {
00109 return v[i];
00110 }
00111
00112 template<typename C>
00113 C interval<C>::inf() const
00114 {
00115 return v[0];
00116 }
00117
00118 template<typename C>
00119 C interval<C>::sup() const
00120 {
00121 return v[1];
00122 }
00123
00124 template<typename C>
00125 C& interval<C>::inf()
00126 {
00127 return v[0];
00128 }
00129
00130 template<typename C>
00131 C& interval<C>::sup()
00132 {
00133 return v[1];
00134 }
00135
00136 template<typename C>
00137 C interval<C>::mid() const
00138 {
00139 return static_cast<C>(0.5)*(v[0]+v[1]);
00140 }
00141
00142 template<typename C>
00143 C interval<C>::diam()const
00144 {
00145 return v[1]-v[0];
00146 }
00147
00148 template<typename C>
00149 C interval<C>::ratio() const
00150 {
00151 if (v[0]!=static_cast<C>(0.0))
00152 return (v[1]/v[0]);
00153 else
00154 return 0.0;
00155 }
00156
00157 template<typename C>
00158 bool interval<C>::operator> (const interval<C>& i) const
00159 {
00160 return v[0]>i.v[1];
00161 }
00162
00163 template<typename C>
00164 bool interval<C>::operator< (const interval<C>& i) const
00165 {
00166 return v[1]<i.v[0];
00167 }
00168
00169 template<typename C>
00170 bool interval<C>::operator==(const interval<C>& i) const
00171 {
00172 return (v[0]==i.v[0]) && (v[1]==i.v[1]);
00173 }
00174
00175 template<typename C>
00176 bool interval<C>::operator!=(const interval<C>& i) const
00177 {
00178 return !(*this==i);
00179 }
00180
00181 template<typename C>
00182 bool interval<C>::operator>=(const interval<C>& i) const
00183 {
00184 return (v[0]>=i.v[0]) && (v[1]>=i.v[1]);
00185 }
00186
00187 template<typename C>
00188 bool interval<C>::operator<=(const interval<C>& i) const
00189 {
00190 return (v[0]<=i.v[0]) && (v[1]<=i.v[1]);
00191 }
00192
00193 template<typename C>
00194 bool interval<C>::pe(const interval<C>& i) const
00195 {
00196 return ((v[0]<i.v[0]) && (v[1]>i.v[0])) || ((v[0]<i.v[1])&&(v[1]>i.v[1]));
00197 }
00198
00199 template<typename C>
00200 bool interval<C>::pne(const interval<C>& i) const
00201 {
00202 return *this!=i;
00203 }
00204
00205 template<typename C>
00206 bool interval<C>::pg(const interval<C>& i) const
00207 {
00208 return v[1]>i.v[0];
00209 }
00210
00211 template<typename C>
00212 bool interval<C>::pge(const interval<C>& i) const
00213 {
00214 return v[1]>=i.v[0];
00215 }
00216
00217 template<typename C>
00218 bool interval<C>::pl(const interval<C>& i) const
00219 {
00220 return v[0]<i.v[1];
00221 }
00222
00223 template<typename C>
00224 bool interval<C>::ple(const interval<C>& i) const
00225 {
00226 return v[0]>=i.v[1];
00227 }
00228
00229 template<typename C>
00230 std::ostream& operator<<( std::ostream& os, const interval<C>& iV )
00231 {
00232 os << "<" << iV.inf() << "," << iV.sup() << ">";
00233 return os;
00234 }
00235
00236 template<typename C> std::string str( const interval<C>& iV )
00237 {
00238 return "<"+ str(iV.inf()) + "," + str(iV.sup()) + ">";
00239 }
00240
00241
00242 namespace impl
00243 {
00244
00245 template<typename C> C numMin4(const C& k1,const C& k2,const C& k3,const C& k4)
00246 {
00247 C tmpmin;
00248
00249 tmpmin = k2;
00250 if (k1<k2)
00251 tmpmin = k1;
00252 if (k3<tmpmin)
00253 tmpmin = k3;
00254 if (k4<tmpmin)
00255 tmpmin = k4;
00256 return tmpmin;
00257 }
00258
00259 template<typename C> C numMax4(const C& k1,const C& k2,const C& k3,const C& k4)
00260 {
00261 C tmpmax;
00262
00263 tmpmax = k2;
00264 if (k1>k2)
00265 tmpmax = k1;
00266 if (k3>tmpmax)
00267 tmpmax = k3;
00268 if (k4>tmpmax)
00269 tmpmax = k4;
00270 return tmpmax;
00271 }
00272
00273 template<typename C> __inline void numMinMax(const C& k1,const C& k2,C& amin,C& amax)
00274 {
00275 if (k1<k2)
00276 {
00277 amin = k1;
00278 amax = k2;
00279 }
00280 else
00281 {
00282 amin = k2;
00283 amax = k1;
00284 }
00285 }
00286
00287 template<typename C> __inline void numMin(const C& k1,const C& k2,C& amin)
00288 {
00289 if (k1<k2)
00290 amin = k1;
00291 else
00292 amin = k2;
00293 }
00294
00295 template<typename C> inline void numMax(const C& k1,const C& k2,C& amax)
00296 {
00297 if (k2<k1)
00298 amax = k1;
00299 else
00300 amax = k2;
00301 }
00302
00303 }
00304
00305 template<typename C> interval<C> operator+(const interval<C>& i1,const interval<C>& i2);
00306 template<typename C> interval<C> operator-(const interval<C>& i1,const interval<C>& i2);
00307 template<typename C> interval<C> operator*(const interval<C>& i1,const interval<C>& i2);
00308 template<typename C> interval<C> operator/(const interval<C>& i1,const interval<C>& i2);
00309
00310 template<typename C>
00311 interval<C> interval<C>::operator-() const
00312 {
00313 return interval<C>(-v[1],-v[0]);
00314 }
00315
00316 template<typename C>
00317 interval<C>& interval<C>::operator+=(const interval<C>& i)
00318 {
00319 v[0] += i.v[0];
00320 v[1] += i.v[1];
00321 return *this;
00322 }
00323
00324 template<typename C>
00325 interval<C>& interval<C>::operator-=(const interval<C>& i)
00326 {
00327 v[0] -= i.v[1];
00328 v[1] -= i.v[0];
00329 return *this;
00330 }
00331
00332 template<typename C>
00333 interval<C>& interval<C>::operator*=(const interval<C>& i)
00334 {
00335 C m1,M1,m2,M2;
00336 impl::numMinMax(v[0]*i.v[0],v[0]*i.v[1],m1,M1);
00337 impl::numMinMax(v[1]*i.v[0],v[1]*i.v[1],m2,M2);
00338 impl::numMin(m1,m2,v[0]);
00339 impl::numMax(M1,M2,v[1]);
00340 return *this;
00341 }
00342
00343
00344 template<typename C>
00345 interval<C>& interval<C>::operator/=(const interval<C>& i)
00346 {
00347 if ((i.v[0]<=0.0) && (i.v[1]>0.0))
00348 LASS_THROW("division by zero");
00349 C m1,M1,m2,M2;
00350 m1 = NumTraits<C>::one / i.v[0];
00351 m2 = NumTraits<C>::one / i.v[1];
00352
00353 impl::numMinMax(v[0]*m1,v[0]*m1,m1,M1);
00354 impl::numMinMax(v[1]*m2,v[1]*m2,m2,M2);
00355 impl::numMin(m1,m2,v[0]);
00356 impl::numMax(M1,M2,v[1]);
00357 return *this;
00358 }
00359
00360
00361 template<typename C>
00362 interval<C>& interval<C>::operator+=(typename util::CallTraits<baseType>::TParam s)
00363 {
00364 v[0] += s;
00365 v[1] += s;
00366 return *this;
00367 }
00368
00369 template<typename C>
00370 interval<C>& interval<C>::operator-=(typename util::CallTraits<baseType>::TParam s)
00371 {
00372 v[0] -= s;
00373 v[1] -= s;
00374 return *this;
00375 }
00376
00377 template<typename C>
00378 interval<C>& interval<C>::operator*=(typename util::CallTraits<baseType>::TParam s)
00379 {
00380 v[0] *= s;
00381 v[1] *= s;
00382
00383 if (s<0.0)
00384 std::swap(v[0],v[1]);
00385
00386 return *this;
00387 }
00388
00389 template<typename C>
00390 interval<C>& interval<C>::operator/=(typename util::CallTraits<baseType>::TParam s)
00391 {
00392 C t = static_cast<C>(1.0)/s;
00393 v[0] *= t;
00394 v[1] *= t;
00395
00396 if (s<0.0)
00397 std::swap(v[0],v[1]);
00398
00399 return *this;
00400 }
00401
00402 template<typename C> inline
00403 interval<C> operator+(const interval<C>& i1,const interval<C>& i2)
00404 {
00405 interval<C> t(i1);
00406 t+=i2;
00407 return t;
00408 }
00409
00410 template<typename C> inline
00411 interval<C> operator-(const interval<C>& i1,const interval<C>& i2)
00412 {
00413 interval<C> t(i1);
00414 t-=i2;
00415 return t;
00416 }
00417
00418 template<typename C> inline
00419 interval<C> operator*(const interval<C>& i1,const interval<C>& i2)
00420 {
00421 interval<C> t(i1);
00422 t*=i2;
00423 return t;
00424 }
00425
00426 template<typename C> inline
00427 interval<C> operator/(const interval<C>& i1,const interval<C>& i2)
00428 {
00429 interval<C> t(i1);
00430 t/=i2;
00431 return t;
00432 }
00433
00434
00435 template<typename C>
00436 C interval<C>::fe(const interval<C>& i) const
00437 {
00438 if (i.isSingleton())
00439 {
00440 if (isSingleton())
00441 if (v[0]==i.v[0])
00442 return static_cast<C>(1.0);
00443 return static_cast<C>(0.0);
00444 }
00445 if (i.v[0]<v[1])
00446 {
00447 return (v[1]-i.v[0])/(i.v[1]-v[0]);
00448 }
00449 return (i.v[1]-v[0])/(v[1]-i.v[0]);
00450 }
00451
00452
00453 template<typename C>
00454 C interval<C>::fne(const interval<C>& i) const
00455 {
00456 return static_cast<C>(1.0)-fe(i);
00457 }
00458
00459
00460 template<typename C>
00461 C interval<C>::fg(const interval<C>& i) const
00462 {
00463 if (i.v[0]<v[1])
00464 {
00465 return (i.v[0]-v[0])/(i.v[1]-v[0]);
00466 }
00467 return (v[0]-i.v[0])/(v[1]-i.v[0]);
00468 }
00469
00470
00471 template<typename C>
00472 C interval<C>::fge(const interval<C>& i) const
00473 {
00474 return std::max(fg(i),fe(i));
00475 }
00476
00477
00478 template<typename C>
00479 C interval<C>::fl(const interval<C>& i) const
00480 {
00481 return static_cast<C>(1.0)-fg(i);
00482 }
00483
00484
00485 template<typename C>
00486 C interval<C>::fle(const interval<C>& i) const
00487 {
00488 return std::max(fl(i),fe(i));
00489 }
00490
00491 template<typename C>
00492 void inpsqr(interval<C>& i)
00493 {
00494 C m1,M1;
00495 m1 = i.v[0]*i.v[0];
00496 M1 = i.v[1]*i.v[1];
00497
00498 impl::numMinMax(m1,M1,i.v[0],i.v[1]);
00499 if ((i.v[0] < 0.0) && (i.v[1]>=0.0))
00500 i.v[0] = 0.0;
00501 }
00502
00503 template<typename C>
00504 void inpsqrt(interval<C>& i)
00505 {
00506 i.v[0] = lass::num::sqrt(i.v[0]);
00507 i.v[1] = lass::num::sqrt(i.v[1]);
00508 }
00509
00510 template<typename C>
00511 void inpexp(interval<C>& i)
00512 {
00513 i.v[0] = lass::num::exp(i.v[0]);
00514 i.v[1] = lass::num::exp(i.v[1]);
00515 }
00516
00517 template<typename C>
00518 void inplog(interval<C>& i)
00519 {
00520 i[0] = lass::num::log(i[0]);
00521 i[1] = lass::num::log(i[1]);
00522 }
00523
00524 template<typename C>
00525 void inpnorm(interval<C>& i)
00526 {
00527 i[0] = lass::num::norm( i[0] );
00528 i[1] = lass::num::norm( i[1] );
00529 }
00530
00531 template<typename C>
00532 void inpinv(interval<C>& i)
00533 {
00534 i[0] = lass::num::inv( i[1] );
00535 i[1] = lass::num::inv( i[0] );
00536 }
00537
00538
00539 template<typename C>
00540 interval<C> sqr(const interval<C>& i)
00541 {
00542 C m1,M1,m2,M2;
00543 m1 = i[0]*i[0];
00544 M1 = i[1]*i[1];
00545 impl::numMinMax(m1,M1,m2,M2);
00546
00547 if (i.contains(0.0))
00548 m2 = 0.0;
00549
00550 return num::interval<C>(m2,M2);
00551 }
00552
00553 template<typename C>
00554 interval<C> sqrt(const interval<C>& i)
00555 {
00556 return interval<C>(lass::num::sqrt(i.inf()),lass::num::sqrt(i.sup()));
00557 }
00558
00559 template<typename C>
00560 interval<C> exp(const interval<C>& i)
00561 {
00562 return interval<C>(lass::num::exp(i.inf()),lass::num::exp(i.sup()));
00563 }
00564
00565 template<typename C>
00566 interval<C> log(const interval<C>& i)
00567 {
00568 return interval<C>(lass::num::log(i.inf()),lass::num::log(i.sup()));
00569 }
00570
00571 template<typename C>
00572 interval<C> set_union(const interval<C>& i1, const interval<C>& i2)
00573 {
00574 return interval<C>( std::min(i1.inf(), i2.inf()), std::max( i1.sup(), i2.sup() ) );
00575 }
00576
00577 template<typename C>
00578 interval<C> set_intersect(const interval<C>& i1, const interval<C>& i2)
00579 {
00580 return interval<C>( std::max(i1.inf(), i2.inf()), std::min( i1.sup(), i2.sup() ) );
00581 }
00582
00583
00584 template<typename C,typename f>
00585 interval<C> applyFunction(const interval<C>& iV, f func )
00586 {
00587 C t1,t2,r1,r2;
00588 t1 = func(iV.inf());
00589 t2 = func(iV.sup());
00590 impl::numMinMax(t1,t2,r1,r2);
00591 return interval<C>(r1,r2);
00592 }