410 lines
12 KiB
Plaintext
410 lines
12 KiB
Plaintext
|
// TR1 complex -*- C++ -*-
|
||
|
|
||
|
// Copyright (C) 2006 Free Software Foundation, Inc.
|
||
|
//
|
||
|
// This file is part of the GNU ISO C++ Library. This library 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, or (at your option)
|
||
|
// any later version.
|
||
|
|
||
|
// This library 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 library; see the file COPYING. If not, write to the Free
|
||
|
// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||
|
// USA.
|
||
|
|
||
|
// As a special exception, you may use this file as part of a free software
|
||
|
// library without restriction. Specifically, if other files instantiate
|
||
|
// templates or use macros or inline functions from this file, or you compile
|
||
|
// this file and link it with other files to produce an executable, this
|
||
|
// file does not by itself cause the resulting executable to be covered by
|
||
|
// the GNU General Public License. This exception does not however
|
||
|
// invalidate any other reasons why the executable file might be covered by
|
||
|
// the GNU General Public License.
|
||
|
|
||
|
/** @file tr1/complex
|
||
|
* This is a TR1 C++ Library header.
|
||
|
*/
|
||
|
|
||
|
#ifndef _TR1_COMPLEX
|
||
|
#define _TR1_COMPLEX 1
|
||
|
|
||
|
#include "../complex"
|
||
|
#include <tr1/common.h>
|
||
|
|
||
|
// namespace std::tr1
|
||
|
namespace std
|
||
|
{
|
||
|
_GLIBCXX_BEGIN_NAMESPACE(tr1)
|
||
|
|
||
|
// Forward declarations.
|
||
|
template<typename _Tp> std::complex<_Tp> acos(const std::complex<_Tp>&);
|
||
|
template<typename _Tp> std::complex<_Tp> asin(const std::complex<_Tp>&);
|
||
|
template<typename _Tp> std::complex<_Tp> atan(const std::complex<_Tp>&);
|
||
|
|
||
|
template<typename _Tp> std::complex<_Tp> acosh(const std::complex<_Tp>&);
|
||
|
template<typename _Tp> std::complex<_Tp> asinh(const std::complex<_Tp>&);
|
||
|
template<typename _Tp> std::complex<_Tp> atanh(const std::complex<_Tp>&);
|
||
|
template<typename _Tp> std::complex<_Tp> fabs(const std::complex<_Tp>&);
|
||
|
|
||
|
/// @brief acos(__z) [8.1.2].
|
||
|
// Effects: Behaves the same as C99 function cacos, defined
|
||
|
// in subclause 7.3.5.1.
|
||
|
template<typename _Tp>
|
||
|
inline std::complex<_Tp>
|
||
|
__complex_acos(const std::complex<_Tp>& __z)
|
||
|
{
|
||
|
const std::complex<_Tp> __t = std::tr1::asin(__z);
|
||
|
const _Tp __pi_2 = 1.5707963267948966192313216916397514L;
|
||
|
return std::complex<_Tp>(__pi_2 - __t.real(), -__t.imag());
|
||
|
}
|
||
|
|
||
|
#if _GLIBCXX_USE_C99_COMPLEX_TR1
|
||
|
inline __complex__ float
|
||
|
__complex_acos(__complex__ float __z)
|
||
|
{ return __builtin_cacosf(__z); }
|
||
|
|
||
|
inline __complex__ double
|
||
|
__complex_acos(__complex__ double __z)
|
||
|
{ return __builtin_cacos(__z); }
|
||
|
|
||
|
inline __complex__ long double
|
||
|
__complex_acos(const __complex__ long double& __z)
|
||
|
{ return __builtin_cacosl(__z); }
|
||
|
|
||
|
template<typename _Tp>
|
||
|
inline std::complex<_Tp>
|
||
|
acos(const std::complex<_Tp>& __z)
|
||
|
{ return __complex_acos(__z.__rep()); }
|
||
|
#else
|
||
|
template<typename _Tp>
|
||
|
inline std::complex<_Tp>
|
||
|
acos(const std::complex<_Tp>& __z)
|
||
|
{ return __complex_acos(__z); }
|
||
|
#endif
|
||
|
|
||
|
/// @brief asin(__z) [8.1.3].
|
||
|
// Effects: Behaves the same as C99 function casin, defined
|
||
|
// in subclause 7.3.5.2.
|
||
|
template<typename _Tp>
|
||
|
inline std::complex<_Tp>
|
||
|
__complex_asin(const std::complex<_Tp>& __z)
|
||
|
{
|
||
|
std::complex<_Tp> __t(-__z.imag(), __z.real());
|
||
|
__t = std::tr1::asinh(__t);
|
||
|
return std::complex<_Tp>(__t.imag(), -__t.real());
|
||
|
}
|
||
|
|
||
|
#if _GLIBCXX_USE_C99_COMPLEX_TR1
|
||
|
inline __complex__ float
|
||
|
__complex_asin(__complex__ float __z)
|
||
|
{ return __builtin_casinf(__z); }
|
||
|
|
||
|
inline __complex__ double
|
||
|
__complex_asin(__complex__ double __z)
|
||
|
{ return __builtin_casin(__z); }
|
||
|
|
||
|
inline __complex__ long double
|
||
|
__complex_asin(const __complex__ long double& __z)
|
||
|
{ return __builtin_casinl(__z); }
|
||
|
|
||
|
template<typename _Tp>
|
||
|
inline std::complex<_Tp>
|
||
|
asin(const std::complex<_Tp>& __z)
|
||
|
{ return __complex_asin(__z.__rep()); }
|
||
|
#else
|
||
|
template<typename _Tp>
|
||
|
inline std::complex<_Tp>
|
||
|
asin(const std::complex<_Tp>& __z)
|
||
|
{ return __complex_asin(__z); }
|
||
|
#endif
|
||
|
|
||
|
/// @brief atan(__z) [8.1.4].
|
||
|
// Effects: Behaves the same as C99 function catan, defined
|
||
|
// in subclause 7.3.5.3.
|
||
|
template<typename _Tp>
|
||
|
std::complex<_Tp>
|
||
|
__complex_atan(const std::complex<_Tp>& __z)
|
||
|
{
|
||
|
const _Tp __r2 = __z.real() * __z.real();
|
||
|
const _Tp __x = _Tp(1.0) - __r2 - __z.imag() * __z.imag();
|
||
|
|
||
|
_Tp __num = __z.imag() + _Tp(1.0);
|
||
|
_Tp __den = __z.imag() - _Tp(1.0);
|
||
|
|
||
|
__num = __r2 + __num * __num;
|
||
|
__den = __r2 + __den * __den;
|
||
|
|
||
|
return std::complex<_Tp>(_Tp(0.5) * atan2(_Tp(2.0) * __z.real(), __x),
|
||
|
_Tp(0.25) * log(__num / __den));
|
||
|
}
|
||
|
|
||
|
#if _GLIBCXX_USE_C99_COMPLEX_TR1
|
||
|
inline __complex__ float
|
||
|
__complex_atan(__complex__ float __z)
|
||
|
{ return __builtin_catanf(__z); }
|
||
|
|
||
|
inline __complex__ double
|
||
|
__complex_atan(__complex__ double __z)
|
||
|
{ return __builtin_catan(__z); }
|
||
|
|
||
|
inline __complex__ long double
|
||
|
__complex_atan(const __complex__ long double& __z)
|
||
|
{ return __builtin_catanl(__z); }
|
||
|
|
||
|
template<typename _Tp>
|
||
|
inline std::complex<_Tp>
|
||
|
atan(const std::complex<_Tp>& __z)
|
||
|
{ return __complex_atan(__z.__rep()); }
|
||
|
#else
|
||
|
template<typename _Tp>
|
||
|
inline std::complex<_Tp>
|
||
|
atan(const std::complex<_Tp>& __z)
|
||
|
{ return __complex_atan(__z); }
|
||
|
#endif
|
||
|
|
||
|
/// @brief acosh(__z) [8.1.5].
|
||
|
// Effects: Behaves the same as C99 function cacosh, defined
|
||
|
// in subclause 7.3.6.1.
|
||
|
template<typename _Tp>
|
||
|
std::complex<_Tp>
|
||
|
__complex_acosh(const std::complex<_Tp>& __z)
|
||
|
{
|
||
|
std::complex<_Tp> __t((__z.real() - __z.imag())
|
||
|
* (__z.real() + __z.imag()) - _Tp(1.0),
|
||
|
_Tp(2.0) * __z.real() * __z.imag());
|
||
|
__t = std::sqrt(__t);
|
||
|
|
||
|
return std::log(__t + __z);
|
||
|
}
|
||
|
|
||
|
#if _GLIBCXX_USE_C99_COMPLEX_TR1
|
||
|
inline __complex__ float
|
||
|
__complex_acosh(__complex__ float __z)
|
||
|
{ return __builtin_cacoshf(__z); }
|
||
|
|
||
|
inline __complex__ double
|
||
|
__complex_acosh(__complex__ double __z)
|
||
|
{ return __builtin_cacosh(__z); }
|
||
|
|
||
|
inline __complex__ long double
|
||
|
__complex_acosh(const __complex__ long double& __z)
|
||
|
{ return __builtin_cacoshl(__z); }
|
||
|
|
||
|
template<typename _Tp>
|
||
|
inline std::complex<_Tp>
|
||
|
acosh(const std::complex<_Tp>& __z)
|
||
|
{ return __complex_acosh(__z.__rep()); }
|
||
|
#else
|
||
|
template<typename _Tp>
|
||
|
inline std::complex<_Tp>
|
||
|
acosh(const std::complex<_Tp>& __z)
|
||
|
{ return __complex_acosh(__z); }
|
||
|
#endif
|
||
|
|
||
|
/// @brief asinh(__z) [8.1.6].
|
||
|
// Effects: Behaves the same as C99 function casin, defined
|
||
|
// in subclause 7.3.6.2.
|
||
|
template<typename _Tp>
|
||
|
std::complex<_Tp>
|
||
|
__complex_asinh(const std::complex<_Tp>& __z)
|
||
|
{
|
||
|
std::complex<_Tp> __t((__z.real() - __z.imag())
|
||
|
* (__z.real() + __z.imag()) + _Tp(1.0),
|
||
|
_Tp(2.0) * __z.real() * __z.imag());
|
||
|
__t = std::sqrt(__t);
|
||
|
|
||
|
return std::log(__t + __z);
|
||
|
}
|
||
|
|
||
|
#if _GLIBCXX_USE_C99_COMPLEX_TR1
|
||
|
inline __complex__ float
|
||
|
__complex_asinh(__complex__ float __z)
|
||
|
{ return __builtin_casinhf(__z); }
|
||
|
|
||
|
inline __complex__ double
|
||
|
__complex_asinh(__complex__ double __z)
|
||
|
{ return __builtin_casinh(__z); }
|
||
|
|
||
|
inline __complex__ long double
|
||
|
__complex_asinh(const __complex__ long double& __z)
|
||
|
{ return __builtin_casinhl(__z); }
|
||
|
|
||
|
template<typename _Tp>
|
||
|
inline std::complex<_Tp>
|
||
|
asinh(const std::complex<_Tp>& __z)
|
||
|
{ return __complex_asinh(__z.__rep()); }
|
||
|
#else
|
||
|
template<typename _Tp>
|
||
|
inline std::complex<_Tp>
|
||
|
asinh(const std::complex<_Tp>& __z)
|
||
|
{ return __complex_asinh(__z); }
|
||
|
#endif
|
||
|
|
||
|
/// @brief atanh(__z) [8.1.7].
|
||
|
// Effects: Behaves the same as C99 function catanh, defined
|
||
|
// in subclause 7.3.6.3.
|
||
|
template<typename _Tp>
|
||
|
std::complex<_Tp>
|
||
|
__complex_atanh(const std::complex<_Tp>& __z)
|
||
|
{
|
||
|
const _Tp __i2 = __z.imag() * __z.imag();
|
||
|
const _Tp __x = _Tp(1.0) - __i2 - __z.real() * __z.real();
|
||
|
|
||
|
_Tp __num = _Tp(1.0) + __z.real();
|
||
|
_Tp __den = _Tp(1.0) - __z.real();
|
||
|
|
||
|
__num = __i2 + __num * __num;
|
||
|
__den = __i2 + __den * __den;
|
||
|
|
||
|
return std::complex<_Tp>(_Tp(0.25) * (log(__num) - log(__den)),
|
||
|
_Tp(0.5) * atan2(_Tp(2.0) * __z.imag(), __x));
|
||
|
}
|
||
|
|
||
|
#if _GLIBCXX_USE_C99_COMPLEX_TR1
|
||
|
inline __complex__ float
|
||
|
__complex_atanh(__complex__ float __z)
|
||
|
{ return __builtin_catanhf(__z); }
|
||
|
|
||
|
inline __complex__ double
|
||
|
__complex_atanh(__complex__ double __z)
|
||
|
{ return __builtin_catanh(__z); }
|
||
|
|
||
|
inline __complex__ long double
|
||
|
__complex_atanh(const __complex__ long double& __z)
|
||
|
{ return __builtin_catanhl(__z); }
|
||
|
|
||
|
template<typename _Tp>
|
||
|
inline std::complex<_Tp>
|
||
|
atanh(const std::complex<_Tp>& __z)
|
||
|
{ return __complex_atanh(__z.__rep()); }
|
||
|
#else
|
||
|
template<typename _Tp>
|
||
|
inline std::complex<_Tp>
|
||
|
atanh(const std::complex<_Tp>& __z)
|
||
|
{ return __complex_atanh(__z); }
|
||
|
#endif
|
||
|
|
||
|
/// @brief fabs(__z) [8.1.8].
|
||
|
// Effects: Behaves the same as C99 function cabs, defined
|
||
|
// in subclause 7.3.8.1.
|
||
|
template<typename _Tp>
|
||
|
inline std::complex<_Tp>
|
||
|
fabs(const std::complex<_Tp>& __z)
|
||
|
{ return std::abs(__z); }
|
||
|
|
||
|
|
||
|
/// @brief Additional overloads [8.1.9].
|
||
|
//
|
||
|
|
||
|
// See common.h for the primary template.
|
||
|
template<typename _Tp, typename _Up>
|
||
|
struct __promote_2<std::complex<_Tp>, _Up>
|
||
|
{
|
||
|
public:
|
||
|
typedef std::complex<typename __promote_2<_Tp, _Up>::__type> __type;
|
||
|
};
|
||
|
|
||
|
template<typename _Tp, typename _Up>
|
||
|
struct __promote_2<_Tp, std::complex<_Up> >
|
||
|
{
|
||
|
public:
|
||
|
typedef std::complex<typename __promote_2<_Tp, _Up>::__type> __type;
|
||
|
};
|
||
|
|
||
|
template<typename _Tp, typename _Up>
|
||
|
struct __promote_2<std::complex<_Tp>, std::complex<_Up> >
|
||
|
{
|
||
|
public:
|
||
|
typedef std::complex<typename __promote_2<_Tp, _Up>::__type> __type;
|
||
|
};
|
||
|
|
||
|
|
||
|
using std::arg;
|
||
|
|
||
|
template<typename _Tp>
|
||
|
inline typename __promote<_Tp>::__type
|
||
|
arg(_Tp __x)
|
||
|
{
|
||
|
typedef typename __promote<_Tp>::__type __type;
|
||
|
return std::arg(std::complex<__type>(__x));
|
||
|
}
|
||
|
|
||
|
using std::conj;
|
||
|
|
||
|
template<typename _Tp>
|
||
|
inline std::complex<typename __promote<_Tp>::__type>
|
||
|
conj(_Tp __x)
|
||
|
{ return __x; }
|
||
|
|
||
|
using std::imag;
|
||
|
|
||
|
template<typename _Tp>
|
||
|
inline typename __promote<_Tp>::__type
|
||
|
imag(_Tp)
|
||
|
{ return _Tp(); }
|
||
|
|
||
|
using std::norm;
|
||
|
|
||
|
template<typename _Tp>
|
||
|
inline typename __promote<_Tp>::__type
|
||
|
norm(_Tp __x)
|
||
|
{
|
||
|
typedef typename __promote<_Tp>::__type __type;
|
||
|
return __type(__x) * __type(__x);
|
||
|
}
|
||
|
|
||
|
using std::polar;
|
||
|
|
||
|
template<typename _Tp, typename _Up>
|
||
|
inline std::complex<typename __promote_2<_Tp, _Up>::__type>
|
||
|
polar(const _Tp& __rho, const _Up& __theta)
|
||
|
{
|
||
|
typedef typename __promote_2<_Tp, _Up>::__type __type;
|
||
|
return std::polar(__type(__rho), __type(__theta));
|
||
|
}
|
||
|
|
||
|
using std::pow;
|
||
|
|
||
|
template<typename _Tp, typename _Up>
|
||
|
inline std::complex<typename __promote_2<_Tp, _Up>::__type>
|
||
|
pow(const std::complex<_Tp>& __x, const _Up& __y)
|
||
|
{
|
||
|
typedef typename __promote_2<_Tp, _Up>::__type __type;
|
||
|
return std::pow(std::complex<__type>(__x), __type(__y));
|
||
|
}
|
||
|
|
||
|
template<typename _Tp, typename _Up>
|
||
|
inline std::complex<typename __promote_2<_Tp, _Up>::__type>
|
||
|
pow(const _Tp& __x, const std::complex<_Up>& __y)
|
||
|
{
|
||
|
typedef typename __promote_2<_Tp, _Up>::__type __type;
|
||
|
return std::pow(__type(__x), std::complex<__type>(__y));
|
||
|
}
|
||
|
|
||
|
template<typename _Tp, typename _Up>
|
||
|
inline std::complex<typename __promote_2<_Tp, _Up>::__type>
|
||
|
pow(const std::complex<_Tp>& __x, const std::complex<_Up>& __y)
|
||
|
{
|
||
|
typedef typename __promote_2<_Tp, _Up>::__type __type;
|
||
|
return std::pow(std::complex<__type>(__x),
|
||
|
std::complex<__type>(__y));
|
||
|
}
|
||
|
|
||
|
using std::real;
|
||
|
|
||
|
template<typename _Tp>
|
||
|
inline typename __promote<_Tp>::__type
|
||
|
real(_Tp __x)
|
||
|
{ return __x; }
|
||
|
|
||
|
_GLIBCXX_END_NAMESPACE
|
||
|
}
|
||
|
|
||
|
#endif
|