GY-63_MS5611/libraries/Complex/complex.cpp
2013-09-29 21:55:40 +02:00

399 lines
6.1 KiB
C++

//
// FILE: Complex.cpp
// AUTHOR: Rob Tillaart
// VERSION: see COMPLEX_LIB_VERSION
// PURPOSE: library for Complex math for Arduino
// URL: http://arduino.cc/playground/Main/ComplexMath
//
// Released to the public domain
//
#include "complex.h"
Complex::Complex(double real, double imag)
{
re = real;
im = imag;
}
Complex::Complex(const Complex &c)
{
re = c.re;
im = c.im;
}
Complex::Complex(double d)
{
re = d;
im = 0;
}
void Complex::set(double real, double imag)
{
re = real;
im = imag;
}
double Complex::real()
{
return re;
}
double Complex::imag()
{
return im;
}
// polar2cartesian
void Complex::polar(double modulus, double phase)
{
re = modulus * cos(phase);
im = modulus * sin(phase);
}
double Complex::phase()
{
return atan2(im, re);
}
double Complex::modulus()
{
return hypot(re, im);
}
// conjugate is the number mirrored in x-axis
Complex Complex::conjugate()
{
return Complex(re,-im);
}
Complex Complex::reciprocal()
{
double f = 1.0/(re*re + im*im);
double r = re*f;
double i = -im*f;
return Complex(r,i);
}
// PRINTING
size_t Complex::printTo(Print& p) const
{
size_t n = 0;
n += p.print(re, 3);
n += p.print(' ');
n += p.print(im, 3);
n += p.print('i');
return n;
};
// EQUALITIES
bool Complex::operator == (Complex c)
{
return (re == c.re) && (im == c.im);
}
bool Complex::operator != (Complex c)
{
return (re != c.re) || (im != c.im);
}
// NEGATE
Complex Complex::operator - ()
{
return Complex(-re, -im);
}
// BASIC MATH
Complex Complex::operator + (Complex c)
{
return Complex(re + c.re, im + c.im);
}
Complex Complex::operator - (Complex c)
{
return Complex(re - c.re, im - c.im);
}
Complex Complex::operator * (Complex c)
{
double r = re * c.re - im * c.im;
double i = re * c.im + im * c.re;
return Complex(r, i);
}
Complex Complex::operator / (Complex c)
{
double f = 1.0/(c.re*c.re + c.im*c.im);
double r = re * c.re + im * c.im;
double i = im * c.re - re * c.im;
return Complex(r * f, i * f);
}
void Complex::operator += (Complex c)
{
re += c.re;
im += c.im;
}
void Complex::operator -= (Complex c)
{
re -= c.re;
im -= c.im;
}
void Complex::operator *= (Complex c)
{
double r = re * c.re - im * c.im;
double i = re * c.im + im * c.re;
re = r;
im = i;
}
void Complex::operator /= (Complex c)
{
double f = 1.0/(c.re*c.re + c.im*c.im);
double r = re * c.re + im * c.im;
double i = re * c.im - im * c.re;
re = r*f;
im = -i*f;
}
#ifdef COMPLEX_EXTENDED
//
// POWER FUNCTIONS
//
Complex Complex::c_sqr()
{
double r = re * re - im * im;
double i = 2 * re * im;
return Complex(r,i);
}
Complex Complex::c_sqrt()
{
double m = modulus();
double r = sqrt(0.5 * (m+re));
double i = sqrt(0.5 * (m-re));
if (im < 0) i = -i;
return Complex(r,i);
}
Complex Complex::c_exp()
{
double e = exp(re);
return Complex(e * cos(im), e * sin(im));
}
Complex Complex::c_log()
{
double m = modulus();
double p = phase();
if (p > PI) p -= 2*PI;
return Complex(log(m), p);
}
Complex Complex::c_pow(Complex c)
{
Complex t = c * c_log();
return t.c_exp();
}
Complex Complex::c_logn(Complex c)
{
return c_log()/c.c_log();
}
Complex Complex::c_log10()
{
return c_logn(10);
}
#endif
#ifdef COMPLEX_GONIO_1
//
// GONIO I - SIN COS TAN
//
Complex Complex::c_sin()
{
return Complex(sin(re) * cosh(im), cos(re) * sinh(im));
}
Complex Complex::c_cos()
{
return Complex(cos(re) * cosh(im), -sin(re) * sinh(im));
}
Complex Complex::c_tan()
{
/* faster but 350 bytes longer!!
double s = sin(re);
double c = cos(re);
double sh = sinh(im);
double ch = cosh(im);
// return Complex(s*ch, c*sh) / Complex(c*ch, -s*sh);
double r0 = s*ch;
double i0 = c*sh;
double cre = c*ch;
double cim = -s*sh;
double f = 1.0/(cre*cre + cim*cim);
double r = r0 * cre + i0 * cim;
double i = r0 * cim - i0 * cre;
return Complex(r * f, -i * f);
*/
return c_sin() / c_cos();
}
Complex Complex::gonioHelper1(int mode)
{
Complex c = (one - this->c_sqr()).c_sqrt();
if (mode == 0)
{
c = c + *this * Complex(0,-1);
}
else
{
c = *this + c * Complex(0,-1);
}
c = c.c_log() * Complex(0,1);
return c;
}
Complex Complex::c_asin()
{
return gonioHelper1(0);
}
Complex Complex::c_acos()
{
return gonioHelper1(1);
}
Complex Complex::c_atan()
{
return (Complex(0,-1) * (Complex(re, im - 1)/Complex(-re, -im - 1)).c_log())/2;
}
#endif
#ifdef COMPLEX_GONIO_2
//
// GONIO II - CSC SEC COT
//
Complex Complex::c_csc()
{
return one / c_sin();
}
Complex Complex::c_sec()
{
return one / c_cos();
}
Complex Complex::c_cot()
{
return one / c_tan();
}
Complex Complex::c_acsc()
{
return (one / *this).c_asin();
}
Complex Complex::c_asec()
{
return (one / *this).c_acos();
}
Complex Complex::c_acot()
{
return (one / *this).c_atan();
}
#endif
#ifdef COMPLEX_GONIO_3
//
// GONIO HYPERBOLICUS I
//
Complex Complex::c_sinh()
{
return Complex(sinh(re) * cos(im), cosh(re)* sin(im));
}
Complex Complex::c_cosh()
{
return Complex(cosh(re) * cos(im), sinh(re)* sin(im));
}
Complex Complex::c_tanh()
{
return c_sinh() / c_cosh();
}
Complex Complex::gonioHelper2(int mode)
{
Complex c = c_sqr();
if (mode==0)
{
c += 1;
}
else
{
c -= 1;
}
c = (*this + c.c_sqrt()).c_log();
return c;
}
Complex Complex::c_asinh()
{
return gonioHelper2(0);
}
Complex Complex::c_acosh()
{
return gonioHelper2(1);
}
Complex Complex::c_atanh()
{
Complex c = (*this + one).c_log();
c = c - (-(*this - one)).c_log();
return c/2;
}
#endif
#ifdef COMPLEX_GONIO_4
//
// GONIO HYPERBOLICUS II
//
Complex Complex::c_csch()
{
return one / c_sinh();
}
Complex Complex::c_sech()
{
return one / c_cosh();
}
Complex Complex::c_coth()
{
return one / c_tanh();
}
Complex Complex::c_acsch()
{
return (one / *this).c_asinh();
}
Complex Complex::c_asech()
{
return (one / *this).c_acosh();
}
Complex Complex::c_acoth()
{
return (one / *this).c_atanh();
}
#endif
// --- END OF FILE ---