// File: /workspace/github_c_makefile_star2_O2/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 %r15
pushq %r14
pushq %r12
pushq %rbx
subq $0x650, %rsp            # imm = 0x650
leaq 0x3d7e(%rip), %rsi      # 0x5020
pushq $0x10
popq %rcx
leaq 0x90(%rsp), %rax
movq %rax, %rdi
rep  movsq (%rsi), %es:(%rdi)
leaq 0x10(%rsp), %rdi
pushq $0x8
popq %rdx
movq %rax, %rsi
callq 0x20d1
leaq 0x3df7(%rip), %rdi      # 0x50c1
callq 0x1070
pushq $0x8
popq %r14
leaq 0x3dc6(%rip), %rbx      # 0x50a0
cmpq $0x88, %r14
je 0x1301
movsd 0x8(%rsp,%r14), %xmm0
movsd 0x10(%rsp,%r14), %xmm1
movq %rbx, %rdi
movb $0x2, %al
callq 0x10c0
addq $0x10, %r14
jmp 0x12da
xorl %eax, %eax
cmpq $0x40, %rax
je 0x1321
movsd 0x90(%rsp,%rax,2), %xmm0
movsd %xmm0, 0x110(%rsp,%rax)
addq $0x8, %rax
jmp 0x1303
leaq 0x10(%rsp), %rdi
leaq 0x110(%rsp), %rsi
pushq $0x8
popq %rdx
callq 0x24ed
leaq 0x3d76(%rip), %rdi      # 0x50b3
callq 0x1070
pushq $0x8
popq %r14
leaq 0x3d53(%rip), %rbx      # 0x50a0
cmpq $0x88, %r14
je 0x1374
movsd 0x8(%rsp,%r14), %xmm0
movsd 0x10(%rsp,%r14), %xmm1
movq %rbx, %rdi
movb $0x2, %al
callq 0x10c0
addq $0x10, %r14
jmp 0x134d
leaq 0x90(%rsp), %rdi
leaq 0x10(%rsp), %rsi
pushq $0x8
popq %rdx
callq 0x232b
leaq 0x3d2f(%rip), %rdi      # 0x50bf
callq 0x1070
pushq $0x8
popq %r14
leaq 0x3d00(%rip), %rbx      # 0x50a0
cmpq $0x88, %r14
je 0x13cd
movsd 0x88(%rsp,%r14), %xmm0
movsd 0x90(%rsp,%r14), %xmm1
movq %rbx, %rdi
movb $0x2, %al
callq 0x10c0
addq $0x10, %r14
jmp 0x13a0
leaq 0x3cf2(%rip), %rdi      # 0x50c6
callq 0x1070
xorpd %xmm0, %xmm0
xorl %ebx, %ebx
cmpq $0x200, %rbx            # imm = 0x200
je 0x141c
movsd %xmm0, (%rsp)
movsd (%rsp), %xmm0
callq 0x1150
movsd %xmm0, 0x450(%rsp,%rbx)
movsd (%rsp), %xmm0
andq $0x0, 0x458(%rsp,%rbx)
addsd 0x3bf2(%rip), %xmm0     # 0x5008
addq $0x10, %rbx
jmp 0x13df
leaq 0x250(%rsp), %rdi
leaq 0x450(%rsp), %rsi
pushq $0x20
popq %rdx
callq 0x20d1
xorpd %xmm0, %xmm0
xorl %eax, %eax
cmpq $0x100, %rax            # imm = 0x100
je 0x147b
movsd 0x250(%rsp,%rax,2), %xmm1
movsd 0x258(%rsp,%rax,2), %xmm2
mulsd %xmm2, %xmm2
mulsd %xmm1, %xmm1
addsd %xmm2, %xmm1
sqrtsd %xmm1, %xmm1
movsd %xmm1, 0x150(%rsp,%rax)
maxsd %xmm0, %xmm1
addq $0x8, %rax
movapd %xmm1, %xmm0
jmp 0x143a
movsd 0x3b8d(%rip), %xmm1     # 0x5010
movsd %xmm1, (%rsp)
divsd %xmm0, %xmm1
movsd %xmm1, 0x8(%rsp)
leaq 0x3c15(%rip), %rbx      # 0x50ae
pushq $0xa
popq %rbp
pushq $0x2d
popq %r14
xorl %r15d, %r15d
cmpq $0x20, %r15
je 0x14ec
movq %rbx, %rdi
movl %r15d, %esi
xorl %eax, %eax
callq 0x10c0
movsd 0x150(%rsp,%r15,8), %xmm0
mulsd 0x8(%rsp), %xmm0
callq 0x1060
cvttsd2si %xmm0, %r12d
subl $0x1, %r12d
jb 0x14e0
movl %r14d, %edi
callq 0x1040
jmp 0x14d0
movl %ebp, %edi
callq 0x1040
incq %r15
jmp 0x14a3
leaq 0x3bee(%rip), %rdi      # 0x50e1
callq 0x1070
xorl %eax, %eax
movsd 0x3b16(%rip), %xmm0     # 0x5018
cmpq $0x50, %rax
je 0x1517
movapd %xmm0, 0x450(%rsp,%rax)
addq $0x10, %rax
jmp 0x1502
pushq $0x50
popq %rax
xorpd %xmm0, %xmm0
cmpq $0x200, %rax            # imm = 0x200
je 0x1535
movapd %xmm0, 0x450(%rsp,%rax)
addq $0x10, %rax
jmp 0x151e
leaq 0x250(%rsp), %rdi
leaq 0x450(%rsp), %rsi
pushq $0x20
popq %rdx
callq 0x20d1
xorpd %xmm0, %xmm0
xorl %eax, %eax
cmpq $0x100, %rax            # imm = 0x100
je 0x1594
movsd 0x250(%rsp,%rax,2), %xmm1
movsd 0x258(%rsp,%rax,2), %xmm2
mulsd %xmm2, %xmm2
mulsd %xmm1, %xmm1
addsd %xmm2, %xmm1
sqrtsd %xmm1, %xmm1
movsd %xmm1, 0x150(%rsp,%rax)
maxsd %xmm0, %xmm1
addq $0x8, %rax
movapd %xmm1, %xmm0
jmp 0x1553
movsd (%rsp), %xmm1
divsd %xmm0, %xmm1
movsd %xmm1, (%rsp)
leaq 0x3b05(%rip), %rbx      # 0x50ae
pushq $0xa
popq %rbp
pushq $0x2d
popq %r14
xorl %r15d, %r15d
cmpq $0x20, %r15
je 0x15fb
movq %rbx, %rdi
movl %r15d, %esi
xorl %eax, %eax
callq 0x10c0
movsd 0x150(%rsp,%r15,8), %xmm0
mulsd (%rsp), %xmm0
callq 0x1060
cvttsd2si %xmm0, %r12d
subl $0x1, %r12d
jb 0x15ef
movl %r14d, %edi
callq 0x1040
jmp 0x15df
movl %ebp, %edi
callq 0x1040
incq %r15
jmp 0x15b3
xorl %eax, %eax
addq $0x650, %rsp            # imm = 0x650
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
retq
nopl (%rax)