// File: /workspace/github_cpp_makefile_star2_O2/kebwi[P]Trifid/src/FourierTransform.cpp
// Function: fourierTest()
void fourierTest()
{
	SeedRandom(0);
	
	cout << "Float type sizes on this machine:" << endl;
	cout << "    float:       " << sizeof(float) << endl;
	cout << "    double:      " << sizeof(double) << endl;
	cout << "    long double: " << sizeof(long double) << endl;
	cout << endl;
	
	cout << "Fourier Transform correctness test:" << endl;
	cout << "This test being performed with a floating point type of size: " << sizeof(Float_t) << endl;
	cout << "See FloatType.h for information on how to set the floating point type." << endl;
	cout << endl;
	
	Float_t a[16];
	for (int j = 0; j < 4; j++)
		for (int i = 0; i < 4; i++)
			a[j * 4 + i] = RandZeroFloat(1.0);
	
	cout.precision(8);
	cout << "Input array and copy/paste for matlab script:" << endl;
	cout << "a = [ ";
	for (int j = 0; j < 4; j++)
		for (int i = 0; i < 4; i++)
		{
			cout << a[j * 4 + i];
			if (i != 4 - 1)
				cout << ", ";
			else if (j != 4 - 1)
				cout << "; ";
			else cout << " ]" << endl;
		}
	cout << "b = fft2(a)" << endl;
	cout << "c = ifft2(b)" << endl;
	cout << endl;
	
	cout << "Original signal:" << endl;
	for (int j = 0; j < 4; j++)
	{
		for (int i = 0; i < 4; i++)
			cout << setw(15) << a[j * 4 + i];
		cout << endl;
	}
	cout << endl;
	
	int err = fft2dInit(log2(4), log2(4));
	if (err != 0)
		cout << err << endl;
	
	rfft2d(a, log2(4), log2(4));
	
	cout << "Fourier Transform:" << endl;
	for (int j = 0; j < 4; j++)
	{
		for (int i = 0; i < 4; i++)
			cout << setw(15) << a[j * 4 + i];
		cout << endl;
	}
	cout << endl;
	
	rifft2d(a, log2(4), log2(4));
	
	cout << "Inverse Fourier Transform (should match original signal above):" << endl;
	for (int j = 0; j < 4; j++)
	{
		for (int i = 0; i < 4; i++)
			cout << setw(15) << a[j * 4 + i];
		cout << endl;
	}
	cout << endl;
	
	//=======================================================================
	
	cout << "Fourier Transform timing test" << endl;
	cout << "This test being performed with a floating point type of size: " << sizeof(Float_t) << endl;
	cout << "See FloatType.h for information on how to set the floating point type." << endl;
	cout << endl;
	
	int dim = 512;
	Float_t *a2 = new Float_t[dim * dim];
	for (int j = 0; j < dim; j++)
		for (int i = 0; i < dim; i++)
			a2[j * dim + i] = RandZeroFloat(1.0);
	
	err = fft2dInit(log2(dim), log2(dim));
	if (err != 0)
		cout << err << endl;
	
	Float_t meanTime_s = 0;
	int numPasses = 100;
	for (int i = 0; i < numPasses; i++)
	{
		unsigned long startTime = getCurrentTime_ms();
		rfft2d(a2, log2(dim), log2(dim));
		unsigned long elapsedTime = getCurrentTime_ms() - startTime;
		meanTime_s += (Float_t)elapsedTime / CURRENT_TIME_PER_SEC_F;
	}
	meanTime_s /= (Float_t)numPasses;
	cout << "Mean time to perform 2D Fourier Transform on a " << dim << " x " << dim << " image: "
		<< meanTime_s << " seconds" << endl << endl;
	
	delete [] a2;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x98, %rsp
xorl %r15d, %r15d
xorl %edi, %edi
callq 0x1c107
movq 0x1b29a(%rip), %rbx     # 0x2ffd0
leaq 0x10214(%rip), %rsi     # 0x24f51
movq %rbx, %rdi
callq 0x32c0
movq %rax, %rdi
callq 0x3120
leaq 0x1021f(%rip), %rsi     # 0x24f73
movq %rbx, %rdi
callq 0x32c0
pushq $0x4
popq %rsi
movq %rax, %rdi
callq 0x31c0
movq %rax, %rdi
callq 0x3120
leaq 0x1020f(%rip), %rsi     # 0x24f85
movq %rbx, %rdi
callq 0x32c0
pushq $0x8
popq %r14
movq %rax, %rdi
movq %r14, %rsi
callq 0x31c0
movq %rax, %rdi
callq 0x3120
leaq 0x101fb(%rip), %rsi     # 0x24f97
movq %rbx, %rdi
callq 0x32c0
pushq $0x10
popq %rsi
movq %rax, %rdi
callq 0x31c0
movq %rax, %rdi
callq 0x3120
movq %rbx, %rdi
callq 0x3120
leaq 0x101e3(%rip), %rsi     # 0x24fa9
movq %rbx, %rdi
callq 0x32c0
movq %rax, %rdi
callq 0x3120
leaq 0x101f0(%rip), %rsi     # 0x24fcd
movq %rbx, %rdi
callq 0x32c0
movq %rax, %rdi
movq %r14, %rsi
callq 0x31c0
movq %rax, %rdi
callq 0x3120
leaq 0x1020d(%rip), %rsi     # 0x2500c
movq %rbx, %rdi
callq 0x32c0
movq %rax, %rdi
callq 0x3120
movq %rbx, %rdi
callq 0x3120
leaq 0x10(%rsp), %r14
cmpq $0x4, %r15
je 0x14e4c
xorl %r12d, %r12d
cmpq $0x4, %r12
je 0x14e43
movsd 0xd225(%rip), %xmm0     # 0x22058
callq 0x1c13b
movsd %xmm0, (%r14,%r12,8)
incq %r12
jmp 0x14e25
incq %r15
addq $0x20, %r14
jmp 0x14e1c
movq (%rbx), %rax
movq -0x18(%rax), %rax
movq $0x8, 0x8(%rbx,%rax)
leaq 0x101f0(%rip), %rsi     # 0x25053
movq %rbx, %rdi
callq 0x32c0
movq %rax, %rdi
callq 0x3120
leaq 0x10207(%rip), %rsi     # 0x25081
movq %rbx, %rdi
callq 0x32c0
leaq 0x10(%rsp), %r13
xorl %ebp, %ebp
leaq 0x101f8(%rip), %r15     # 0x25088
leaq 0xf5d0(%rip), %r12      # 0x24467
cmpq $0x4, %rbp
je 0x14ef5
xorl %r14d, %r14d
cmpq $0x4, %r14
je 0x14eec
movsd (%r13,%r14,8), %xmm0
movq %rbx, %rdi
callq 0x3460
movq %rbx, %rdi
cmpq $0x3, %r14
jne 0x14eda
cmpq $0x3, %rbp
jne 0x14edf
leaq 0x101c0(%rip), %rsi     # 0x2508b
callq 0x32c0
movq %rax, %rdi
callq 0x3120
jmp 0x14ee7
movq %r12, %rsi
jmp 0x14ee2
movq %r15, %rsi
callq 0x32c0
incq %r14
jmp 0x14ea0
incq %rbp
addq $0x20, %r13
jmp 0x14e97
leaq 0x10192(%rip), %rsi     # 0x2508e
movq %rbx, %rdi
callq 0x32c0
movq %rax, %rdi
callq 0x3120
leaq 0x10187(%rip), %rsi     # 0x2509a
movq %rbx, %rdi
callq 0x32c0
movq %rax, %rdi
callq 0x3120
movq %rbx, %rdi
callq 0x3120
leaq 0x10175(%rip), %rsi     # 0x250a7
movq %rbx, %rdi
callq 0x32c0
movq %rax, %rdi
callq 0x3120
leaq 0x10(%rsp), %r14
xorl %r15d, %r15d
cmpq $0x4, %r15
je 0x14f8d
xorl %r12d, %r12d
cmpq $0x4, %r12
je 0x14f7c
movq (%rbx), %rax
movq -0x18(%rax), %rax
movq $0xf, 0x10(%rbx,%rax)
movsd (%r14,%r12,8), %xmm0
movq %rbx, %rdi
callq 0x3460
incq %r12
jmp 0x14f53
movq %rbx, %rdi
callq 0x3120
incq %r15
addq $0x20, %r14
jmp 0x14f4a
movq 0x1b03c(%rip), %rbx     # 0x2ffd0
movq %rbx, %rdi
callq 0x3120
pushq $0x2
popq %rdi
movq %rdi, %rsi
callq 0x1c4a0
testl %eax, %eax
je 0x14fc1
movq 0x1b01e(%rip), %rdi     # 0x2ffd0
movl %eax, %esi
callq 0x34b0
movq %rax, %rdi
callq 0x3120
leaq 0x10(%rsp), %r14
pushq $0x2
popq %rdx
movq %r14, %rdi
movq %rdx, %rsi
callq 0x1ce73
leaq 0x100dd(%rip), %rsi     # 0x250b8
movq %rbx, %rdi
callq 0x32c0
movq %rax, %rdi
callq 0x3120
xorl %r15d, %r15d
cmpq $0x4, %r15
je 0x15031
xorl %r12d, %r12d
cmpq $0x4, %r12
je 0x15020
movq (%rbx), %rax
movq -0x18(%rax), %rax
movq $0xf, 0x10(%rbx,%rax)
movsd (%r14,%r12,8), %xmm0
movq %rbx, %rdi
callq 0x3460
incq %r12
jmp 0x14ff7
movq %rbx, %rdi
callq 0x3120
incq %r15
addq $0x20, %r14
jmp 0x14fee
movq %rbx, %rdi
callq 0x3120
leaq 0x10(%rsp), %r14
pushq $0x2
popq %rdx
movq %r14, %rdi
movq %rdx, %rsi
callq 0x1d1be
leaq 0x10078(%rip), %rsi     # 0x250cb
movq %rbx, %rdi
callq 0x32c0
movq %rax, %rdi
callq 0x3120
xorl %r15d, %r15d
cmpq $0x4, %r15
je 0x150a9
xorl %r12d, %r12d
cmpq $0x4, %r12
je 0x15098
movq (%rbx), %rax
movq -0x18(%rax), %rax
movq $0xf, 0x10(%rbx,%rax)
movsd (%r14,%r12,8), %xmm0
movq %rbx, %rdi
callq 0x3460
incq %r12
jmp 0x1506f
movq %rbx, %rdi
callq 0x3120
incq %r15
addq $0x20, %r14
jmp 0x15066
movq 0x1af20(%rip), %rbx     # 0x2ffd0
movq %rbx, %rdi
callq 0x3120
leaq 0x1004c(%rip), %rsi     # 0x2510b
movq %rbx, %rdi
callq 0x32c0
movq %rax, %rdi
callq 0x3120
leaq 0xfef7(%rip), %rsi      # 0x24fcd
movq %rbx, %rdi
callq 0x32c0
pushq $0x8
popq %rsi
movq %rax, %rdi
callq 0x31c0
movq %rax, %rdi
callq 0x3120
leaq 0xff14(%rip), %rsi      # 0x2500c
movq %rbx, %rdi
callq 0x32c0
movq %rax, %rdi
callq 0x3120
movq %rbx, %rdi
callq 0x3120
movl $0x200000, %edi         # imm = 0x200000
callq 0x3030
movq %rax, %rbx
xorl %r14d, %r14d
movq %rax, %r15
cmpq $0x200, %r14            # imm = 0x200
je 0x1515c
xorl %r12d, %r12d
cmpq $0x200, %r12            # imm = 0x200
je 0x15150
movsd 0xcf18(%rip), %xmm0     # 0x22058
callq 0x1c13b
movsd %xmm0, (%r15,%r12,8)
incq %r12
jmp 0x1512f
incq %r14
addq $0x1000, %r15           # imm = 0x1000
jmp 0x15123
pushq $0x9
popq %rdi
movq %rdi, %rsi
callq 0x1c4a0
testl %eax, %eax
je 0x15181
movq 0x1ae5e(%rip), %rdi     # 0x2ffd0
movl %eax, %esi
callq 0x34b0
movq %rax, %rdi
callq 0x3120
xorpd %xmm0, %xmm0
pushq $0x64
popq %rbp
pushq $0x9
popq %r14
subl $0x1, %ebp
jb 0x151ea
movsd %xmm0, 0x8(%rsp)
callq 0x3c71
movq %rax, %r15
movq %rbx, %rdi
movq %r14, %rsi
movq %r14, %rdx
callq 0x1ce73
callq 0x3c71
subq %r15, %rax
movq %rax, %xmm0
punpckldq 0xce5e(%rip), %xmm0 # xmm0 = xmm0[0],mem[0],xmm0[1],mem[1]
subpd 0xce66(%rip), %xmm0     # 0x22030
movapd %xmm0, %xmm1
unpckhpd %xmm0, %xmm1            # xmm1 = xmm1[1],xmm0[1]
addsd %xmm0, %xmm1
movsd 0x8(%rsp), %xmm0
divsd 0xf9bc(%rip), %xmm1     # 0x24ba0
addsd %xmm1, %xmm0
jmp 0x1518c
divsd 0xe96e(%rip), %xmm0     # 0x23b60
movsd %xmm0, 0x8(%rsp)
movq 0x1add1(%rip), %rdi     # 0x2ffd0
leaq 0xff23(%rip), %rsi      # 0x25129
callq 0x32c0
movq %rax, %rdi
movl $0x200, %esi            # imm = 0x200
callq 0x34b0
leaq 0xff3a(%rip), %rsi      # 0x25159
movq %rax, %rdi
callq 0x32c0
movq %rax, %rdi
movl $0x200, %esi            # imm = 0x200
callq 0x34b0
leaq 0xff22(%rip), %rsi      # 0x2515d
movq %rax, %rdi
callq 0x32c0
movq %rax, %rdi
movsd 0x8(%rsp), %xmm0
callq 0x3460
leaq 0xff0e(%rip), %rsi      # 0x25166
movq %rax, %rdi
callq 0x32c0
movq %rax, %rdi
callq 0x3120
movq %rax, %rdi
callq 0x3120
movq %rbx, %rdi
callq 0x3380
addq $0x98, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq