自己写了个complex类

类别:编程语言 点击:0 评论:0 推荐:

//: complex.h

#ifndef _COMPLEX_H_
#define _COMPLEX_H_

namespace numeric {

//////////////////////////////////////////////////////////////////////////

#include <math.h>
#define LOG10   2.30258512496948
//////////////////////////////////////////////////////////////////////////

//template<typename _tp>
//class complex;
//
//template<class _arg1, class _arg2, class _oper>
//struct _binary_expr_cc;

//////////////////////////////////////////////////////////////////////////

template<typename _tp1, typename _tp2>
struct _return_type
{
    typedef double value_type;
};

template<typename _tp1>
struct _return_type<_tp1, long double>
{
    typedef long double value_type;
};

template<typename _tp2>
struct _return_type<long double, _tp2>
{
    typedef long double value_type;
};

template<>
struct _return_type<float, float>
{
    typedef float value_type;
};

//////////////////////////////////////////////////////////////////////////

template<typename _tp>
struct constnt
{
    typedef typename _tp value_type;

public:
    const _tp& _m_cnst;

public:
    constnt(const _tp& __t) : _m_cnst(__t) {}
    //constnt(const constnt& __c) : _m_cnst(__c._m_cnst) { }

public:
    inline value_type real() const
    { return _m_cnst; }
   
    inline value_type imag() const
    { return 0; }
};

//////////////////////////////////////////////////////////////////////////

struct _abs_cc
{
    template<class _arg>
    static inline typename _arg::value_type
    evaluate(const _arg& __a)
    { return sqrt(__a.real()*__a.real()+__a.imag()*__a.imag()); }
};

struct _arg_cc
{
    template<class _arg>
    static inline typename _arg::value_type
    evaluate(const _arg& __a)
    { return atan2(__a.imag(), __a.real()); }
};

struct _norm_cc
{
    template<class _arg>
    static inline typename _arg::value_type
    evaluate(const _arg& __a)
    { return (__a.real()*__a.real()+__a.imag()*__a.imag()); }
};

//////////////////////////////////////////////////////////////////////////

struct _conjg_cc
{
    template<class _arg>
    static inline typename _arg::value_type
    real(const _arg& __a)
    { return  __a.real(); }

    template<class _arg>
    static inline typename _arg::value_type
    imag(const _arg& __a)
    { return -__a.imag(); }
};

struct _cos_cc
{
    template<class _arg>
    static inline typename _arg::value_type
    real(const _arg& __a)
    { return  cos(__a.real())*cosh(__a.imag()); }

    template<class _arg>
    static inline typename _arg::value_type
    imag(const _arg& __a)
    { return -sin(__a.real())*sinh(__a.imag()); }
};

struct _cosh_cc
{
    template<class _arg>
    static inline typename _arg::value_type
    real(const _arg& __a)
    { return cosh(__a.real())*cos(__a.imag()); }
   
    template<class _arg>
    static inline typename _arg::value_type
    imag(const _arg& __a)
    { return sinh(__a.real())*sin(__a.imag()); }
};

struct _exp_cc
{
    template<class _arg>
    static inline typename _arg::value_type
    real(const _arg& __a)
    {
        typedef typename _arg::value_type value_type;
        //value_type tmp = exp(__a.real());
        return exp(__a.real())*cos(__a.imag());
    }

    template<class _arg>
    static inline typename _arg::value_type
    imag(const _arg& __a)
    {
        typedef typename _arg::value_type value_type;
        //value_type tmp = exp(__a.real());
        return exp(__a.real())*sin(__a.imag());
    }
};

struct _log_cc
{
    template<class _arg>
    static inline typename _arg::value_type
    real(const _arg& __a)
    {
        typedef typename _arg::value_type value_type;
        value_type tmp = __a.real()*__a.real()+__a.imag()*__a.imag();
        return log(tmp)*0.5;
    }

    template<class _arg>
    static inline typename _arg::value_type
    imag(const _arg& __a)
    {
        return atan2(__a.imag(), __a.real());
    }
};

struct _log10_cc
{
    template<class _arg>
    static inline typename _arg::value_type
    real(const _arg& __a)
    {
        typedef typename _arg::value_type value_type;
        value_type tmp = __a.real()*__a.real()+__a.imag()*__a.imag();
        return log10(tmp)*0.5;
    }

    template<class _arg>
    static inline typename _arg::value_type
    imag(const _arg& __a)
    {
        return arg(__a)/LOG10;
    }
};

struct _sin_cc
{
    template<class _arg>
    static inline typename _arg::value_type
    real(const _arg& __a)
    { return sin(__a.real())*cosh(__a.imag()); }
   
    template<class _arg>
    static inline typename _arg::value_type
    imag(const _arg& __a)
    { return cos(__a.real())*sinh(__a.imag()); }
};

struct _sinh_cc
{
    template<class _arg>
    static inline typename _arg::value_type
    real(const _arg& __a)
    { return sinh(__a.real())*cos(__a.imag()); }

    template<class _arg>
    static inline typename _arg::value_type
    imag(const _arg& __a)
    { return cosh(__a.real())*sin(__a.imag()); }
};

//////////////////////////////////////////////////////////////////////////

struct _pow_cc
{
    template<class _arg1, class _arg2>
    static inline typename _return_type<typename _arg1::value_type,
        typename _arg2::value_type>::value_type
    real(const _arg1& __a, const _arg2& __b)
    {
        //typedef typename
        //_return_type<typename _arg1::value_type,
        //           typename _arg2::value_type
        //          >::value_type value_type;
        //value_type t1 = log(__a.real()*__a.real()+__a.imag()*__a.imag())*0.5;
        //value_type t2 = arg(__a);
        //return exp(t1*__b.real()-t2*__b.imag())*cos(t1*__b.imag()+t2*__b.real());
        return exp(__b*log(__a)).real();
    }

    template<class _arg1, class _arg2>
    static inline typename _return_type<typename _arg1::value_type,
        typename _arg2::value_type>::value_type
    imag(const _arg1& __a, const _arg2& __b)
    {
        //typedef typename
        //_return_type<typename _arg1::value_type,
        //           typename _arg2::value_type
        //          >::value_type value_type;
        //value_type t1 = log(__a.real()*__a.real()+__a.imag()*__a.imag())*0.5;
        //value_type t2 = arg(__a);
        //return exp(t1*__b.real()-t2*__b.imag())*sin(t1*__b.imag()+t2*__b.real());
        return exp(__b*log(__a)).imag();
    }
};

//////////////////////////////////////////////////////////////////////////

struct _unary_add_cc
{
    template<class _arg>
    static inline typename _arg::value_type
    real(const _arg& __a)
    { return __a.real(); }

    template<class _arg>
    static inline typename _arg::value_type
    imag(const _arg& __a)
    { return __a.imag(); }
};

//////////////////////////////////////////////////////////////////////////

struct _unary_sub_cc
{
    template<class _arg>
    static inline typename _arg::value_type
    real(const _arg& __a)
    { return -__a.real(); }

    template<class _arg>
    static inline typename _arg::value_type
    imag(const _arg& __a)
    { return -__a.imag(); }
};

//////////////////////////////////////////////////////////////////////////

struct _binary_add_cc
{
    template<class _arg1, class _arg2>
    static inline typename _return_type<typename _arg1::value_type,
        typename _arg2::value_type>::value_type
    real(const _arg1& __a, const _arg2& __b)
    { return __a.real() + __b.real(); }

    template<class _arg1, class _arg2>
    static inline typename _return_type<typename _arg1::value_type,
        typename _arg2::value_type>::value_type
    imag(const _arg1& __a, const _arg2& __b)
    { return __a.imag() + __b.imag(); }
};

//////////////////////////////////////////////////////////////////////////

struct _binary_sub_cc
{
    template<class _arg1, class _arg2>
    static inline typename _return_type<typename _arg1::value_type,
        typename _arg2::value_type>::value_type
    real(const _arg1& __a, const _arg2& __b)
    { return __a.real() - __b.real(); }

    template<class _arg1, class _arg2>
    static inline typename _return_type<typename _arg1::value_type,
        typename _arg2::value_type>::value_type
    imag(const _arg1& __a, const _arg2& __b)
    { return __a.imag() - __b.imag(); }
};

//////////////////////////////////////////////////////////////////////////

struct _binary_mul_cc
{
    template<class _arg1, class _arg2>
    static inline typename _return_type<typename _arg1::value_type,
        typename _arg2::value_type>::value_type
    real(const _arg1& __a, const _arg2& __b)
    { return __a.real()*__b.real() - __a.imag()*__b.imag(); }

    template<class _arg1, class _arg2>
    static inline typename _return_type<typename _arg1::value_type,
        typename _arg2::value_type>::value_type
    imag(const _arg1& __a, const _arg2& __b)
    { return __a.imag()*__b.real() + __a.real()*__b.imag(); }
};

//////////////////////////////////////////////////////////////////////////

struct _binary_div_cc
{
    template<class _arg1, class _arg2>
    static inline typename _return_type<typename _arg1::value_type,
        typename _arg2::value_type>::value_type
    real(const _arg1& __a, const _arg2& __b)
    { return (__a.real()*__b.real() + __a.imag()*__b.imag())/
             (__b.real()*__b.real() + __b.imag()*__b.imag()); }

    template<class _arg1, class _arg2>
    static inline typename _return_type<typename _arg1::value_type,
        typename _arg2::value_type>::value_type
    imag(const _arg1& __a, const _arg2& __b)
    { return (__a.imag()*__b.real() - __a.real()*__b.imag())/
             (__b.real()*__b.real() + __b.imag()*__b.imag()); }
};

//////////////////////////////////////////////////////////////////////////

template<class _arg, class _oper>
struct _unary_expr_cc
{
    typedef typename _arg::value_type value_type;

public:
    const _arg& _m_arg;

public:
    _unary_expr_cc(const _arg& __a) : _m_arg(__a)
    { }

    inline value_type real() const
    { return _oper::real(_m_arg); }

    inline value_type imag() const
    { return _oper::imag(_m_arg); }

public:
    _unary_expr_cc<_unary_expr_cc<_arg,_oper>,_unary_add_cc>
    operator+() const
    {
        typedef _unary_expr_cc<_unary_expr_cc<_arg,_oper>,
                               _unary_add_cc> _expr;
        return _expr(*this);
    }

    _unary_expr_cc<_unary_expr_cc<_arg,_oper>,_unary_sub_cc>
    operator-() const
    {
        typedef _unary_expr_cc<_unary_expr_cc<_arg,_oper>,
                               _unary_sub_cc> _expr;
        return _expr(*this);
    }
};

//////////////////////////////////////////////////////////////////////////

template<class _arg1, class _arg2, class _oper>
struct _binary_expr_cc
{
    typedef typename
    _return_type<typename _arg1::value_type,
                 typename _arg2::value_type>::value_type
    value_type;

public:
    const _arg1& _m_arg1;
    const _arg2& _m_arg2;
   
public:
    _binary_expr_cc(const _arg1& __a, const _arg2& __b)
        : _m_arg1(__a), _m_arg2(__b)
    { }

public:
    inline value_type real() const
    { return _oper::real(_m_arg1, _m_arg2); }

    inline value_type imag() const
    { return _oper::imag(_m_arg1, _m_arg2); }

public:
    _unary_expr_cc<_binary_expr_cc<_arg1,_arg2,_oper>,_unary_add_cc>
    operator+() const
    {
        typedef _unary_expr_cc<_binary_expr_cc<_arg1,_arg2,_oper>,
                               _unary_add_cc
                              > _expr;
        return _expr(*this);
    }

    _unary_expr_cc<_binary_expr_cc<_arg1,_arg2,_oper>,_unary_sub_cc>
    operator-() const
    {
        typedef _unary_expr_cc<_binary_expr_cc<_arg1,_arg2,_oper>,
                               _unary_sub_cc
                              > _expr;
        return _expr(*this);
    }
};

//////////////////////////////////////////////////////////////////////////

#ifdef _DEBUG
// 在debug下,由于编译器对生成的临时变量严格按照C++标准来处理(也就是临时
// 变量生存期问题),所以需要针对常量类型进行特化。但是现在的编译器在
// release下都能对代码作出很好的优化,临时变量被优化掉了,所以没有特化
// 也能得到正确的结果!
template<typename _tp, class _arg2, class _oper>
struct _binary_expr_cc<constnt<_tp>,_arg2,_oper>
{
    typedef typename
    _return_type<typename _tp,
                 typename _arg2::value_type>::value_type
    value_type;

public:
    const constnt<_tp> _m_arg1;
    const _arg2& _m_arg2;
   
public:
    _binary_expr_cc(const constnt<_tp>& __a, const _arg2& __b)
        : _m_arg1(__a), _m_arg2(__b)
    { //cout << "hello" << endl; }

public:
    inline value_type real() const
    { return _oper::real(_m_arg1, _m_arg2); }

    inline value_type imag() const
    { return _oper::imag(_m_arg1, _m_arg2); }

public:
    _unary_expr_cc<_binary_expr_cc<constnt<_tp>,_arg2,_oper>,_unary_add_cc>
    operator+() const
    {
        typedef _unary_expr_cc<_binary_expr_cc<constnt<_tp>,_arg2,_oper>,
                               _unary_add_cc
                              > _expr;
        return _expr(*this);
    }
};

//////////////////////////////////////////////////////////////////////////

template<class _arg1, class _tp, class _oper>
struct _binary_expr_cc<_arg1,constnt<_tp>,_oper>
{
    typedef typename
    _return_type<typename _arg1::value_type,
                 typename _tp
                >::value_type value_type;

public:
    const _arg1& _m_arg1;
    const constnt<_tp> _m_arg2;
   
public:
    _binary_expr_cc(const _arg1& __a, const constnt<_tp>& __b)
        : _m_arg1(__a), _m_arg2(__b)
    { }

public:
    inline value_type real() const
    { return _oper::real(_m_arg1, _m_arg2); }

    inline value_type imag() const
    { return _oper::imag(_m_arg1, _m_arg2); }

public:
    _unary_expr_cc<_binary_expr_cc<_arg1,constnt<_tp>,_oper>,
                   _unary_add_cc
                  >
    operator+() const
    {
        typedef _unary_expr_cc<_binary_expr_cc<_arg1,constnt<_tp>,_oper>,
                               _unary_add_cc
                              > _expr;
        return _expr(*this);
    }

    _unary_expr_cc<_binary_expr_cc<_arg1,constnt<_tp>,_oper>,
                   _unary_sub_cc
                  >
    operator-() const
    {
        typedef _unary_expr_cc<_binary_expr_cc<_arg1,constnt<_tp>,_oper>,
                               _unary_sub_cc
                              > _expr;
        return _expr(*this);
    }
};
#endif // _DEBUG

//////////////////////////////////////////////////////////////////////////

template<typename _tp>
class complex
{
public:
    typedef typename _tp value_type;

protected:
    value_type _m_real;
    value_type _m_imag;

public:
    complex(const _tp& __real = _tp(), const _tp& __imag = _tp())
        : _m_real(__real), _m_imag(__imag)
    {
#ifdef _DEBUG
        if ((typeid(value_type) != typeid(float))  &&
            (typeid(value_type) != typeid(double)) &&
            (typeid(value_type) != typeid(long double))) {
            cout << "complex模板参数类型只支持浮点数!" << endl;
            exit(0);
        }
#endif // _DEBUG
    }

    complex(const complex& __c)
        : _m_real(__c._m_real), _m_imag(__c._m_imag)
    { }

public:
    template<class _arg, class _oper>
    complex(const _unary_expr_cc<_arg,_oper>& __e)
        : _m_real(__e.real()), _m_imag(__e.imag())
    { }

    template<class _arg1, class _arg2, class _oper>
    complex(const _binary_expr_cc<_arg1,_arg2,_oper>& __e)
        : _m_real(__e.real()), _m_imag(__e.imag())
    { }

public:
    inline complex& operator=(const complex& __c)
    {
        _m_real = __c.real();
        _m_imag = __c.imag();
        return *this;
    }

    template<class _arg, class _oper>
    inline complex& operator=(const _unary_expr_cc<_arg,_oper>& __e)
    {
        _m_real = __e.real();
        _m_imag = __e.imag();
        return *this;
    }

    template<class _arg1, class _arg2, class _oper>
    inline complex& operator=(const _binary_expr_cc<_arg1,_arg2,_oper>& __e)
    {
        _m_real = __e.real();
        _m_imag = __e.imag();
        return *this;
    }

public:
    inline complex& operator+=(const complex& __c)
    {
        _m_real += __c.real();
        _m_imag += __c.imag();
        return *this;
    }

    template<class _arg, class _oper>
    inline complex& operator+=(const _unary_expr_cc<_arg,_oper>& __e)
    {
        _m_real += __e.real();
        _m_imag += __e.imag();
        return *this;
    }

    template<class _arg1, class _arg2, class _oper>
    inline complex& operator+=(const _binary_expr_cc<_arg1,_arg2,_oper>& __e)
    {
        _m_real += __e.real();
        _m_imag += __e.imag();
        return *this;
    }

    inline complex& operator-=(const complex& __c)
    {
        _m_real -= __c.real();
        _m_imag -= __c.imag();
        return *this;
    }

    template<class _arg, class _oper>
    inline complex& operator-=(const _unary_expr_cc<_arg,_oper>& __e)
    {
        _m_real -= __e.real();
        _m_imag -= __e.imag();
        return *this;
    }

    template<class _arg1, class _arg2, class _oper>
    inline complex& operator-=(const _binary_expr_cc<_arg1,_arg2,_oper>& __e)
    {
        _m_real -= __e.real();
        _m_imag -= __e.imag();
        return *this;
    }

    inline complex& operator*=(const complex& __c)
    {
        static _tp rx, iy;

        rx = _m_real*__c.real() - _m_imag*__c.imag();
        iy = _m_real*__c.imag() + _m_imag*__c.real();

        _m_real = rx;
        _m_imag = iy;
        return *this;
    }

    template<class _arg, class _oper>
    inline complex& operator*=(const _unary_expr_cc<_arg,_oper>& __e)
    {
        static _tp rx, iy, ex, ey;

        ex = __e.real();
        ey = __e.imag();

        rx = _m_real*ex - _m_imag*ey;
        iy = _m_real*ey + _m_imag*ex;

        _m_real = rx;
        _m_imag = iy;
       
        return *this;
    }

    template<class _arg1, class _arg2, class _oper>
    inline complex& operator*=(const _binary_expr_cc<_arg1,_arg2,_oper>& __e)
    {
        static _tp rx, iy;

        rx = _m_real*__e.real() - _m_imag*__e.imag();
        iy = _m_real*__e.imag() + _m_imag*__e.real();

        _m_real = rx;
        _m_imag = iy;
        return *this;
    }

    inline complex& operator/=(const complex& __c)
    {
        static _tp rx, iy, cx, cy, rt;

        cx = __c.real();
        cy = __c.imag();

        rt = 1/(cx*cx+cy*cy);

        rx =  _m_real*cx + _m_imag*cy;
        iy = -_m_real*cy + _m_imag*cx;

        _m_real = rx*rt;
        _m_imag = iy*rt;
       
        return *this;
    }

    template<class _arg, class _oper>
    inline complex& operator/=(const _unary_expr_cc<_arg,_oper>& __e)
    {
        static _tp rx, iy, ex, ey, rt;

        ex = __e.real();
        ey = __e.imag();

        rt = 1/(ex*ex+ey*ey);

        rx =  _m_real*ex + _m_imag*ey;
        iy = -_m_real*ey + _m_imag*ex;

        _m_real = rx*rt;
        _m_imag = iy*rt;
       
        return *this;
    }

    template<class _arg1, class _arg2, class _oper>
    inline complex& operator/=(const _binary_expr_cc<_arg1,_arg2,_oper>& __e)
    {
        static _tp rx, iy, ex, ey, rt;

        ex = __e.real();
        ey = __e.imag();

        rt = 1/(ex*ex+ey*ey);

        rx =  _m_real*ex + _m_imag*ey;
        iy = -_m_real*ey + _m_imag*ex;

        _m_real = rx*rt;
        _m_imag = iy*rt;
       
        return *this;
    }

public:
    inline value_type real() const { return _m_real; }
    inline value_type imag() const { return _m_imag; }

    inline value_type& real() { return _m_real; }
    inline value_type& imag() { return _m_imag; }

public:
    _unary_expr_cc<complex<_tp>,_unary_add_cc> operator+() const
    { return _unary_expr_cc<complex<_tp>,_unary_add_cc>(*this); }

    _unary_expr_cc<complex<_tp>,_unary_sub_cc> operator-() const
    { return _unary_expr_cc<complex<_tp>,_unary_sub_cc>(*this); }

};

//////////////////////////////////////////////////////////////////////////

//template<class _arg1, class _arg2>
//_binary_expr_cc<_arg1,_arg2,_add_cc>
//operator+(const _arg1& a, const _arg2& b)
//{
//  typedef _binary_expr_cc<_arg1,_arg2,_add_cc> _expr;
//  return _expr(a,b);
//}

#define _DEFINE_COMPLEX_BINARY_FUNC(_func, _name)                       \
                                                                        \
template<class _arg11,class _arg12,class _oper1,                        \
         class _arg21,class _arg22,class _oper2>                        \
inline                                                                  \
_binary_expr_cc<_binary_expr_cc<_arg11,_arg12,_oper1>,                  \
                _binary_expr_cc<_arg21,_arg22,_oper2>,                  \
                _name                                                   \
               >                                                        \
_func(const _binary_expr_cc<_arg11,_arg12,_oper1>& a,                   \
      const _binary_expr_cc<_arg21,_arg22,_oper2>& b)                   \
{                                                                       \
    typedef _binary_expr_cc<_binary_expr_cc<_arg11,_arg12,_oper1>,      \
                            _binary_expr_cc<_arg21,_arg22,_oper2>,      \
                            _name                                       \
                           > _expr;                                     \
    return _expr(a,b);                                                  \
}                                                                       \
                                                                        \
template<class _arg1,class _oper1,                                      \
         class _arg21,class _arg22,class _oper2>                        \
inline                                                                  \
_binary_expr_cc<_unary_expr_cc<_arg1,_oper1>,                           \
                _binary_expr_cc<_arg21,_arg22,_oper2>,                  \
                _name                                                   \
               >                                                        \
_func(const _unary_expr_cc<_arg1,_oper1>& a,                            \
      const _binary_expr_cc<_arg21,_arg22,_oper2>& b)                   \
{                                                                       \
    typedef _binary_expr_cc<_unary_expr_cc<_arg1,_oper1>,               \
                            _binary_expr_cc<_arg21,_arg22,_oper2>,      \
                            _name                                       \
                           > _expr;                                     \
    return _expr(a,b);                                                  \
}                                                                       \
                                                                        \
template<class _arg11,class _arg12,class _oper1,                        \
         class _arg2,class _oper2>                                      \
inline                                                                  \
_binary_expr_cc<_binary_expr_cc<_arg11,_arg12,_oper1>,                  \
                _unary_expr_cc<_arg2,_oper2>,                           \
                _name                                                   \
               >                                                        \
_func(const _binary_expr_cc<_arg11,_arg12,_oper1>& a,                   \
      const _unary_expr_cc<_arg2,_oper2>& b)                            \
{                                                                       \
    typedef _binary_expr_cc<_binary_expr_cc<_arg11,_arg12,_oper1>,      \
                            _unary_expr_cc<_arg2,_oper2>,               \
                            _name                                       \
                           > _expr;                                     \
    return _expr(a,b);                                                  \
}                                                                       \
                                                                        \
template<class _arg1,class _oper1,                                      \
         class _arg2,class _oper2>                                      \
inline                                                                  \
_binary_expr_cc<_unary_expr_cc<_arg1,_oper1>,                           \
                _unary_expr_cc<_arg2,_oper2>,                           \
                _name                                                   \
               >                                                        \
_func(const _unary_expr_cc<_arg1,_oper1>& a,                            \
      const _unary_expr_cc<_arg2,_oper2>& b)                            \
{                                                                       \
    typedef _binary_expr_cc<_unary_expr_cc<_arg1,_oper1>,               \
                            _unary_expr_cc<_arg2,_oper2>,               \
                            _name                                       \
                           > _expr;                                     \
    return _expr(a,b);                                                  \
}                                                                       \
                                                                        \
template<class _arg11, class _arg12, class _oper, class _tp>            \
inline                                                                  \
_binary_expr_cc<_binary_expr_cc<_arg11,_arg12,_oper>,                   \
                complex<_tp>,                                           \
                _name                                                   \
               >                                                        \
_func(const _binary_expr_cc<_arg11,_arg12,_oper>& a,                    \
      const complex<_tp>& b)                                            \
{                                                                       \
    typedef _binary_expr_cc<_binary_expr_cc<_arg11,_arg12,_oper>,       \
                            complex<_tp>,                               \
                            _name                                       \
                           > _expr;                                     \
    return _expr(a,b);                                                  \
}                                                                       \
                                                                        \
template<class _tp, class _arg21, class _arg22, class _oper>            \
inline                                                                  \
_binary_expr_cc<complex<_tp>,                                           \
                _binary_expr_cc<_arg21,_arg22,_oper>,                   \
                _name                                                   \
               >                                                        \
_func(const complex<_tp>& a,                                            \
      const _binary_expr_cc<_arg21,_arg22,_oper>& b)                    \
{                                                                       \
    typedef _binary_expr_cc<complex<_tp>,                               \
                            _binary_expr_cc<_arg21,_arg22,_oper>,       \
                            _name                                       \
                           > _expr;                                     \
    return _expr(a,b);                                                  \
}                                                                       \
                                                                        \
template<class _arg11, class _arg12, class _oper, class _tp>            \
inline                                                                  \
_binary_expr_cc<_binary_expr_cc<_arg11,_arg12,_oper>,                   \
                constnt<_tp>,                                           \
                _name                                                   \
               >                                                        \
_func(const _binary_expr_cc<_arg11,_arg12,_oper>& a, const _tp& b)      \
{                                                                       \
    typedef _binary_expr_cc<_binary_expr_cc<_arg11,_arg12,_oper>,       \
                            constnt<_tp>,                               \
                            _name                                       \
                           > _expr;                                     \
    return _expr(a,b);                                                  \
}                                                                       \
                                                                        \
template<class _tp, class _arg21, class _arg22, class _oper>            \
inline                                                                  \
_binary_expr_cc<constnt<_tp>,                                           \
                _binary_expr_cc<_arg21,_arg22,_oper>,                   \
                _name                                                   \
               >                                                        \
_func(const _tp& a, const _binary_expr_cc<_arg21,_arg22,_oper>& b)      \
{                                                                       \
    typedef _binary_expr_cc<constnt<_tp>,                               \
                            _binary_expr_cc<_arg21,_arg22,_oper>,       \
                            _name                                       \
                           > _expr;                                     \
    return _expr(a,b);                                                  \
}                                                                       \
                                                                        \
template<class _arg,class _oper,class _tp>                              \
inline                                                                  \
_binary_expr_cc<_unary_expr_cc<_arg,_oper>,                             \
                complex<_tp>,                                           \
                _name                                                   \
               >                                                        \
_func(const _unary_expr_cc<_arg,_oper>& a, const complex<_tp>& b)       \
{                                                                       \
    typedef _binary_expr_cc<_unary_expr_cc<_arg,_oper>,                 \
                            complex<_tp>,                               \
                            _name                                       \
                           > _expr;                                     \
    return _expr(a,b);                                                  \
}                                                                       \
                                                                        \
template<class _tp, class _arg,class _oper>                             \
inline                                                                  \
_binary_expr_cc<complex<_tp>,                                           \
                _unary_expr_cc<_arg,_oper>,                             \
                _name                                                   \
               >                                                        \
_func(const complex<_tp>& a, const _unary_expr_cc<_arg,_oper>& b)       \
{                                                                       \
    typedef _binary_expr_cc<complex<_tp>,                               \
                            _unary_expr_cc<_arg,_oper>,                 \
                            _name                                       \
                           > _expr;                                     \
    return _expr(a,b);                                                  \
}                                                                       \
                                                                        \
template<class _arg,class _oper,class _tp>                              \
inline                                                                  \
_binary_expr_cc<_unary_expr_cc<_arg,_oper>,                             \
                constnt<_tp>,                                           \
                _name                                                   \
               >                                                        \
_func(const _unary_expr_cc<_arg,_oper>& a, const constnt<_tp>& b)       \
{   /*这个函数不常用,只是用作备用*/                                    \
    typedef _binary_expr_cc<_unary_expr_cc<_arg,_oper>,                 \
                            constnt<_tp>,                               \
                            _name                                       \
                           > _expr;                                     \
    return _expr(a,b);                                                  \
}                                                                       \
                                                                        \
template<class _tp, class _arg,class _oper>                             \
inline                                                                  \
_binary_expr_cc<constnt<_tp>,                                           \
                _unary_expr_cc<_arg,_oper>,                             \
                _name                                                   \
               >                                                        \
_func(const constnt<_tp>& a, const _unary_expr_cc<_arg,_oper>& b)       \
{                                                                       \
    typedef _binary_expr_cc<constnt<_tp>,                               \
                            _unary_expr_cc<_arg,_oper>,                 \
                            _name                                       \
                           > _expr;                                     \
    return _expr(a,b);                                                  \
}                                                                       \
                                                                        \
template<class _arg,class _oper,class _tp>                              \
inline                                                                  \
_binary_expr_cc<_unary_expr_cc<_arg,_oper>,                             \
                constnt<_tp>,                                           \
                _name                                                   \
               >                                                        \
_func(const _unary_expr_cc<_arg,_oper>& a, const _tp& b)                \
{                                                                       \
    typedef _binary_expr_cc<_unary_expr_cc<_arg,_oper>,                 \
                            constnt<_tp>,                               \
                            _name                                       \
                           > _expr;                                     \
    return _expr(a,b);                                                  \
}                                                                       \
                                                                        \
template<class _tp, class _arg,class _oper>                             \
inline                                                                  \
_binary_expr_cc<constnt<_tp>,                                           \
                _unary_expr_cc<_arg,_oper>,                             \
                _name                                                   \
               >                                                        \
_func(const _tp& a, const _unary_expr_cc<_arg,_oper>& b)                \
{                                                                       \
    typedef _binary_expr_cc<constnt<_tp>,                               \
                            _unary_expr_cc<_arg,_oper>,                 \
                            _name                                       \
                           > _expr;                                     \
    return _expr(a,b);                                                  \
}                                                                       \
                                                                        \
template<class _tp1, class _tp2>                                        \
inline                                                                  \
_binary_expr_cc<complex<_tp1>,complex<_tp2>,_name>                      \
_func(const complex<_tp1>& __a, const complex<_tp2>& __b)               \
{                                                                       \
    typedef _binary_expr_cc<complex<_tp1>,                              \
                            complex<_tp2>,                              \
                            _name                                       \
                           > _expr;                                     \
    return _expr(__a,__b);                                              \
}                                                                       \
                                                                        \
template<class _tp1, class _tp2>                                        \
inline                                                                  \
_binary_expr_cc<complex<_tp1>,                                          \
                constnt<_tp2>,                                          \
                _name                                                   \
               >                                                        \
_func(const complex<_tp1>& __a, const _tp2& __b)                        \
{                                                                       \
    typedef _binary_expr_cc<complex<_tp1>,                              \
                            constnt<_tp2>,                              \
                            _name                                       \
                           > _expr;                                     \
    return _expr(__a,__b);                                              \
}                                                                       \
                                                                        \
template<class _tp1, class _tp2>                                        \
inline                                                                  \
_binary_expr_cc<constnt<_tp1>,                                          \
                complex<_tp2>,                                          \
                _name                                                   \
               >                                                        \
_func(const _tp1& a, const complex<_tp2>& b)                            \
{                                                                       \
    typedef _binary_expr_cc<constnt<_tp1>,                              \
                            complex<_tp2>,                              \
                            _name                                       \
                           > _expr;                                     \
    return _expr(a,b);                                                  \
}

_DEFINE_COMPLEX_BINARY_FUNC(operator+, _binary_add_cc)
_DEFINE_COMPLEX_BINARY_FUNC(operator-, _binary_sub_cc)
_DEFINE_COMPLEX_BINARY_FUNC(operator*, _binary_mul_cc)
_DEFINE_COMPLEX_BINARY_FUNC(operator/, _binary_div_cc)
_DEFINE_COMPLEX_BINARY_FUNC(      pow,        _pow_cc)

//////////////////////////////////////////////////////////////////////////

#define _DEFINE_COMPLEX_UNARY_FUNC(_func, _name)                        \
                                                                        \
template<class _arg1, class _arg2, class _oper>                         \
_unary_expr_cc<_binary_expr_cc<_arg1,_arg2,_oper>,                      \
               _name                                                    \
              >                                                         \
_func(const _binary_expr_cc<_arg1,_arg2,_oper>& __e)                    \
{                                                                       \
    typedef _unary_expr_cc<_binary_expr_cc<_arg1,_arg2,_oper>,          \
                           _name                                        \
                          > _expr;                                      \
    return _expr(__e);                                                  \
}                                                                       \
                                                                        \
template<class _arg, class _oper>                                       \
_unary_expr_cc<_unary_expr_cc<_arg,_oper>,                              \
               _name                                                    \
              >                                                         \
_func(const _unary_expr_cc<_arg,_oper>& __e)                            \
{                                                                       \
    typedef _unary_expr_cc<_unary_expr_cc<_arg,_oper>,                  \
                           _name                                        \
                          > _expr;                                      \
    return _expr(__e);                                                  \
}                                                                       \
                                                                        \
template<class _tp>                                                     \
_unary_expr_cc<complex<_tp>,                                            \
               _name                                                    \
              >                                                         \
_func(const complex<_tp>& __c)                                          \
{                                                                       \
    typedef _unary_expr_cc<complex<_tp>,                                \
                           _name                                        \
                          > _expr;                                      \
    return _expr(__c);                                                  \
}

_DEFINE_COMPLEX_UNARY_FUNC(  cos,   _cos_cc)
_DEFINE_COMPLEX_UNARY_FUNC( cosh,  _cosh_cc)
_DEFINE_COMPLEX_UNARY_FUNC(  exp,   _exp_cc)
_DEFINE_COMPLEX_UNARY_FUNC(  log,   _log_cc)
_DEFINE_COMPLEX_UNARY_FUNC(log10, _log10_cc)
_DEFINE_COMPLEX_UNARY_FUNC(  sin,   _sin_cc)
_DEFINE_COMPLEX_UNARY_FUNC( sinh,  _sinh_cc)

//////////////////////////////////////////////////////////////////////////

#define _DEFINE_COMPLEX_UNARY_FUNC_EX(_func, _name)                     \
                                                                        \
template<class _arg1, class _arg2, class _oper>                         \
typename _return_type<typename _arg1::value_type,                       \
                      typename _arg2::value_type                        \
                     >::value_type                                      \
_func(const _binary_expr_cc<_arg1,_arg2,_oper>& __e)                    \
{                                                                       \
    return _name::evaluate(__e);                                        \
}                                                                       \
                                                                        \
template<class _arg, class _oper>                                       \
typename _arg::value_type                                               \
_func(const _unary_expr_cc<_arg,_oper>& __e)                            \
{                                                                       \
    return _name::evaluate(__e);                                        \
}                                                                       \
                                                                        \
template<typename _tp>                                                  \
typename _tp                                                            \
  _func(const complex<_tp>& __c)                                        \
{                                                                       \
    return _name::evaluate(__c);                                        \
}

_DEFINE_COMPLEX_UNARY_FUNC_EX( abs,  _abs_cc)
_DEFINE_COMPLEX_UNARY_FUNC_EX( arg,  _arg_cc)
_DEFINE_COMPLEX_UNARY_FUNC_EX(norm, _norm_cc)

//////////////////////////////////////////////////////////////////////////

}

#endif // _COMPLEX_H_


// test.cpp

#include <ctime>
#include <iostream>
using namespace std;

//#include <complex>
//using namespace std;

#include "complex.h"
using namespace numeric;

void main()
{
    complex<double> c1(1,1), c2(2,2), c3(3,3), c4(4,4), c5(5,5), cc(0,0);
    double d = 1.2, rx = 0, iy = 0;

    clock_t time = clock();
    for (int i=0; i<10000; ++i) {
        for (int j=0; j<10000; ++j) {
            // 由于被编译器的循环优化会优化=,所以采用@=
            cc *= cos(d+(c1+c2)+c3);
        }
    }
    time = clock() - time;
    cout << (double)time/CLK_TCK << endl;

    cout << '(' << rx
         << ',' << iy
         << ')' << endl;
    cout << '(' << cc.real()
         << ',' << cc.imag()
         << ')' << endl;

}

/*************************************************************************

程序分别用intel c++ compiler 8.0, vc7.1和gcc 3.3.3编译。其中icc80和vc71
顺利编译通过,gcc编译出错。

首先用intel的编译器来测试程序:
(1) 简单运算(+,-,*,/,=,+=,-=,*=,/=)
    通过测试发现,它在+、-及+=、-=上的效率约是compaq visual fortran 6.5
    的complex类型的两倍多。而在稍微复杂的*、/、*=、/=上,它的效率要高出
    cvf好多。
(2) 函数计算(cos, sin, exp, log)
    这些函数计算与cvf相比仍然约是两倍多(fortran没有log10、sinh和cosh)。
(3) pow函数
    在测试的时候发现一个有趣的问题:intel编译器在处理pow函数时对数据非常
    敏感。比如申明
        complex<double> c1(1,1),c2(2,2),c3(3,3),cc(0,0);
        double d = 1.2;
    然后计算下面语句10000*10000次
        cc += pow(d+c1+c2,c3);
    如果将c2(2,2)的虚部改为任何不为2的数,对比两次计算耗时,可以发现两者
    差别居然有近70倍。
    fortan没有pow函数,但是pow(x,y)可以表达成exp(y*log(x))。
   
使用vs71编译器来测试程序:
(1) 简单运算(+,-,*,/,=,+=,-=,*=,/=)
    编译出的程序运行效率和visual fortran差不多,+=和-=稍微低于fortran,而
    *=则约是fortran的1/3,但是/=居然有fortran的两倍。
(2) 函数计算(cos, sin, exp, sinh, cosh)
    使用@=(@可以是+、-、*、/)运算符时,计算的效率和stl的complex没什么差别。
(3) 函数(log, log10)
    这两个函数与(2)中的函数表现差不多,但是如果将@=(+=或-=)中的一个赋值
    表达式注释掉,效率就会高出很多,但这个方法对(2)中的函数不管用。
(4) 函数(pow)
    这个函数如果直接使用@=的话,也和stl的complex类差不多。但是(3)中的方法对
    它也有效,更有意思的地方是——如果在循环中直接赋值:
        cc.real() += pow(d+c1+c2,c3).real();
        cc.imag() += pow(d+c1+c2,c3).imag();
    这样得到的效率居然是fortran的两倍多。但是这种方法对(3)(2)都不管用。

*************************************************************************/

本文地址:http://com.8s8s.com/it/it24893.htm