Arduino Playground is read-only starting December 31st, 2018. For more info please look at this Forum Post

A complex math library for Arduino.

Last Modified: October 18, 2015, at 06:19 AM
By:
Platforms: All (no hw dependencies)

Forum Thread for remarks

The latest version of the lib is in the above thread and can also be found on github

Complex Math

A complex number is a compound datatype that can be represented as a point in a (numeric) plane, so it needs 2 doubles. These are called the Real part and the imaginary part.

Although most sketches for the Arduino can be solved by using integer or float math, sometimes you need complex numbers. For those occasions this library is written. The set of functions is quite complete but more can be added.

A library is always in progress, and there might be changes and optimizations overtime as the functions are now member functions and I rather prefer to make several of them static so it behaves like the math.h lib.

The output generated by the test sketch is identical for both IDE 0.22 and IDE 1.0 but the size of the test sketch differs: - 0.22: 18594 - 1.0: 19050 => 456 bytes

Size

The library is really BIG if you use all functions (like the test app) so stripping it into a version which includes only the used functions is an option. The compiler does a good job here.

  • added in 0.1.04: The library has #defines in the complex.h file to exclude parts of the complex class.
#define COMPLEX_EXTENDED
#define COMPLEX_GONIO_1
#define COMPLEX_GONIO_2 
#define COMPLEX_GONIO_3 
#define COMPLEX_GONIO_4 

  • removed in 0.1.09 as compiler does handle this.

Performance

The library is work in progress and little time is spent yet to optimize speed and size. In fact I do not expect many optimizations possible. Furthermore as all complex functions need multiple float operations you should never expect high performances - now or in the future - of this lib on the Arduino (328) platform.

Todo

  • Make static functions like math.h
  • optimize speed
  • Mandelbrot demo

Code (test sketch)

The test code shows how the lib can currently (0.1.04) be used.

//
//    FILE: complex.ino
//  AUTHOR: Rob Tillaart
//    DATE: 2012-03-10
//
// PUPROSE: test complex math
//

#include "complex.h"

void PrintComplex(Complex c)
{
  Serial.print(c.real(),3);
  Serial.print("\t ");
  Serial.print(c.imag(),3);
  Serial.println("i");
}

void setup()
{
  Serial.begin(115200);
  Serial.println("\n  Complex numbers test for Arduino"); 
  Serial.println("\n1. PrintComplex");

  Complex c1(10.0,-2.0);
  Complex c2(3,0);
  Complex c3(-10,4);
  Complex c4(-5,-5);
  Complex c5(0,0);

  PrintComplex(c1);        PrintComplex(c2);
  PrintComplex(c3);        PrintComplex(c4);
  c3.set(0,0);             PrintComplex(c3);

  Serial.println("\n2. ==  != ");
  c5 = c1;
  if (c5 == c1) Serial.println("ok :)");
  else Serial.println(" fail :(");
  c5 = c1 + 1;
  if (c5 != c1) Serial.println("ok :)");
  else Serial.println(" fail :(");
  c5 = 3;
  if (c5 == 3) Serial.println("ok :)");
  else Serial.println(" fail :(");


  Serial.println("\n3. negation - ");
  c5 = -c1;                PrintComplex(c5);
  c5 = -c5;                PrintComplex(c5);
  if (c5 == c1) Serial.println("ok :)");
  else Serial.println(" fail :(");


  Serial.println("\n4. + - ");
  c5 = c1 + c2;            PrintComplex(c5);
  c5 = c1 + 3;             PrintComplex(c5);
  c5 = c1 - c2;            PrintComplex(c5);
  c5 = c1 - 3;             PrintComplex(c5);


  Serial.println("\n5. * / ");
  c5 = c1 * c2;            PrintComplex(c5);
  c5 = c5 * 3;             PrintComplex(c5);
  c5 = c5 / c2;            PrintComplex(c5);
  c5 = c5 / 3;             PrintComplex(c5);

  c5 = c1 / c2 * c2;       PrintComplex(c5);  
  c5 = c1 * c4 / c4;       PrintComplex(c5);  


  Serial.println("\n6. assign += -= etc");
  c5 = c1;
  c5 += c1;                PrintComplex(c5);
  c5 += 3;                 PrintComplex(c5);
  c5 -= c1;                PrintComplex(c5);
  c5 -= 3;                 PrintComplex(c5);
  c5 *= c1;                PrintComplex(c5);
  c5 *= 3;                 PrintComplex(c5);
  c5 /= c1;                PrintComplex(c5);
  c5 /= 3;                 PrintComplex(c5);


  Serial.println("\n7. phase modulus polar");
  double m = c1.modulus(); Serial.println(m);
  double p = c1.phase();   Serial.println(p);
  c5.polar(m, p);          PrintComplex(c5);


  Serial.println("\n8. conjugate & reciprocal");
  c5 = c1.conjugate();     PrintComplex(c5);
  c5 = c5.conjugate();     PrintComplex(c5);
  c5 = c1.reciprocal();    PrintComplex(c5);
  c5 = c5.reciprocal();    PrintComplex(c5);

#ifdef COMPLEX_EXTENDED  
  Serial.println("\n9. power: exp log pow sqrt logn log10");
  c5 = c1.c_exp();         PrintComplex(c5);
  c5 = c5.c_log();         PrintComplex(c5);
  c5 = c1.c_pow(2);        PrintComplex(c5);
  c5 = c5.c_sqrt();        PrintComplex(c5);
  c5 = c1.c_pow(c2);       PrintComplex(c5);
  c5 = c5.c_pow(c2.reciprocal());       PrintComplex(c5);
  c5 = c5.c_logn(c4);       PrintComplex(c5);
  c5 = c4.c_pow(c5);        PrintComplex(c5);
  c5 = c5.c_log10();        PrintComplex(c5);
#endif

#ifdef COMPLEX_GONIO_1
  Serial.println("\n10. gonio: sin cos tan asin acos atan");
  c1.set(0.5, 0.5);
  c5 = c1.c_sin();         PrintComplex(c5);
  c5 = c5.c_asin();        PrintComplex(c5); 
  c5 = c1.c_cos();         PrintComplex(c5);
  c5 = c5.c_acos();        PrintComplex(c5);
  c5 = c1.c_tan();         PrintComplex(c5);
  c5 = c5.c_atan();        PrintComplex(c5);
#endif

#ifdef COMPLEX_GONIO_2
  Serial.println("\n11. gonio csc sec cot acsc asec acot");
  c1.set(0.5, 0.5);
  c5 = c1.c_csc();         PrintComplex(c5);
  c5 = c5.c_acsc();        PrintComplex(c5); 
  c5 = c1.c_sec();         PrintComplex(c5);
  c5 = c5.c_asec();        PrintComplex(c5);
  c5 = c1.c_cot();         PrintComplex(c5);
  c5 = c5.c_acot();        PrintComplex(c5);
#endif

#ifdef COMPLEX_GONIO_3
  Serial.println("\n12. gonio hyperbolicus I ");
  c1.set(0.5, 0.5);
  c5 = c1.c_sinh();         PrintComplex(c5);
  c5 = c5.c_asinh();        PrintComplex(c5); 
  c5 = c1.c_cosh();         PrintComplex(c5);
  c5 = c5.c_acosh();        PrintComplex(c5);
  c5 = c1.c_tanh();         PrintComplex(c5);
  c5 = c5.c_atanh();        PrintComplex(c5);
#endif

#ifdef COMPLEX_GONIO_4
  Serial.println("\n13. gonio hyperbolicus II ");
  c1.set(0.5, 0.5);
  c5 = c1.c_csch();         PrintComplex(c5);
  c5 = c5.c_acsch();        PrintComplex(c5); 
  c5 = c1.c_sech();         PrintComplex(c5);
  c5 = c5.c_asech();        PrintComplex(c5);
  c5 = c1.c_coth();         PrintComplex(c5);
  c5 = c5.c_acoth();        PrintComplex(c5);
#endif

  Serial.println("\n.. Complex done");  
}

void loop()
{
}
//
// END OF FILE
//