casa
$Rev:20696$
|
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