core/vnl/vnl_complex.h
Go to the documentation of this file.
00001 // This is core/vnl/vnl_complex.h
00002 #ifndef vnl_complex_h_
00003 #define vnl_complex_h_
00004 #ifdef VCL_NEEDS_PRAGMA_INTERFACE
00005 #pragma interface
00006 #endif
00007 //:
00008 // \file
00009 // \brief Complex additions to vnl_math.
00010 //
00011 // We don't want everyone to pay for complex when they don't need it, as
00012 // its ratio of expense to frequency of use is high. So we define those
00013 // functions from vnl_math which use complex here instead.
00014 // In a sense, vnl_math should be a namespace, and this file adds to that
00015 // namespace.
00016 //
00017 // \verbatim
00018 //  Modifications
00019 //   LSB (Manchester) 26/3/01 Tidied documentation
00020 // \endverbatim
00021 
00022 #include <vcl_cmath.h> // for sqrt(double)
00023 #include <vcl_complex.h>
00024 #include <vcl_iosfwd.h>
00025 #include <vnl/vnl_math.h>
00026 
00027 // these function could have been templated, if not for the
00028 // broken overload resolution of SGI CC 7.2.x -- fsm
00029 
00030 #define macro(T) \
00031 inline bool vnl_math_isnan(vcl_complex<T >const& z){return vnl_math_isnan(vcl_real(z)) || vnl_math_isnan(vcl_imag(z));} \
00032 inline bool vnl_math_isfinite(vcl_complex<T >const& z){return vnl_math_isfinite(vcl_real(z)) && vnl_math_isfinite(vcl_imag(z));} \
00033 inline T vnl_math_abs(vcl_complex<T > const& z) { return vcl_abs(z); } \
00034 inline vcl_complex<T > vnl_math_sqr(vcl_complex<T > const& z) { return z*z; } \
00035 inline T vnl_math_squared_magnitude(vcl_complex<T > const& z) { return vcl_norm(z); }
00036 macro(float)
00037 macro(double)
00038 macro(long double)
00039 #undef macro
00040 
00041 #if 0
00042 // isinf
00043 template <class T> inline
00044 bool vnl_math_isinf(const vcl_complex<T>& z)
00045 {
00046   return vnl_math_isinf(vcl_real(z)) || vnl_math_isinf(vcl_imag(z));
00047 }
00048 #endif
00049 
00050 #ifdef NEED_COMPLEX_BIGNUM // should never be defined ;-)
00051 
00052 #include <vnl/vnl_bignum.h>
00053 
00054 inline bool vnl_math_isnan(vcl_complex<vnl_bignum> const& ) { return false; }
00055 inline bool vnl_math_isfinite(vcl_complex<vnl_bignum> const&) { return true; }
00056 inline vnl_bignum vnl_math_squared_magnitude(vcl_complex<vnl_bignum> const& z) { return vcl_norm(z); }
00057 inline vnl_bignum vnl_math_abs(vcl_complex<vnl_bignum> const& z) { return vcl_sqrt(double(vcl_norm(z))); }
00058 inline vcl_complex<vnl_bignum> vnl_math_sqr(vcl_complex<vnl_bignum> const& z) { return z*z; }
00059 inline vcl_ostream& operator<<(vcl_ostream& s, vcl_complex<vnl_bignum> const& z)
00060 { return s << '(' << z.real() << ',' << z.imag() << ')'; }
00061 inline vcl_istream& operator>>(vcl_istream& s, vcl_complex<vnl_bignum>& z)
00062 { vnl_bignum r, i; s >> r >> i; z=vcl_complex<vnl_bignum>(r,i); return s; }
00063 
00064 #endif // NEED_COMPLEX_BIGNUM
00065 
00066 #ifdef NEED_COMPLEX_RATIONAL // should probably not be defined ;-)
00067 
00068 #include <vnl/vnl_rational.h>
00069 
00070 inline bool vnl_math_isnan(vcl_complex<vnl_rational> const& z)
00071 { return vnl_math_isnan(vcl_real(z)) || vnl_math_isnan(vcl_imag(z)); }
00072 inline bool vnl_math_isfinite(vcl_complex<vnl_rational> const& z)
00073 { return vnl_math_isfinite(vcl_real(z)) && vnl_math_isfinite(vcl_imag(z)); }
00074 inline vnl_rational vnl_math_squared_magnitude(vcl_complex<vnl_rational> const& z) { return vcl_norm(z); }
00075 inline vnl_rational vnl_math_abs(vcl_complex<vnl_rational> const& z) { return vcl_sqrt(double(vcl_norm(z))); }
00076 inline vcl_complex<vnl_rational> vnl_math_sqr(vcl_complex<vnl_rational> const& z) { return z*z; }
00077 inline vcl_ostream& operator<< (vcl_ostream& s, vcl_complex<vnl_rational> const& z)
00078 { return s << '(' << z.real() << ',' << z.imag() << ')'; }
00079 inline vcl_istream& operator>> (vcl_istream& s, vcl_complex<vnl_rational>& z)
00080 { vnl_rational r, i; s >> r >> i; z=vcl_complex<vnl_rational>(r,i); return s; }
00081 
00082 #endif // NEED_COMPLEX_RATIONAL
00083 
00084 #endif // vnl_complex_h_