/*
Copyright (C) 2000-2004
Code contributed by Greg Collecutt, Joseph Hope and Paul Cochrane
This file is part of xmds.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/*
$Id: xmdscomplex.h,v 1.11 2004/10/21 09:41:33 paultcochrane Exp $
*/
/*! @file xmdscomplex.h
@brief Functions and overloads for fftw_complex types
*/
#include <math.h>
extern "C++" {
#include <iomanip>
// **********************************************
// rectangular complex and polar complex creation
// **********************************************
//! Rectangular complex object creation
inline fftw_complex rcomplex(const double& re, const double& im) {
fftw_complex z;
z.re = re;
z.im = im;
return z;
}
//! Polar complex object creation
inline fftw_complex pcomplex(const double& mag, const double& phase) {
fftw_complex z;
z.re = mag*cos(phase);
z.im = mag*sin(phase);
return z;
}
// **********************************************
// external fftw_complex overloads
// **********************************************
//! Overloaded complex addition operator
inline fftw_complex operator + (fftw_complex z) {
return z;
}
//! Overloaded complex addition operator
inline fftw_complex operator + (fftw_complex z1, const fftw_complex& z2) {
z1.re += z2.re;
z1.im += z2.im;
return z1;
}
//! Overloaded complex addition operator
inline fftw_complex operator + (fftw_complex z, const double& d) {
z.re += d;
return z;
}
//! Overloaded complex addition operator
inline fftw_complex operator + (const double& d, fftw_complex z) {
z.re += d;
return z;
}
//! Overloaded complex addition operator
inline fftw_complex operator + (fftw_complex z, const int& j) {
z.re += j;
return z;
}
//! Overloaded complex addition operator
inline fftw_complex operator + (const int& j, fftw_complex z) {
z.re += j;
return z;
}
//! Overloaded complex subtraction operator
inline fftw_complex operator - (fftw_complex z) {
z.im = -z.im;
z.re = -z.re;
return z;
}
//! Overloaded complex subtraction operator
inline fftw_complex operator - (fftw_complex z1, const fftw_complex& z2) {
z1.re -= z2.re;
z1.im -= z2.im;
return z1;
}
//! Overloaded complex subtraction operator
inline fftw_complex operator - (fftw_complex z, const double& d) {
z.re -= d;
return z;
}
//! Overloaded complex subtraction operator
inline fftw_complex operator - (const double& d, fftw_complex z) {
z.re = d-z.re;
z.im = -z.im;
return z;
}
//! Overloaded complex subtraction operator
inline fftw_complex operator - (fftw_complex z, const int& j) {
z.re -= j;
return z;
}
//! Overloaded complex subtraction operator
inline fftw_complex operator - (const int& j, fftw_complex z) {
z.re = j-z.re;
z.im = -z.im;
return z;
}
//! Overloaded complex multiplication operator
inline fftw_complex operator * (const fftw_complex& z1, const fftw_complex& z2) {
fftw_complex z;
z.re = z1.re*z2.re - z1.im*z2.im;
z.im = z1.im*z2.re + z1.re*z2.im;
return z;
}
//! Overloaded complex multiplication operator
inline fftw_complex operator * (fftw_complex z, const double& d) {
z.re *= d;
z.im *= d;
return z;
}
//! Overloaded complex multiplication operator
inline fftw_complex operator * (const double& d, fftw_complex z) {
z.re *= d;
z.im *= d;
return z;
}
//! Overloaded complex multiplication operator
inline fftw_complex operator * (fftw_complex z, const int& j) {
z.re *= j;
z.im *= j;
return z;
}
//! Overloaded complex multiplication operator
inline fftw_complex operator * (const int& j, fftw_complex z) {
z.re *= j;
z.im *= j;
return z;
}
//! Overloaded complex division operator
inline fftw_complex operator / (fftw_complex z1, const fftw_complex& z2) {
const double c = z2.re*z2.re + z2.im*z2.im;
const double temp = (z1.re*z2.re + z1.im*z2.im)/c;
z1.im = (z1.im*z2.re - z1.re*z2.im)/c;
z1.re = temp;
return z1;
}
//! Overloaded complex division operator
inline fftw_complex operator / (fftw_complex z, const double& d) {
z.re /= d;
z.im /= d;
return z;
}
//! Overloaded complex division operator
inline fftw_complex operator / (const double& d, fftw_complex z) {
double c = z.re*z.re + z.im*z.im;
z.re *= d/c;
z.im *= -d/c;
return z;
}
//! Overloaded complex division operator
inline fftw_complex operator / (fftw_complex z, const int& j) {
z.re /= j;
z.im /= j;
return z;
}
//! Overloaded complex division operator
inline fftw_complex operator / (const int& j, fftw_complex z) {
double c = z.re*z.re + z.im*z.im;
z.re *= j/c;
z.im *= -j/c;
return z;
}
//! Overloaded complex less than operator
inline bool operator < (const double& d, const fftw_complex& z) {
return d < z.re*z.re+z.im*z.im;
}
//! Overloaded complex greater than operator
inline bool operator > (const double& d, const fftw_complex& z) {
return d > z.re*z.re+z.im*z.im;
}
//! Overloaded complex less than or equal to operator
inline bool operator <= (const double& d, const fftw_complex& z) {
return d <= z.re*z.re+z.im*z.im;
}
//! Overloaded complex greater than or equal to operator
inline bool operator >= (const double& d, const fftw_complex& z) {
return d >= z.re*z.re+z.im*z.im;
}
//! Overloaded complex equality operator
inline bool operator == (const double& d, const fftw_complex& z) {
return d == z.re*z.re+z.im*z.im;
}
//! Overloaded complex inequality operator
inline bool operator != (const double& d, const fftw_complex& z) {
return d != z.re*z.re+z.im*z.im;
}
// **********************************************
// some unary complex functions
// **********************************************
//! Returns real part of a complex number
inline double real(const fftw_complex& z) {
return z.re;
}
//! Returns imaginary part of a complex number
inline double imag(const fftw_complex& z) {
return z.im;
}
//! Returns modulus squared of a complex number
inline double mod2(const fftw_complex& z) {
return z.re*z.re + z.im*z.im;
}
//! Returns modulus of a complex number
inline double mod(const fftw_complex& z) {
return sqrt(z.re*z.re + z.im*z.im);
}
//! Returns arg of a complex number
inline double arg(const fftw_complex& z) {
double _phi=0;
if(fabs(z.re)<1e-100) {
if(z.im>0)
_phi=M_PI/2;
else if(z.im<0)
_phi=-M_PI/2;
}
else {
_phi=atan(z.im/z.re);
if(z.re<0)
_phi += M_PI;
}
return _phi;
}
//! Returns the complex conjugate
inline fftw_complex conj(fftw_complex z) {
z.im = -z.im;
return z;
}
//! Returns the complex exponential
inline fftw_complex c_exp(const fftw_complex& z1) {
fftw_complex z;
z.re = exp(z1.re)*cos(z1.im);
z.im = exp(z1.re)*sin(z1.im);
return(z);
}
//! Returns the complex natural logarithm
inline fftw_complex c_log(const fftw_complex& z1) {
fftw_complex z;
double _m = mod(z1);
if(fabs(_m)>1e-100)
z.re = log(_m);
else
z.re = -46;
z.im = arg(z1);
return z;
}
//! Returns the complex square root
inline fftw_complex c_sqrt(const fftw_complex z1) {
const double _m = sqrt(mod(z1));
const double _a = arg(z1)/2;
return pcomplex(_m,_a);
}
// **********************************************
// a nice complex class
// **********************************************
//! A nice complex class
class complex : public fftw_complex {
public:
//Constructors
//! Constructor of complex object
complex() {
re = 0;
im = 0;
}
//! Constructor of complex object
/*!
This could be "explicit", providing extra warnings
*/
complex(const fftw_complex& z) {
re = z.re;
im = z.im;
}
//! Constructor of complex object
/*!
This could be "explicit", providing extra warnings
*/
complex(const double& d) {
re = d;
im = 0;
}
//! Constructor of complex object
complex(const double& real, const double& imag, const bool& polar=false) {
if (polar) {
re = real*cos(imag);
im = real*sin(imag);
}
else {
re = real;
im = imag;
}
}
//! Addition operator
inline complex& operator + () {
return *this;
}
//! Subtraction operator
inline complex& operator - () {
re = -re;
im = -im;
return *this;
}
//! Assignment operator
inline complex& operator = (const fftw_complex& z) {
re = z.re;
im = z.im;
return *this;
}
//! Assignment operator
inline complex& operator = (const double& d) {
re = d;
im = 0;
return *this;
}
//! Conversion to double operator
inline operator double() const {
return re;
}
//! += operator
inline complex& operator += (const fftw_complex& z) {
re += z.re;
im += z.im;
return *this;
}
//! += operator
inline complex& operator += (const double& d) {
re += d;
return *this;
}
//! -= operator
inline complex& operator -= (const fftw_complex& z) {
re -= z.re;
im -= z.im;
return *this;
}
//! -= operator
inline complex& operator -= (const double& d) {
re -= d;
return *this;
}
//! *= operator
inline complex& operator *= (const fftw_complex& z) {
const double temp = re*z.re - im*z.im;
im = im*z.re + re*z.im;
re = temp;
return *this;
}
//! *= operator
inline complex& operator *= (const double& d) {
re *= d;
im *= d;
return *this;
}
//! /= operator
inline complex& operator /= (const fftw_complex& z) {
const double c = z.re*z.re + z.im*z.im;
const double temp = (re*z.re + im*z.im)/c;
im = (im*z.re - re*z.im)/c;
re=temp;
return *this;
}
//! /= operator
inline complex& operator /= (const double& d) {
re /= d;
im /= d;
return *this;
}
//! /= operator
inline complex& operator /= (const int& j) {
re /= j;
im /= j;
return *this;
}
//! Less than comparison operator
inline bool operator < (const fftw_complex& z) const {
return re*re+im*im < z.re*z.re+z.im*z.im;
}
//! Less than comparison operator
inline bool operator < (const double& d) const {
return re*re+im*im < d;
}
//! Greater than comparison operator
inline bool operator > (const fftw_complex& z) const {
return re*re+im*im > z.re*z.re+z.im*z.im;
}
//! Greater than comparison operator
inline bool operator > (const double& d) const {
return re*re+im*im > d;
}
//! Less than or equal to comparison operator
inline bool operator <= (const fftw_complex& z) const {
return re*re+im*im <= z.re*z.re+z.im*z.im;
}
//! Less than or equal to comparison operator
inline bool operator <= (const double& d) const {
return re*re+im*im <= d;
}
//! Greater than or equal to comparison operator
inline bool operator >= (const fftw_complex& z) const {
return re*re+im*im >= z.re*z.re+z.im*z.im;
}
//! Greater than or equal to comparison operator
inline bool operator >= (const double& d) const {
return re*re+im*im >= d;
}
//! Equality comparison operator
inline bool operator == (const complex& z) const {
return re == z.re && im == z.im;
}
//! Equality comparison operator
inline bool operator == (const double& d) const {
return re == d && im == 0;
}
//! Inequality comparison operator
inline bool operator != (const complex& z) const {
return re!=z.re || im!=z.im;
}
//! Inequality comparison operator
inline bool operator != (const double& d) const {
return re!=d || im!=0;
}
//! Complex conjugate operator
/*!
We define operator ~ to be the complex conjugate
*/
inline complex operator ~ () const {
complex z = *this;
z.im = -z.im;
return z;
}
};
//! Define the complex number i
const complex i = complex(0, 1);
} // extern "C++"
syntax highlighted by Code2HTML, v. 0.9.1