morse-wip/src/complex.h

147 wiersze
3.4 KiB
C++

// ----------------------------------------------------------------------------
// complex.h -- Complex arithmetic
//
// Copyright (C) 2006-2008
// Dave Freese, W1HKJ
// Copyright (C) 2008
// Stelios Bounanos, M0GLD
//
// This file is part of fldigi.
//
// Fldigi 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 3 of the License, or
// (at your option) any later version.
//
// Fldigi 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 fldigi. If not, see <http://www.gnu.org/licenses/>.
// ----------------------------------------------------------------------------
#ifndef _COMPLEX_H
#define _COMPLEX_H
#include <cmath>
class complex {
public:
double re;
double im;
complex(double r = 0.0, double i = 0.0)
: re(r), im(i) { }
double real() { return re; };
void real(double R) {re = R;};
double imag() { return im; };
void imag(double I) {im = I;};
// Z = X * Y
complex& operator*=(const complex& y) {
double temp = re * y.re - im * y.im;
im = re * y.im + im * y.re;
re = temp;
return *this;
}
complex operator*(const complex& y) const {
return complex(re * y.re - im * y.im, re * y.im + im * y.re);
}
// Z = X * y
complex& operator*=(double y) {
re *= y;
im *= y;
return *this;
}
complex operator*(double y) const {
return complex(re * y, im * y);
}
// Z = X + Y
complex& operator+=(const complex& y) {
re += y.re;
im += y.im;
return *this;
}
complex operator+(const complex& y) const {
return complex(re + y.re, im + y.im);
}
// Z = X - Y
complex& operator-=(const complex& y) {
re -= y.re;
im -= y.im;
return *this;
}
complex operator-(const complex& y) const {
return complex(re - y.re, im - y.im);
}
// Z = X / Y
complex& operator/=(const complex& y) {
double temp, denom = y.re*y.re + y.im*y.im;
if (denom == 0.0) denom = 1e-10;
temp = (re * y.re + im * y.im) / denom;
im = (im * y.re - re * y.im) / denom;
re = temp;
return *this;
}
complex operator/(const complex& y) const {
double denom = y.re*y.re + y.im*y.im;
if (denom == 0.0) denom = 1e-10;
return complex((re * y.re + im * y.im) / denom, (im * y.re - re * y.im) / denom);
}
// Z = (complex conjugate of X) * Y
// Z1 = x1 + jy1, or Z1 = |Z1|exp(jP1)
// Z2 = x2 + jy2, or Z2 = |Z2|exp(jP2)
// Z = (x1 - jy1) * (x2 + jy2)
// or Z = |Z1|*|Z2| exp (j (P2 - P1))
complex& operator%=(const complex& y) {
double temp = re * y.re + im * y.im;
im = re * y.im - im * y.re;
re = temp;
return *this;
}
complex operator%(const complex& y) const {
complex z;
z.re = re * y.re + im * y.im;
z.im = re * y.im - im * y.re;
return z;
}
// n = |Z| * |Z|
double norm() const {
return (re * re + im * im);
}
// n = |Z|
double mag() const {
return sqrt(norm());
}
// Z = x + jy
// Z = |Z|exp(jP)
// arg returns P
double arg() const {
return atan2(im, re);
}
};
inline complex cmac (const complex *a, const complex *b, int ptr, int len) {
complex z;
ptr %= len;
for (int i = 0; i < len; i++) {
z += a[i] * b[ptr];
ptr = (ptr + 1) % len;
}
return z;
}
#endif