1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163
|
#ifndef COMPLEX_OPS_H
#define COMPLEX_OPS_H
/*
* Functions to handle arithmetic operations on NumPy complex values
*/
#include <numpy/arrayobject.h>
template <class c_type, class npy_type>
class complex_wrapper : public npy_type {
public:
/* Constructor */
complex_wrapper( const c_type r = c_type(0), const c_type i = c_type(0) ){
npy_type::real = r;
npy_type::imag = i;
}
/* Conversion */
operator bool() const {
if (npy_type::real == 0 && npy_type::imag == 0) {
return false;
} else {
return true;
}
}
/* Operators */
complex_wrapper operator-() const {
return complex_wrapper(-npy_type::real,-npy_type::imag);
}
complex_wrapper operator+(const complex_wrapper& B) const {
return complex_wrapper(npy_type::real + B.real, npy_type::imag + B.imag);
}
complex_wrapper operator-(const complex_wrapper& B) const {
return complex_wrapper(npy_type::real - B.real, npy_type::imag - B.imag);
}
complex_wrapper operator*(const complex_wrapper& B) const {
return complex_wrapper(npy_type::real * B.real - npy_type::imag * B.imag,
npy_type::real * B.imag + npy_type::imag * B.real);
}
complex_wrapper operator/(const complex_wrapper& B) const {
complex_wrapper result;
c_type denom = 1.0 / (B.real * B.real + B.imag * B.imag);
result.real = (npy_type::real * B.real + npy_type::imag * B.imag) * denom;
result.imag = (npy_type::imag * B.real - npy_type::real * B.imag) * denom;
return result;
}
/* in-place operators */
complex_wrapper& operator+=(const complex_wrapper & B){
npy_type::real += B.real;
npy_type::imag += B.imag;
return (*this);
}
complex_wrapper& operator-=(const complex_wrapper & B){
npy_type::real -= B.real;
npy_type::imag -= B.imag;
return (*this);
}
complex_wrapper& operator*=(const complex_wrapper & B){
c_type temp = npy_type::real * B.real - npy_type::imag * B.imag;
npy_type::imag = npy_type::real * B.imag + npy_type::imag * B.real;
npy_type::real = temp;
return (*this);
}
complex_wrapper& operator/=(const complex_wrapper & B){
c_type denom = 1.0 / (B.real * B.real + B.imag * B.imag);
c_type temp = (npy_type::real * B.real + npy_type::imag * B.imag) * denom;
npy_type::imag = (npy_type::imag * B.real - npy_type::real * B.imag) * denom;
npy_type::real = temp;
return (*this);
}
/* Boolean operations */
bool operator==(const complex_wrapper& B) const{
return npy_type::real == B.real && npy_type::imag == B.imag;
}
bool operator!=(const complex_wrapper& B) const{
return npy_type::real != B.real || npy_type::imag != B.imag;
}
bool operator<(const complex_wrapper& B) const{
if (npy_type::real == B.real){
return npy_type::imag < B.imag;
} else {
return npy_type::real < B.real;
}
}
bool operator>(const complex_wrapper& B) const{
if (npy_type::real == B.real){
return npy_type::imag > B.imag;
} else {
return npy_type::real > B.real;
}
}
bool operator<=(const complex_wrapper& B) const{
if (npy_type::real == B.real){
return npy_type::imag <= B.imag;
} else {
return npy_type::real <= B.real;
}
}
bool operator>=(const complex_wrapper& B) const{
if (npy_type::real == B.real){
return npy_type::imag >= B.imag;
} else {
return npy_type::real >= B.real;
}
}
template <class T>
bool operator==(const T& B) const{
return npy_type::real == B && npy_type::imag == T(0);
}
template <class T>
bool operator!=(const T& B) const{
return npy_type::real != B || npy_type::imag != T(0);
}
template <class T>
bool operator<(const T& B) const{
if (npy_type::real == B) {
return npy_type::imag < T(0);
} else {
return npy_type::real < B;
}
}
template <class T>
bool operator>(const T& B) const{
if (npy_type::real == B) {
return npy_type::imag > T(0);
} else {
return npy_type::real > B;
}
}
template <class T>
bool operator<=(const T& B) const{
if (npy_type::real == B) {
return npy_type::imag <= T(0);
} else {
return npy_type::real <= B;
}
}
template <class T>
bool operator>=(const T& B) const{
if (npy_type::real == B) {
return npy_type::imag >= T(0);
} else {
return npy_type::real >= B;
}
}
complex_wrapper& operator=(const complex_wrapper& B){
npy_type::real = B.real;
npy_type::imag = B.imag;
return (*this);
}
complex_wrapper& operator=(const c_type& B){
npy_type::real = B;
npy_type::imag = c_type(0);
return (*this);
}
};
typedef complex_wrapper<float,npy_cfloat> npy_cfloat_wrapper;
typedef complex_wrapper<double,npy_cdouble> npy_cdouble_wrapper;
typedef complex_wrapper<long double,npy_clongdouble> npy_clongdouble_wrapper;
#endif
|