分享
 
 
 

自己写了个complex类

王朝other·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

//: 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)都不管用。

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

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有