casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
Complex.h
Go to the documentation of this file.
00001 //# Complex.h: Single and double precision complex numbers
00002 //# Copyright (C) 2000,2001,2002,2004
00003 //# Associated Universities, Inc. Washington DC, USA.
00004 //#
00005 //# This library is free software; you can redistribute it and/or modify it
00006 //# under the terms of the GNU Library General Public License as published by
00007 //# the Free Software Foundation; either version 2 of the License, or (at your
00008 //# option) any later version.
00009 //#
00010 //# This library is distributed in the hope that it will be useful, but WITHOUT
00011 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00012 //# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
00013 //# License for more details.
00014 //#
00015 //# You should have received a copy of the GNU Library General Public License
00016 //# along with this library; if not, write to the Free Software Foundation,
00017 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
00018 //#
00019 //# Correspondence concerning AIPS++ should be addressed as follows:
00020 //#        Internet email: aips2-request@nrao.edu.
00021 //#        Postal address: AIPS++ Project Office
00022 //#                        National Radio Astronomy Observatory
00023 //#                        520 Edgemont Road
00024 //#                        Charlottesville, VA 22903-2475 USA
00025 //#
00026 //# $Id: Complex.h 21130 2011-10-18 07:39:05Z gervandiepen $
00027 
00028 
00029 #ifndef CASA_COMPLEX_H
00030 #define CASA_COMPLEX_H
00031 
00032 
00033 //# Includes
00034 #include <casa/aips.h>
00035 #include <casa/BasicSL/Complexfwd.h>
00036 #include <casa/complex.h>
00037 
00038 namespace casa { //# NAMESPACE CASA - BEGIN
00039 
00040 // <summary>
00041 // Single and double precision complex numbers
00042 // </summary>
00043 // <reviewed reviewer="UNKNOWN" date="before2004/08/25" tests="" demos="">
00044 // </reviewed>
00045 
00046 // <synopsis>
00047 // The class <src>Complex</src> is a straight typedef as the 
00048 // standard library <src>complex<float></src>.
00049 //
00050 // In a similar way <src>DComplex</src> is typedef-ed as
00051 // <src>complex<double></src>.
00052 //
00053 // <linkto class=IComplex>IComplex</linkto> is defined as a specific class.
00054 // It is only used by the <src>FITS</src> classes.
00055 //
00056 // <src>lDComplex</src> has not been defined: <src>long double</src> is not
00057 // part of the standard aips++ data suite (yet)
00058 //
00059 // A set of global functions are added for historic reasons (they were present
00060 // in the original aips++/gcc complex implementation).
00061 //
00062 // See the standard library documentation for the expected behaviour of 
00063 // the <src>Complex</src> and <src>DComplex</src> classes.
00064 //
00065 // <note role=tip> In the following all references to <src>Complex</src>
00066 // can be replaced with <src>DComplex</src>. with simultaneous
00067 // replacement of <src>Float</src> with <src>Double</src>. </note>
00068 //
00069 // Complex numbers may be constructed and used in the following ways:
00070 // <dl>
00071 // <dt>Complex x;</dt>
00072 // <dd>  Declares an uninitialized Complex. </dd>
00073 // 
00074 // <dt>Complex x = 2; Complex y(2.0);</dt>
00075 // <dd>  Set x and y to the Complex value (2.0, 0.0); </dd>
00076 // 
00077 // <dt>Complex x(2, 3);</dt>
00078 // <dd>  Sets x to the Complex value (2, 3); </dd>
00079 // 
00080 // <dt>Complex u(x); Complex v = x;</dt>
00081 // <dd>  Set u and v to the same value as x. </dd>
00082 // 
00083 // <dt>Float real(Complex& x);</dt>
00084 // <dd>  returns the real part of x. </dd>
00085 // 
00086 // <dt>Float imag(Complex& x);</dt>
00087 // <dd>  returns the imaginary part of x. </dd>
00088 // 
00089 // <dt>Float abs(Complex& x);</dt>
00090 // <dd>  returns the magnitude of x. </dd>
00091 // 
00092 // <dt>Float norm(Complex& x);</dt>
00093 // <dd>  returns the square of the magnitude of x. </dd>
00094 // 
00095 // <dt>Float arg(Complex& x);</dt>
00096 // <dd>  returns the argument (amplitude) of x. </dd>
00097 // 
00098 // <dt>Complex polar(Float r, Float t = 0.0);</dt>
00099 // <dd>  returns a Complex with abs of r and arg of t. </dd>
00100 // 
00101 // <dt>Complex conj(Complex& x);</dt>
00102 // <dd>  returns the complex conjugate of x </dd>
00103 // 
00104 // <dt>Complex cos(Complex& x);</dt>
00105 // <dd>  returns the complex cosine of x. </dd>
00106 // 
00107 // <dt>Complex sin(Complex& x);</dt>
00108 // <dd>  returns the complex sine of x. </dd>
00109 // 
00110 // <dt>Complex cosh(Complex& x);</dt>
00111 // <dd>  returns the complex hyperbolic cosine of x. </dd>
00112 // 
00113 // <dt>Complex sinh(Complex& x);</dt>
00114 // <dd>  returns the complex hyperbolic sine of x. </dd>
00115 // 
00116 // <dt>Complex exp(Complex& x);</dt>
00117 // <dd>  returns the exponential of x. </dd>
00118 // 
00119 // <dt>Complex log(Complex& x);</dt>
00120 // <dd>  returns the natural log of x. </dd>
00121 // 
00122 // <dt>Complex pow(Complex& x, long p);</dt>
00123 // <dd>  returns x raised to the p power. </dd>
00124 // 
00125 // <dt>Complex pow(Complex& x, Complex& p);</dt>
00126 // <dd>  returns x raised to the p power. </dd>
00127 // 
00128 // <dt>Complex sqrt(Complex& x);</dt>
00129 // <dd>  returns the square root of x. </dd>
00130 // 
00131 // <dt> Complex min(Complex x,Complex y);
00132 // <dd> Returns the minumum of x,y (using operator<=, i.e. the norm).
00133 //
00134 // <dt> Complex max(Complex x,Complex y);
00135 // <dd> Returns the maximum of x,y (using operator>=, i.e. the norm).
00136 //
00137 // <dt>Bool near(Complex val1, Complex val2, Double tol = 1.0e-5);</dt>
00138 // <dd>  returns whether val1 is relatively near val2 (see Math.h).
00139 //      (Note the Double tolerance) </dd>
00140 //
00141 // <dt>Bool nearAbs(Complex val1, Complex val2, Double tol = 1.0e-5);</dt>
00142 // <dd>  returns whether val1 is absolutely near val2 (see Math.h).
00143 //      (Note the Double tolerance) </dd>
00144 //
00145 // <dt>ostream << x;</dt>
00146 // <dd>  prints x in the form (re, im). </dd>
00147 // 
00148 // <dt>istream >> x;</dt>
00149 //  <dd> reads x in the form (re, im), or just (re) or re in which case the
00150 //      imaginary part is set to zero. </dd>
00151 // </dl> 
00152 // </synopsis>
00153 
00154 //# <todo asof="2000/11/27">
00155 //# </todo>
00156 
00157 // <group name="Complex_desc">
00158 
00159 // <summary>Complex NaN and Infinity</summary>
00160 // <reviewed reviewer="UNKNOWN" date="before2004/08/25" tests="" demos="">
00161 // </reviewed>
00162 // <group name="Complex NaN and Infinity">
00163 Bool isNaN (const Complex& val);
00164 void setNaN(Complex& val);
00165 Bool isInf (const Complex& val);
00166 void setInf(Complex& val);
00167 Bool isFinite(const Complex& val);
00168 // </group>
00169 
00170 // <summary>Complex comparisons </summary>
00171 // <reviewed reviewer="UNKNOWN" date="before2004/08/25" tests="" demos="">
00172 // </reviewed>
00173 // <group name="Complex comparisons">
00174 //# On Linux comparing the norm does not work well in debug mode
00175 //# for equal values. Therefore they are compared for equality first.
00176 inline Bool operator>= (const Complex& left, const Complex& right)
00177   { return left==right  ?  True : norm(left) >= norm(right); }
00178 inline Bool operator>  (const Complex& left, const Complex& right)
00179   { return left==right  ?  False : norm(left) > norm(right); }
00180 inline Bool operator<= (const Complex& left, const Complex& right)
00181   { return left==right  ?  True : norm(left) <= norm(right); }
00182 inline Bool operator<  (const Complex& left, const Complex& right)
00183   { return left==right  ?  False : norm(left) < norm(right); }
00184 // </group>
00185 
00186 
00187 // <summary>DComplex NaN and Infinity</summary>
00188 // <reviewed reviewer="UNKNOWN" date="before2004/08/25" tests="" demos="">
00189 // </reviewed>
00190 // <group name="DComplex NaN and Infinity">
00191 Bool isNaN (const DComplex& val);
00192 void setNaN(DComplex& val);
00193 Bool isInf (const DComplex& val);
00194 void setInf(DComplex& val);
00195 Bool isFinite(const DComplex& val);
00196 // </group>
00197 
00198 // <summary> DComplex comparisons </summary>
00199 // <reviewed reviewer="UNKNOWN" date="before2004/08/25" tests="" demos="">
00200 // </reviewed>
00201 // <group name="DComplex comparisons">
00202 inline Bool operator>= (const DComplex& left, const DComplex& right)
00203   { return norm(left) >= norm(right); }
00204 inline Bool operator>  (const DComplex& left, const DComplex& right)
00205   { return norm(left) >  norm(right); }
00206 inline Bool operator<= (const DComplex& left, const DComplex& right)
00207   { return norm(left) <= norm(right); }
00208 inline Bool operator<  (const DComplex& left, const DComplex& right)
00209   { return norm(left) <  norm(right); }
00210 // </group>
00211 
00212 
00213 //# Global functions
00214 // <summary> Additional complex mathematical functions </summary>
00215 // <reviewed reviewer="UNKNOWN" date="before2004/08/25" tests="" demos="">
00216 // </reviewed>
00217 // <group name=math>
00218 inline Double fabs(const DComplex &val) { return std::abs(val); }
00219 inline Float fabs(const Complex &val) { return std::abs(val); }
00220 
00221 inline DComplex square(const DComplex &val) { return val*val; }
00222 inline Complex square(const Complex &val) { return val*val; }
00223 
00224 inline DComplex cube(const DComplex &val) { return val*val*val; }
00225 inline Complex cube(const Complex &val) { return val*val*val; }
00226 
00227 // The log10 should be in stl
00228 // <group>
00229 #if defined(NEEDS_LOG10_COMPLEX)
00230 Complex log10(const Complex &val);
00231 DComplex log10(const DComplex &val);
00232 #endif
00233 // </group>
00234 
00235 // ArrayMath::pow needs this pow function (on SGI).
00236 inline Complex pow(const Complex& val, Double p) { return std::pow(val,Float(p)); }
00237 
00238 // QMath and scimath need these operators * and / 
00239 // <group>
00240 inline Complex operator*(const Complex& val, Double f) { return val*Float(f); }
00241 inline Complex operator*(Double f, const Complex& val) { return val*Float(f); }
00242 inline Complex operator/(const Complex& val, Double f) { return val/Float(f); }
00243 inline Complex operator/(Double f, const Complex& val) { return Float(f)/val; }
00244 // </group>
00245 // These operators are useful, otherwise both Float and Double are applicable
00246 // for Ints.
00247 // <group>
00248 inline Complex operator*(const Complex& val, Int f) { return val*Float(f); }
00249 inline Complex operator*(Int f, const Complex& val) { return val*Float(f); }
00250 inline Complex operator/(const Complex& val, Int f) { return val/Float(f); }
00251 inline Complex operator/(Int f, const Complex& val) { return Float(f)/val; }
00252 // </group>
00253 // </group>
00254 
00255 // <summary> The near functions </summary>
00256 // <reviewed reviewer="UNKNOWN" date="before2004/08/25" tests="" demos="">
00257 // </reviewed>
00258 // <group name=near>
00259 Bool near(const Complex &val1, const Complex &val2, Double tol=1.0e-5);
00260 Bool near(const DComplex &val1, const DComplex &val2, Double tol=1.0e-13);
00261 Bool nearAbs(const Complex &val1, const Complex &val2, Double tol=1.0e-5);
00262 Bool nearAbs(const DComplex &val1, const DComplex &val2, Double tol=1.0e-13);
00263 inline Bool allNear(const Complex &val1, const Complex &val2,
00264                     Double tol=1.0e-5)
00265   { return near(val1, val2, tol); }
00266 inline Bool allNear(const DComplex &val1, const DComplex &val2, 
00267                     Double tol=1.0e-13)
00268   { return near(val1, val2, tol); }
00269 inline Bool allNearAbs(const Complex &val1, const Complex &val2, 
00270                        Double tol=1.0e-5)
00271   { return nearAbs(val1, val2, tol); }
00272 inline Bool allNearAbs(const DComplex &val1, const DComplex &val2, 
00273                        Double tol=1.0e-13)
00274   { return nearAbs(val1, val2, tol); }
00275 // </group>
00276 
00277 // <summary> Max and min, floor and ceil functions </summary>
00278 // <reviewed reviewer="UNKNOWN" date="before2004/08/25" tests="" demos="">
00279 // </reviewed>
00280 // <group name=maxmin>
00281 inline Complex max(const Complex &x, const Complex &y)
00282   { return x >= y ? x : y; }
00283 inline DComplex max(const DComplex &x, const DComplex &y)
00284   { return x >= y ? x : y; }
00285 
00286 inline Complex min(const Complex &x, const Complex &y)
00287   { return x <= y ? x : y; }
00288 inline DComplex min(const DComplex &x, const DComplex &y)
00289   { return x <= y ? x : y; }
00290 
00291 inline Complex floor(const Complex &x) {
00292   return Complex(std::floor(x.real()), std::floor(x.imag())); }
00293 inline DComplex floor(const DComplex &x) {
00294   return DComplex(std::floor(x.real()), std::floor(x.imag())); }
00295 
00296 inline Complex ceil(const Complex &x) {
00297   return Complex(std::ceil(x.real()), std::ceil(x.imag())); }
00298 inline DComplex ceil(const DComplex &x) {
00299   return DComplex(std::ceil(x.real()), std::ceil(x.imag())); }
00300 // </group>
00301 
00302 // <summary> fmod </summary>
00303 // <reviewed reviewer="UNKNOWN" date="before2004/08/25" tests="" demos="">
00304 // </reviewed>
00305 // <group name=fmod>
00306 DComplex fmod(const DComplex &in, const DComplex &f);
00307 Complex fmod(const Complex &in, const Complex &f);
00308 // </group>
00309 
00310 // <summary> Inverse trigonometry </summary>
00311 // <reviewed reviewer="UNKNOWN" date="before2004/08/25" tests="" demos="">
00312 // </reviewed>
00313 // <group name=inverse>
00314 // atan not valid for z == -1
00315 DComplex atan(const DComplex &in);
00316 Complex atan(const Complex &in);
00317 DComplex asin(const DComplex &in);
00318 Complex asin(const Complex &in);
00319 DComplex acos(const DComplex &in);
00320 Complex acos(const Complex &in);
00321 DComplex atan2(const DComplex &in, const DComplex &t2);
00322 Complex atan2(const Complex &in, const Complex &t2);
00323 // </group>
00324 
00325 // <summary> Error function </summary>
00326 // <reviewed reviewer="UNKNOWN" date="before2004/08/25" tests="" demos="">
00327 // </reviewed>
00328 // <group name=erf>
00329 // Preliminary to get Functionals working. erf(z) will return erf(real(z))
00330 // only for now.
00331 DComplex erf(const DComplex &in);
00332 Complex erf(const Complex &in);
00333 DComplex erfc(const DComplex &in);
00334 Complex erfc(const Complex &in);
00335 // </group>
00336 
00337 // </group>
00338 
00339 } //# NAMESPACE CASA - END
00340 
00341 // Define real & complex conjugation for non-complex types
00342 // and put comparisons into std namespace.
00343 namespace std { 
00344   inline float  conj(float  x) { return x; }
00345   inline double conj(double x) { return x; }
00346   inline float  real(float  x) { return x; }
00347   inline double real(double x) { return x; }
00348   inline float  imag(float   ) { return 0; }
00349   inline double imag(double  ) { return 0; }
00350   
00351   using casa::operator>;
00352   using casa::operator>=;
00353   using casa::operator<;
00354   using casa::operator<=;
00355 }
00356 
00357 #endif