Programing errors from C to Arduino

Hi

I converted the following program in C

#include <stdio.h>
#include <math.h>
#include <complex.h>
 
double PI;
typedef double complex cplx;
 
void _fft(cplx buf[], cplx out[], int n, int step)
{
	if (step < n) {
		_fft(out, buf, n, step * 2);
		_fft(out + step, buf + step, n, step * 2);
 
		for (int i = 0; i < n; i += 2 * step) {
			cplx t = cexp(-I * PI * i / n) * out[i + step];
			buf[i / 2]     = out[i] + t;
			buf[(i + n)/2] = out[i] - t;
		}
	}
}
 
void fft(cplx buf[], int n)
{
	cplx out[n];
	for (int i = 0; i < n; i++) out[i] = buf[i];
 
	_fft(buf, out, n, 1);
}
 
 
void show(const char * s, cplx buf[]) {
	printf("%s", s);
	for (int i = 0; i < 8; i++)
		if (!cimag(buf[i]))
			printf("%g ", creal(buf[i]));
		else
			printf("(%g, %g) ", creal(buf[i]), cimag(buf[i]));
}
 
int main()
{
	PI = atan2(1, 1) * 4;
	cplx buf[] = {1, 1, 1, 1, 0, 0, 0, 0};
 
	show("Data: ", buf);
	fft(buf, 8);
	show("\nFFT : ", buf);
 
	return 0;
}

into Arduino as such

double PI;
typedef double complex cplx;

void _fft(cplx buf[], cplx out[], int n, int step)
{
  if (step < n) {
    _fft(out, buf, n, step * 2);
    _fft(out + step, buf + step, n, step * 2);
 
    for (int i = 0; i < n; i += 2 * step) {
      cplx t = cexp(-I * PI * i / n) * out[i + step];
      buf[i / 2]     = out[i] + t;
      buf[(i + n)/2] = out[i] - t;
    }
  }
}
 
void fft(cplx buf[], int n)
{
  cplx out[n];
  for (int i = 0; i < n; i++) out[i] = buf[i];
 
  _fft(buf, out, n, 1);
}

void show(const char * s, cplx buf[]) {
  Serial.print("%s", s);
  for (int i = 0; i < 8; i++)
    if (!cimag(buf[i]))
      Serial.print("%g ", creal(buf[i]));
    else
      Serial.println("(%g, %g) ", creal(buf[i]), cimag(buf[i]));
}

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
}


void loop() {
  // put your main code here, to run repeatedly:
  PI = atan2(1, 1) * 4;
  cplx buf[] = {1, 1, 1, 1, 0, 0, 0, 0};
 
  show("Data: ", buf);
  fft(buf, 8);
  show("\nFFT : ", buf);

}

Upon compiling, I get error,

expected initializer before 'cplx'

How do I solve it??

typedef double complex cplx;

What do you think this is doing? A typedef statement takes a type and a name that you want to use in its place. Since the type is double, that means that you want to be able to use "complex cplx" in it's place.

But that is:
a) not allowed. A typedef'd name can not have spaces
b) not what you are trying to use as the new name

Unfortunately that isn’t going to be your last problem either:

cplx t = cexp(-I * PI * i / n) * out[i + step];

is calling into a C++ library that handles complex numbers. As is creal(…) and cimag(…)

I’d recommend searching for an Arduino specific FFT library in the first instance. This post, for example, discusses a couple: https://forum.arduino.cc/index.php?topic=299461.0

PaulS:

typedef double complex cplx;

What do you think this is doing? A typedef statement takes a type and a name that you want to use in its place. Since the type is double, that means that you want to be able to use "complex cplx" in it's place.

But that is:
a) not allowed. A typedef'd name can not have spaces
b) not what you are trying to use as the new name

How do I define it then??

How do I define it then??

That would depend on what "it" is, don't you think?

typedef double complex cplx;

the thing is, I don't see how this would be legal in normal C either.
Where did you get complex.h?

typedef complex cplx;

Would be more likely.

westfw:
the thing is, I don't see how this would be legal in normal C either.
Where did you get complex.h?

Would be more likely.

I'll try that

I intend to use FFT in arduino and the Module that I use for long distance data transfer does not support Arduino libraries.

C99 added a complex library.
http://en.cppreference.com/w/c/numeric/complex

I don't know whether that is available in the AVR toolchain.

Ah. If C99 added a complex type to the language, then it need not obey the same sort of typedef restrictions or syntax as it would if you were implementing it as a manually-tacked-on addition using macros/etc.

I see Complex (Using the GNU Compiler Collection (GCC))

This suggests that you would want

typedef double _Complex cplx;

Note that on AVR, a double is the same as a float.

As Paul_Martinsen points out, this is likely to be only the beginning of your problems, since I don't think that the avr libraries include any of the complex math functions. (but they might be off in gcclib instead?) You might have better luck on a Due or Zero.

Even if it does have the functions, it will be really slooooowwww.