Horus Doc || C++ Reference || Class Overview   Pixels   Images   Detector   Geometry   Registry || Doxygen's quick Index  

HxComplex.h

00001 /*
00002  *  Copyright (c) 2001, University of Amsterdam, The Netherlands.
00003  *  All rights reserved.
00004  *
00005  *
00006  *  Author(s):
00007  *  Jan-Mark Geusebroek (mark@science.uva.nl)
00008  *  Dennis Koelma (koelma@wins.uva.nl)
00009  *  Edo Poll (poll@wins.uva.nl)
00010  */
00011 
00012 #ifndef HxComplex_h
00013 #define HxComplex_h
00014 
00015 //#include <stdlib>
00016 
00017 #include "HxIoFwd.h"
00018 #include "HxMath.h"
00019 #include "HxString.h"
00020 
00021 #undef min
00022 #undef max
00023 
00024 class HxScalarInt;
00025 #include  "HxScalarDouble.h"
00026 class HxVec2Int;
00027 class HxVec2Double;
00028 class HxVec3Int;
00029 class HxVec3Double;
00030 
00031 
00035 class L_HXBASIS HxComplex
00036 {
00037 public:
00038 
00040 
00042                             HxComplex();
00043 
00045                             HxComplex(double re, double im);
00046                             
00048                             HxComplex(const HxComplex& rhs);
00050 
00051     void*                   operator new(size_t, void * = 0);
00052 
00053     HxComplex&              operator=(const HxComplex& rhs);
00054 
00056 
00059     int                     dim() const;
00060     
00062     double                  x() const;
00063     
00065     double                  y() const;
00066 
00068     double                  getValue(int dimension) const; // dimension: 1 or 2
00069     void                    setValue(int dimension, double value); // dimension: 1 or 2
00071 
00073 /** \name Conversion*/
00075                             operator HxScalarInt() const;
00076 
00078                             operator HxScalarDouble() const;
00079 
00081                             operator HxVec2Int() const;
00082 
00084                             operator HxVec2Double() const;
00085 
00087                             operator HxVec3Int() const;
00088 
00090                             operator HxVec3Double() const;
00092 
00094 
00098     int                     operator==(const HxComplex& v) const;
00099 
00101     int                     operator!=(const HxComplex& v) const;
00102 
00104     int                     operator< (const HxComplex& v) const;
00105 
00107     int                     operator<=(const HxComplex& v) const;
00108 
00110     int                     operator> (const HxComplex& v) const;
00111 
00113     int                     operator>=(const HxComplex& v) const;
00114 
00119     static const HxComplex SMALL_VAL;
00120 
00125     static const HxComplex LARGE_VAL;
00127 
00129 
00133     HxComplex               operator-() const;
00134 
00136     HxComplex               complement() const;
00137 
00139     HxComplex               conjugate() const;
00140 
00142     HxScalarDouble          abs() const;
00143 
00145     HxScalarDouble          arg() const;
00146 
00148     HxComplex               ceil() const;
00149 
00151     HxComplex               floor() const;
00152 
00154     HxComplex               round() const;
00155 
00157     HxComplex               sum() const;
00158     
00160     HxComplex               product() const;
00161 
00163     HxScalarDouble          min() const;
00164 
00166     HxScalarDouble          max() const;
00167 
00169     HxScalarDouble          norm1() const;
00170 
00172     HxScalarDouble          norm2() const;
00173 
00175     HxScalarDouble          normInf() const;
00176 
00178     HxComplex               sqrt() const;
00179 
00181     HxComplex               sin() const;
00182 
00184     HxComplex               cos() const;
00185 
00187     HxComplex               tan() const;
00188 
00190     HxComplex               asin() const;
00191 
00193     HxComplex               acos() const;
00194 
00196     HxComplex               atan() const;
00197 
00199     HxComplex               atan2() const;
00200 
00202     HxComplex               sinh() const;
00203 
00205     HxComplex               cosh() const;
00206 
00208     HxComplex               tanh() const;
00209 
00211     HxComplex               exp() const;
00212 
00214     HxComplex               log() const;
00215 
00217     HxComplex               log10() const;
00219 
00221 
00225     HxComplex&              operator+=(const HxComplex& v);
00226 
00228     HxComplex&              operator-=(const HxComplex& v);
00229 
00231     HxComplex&              operator*=(const HxComplex& v);
00232 
00234     HxComplex&              operator/=(const HxComplex& v);
00235 
00236 
00238     friend HxComplex        operator+(const HxComplex& v1,
00239                                       const HxComplex& v2);
00240 
00242     friend HxComplex        operator-(const HxComplex& v1,
00243                                       const HxComplex& v2);
00244 
00246     friend HxComplex        operator*(const HxComplex& v1,
00247                                       const HxComplex& v2);
00248 
00250     friend HxComplex        operator/(const HxComplex& v1,
00251                                       const HxComplex& v2);
00252 
00253 
00255     HxComplex               min(const HxComplex& v) const;
00256 
00258     HxComplex&              minAssign(const HxComplex& v);
00259 
00261     HxComplex               max(const HxComplex& v) const;
00262 
00264     HxComplex&              maxAssign(const HxComplex& v);
00265 
00267     HxComplex               inf(const HxComplex& v) const;
00268 
00270     HxComplex&              infAssign(const HxComplex& v);
00271 
00273     HxComplex               sup(const HxComplex& v) const;
00274 
00276     HxComplex&              supAssign(const HxComplex& v);
00277 
00279     HxComplex               pow(const HxComplex& v) const;
00280 
00282     HxComplex               mod(const HxComplex& v) const;
00283 
00285     HxComplex               and(const HxComplex& v) const;
00286 
00288     HxComplex               or(const HxComplex& v) const;
00289 
00291     HxComplex               xor(const HxComplex& v) const;
00292 
00294     HxComplex               leftShift(const HxComplex& v) const;
00295 
00297     HxComplex               rightShift(const HxComplex& v) const;
00298 
00300     HxScalarDouble          dot(const HxComplex& v) const;
00301 
00303     HxComplex               cross(const HxComplex& v) const;
00305 
00307 
00309     STD_OSTREAM&            put(STD_OSTREAM& os) const;
00310 
00312     HxString                toString() const;
00314 
00315 private:
00316     double                  _values[2];
00317 };
00318 
00319 typedef HxComplex (*HxUpoComplex)(const HxComplex& a);
00320 typedef HxComplex (*HxBpoComplex)(const HxComplex& a1, const HxComplex& a2);
00321 
00322 inline STD_OSTREAM&
00323 operator<<(STD_OSTREAM& os, const HxComplex v)
00324 {
00325     return v.put(os);
00326 }
00327 
00328 inline
00329 HxComplex::HxComplex() 
00330 { 
00331 }
00332 
00333 inline
00334 HxComplex::HxComplex(double re, double im)
00335 {
00336     _values[0] = re;
00337     _values[1] = im;
00338 }
00339 
00340 inline
00341 HxComplex::HxComplex(const HxComplex& v)
00342 {
00343     _values[0] = v._values[0];
00344     _values[1] = v._values[1];
00345 }
00346 
00347 inline HxComplex&
00348 HxComplex::operator=(const HxComplex& rhs)
00349 {
00350     _values[0] = rhs._values[0];
00351     _values[1] = rhs._values[1];
00352     return *this;
00353 }
00354 
00355 inline void*
00356 HxComplex::operator new(size_t size, void *m) 
00357 {
00358     return m ? m : new char[size];
00359 }
00360 
00361 inline int
00362 HxComplex::dim() const 
00363 { 
00364     return 2;
00365 }
00366 
00367 inline double
00368 HxComplex::x() const 
00369 { 
00370     return _values[0];
00371 }
00372 
00373 inline double
00374 HxComplex::y() const 
00375 { 
00376     return _values[1]; 
00377 }
00378 
00379 inline double
00380 HxComplex::getValue(int dim) const
00381 { 
00382     return _values[dim - 1]; 
00383 }
00384 
00385 inline void
00386 HxComplex::setValue(int dim, double val)
00387 { 
00388     _values[dim - 1] = val; 
00389 }
00390 
00391 inline int
00392 HxComplex::operator==(const HxComplex& v) const
00393 {
00394     return (_values[0] == v._values[0]) && (_values[1] == v._values[1]);
00395 }
00396 
00397 inline int
00398 HxComplex::operator!=(const HxComplex& v) const
00399 {
00400     return (_values[0] != v._values[0]) || (_values[1] != v._values[1]);
00401 }
00402 
00403 inline int
00404 HxComplex::operator<(const HxComplex& v) const
00405 {
00406     return (fabs(_values[0]) + fabs(_values[1])) <
00407            (fabs(v._values[0]) + fabs(v._values[1]));
00408 }
00409 
00410 inline int
00411 HxComplex::operator<=(const HxComplex& v) const
00412 {
00413     return (fabs(_values[0]) + fabs(_values[1])) <=
00414            (fabs(v._values[0]) + fabs(v._values[1]));
00415 }
00416 
00417 inline int
00418 HxComplex::operator>(const HxComplex& v) const
00419 {
00420     return (fabs(_values[0]) + fabs(_values[1])) >
00421            (fabs(v._values[0]) + fabs(v._values[1]));
00422 }
00423 
00424 inline int
00425 HxComplex::operator>=(const HxComplex& v) const
00426 {
00427     return (fabs(_values[0]) + fabs(_values[1])) >=
00428            (fabs(v._values[0]) + fabs(v._values[1]));
00429 }
00430 
00431 inline HxComplex
00432 HxComplex::operator-() const
00433 {
00434     return HxComplex(-_values[0], -_values[1]);
00435 }
00436 
00437 inline HxComplex
00438 HxComplex::complement() const
00439 {
00440     return HxComplex(-_values[0], -_values[1]);
00441 }
00442 
00443 inline HxComplex
00444 HxComplex::conjugate() const
00445 {
00446     return HxComplex(_values[0], -_values[1]);
00447 }
00448 
00449 inline HxScalarDouble
00450 HxComplex::abs() const
00451 {
00452     return HxScalarDouble(::sqrt(_values[0]*_values[0]+_values[1]*_values[1]));
00453 }
00454 
00455 inline HxScalarDouble
00456 HxComplex::arg() const
00457 {
00458     return HxScalarDouble(::atan2(_values[1], _values[0]));
00459 }
00460 
00461 inline HxComplex
00462 HxComplex::ceil() const
00463 {
00464     return HxComplex(::ceil(_values[0]), ::ceil(_values[1]));
00465 }
00466 
00467 inline HxComplex
00468 HxComplex::floor() const
00469 {
00470     return HxComplex(::floor(_values[0]), ::floor(_values[1]));
00471 }
00472 
00473 inline HxComplex
00474 HxComplex::round() const
00475 {
00476     return HxComplex((int) (_values[0] + ((_values[0] >= 0) ? 0.5 : -0.5)),
00477                         (int) (_values[1] + ((_values[1] >= 0) ? 0.5 : -0.5)));
00478 }
00479 
00480 inline HxComplex
00481 HxComplex::sqrt() const
00482 {
00483     double a = _values[0];
00484     double b = _values[1];
00485     double sq = a*a+b*b;
00486     double arg = ::atan(b/a)*0.5;
00487     double mul = ::pow(sq, 0.25)*::exp(a*0.5);
00488 
00489     return HxComplex(mul*::cos(arg), mul*::sin(arg));
00490 }
00491 
00492 inline HxComplex
00493 HxComplex::sin() const
00494 {
00495     return HxComplex(::sin(_values[0])*::cosh(_values[1]),
00496         ::cos(_values[0])*::sinh(_values[1]));
00497 }
00498 
00499 inline HxComplex
00500 HxComplex::cos() const
00501 {
00502     return HxComplex(::cos(_values[0])*::cosh(_values[1]),
00503         -::sin(_values[0])*::sinh(_values[1]));
00504 }
00505 
00506 inline HxComplex
00507 HxComplex::tan() const
00508 {
00509     double den = ::cos(2*_values[0])+::cosh(2*_values[1]);
00510 
00511     return HxComplex(::sin(2*_values[0])/den, ::sinh(2*_values[1])/den);
00512 }
00513 
00514 inline HxComplex
00515 HxComplex::asin() const
00516 {
00517     double a = _values[0];
00518     double b = _values[1];
00519 
00520     HxComplex c = HxComplex(1-a*a+b*b, 2*a*b).sqrt() + HxComplex(-b,a);
00521 
00522     return HxComplex(c.arg().x(), -::log(c.abs().x()));
00523 }
00524 
00525 inline HxComplex
00526 HxComplex::acos() const
00527 {
00528     double a = _values[0];
00529     double b = _values[1];
00530 
00531     HxComplex c = HxComplex(1-a*a+b*b, 2*a*b).sqrt() + HxComplex(-b,a);
00532 
00533     return HxComplex(M_PI/2.0 - c.arg().x(), ::log(c.abs().x()));
00534 }
00535 
00536 inline HxComplex
00537 HxComplex::atan() const
00538 {
00539     double a = _values[0];
00540     double b = _values[1];
00541 
00542     HxComplex cp = HxComplex(1-b,a);
00543     HxComplex cm = HxComplex(1+b,-a);
00544 
00545     return HxComplex(0.5*(cp.arg().x()-cm.arg().x()),
00546         0.5*(::log(cm.abs().x())-::log(cp.abs().x())));
00547 }
00548 
00549 inline HxComplex
00550 HxComplex::sinh() const
00551 {
00552     return HxComplex(::sinh(_values[0])*::cos(_values[1]),
00553         ::cosh(_values[0])*::sin(_values[1]));
00554 }
00555 
00556 inline HxComplex
00557 HxComplex::cosh() const
00558 {
00559     return HxComplex(::cosh(_values[0])*::cos(_values[1]),
00560         ::sinh(_values[0])*::sin(_values[1]));
00561 }
00562 
00563 inline HxComplex
00564 HxComplex::tanh() const
00565 {
00566     double den = ::cosh(2*_values[0])+::cos(2*_values[1]);
00567 
00568     return HxComplex(::sinh(2*_values[0])/den, ::sin(2*_values[1])/den);
00569 }
00570 
00571 inline HxComplex
00572 HxComplex::exp() const
00573 {
00574     double ea = ::exp(_values[0]);
00575     return HxComplex(::cos(_values[1])*ea, ::sin(_values[1])*ea);
00576 }
00577 
00578 inline HxComplex
00579 HxComplex::log() const
00580 {
00581     double re = _values[0];
00582     double im = _values[1];
00583     double mag = ::sqrt(re*re+im*im);
00584 
00585     return HxComplex(::log(mag), ::atan(re/im));
00586 }
00587 
00588 const double theLog10 = 1./log(10.0);
00589 
00590 inline HxComplex
00591 HxComplex::log10() const
00592 {
00593     double re = _values[0];
00594     double im = _values[1];
00595     double mag = ::sqrt(re*re+im*im);
00596 
00597     return HxComplex(::log(mag)*theLog10, ::atan(re/im)*theLog10);
00598 }
00599 
00600 inline HxComplex&
00601 HxComplex::operator+=(const HxComplex& v)
00602 {
00603     _values[0] += v._values[0];
00604     _values[1] += v._values[1];
00605     return *this;
00606 }
00607 
00608 inline HxComplex&
00609 HxComplex::operator-=(const HxComplex& v)
00610 {
00611     _values[0] -= v._values[0];
00612     _values[1] -= v._values[1];
00613     return *this;
00614 }
00615 
00616 inline HxComplex&
00617 HxComplex::operator*=(const HxComplex& v)
00618 {
00619     double re = _values[0]*v._values[0] - _values[1]*v._values[1];
00620     double im = _values[0]*v._values[1] + _values[1]*v._values[0];
00621     _values[0] = re;
00622     _values[1] = im;
00623     return *this;
00624 }
00625 
00626 inline HxComplex&
00627 HxComplex::operator/=(const HxComplex& v)
00628 {
00629     double re = v._values[0];
00630     double im = v._values[1];
00631     double sq = re*re+im*im;
00632 
00633     double mulre = _values[0]*re + _values[1]*im;
00634     double mulim = _values[1]*re - _values[0]*im;
00635     _values[0] = mulre / sq;
00636     _values[1] = mulim / sq;
00637 
00638     return *this;
00639 }
00640 
00641 inline HxComplex
00642 operator+(const HxComplex& v1, const HxComplex& v2)
00643 {
00644     return HxComplex(v1._values[0] + v2._values[0],
00645                         v1._values[1] + v2._values[1]);
00646 }
00647 
00648 inline HxComplex
00649 operator-(const HxComplex& v1, const HxComplex& v2)
00650 {
00651     return HxComplex(v1._values[0] - v2._values[0],
00652                         v1._values[1] - v2._values[1]);
00653 }
00654 
00655 inline HxComplex
00656 operator*(const HxComplex& v1, const HxComplex& v2)
00657 {
00658     double re = v1._values[0]*v2._values[0] - v1._values[1]*v2._values[1];
00659     double im = v1._values[0]*v2._values[1] + v1._values[1]*v2._values[0];
00660 
00661     return HxComplex(re, im);
00662 }
00663 
00664 inline HxComplex
00665 operator/(const HxComplex& v1, const HxComplex& v2)
00666 {
00667     double re = v2._values[0];
00668     double im = v2._values[1];
00669     double sq = re*re+im*im;
00670 
00671     double mulre = v1._values[0]*re + v1._values[1]*im;
00672     double mulim = v1._values[1]*re - v1._values[0]*im;
00673 
00674     return HxComplex(mulre / sq, mulim / sq);
00675 }
00676 
00677 inline HxComplex
00678 HxComplex::min(const HxComplex& v) const
00679 {
00680     return (operator<(v)) ? (*this) : v;
00681 }
00682 
00683 inline HxComplex&
00684 HxComplex::minAssign(const HxComplex& v)
00685 {
00686     if (operator<(v))
00687         return *this;
00688     operator=(v);
00689     return *this;
00690 }
00691 
00692 inline HxComplex
00693 HxComplex::max(const HxComplex& v) const
00694 {
00695     return (operator>(v)) ? (*this) : v;
00696 }
00697 
00698 inline HxComplex&
00699 HxComplex::maxAssign(const HxComplex& v)
00700 {
00701     if (operator>(v))
00702         return *this;
00703     operator=(v);
00704     return *this;
00705 }
00706 
00707 inline HxComplex
00708 HxComplex::inf(const HxComplex& v) const
00709 {
00710     return HxComplex((_values[0] < v._values[0]) ? _values[0] : v._values[0],
00711                        (_values[1] < v._values[1]) ? _values[1] : v._values[1]);
00712 }
00713 
00714 inline HxComplex&
00715 HxComplex::infAssign(const HxComplex& v)
00716 {
00717     _values[0] = (_values[0] < v._values[0]) ? _values[0] : v._values[0];
00718     _values[1] = (_values[1] < v._values[1]) ? _values[1] : v._values[1];
00719     return *this;
00720 }
00721 
00722 inline HxComplex
00723 HxComplex::sup(const HxComplex& v) const
00724 {
00725     return HxComplex((_values[0] > v._values[0]) ? _values[0] : v._values[0],
00726                        (_values[1] > v._values[1]) ? _values[1] : v._values[1]);
00727 }
00728 
00729 inline HxComplex&
00730 HxComplex::supAssign(const HxComplex& v)
00731 {
00732     _values[0] = (_values[0] > v._values[0]) ? _values[0] : v._values[0];
00733     _values[1] = (_values[1] > v._values[1]) ? _values[1] : v._values[1];
00734     return *this;
00735 }
00736 
00737 inline HxComplex
00738 HxComplex::pow(const HxComplex& v) const
00739 {
00740     if (v._values[1] == 0) {
00741         double a = _values[0];
00742         double b = _values[1];
00743         double c = v._values[0];
00744         double sq = a*a+b*b;
00745         double arg = ::atan(b/a)*c;
00746         double mul = ::pow(sq, c/2)*::exp(a*c);
00747 
00748         return HxComplex(mul*::cos(arg), mul*::sin(arg));
00749     }
00750 
00751     return (v * (*this).log()).exp();
00752 }
00753 
00754 inline HxComplex
00755 HxComplex::mod(const HxComplex&) const
00756 {
00757     return (*this);
00758 }
00759 
00760 inline HxComplex
00761 HxComplex::and(const HxComplex&) const
00762 {
00763     return (*this);
00764 }
00765 
00766 inline HxComplex
00767 HxComplex::or(const HxComplex&) const
00768 {
00769     return (*this);
00770 }
00771 
00772 inline HxComplex
00773 HxComplex::xor(const HxComplex&) const
00774 {
00775     return (*this);
00776 }
00777 
00778 inline HxComplex
00779 HxComplex::leftShift(const HxComplex&) const
00780 {
00781     return (*this);
00782 }
00783 
00784 inline HxComplex
00785 HxComplex::rightShift(const HxComplex&) const
00786 {
00787     return (*this);
00788 }
00789 
00790 inline HxComplex
00791 HxComplex::cross(const HxComplex&) const
00792 {
00793     return HxComplex(0, 0);
00794 }
00795 
00796 inline HxComplex
00797 HxComplex::sum() const
00798 {
00799     return *this;
00800 }
00801 
00802 inline HxComplex
00803 HxComplex::product() const
00804 {
00805     return *this;
00806 }
00807 
00808 inline HxScalarDouble
00809 HxComplex::min() const
00810 {
00811     return (_values[0] < _values[1]) ? _values[0] : _values[1];
00812 }
00813 
00814 inline HxScalarDouble
00815 HxComplex::max() const
00816 {
00817     return (_values[0] > _values[1]) ? _values[0] : _values[1];
00818 }
00819 
00820 #endif

Generated on Tue Feb 3 14:18:33 2004 for C++Reference by doxygen1.2.12 written by Dimitri van Heesch, © 1997-2001