502 lines
12 KiB
Plaintext
502 lines
12 KiB
Plaintext
///////////////////////////////////////////////////////////////////////////
|
|
// FILE: complex (Complex numbers)
|
|
//
|
|
// =========================================================================
|
|
//
|
|
// Open Watcom Project
|
|
//
|
|
// Copyright (c) 2004-2010 The Open Watcom Contributors. All Rights Reserved.
|
|
//
|
|
// This file is automatically generated. Do not edit directly.
|
|
//
|
|
// =========================================================================
|
|
//
|
|
// Description: This header is part of the C++ standard library. It
|
|
// provides support for complex numbers with varying levels
|
|
// of precision.
|
|
///////////////////////////////////////////////////////////////////////////
|
|
#ifndef _COMPLEX_INCLUDED
|
|
#define _COMPLEX_INCLUDED
|
|
|
|
#ifndef _ENABLE_AUTODEPEND
|
|
#pragma read_only_file;
|
|
#endif
|
|
|
|
#ifndef __cplusplus
|
|
#error This header file requires C++
|
|
#endif
|
|
|
|
#ifndef _CMATH_INCLUDED
|
|
#include <cmath>
|
|
#endif
|
|
|
|
namespace std {
|
|
|
|
template< class FloatT >
|
|
class complex {
|
|
public:
|
|
typedef FloatT value_type;
|
|
|
|
complex( const FloatT &r = FloatT( ), const FloatT &i = FloatT( ) ) :
|
|
re( r ), im( i )
|
|
{ }
|
|
|
|
FloatT real( ) const { return( re ); }
|
|
FloatT imag( ) const { return( im ); }
|
|
|
|
complex &operator= ( const FloatT & );
|
|
complex &operator+=( const FloatT & );
|
|
complex &operator-=( const FloatT & );
|
|
complex &operator*=( const FloatT & );
|
|
complex &operator/=( const FloatT & );
|
|
|
|
complex &operator= ( const complex & );
|
|
complex &operator+=( const complex & );
|
|
complex &operator-=( const complex & );
|
|
complex &operator*=( const complex & );
|
|
complex &operator/=( const complex & );
|
|
|
|
private:
|
|
FloatT re;
|
|
FloatT im;
|
|
};
|
|
|
|
//
|
|
// Complex members.
|
|
//
|
|
|
|
template< class FloatT >
|
|
inline
|
|
complex< FloatT > &complex< FloatT >::operator=( const FloatT &num )
|
|
{
|
|
re = num;
|
|
im = FloatT( );
|
|
return( *this );
|
|
}
|
|
|
|
template< class FloatT >
|
|
inline
|
|
complex< FloatT > &complex< FloatT >::operator+=( const FloatT &num )
|
|
{
|
|
re += num;
|
|
return( *this );
|
|
}
|
|
|
|
template< class FloatT >
|
|
inline
|
|
complex< FloatT > &complex< FloatT >::operator-=( const FloatT &num )
|
|
{
|
|
re -= num;
|
|
return( *this );
|
|
}
|
|
|
|
template< class FloatT >
|
|
inline
|
|
complex< FloatT > &complex< FloatT >::operator*=( const FloatT &num )
|
|
{
|
|
re *= num;
|
|
im *= num;
|
|
return( *this );
|
|
}
|
|
|
|
template< class FloatT >
|
|
inline
|
|
complex< FloatT > &complex< FloatT >::operator/=( const FloatT &num )
|
|
{
|
|
re /= num;
|
|
im /= num;
|
|
return( *this );
|
|
}
|
|
|
|
template< class FloatT >
|
|
inline
|
|
complex< FloatT > &complex< FloatT >::operator=( const complex &num )
|
|
{
|
|
re = num.re;
|
|
im = num.im;
|
|
return( *this );
|
|
}
|
|
|
|
template< class FloatT >
|
|
inline
|
|
complex< FloatT > &complex< FloatT >::operator+=( const complex &num )
|
|
{
|
|
re += num.re;
|
|
im += num.im;
|
|
return( *this );
|
|
}
|
|
|
|
template< class FloatT >
|
|
inline
|
|
complex< FloatT > &complex< FloatT >::operator-=( const complex &num )
|
|
{
|
|
re -= num.re;
|
|
im -= num.im;
|
|
return( *this );
|
|
}
|
|
|
|
template< class FloatT >
|
|
inline
|
|
complex< FloatT > &complex< FloatT >::operator*=( const complex &num )
|
|
{
|
|
FloatT new_re( re * num.re - im * num.im );
|
|
FloatT new_im( re * num.im + im * num.re );
|
|
re = new_re;
|
|
im = new_im;
|
|
return( *this );
|
|
}
|
|
|
|
template< class FloatT >
|
|
inline
|
|
complex< FloatT > &complex< FloatT >::operator/=( const complex &num )
|
|
{
|
|
FloatT denom( num.re * num.re + num.im * num.im );
|
|
FloatT new_re( re * num.re + im * num.im );
|
|
FloatT new_im( im * num.re - re * num.im );
|
|
re = new_re / denom;
|
|
im = new_im / denom;
|
|
return( *this );
|
|
}
|
|
|
|
//
|
|
// Complex non-members.
|
|
//
|
|
|
|
template< class FloatT >
|
|
inline
|
|
complex< FloatT > operator+( const complex< FloatT > &x )
|
|
{
|
|
return( x );
|
|
}
|
|
|
|
template< class FloatT >
|
|
inline
|
|
complex< FloatT > operator+(
|
|
const complex< FloatT > &x,
|
|
const complex< FloatT > &y )
|
|
{
|
|
complex< FloatT > temp( x );
|
|
temp += y;
|
|
return( temp );
|
|
}
|
|
|
|
template< class FloatT >
|
|
inline
|
|
complex< FloatT > operator+( const complex< FloatT > &x, const FloatT &y )
|
|
{
|
|
complex< FloatT > temp( x );
|
|
temp += y;
|
|
return( temp );
|
|
}
|
|
|
|
template< class FloatT >
|
|
inline
|
|
complex< FloatT > operator+( const FloatT &x, const complex< FloatT > &y )
|
|
{
|
|
complex< FloatT > temp( x );
|
|
temp += y;
|
|
return( temp );
|
|
}
|
|
|
|
template< class FloatT >
|
|
inline
|
|
complex< FloatT > operator-( const complex< FloatT > &x )
|
|
{
|
|
return( complex< FloatT >( -x.real( ), -x.imag( ) ) );
|
|
}
|
|
|
|
template< class FloatT >
|
|
inline
|
|
complex< FloatT > operator-(
|
|
const complex< FloatT > &x,
|
|
const complex< FloatT > &y )
|
|
{
|
|
complex< FloatT > temp( x );
|
|
temp -= y;
|
|
return( temp );
|
|
}
|
|
|
|
template< class FloatT >
|
|
inline
|
|
complex< FloatT > operator-( const complex< FloatT > &x, const FloatT &y )
|
|
{
|
|
complex< FloatT > temp( x );
|
|
temp -= y;
|
|
return( temp );
|
|
}
|
|
|
|
template< class FloatT >
|
|
inline
|
|
complex< FloatT > operator-( const FloatT &x, const complex< FloatT > &y )
|
|
{
|
|
complex< FloatT > temp( x );
|
|
temp -= y;
|
|
return( temp );
|
|
}
|
|
|
|
template< class FloatT >
|
|
inline
|
|
complex< FloatT > operator*(
|
|
const complex< FloatT > &x,
|
|
const complex< FloatT > &y )
|
|
{
|
|
complex< FloatT > temp( x );
|
|
temp *= y;
|
|
return( temp );
|
|
}
|
|
|
|
template< class FloatT >
|
|
inline
|
|
complex< FloatT > operator*( const complex< FloatT > &x, const FloatT &y )
|
|
{
|
|
complex< FloatT > temp( x );
|
|
temp *= y;
|
|
return( temp );
|
|
}
|
|
|
|
template< class FloatT >
|
|
inline
|
|
complex< FloatT > operator*( const FloatT &x, const complex< FloatT > &y )
|
|
{
|
|
complex< FloatT > temp( x );
|
|
temp *= y;
|
|
return( temp );
|
|
}
|
|
|
|
template< class FloatT >
|
|
inline
|
|
complex< FloatT > operator/(
|
|
const complex< FloatT > &x,
|
|
const complex< FloatT > &y )
|
|
{
|
|
complex< FloatT > temp( x );
|
|
temp /= y;
|
|
return( temp );
|
|
}
|
|
|
|
template< class FloatT >
|
|
inline
|
|
complex< FloatT > operator/( const complex< FloatT > &x, const FloatT &y )
|
|
{
|
|
complex< FloatT > temp( x );
|
|
temp /= y;
|
|
return( temp );
|
|
}
|
|
|
|
template< class FloatT >
|
|
inline
|
|
complex< FloatT > operator/( const FloatT &x, const complex< FloatT > &y )
|
|
{
|
|
complex< FloatT > temp( x );
|
|
temp /= y;
|
|
return( temp );
|
|
}
|
|
|
|
template< class FloatT >
|
|
inline
|
|
bool operator==( const complex< FloatT > &x, const complex< FloatT > &y )
|
|
{
|
|
return( ( x.real( ) == y.real( ) ) && ( x.imag( ) == y.imag( ) ) );
|
|
}
|
|
|
|
template< class FloatT >
|
|
inline
|
|
complex< FloatT > operator==( const complex< FloatT > &x, const FloatT &y )
|
|
{
|
|
return( ( x.real( ) == y ) && ( x.imag( ) == FloatT( ) ) );
|
|
}
|
|
|
|
template< class FloatT >
|
|
inline
|
|
complex< FloatT > operator==( const FloatT &x, const complex< FloatT > &y )
|
|
{
|
|
return( ( x == y.real( ) ) && ( FloatT( ) == y.imag( ) ) );
|
|
}
|
|
|
|
template< class FloatT >
|
|
inline
|
|
bool operator!=( const complex< FloatT > &x, const complex< FloatT > &y )
|
|
{
|
|
return( ( x.real( ) != y.real( ) ) || ( x.imag( ) != y.imag( ) ) );
|
|
}
|
|
|
|
template< class FloatT >
|
|
inline
|
|
complex< FloatT > operator!=( const complex< FloatT > &x, const FloatT &y )
|
|
{
|
|
return( ( x.real( ) != y ) || ( x.imag( ) != FloatT( ) ) );
|
|
}
|
|
|
|
template< class FloatT >
|
|
inline
|
|
complex< FloatT > operator!=( const FloatT &x, const complex< FloatT > &y )
|
|
{
|
|
return( ( x != y.real( ) ) || ( FloatT( ) != y.imag( ) ) );
|
|
}
|
|
|
|
template< class FloatT >
|
|
inline
|
|
FloatT real( const complex< FloatT > &x )
|
|
{
|
|
return( x.real( ) );
|
|
}
|
|
|
|
template< class FloatT >
|
|
inline
|
|
FloatT imag( const complex< FloatT > &x )
|
|
{
|
|
return( x.imag( ) );
|
|
}
|
|
|
|
template< class FloatT >
|
|
inline
|
|
FloatT abs( const complex< FloatT > &x )
|
|
{
|
|
return( sqrt( x.real( ) * x.real( ) + x.imag( ) * x.imag( ) ) );
|
|
}
|
|
|
|
template< class FloatT >
|
|
inline
|
|
FloatT arg( const complex< FloatT > &x )
|
|
{
|
|
return( atan2( x.imag( ), x.real( ) ) );
|
|
}
|
|
|
|
template< class FloatT >
|
|
inline
|
|
FloatT norm( const complex< FloatT > &x )
|
|
{
|
|
return( x.real( ) * x.real( ) + x.imag( ) * x.imag( ) );
|
|
}
|
|
|
|
template< class FloatT >
|
|
inline
|
|
complex< FloatT > conj( const complex< FloatT > &x )
|
|
{
|
|
return( complex< FloatT >( x.real( ), -x.imag( ) ) );
|
|
}
|
|
|
|
template< class FloatT >
|
|
inline
|
|
complex< FloatT > polar( const FloatT &rho, const FloatT &theta )
|
|
{
|
|
return( complex< FloatT >( rho * cos( theta ), rho * sin( theta ) ) );
|
|
}
|
|
|
|
template< class FloatT >
|
|
complex< FloatT > cos( const complex< FloatT > &x )
|
|
{
|
|
return( complex< FloatT >( cos( x.real( ) ) * cosh( x.imag( ) ),
|
|
-sin( x.real( ) ) * sinh( x.imag( ) ) ) );
|
|
}
|
|
|
|
template< class FloatT >
|
|
complex< FloatT > cosh( const complex< FloatT > &x )
|
|
{
|
|
return( complex< FloatT >( cosh( x.real( ) ) * cos( x.imag( ) ),
|
|
sinh( x.real( ) ) * sin( x.imag( ) ) ) );
|
|
}
|
|
|
|
template< class FloatT >
|
|
complex< FloatT > exp( const complex< FloatT > &x )
|
|
{
|
|
FloatT multiplier( exp( x.real( ) ) );
|
|
return( complex< FloatT >( multiplier * cos( x.imag( ) ),
|
|
multiplier * sin( x.imag( ) ) ) );
|
|
}
|
|
|
|
template< class FloatT >
|
|
complex< FloatT > log( const complex< FloatT > &x )
|
|
{
|
|
FloatT mag_rp( abs( x.real( ) ) );
|
|
FloatT mag_ip( abs( x.imag( ) ) );
|
|
|
|
// Handle cases when mag_rp and mag_ip are very different.
|
|
if( mag_rp > 32 * mag_ip ) {
|
|
FloatT temp1( x.imag( ) / x.real( ) );
|
|
FloatT temp2( 1.0 + ( temp1 * temp1 ) );
|
|
return( complex< FloatT >( log( mag_rp ) + 0.5 * log( temp2 ),
|
|
atan2( x.imag( ), x.real( ) ) ) );
|
|
}
|
|
else if( mag_ip > 32 * mag_rp ) {
|
|
FloatT temp1( x.real( ) / x.imag( ) );
|
|
FloatT temp2( 1.0 + ( temp1 * temp1 ) );
|
|
return( complex< FloatT >( log( mag_ip ) + 0.5 * log( temp2 ),
|
|
atan2( x.imag( ), x.real( ) ) ) );
|
|
}
|
|
|
|
// Otherwise use the direct expression.
|
|
return( complex< FloatT >( 0.5 * log( x.real( ) * x.real( ) +
|
|
x.imag( ) * x.imag( ) ),
|
|
atan2( x.imag( ), x.real( ) ) ) );
|
|
}
|
|
|
|
template< class FloatT >
|
|
complex< FloatT > log10( const complex< FloatT > &x )
|
|
{
|
|
FloatT ten( 10.0 ); // So overload resolution chooses right log.
|
|
return( log( x ) / log( ten ) );
|
|
}
|
|
|
|
template< class FloatT >
|
|
complex< FloatT > pow( const complex< FloatT > &x, int y )
|
|
{
|
|
return( exp( static_cast< FloatT >( y ) * log( x ) ) );
|
|
}
|
|
|
|
template< class FloatT >
|
|
complex< FloatT > pow(
|
|
const complex< FloatT > &x, const complex< FloatT > &y )
|
|
{
|
|
return( exp( y * log( x ) ) );
|
|
}
|
|
|
|
template< class FloatT >
|
|
complex< FloatT > pow( const complex< FloatT > &x, const FloatT &y )
|
|
{
|
|
return( exp( y * log( x ) ) );
|
|
}
|
|
|
|
template< class FloatT >
|
|
complex< FloatT > pow( const FloatT &x, const complex< FloatT > &y )
|
|
{
|
|
return( exp( y * log( x ) ) );
|
|
}
|
|
|
|
template< class FloatT >
|
|
complex< FloatT > sin( const complex< FloatT > &x )
|
|
{
|
|
return( complex< FloatT >( sin( x.real( ) ) * cosh( x.imag( ) ),
|
|
cos( x.real( ) ) * sinh( x.imag( ) ) ) );
|
|
}
|
|
|
|
template< class FloatT >
|
|
complex< FloatT > sinh( const complex< FloatT > &x )
|
|
{
|
|
return( complex< FloatT >( sinh( x.real( ) ) * cos( x.imag( ) ),
|
|
cosh( x.real( ) ) * sin( x.imag( ) ) ) );
|
|
}
|
|
|
|
template< class FloatT >
|
|
complex< FloatT > sqrt( const complex< FloatT > &x )
|
|
{
|
|
return( complex< FloatT >( polar( sqrt( abs( x ) ),
|
|
arg( x ) / 2 ) ) );
|
|
}
|
|
|
|
template< class FloatT >
|
|
complex< FloatT > tan( const complex< FloatT > &x )
|
|
{
|
|
return( sin( x ) / cos( x ) );
|
|
}
|
|
|
|
template< class FloatT >
|
|
complex< FloatT > tanh( const complex< FloatT > &x )
|
|
{
|
|
return( sinh( x ) / cosh( x ) );
|
|
}
|
|
|
|
} // namespace std
|
|
|
|
#endif
|