// File: /workspace/github_c_makefile_star2_O3/cyb70289[P]tt/tests/dft.c
// Function: main
int main(void)
{
	double in[8][2] = {
		{ 0.3535, 0 },
		{ 0.3535, 0 },
		{ 0.6464, 0 },
		{ 1.0607, 0 },
		{ 0.3535, 0 },
		{ -1.0607, 0 },
		{ -1.3535, 0 },
		{ -0.3535, 0 },
	};

	double out[8][2];
	tt_fft(out, in, 8);
	printf("DFT:\n");
	for (int i = 0; i < 8; i++)
		printf("%.4f + %.4fj\n", out[i][0], out[i][1]);

	double in2[8];
	for (int i = 0; i < 8; i++)
		in2[i] = in[i][0];
	tt_fft_real(out, in2, 8);
	printf("\nDFT(real):\n");
	for (int i = 0; i < 8; i++)
		printf("%.4f + %.4fj\n", out[i][0], out[i][1]);

	tt_ifft(in, out, 8);

	printf("\nIDFT:\n");
	for (int i = 0; i < 8; i++)
		printf("%.4f + %.4fj\n", in[i][0], in[i][1]);

	printf("\nDFT Leakage(peak at 6.2):\n");
	double sample[32][2];
	sample_sine(1000, 5000, 32, sample);	/* 32 / (5000 / 1000) = 6.2 */

	double dft[32][2];
	tt_fft(dft, sample, 32);

	double max = 0, mag[32];
	for (int i = 0; i < 32; i++) {
		mag[i] = sqrt(dft[i][0] * dft[i][0] + dft[i][1] * dft[i][1]);
		if (mag[i] > max)
			max = mag[i];
	}

	double ratio = 77 / max;
	for (int i = 0; i < 32; i++) {
		printf("%02d", i);
		int l = (int)round(mag[i] * ratio);
		while (l--)
			putchar('-');
		putchar('\n');
	};

	printf("\nSINC(5 ones):\n");
	sample_rect(5, 32, sample);
	tt_fft(dft, sample, 32);

	max = 0;
	for (int i = 0; i < 32; i++) {
		mag[i] = sqrt(dft[i][0] * dft[i][0] + dft[i][1] * dft[i][1]);
		if (mag[i] > max)
			max = mag[i];
	}

	ratio = 77 / max;
	for (int i = 0; i < 32; i++) {
		printf("%02d", i);
		int l = (int)round(mag[i] * ratio);
		while (l--)
			putchar('-');
		putchar('\n');
	};

#if 0
	/* FFT fast multiplication */
	uint ai = 12345678, bi = 87654321;
	double a[4] = { ai & 0xFFFF, ai >> 16, 0 , 0 };
	double b[4] = { bi & 0xFFFF, bi >> 16, 0 , 0 };
	double c[4][2];
	double A[4][2], B[4][2], C[4][2];
	tt_fft_real(A, a, 4);
	tt_fft_real(B, b, 4);
	for (int i = 0; i < 4; i++)
		tt_complex_mul(C[i], A[i], B[i]);
	tt_ifft(c, C, 4);
	printf("%u * %u = ", ai, bi);
	for (int i = 2; i >= 0; i--) {
		printf("(%.0f << %d)", c[i][0], 16 * i);
		if (i)
			printf(" + ");
	}
	printf("\n");
#endif

#if 0
	/* FFT rounding error */
	#define N	1024
	double a[N*2], b[N*2], c[N*2][2];
	double A[N*2][2], B[N*2][2], C[N*2][2];
	for (int i = 0; i < N; i++)
		a[i] = b[i] = 65535;
	for (int i = N; i < N*2; i++)
		a[i] = b[i] = 0;
	tt_fft_real(A, a, N*2);
	tt_fft_real(B, b, N*2);
	for (int i = 0; i < N*2; i++)
		tt_complex_mul(C[i], A[i], B[i]);
	tt_ifft(c, C, N*2);
	for (int i = 0; i < N*2; i++)
		if (fabs(c[i][1]) >  0.4)
			printf("%f %f\n", c[i][0], c[i][1]);
#endif

	return 0;
}

// Assembly:
pushq %rbp
pushq %r14
pushq %rbx
subq $0x650, %rsp            # imm = 0x650
leaq 0x3902(%rip), %rsi      # 0x5020
leaq 0x90(%rsp), %rax
movl $0x10, %ecx
movq %rax, %rdi
rep  movsq (%rsi), %es:(%rdi)
leaq 0x10(%rsp), %rdi
movq %rax, %rsi
movl $0x8, %edx
callq 0x23cb
leaq 0x3977(%rip), %rdi      # 0x50c1
callq 0x1070
xorl %r14d, %r14d
leaq 0x3947(%rip), %rbx      # 0x50a0
movsd 0x10(%rsp,%r14), %xmm0
movsd 0x18(%rsp,%r14), %xmm1
movq %rbx, %rdi
movb $0x2, %al
callq 0x10c0
addq $0x10, %r14
cmpq $0x80, %r14
jne 0x1759
xorl %eax, %eax
movsd 0x90(%rsp,%rax,2), %xmm0
movhpd 0xa0(%rsp,%rax,2), %xmm0 # xmm0 = xmm0[0],mem[0]
movapd %xmm0, 0x110(%rsp,%rax)
addq $0x10, %rax
cmpq $0x40, %rax
jne 0x1780
leaq 0x10(%rsp), %rdi
leaq 0x110(%rsp), %rsi
movl $0x8, %edx
callq 0x2870
leaq 0x38f0(%rip), %rdi      # 0x50b3
callq 0x1070
xorl %r14d, %r14d
leaq 0x38ce(%rip), %rbx      # 0x50a0
movsd 0x10(%rsp,%r14), %xmm0
movsd 0x18(%rsp,%r14), %xmm1
movq %rbx, %rdi
movb $0x2, %al
callq 0x10c0
addq $0x10, %r14
cmpq $0x80, %r14
jne 0x17d2
leaq 0x90(%rsp), %rdi
leaq 0x10(%rsp), %rsi
movl $0x8, %edx
callq 0x2682
leaq 0x38aa(%rip), %rdi      # 0x50bf
callq 0x1070
xorl %r14d, %r14d
leaq 0x387c(%rip), %rbx      # 0x50a0
movsd 0x90(%rsp,%r14), %xmm0
movsd 0x98(%rsp,%r14), %xmm1
movq %rbx, %rdi
movb $0x2, %al
callq 0x10c0
addq $0x10, %r14
cmpq $0x80, %r14
jne 0x1824
leaq 0x3870(%rip), %rdi      # 0x50c6
callq 0x1070
xorpd %xmm0, %xmm0
movl $0x8, %ebx
movsd %xmm0, (%rsp)
movsd (%rsp), %xmm0
callq 0x1160
movsd %xmm0, 0x448(%rsp,%rbx)
movsd (%rsp), %xmm0
movq $0x0, 0x450(%rsp,%rbx)
addsd 0x3773(%rip), %xmm0     # 0x5008
addq $0x10, %rbx
cmpq $0x208, %rbx            # imm = 0x208
jne 0x1864
leaq 0x250(%rsp), %rdi
leaq 0x450(%rsp), %rsi
movl $0x20, %edx
callq 0x23cb
xorpd %xmm0, %xmm0
xorl %eax, %eax
movapd %xmm0, %xmm1
movsd 0x250(%rsp,%rax,2), %xmm0
movsd 0x258(%rsp,%rax,2), %xmm2
mulsd %xmm2, %xmm2
mulsd %xmm0, %xmm0
addsd %xmm2, %xmm0
sqrtsd %xmm0, %xmm0
movsd %xmm0, 0x150(%rsp,%rax)
maxsd %xmm1, %xmm0
addq $0x8, %rax
cmpq $0x100, %rax            # imm = 0x100
jne 0x18c2
movsd 0x3707(%rip), %xmm1     # 0x5010
movsd %xmm1, (%rsp)
divsd %xmm0, %xmm1
movsd %xmm1, 0x8(%rsp)
leaq 0x378f(%rip), %rbx      # 0x50ae
xorl %r14d, %r14d
movq %rbx, %rdi
movl %r14d, %esi
xorl %eax, %eax
callq 0x10c0
movsd 0x150(%rsp,%r14,8), %xmm0
mulsd 0x8(%rsp), %xmm0
callq 0x1060
cvttsd2si %xmm0, %ebp
testl %ebp, %ebp
je 0x195a
movl $0x2d, %edi
callq 0x1040
decl %ebp
jne 0x194c
movl $0xa, %edi
callq 0x1040
incq %r14
cmpq $0x20, %r14
jne 0x1922
leaq 0x376d(%rip), %rdi      # 0x50e1
callq 0x1070
xorl %eax, %eax
movsd 0x3695(%rip), %xmm0     # 0x5018
movapd %xmm0, 0x450(%rsp,%rax)
addq $0x10, %rax
cmpq $0x50, %rax
jne 0x1983
leaq 0x4a0(%rsp), %rdi
xorl %ebx, %ebx
movl $0x1b0, %edx            # imm = 0x1B0
xorl %esi, %esi
callq 0x10e0
leaq 0x250(%rsp), %rdi
leaq 0x450(%rsp), %rsi
movl $0x20, %edx
callq 0x23cb
xorpd %xmm0, %xmm0
movapd %xmm0, %xmm1
movsd 0x250(%rsp,%rbx,2), %xmm0
movsd 0x258(%rsp,%rbx,2), %xmm2
mulsd %xmm2, %xmm2
mulsd %xmm0, %xmm0
addsd %xmm2, %xmm0
sqrtsd %xmm0, %xmm0
movsd %xmm0, 0x150(%rsp,%rbx)
maxsd %xmm1, %xmm0
addq $0x8, %rbx
cmpq $0x100, %rbx            # imm = 0x100
jne 0x19ca
movsd (%rsp), %xmm1
divsd %xmm0, %xmm1
movsd %xmm1, (%rsp)
leaq 0x368f(%rip), %rbx      # 0x50ae
xorl %r14d, %r14d
movq %rbx, %rdi
movl %r14d, %esi
xorl %eax, %eax
callq 0x10c0
movsd 0x150(%rsp,%r14,8), %xmm0
mulsd (%rsp), %xmm0
callq 0x1060
cvttsd2si %xmm0, %ebp
testl %ebp, %ebp
je 0x1a59
movl $0x2d, %edi
callq 0x1040
decl %ebp
jne 0x1a4b
movl $0xa, %edi
callq 0x1040
incq %r14
cmpq $0x20, %r14
jne 0x1a22
xorl %eax, %eax
addq $0x650, %rsp            # imm = 0x650
popq %rbx
popq %r14
popq %rbp
retq
nop