I am currently trying to implement a discrete integration over complex numbers for a complex fourier transform.
However, the implementation that I made in go yields a wrong result.
Here is my implementation:
n = input() //It is a function argument
cumulativeValue := 0 + 0i
currentTime := 0.00
const deltaTime = 0.001
const precision = 0.0001
for cmpFloat(currentTime, 1.00, precision) < 0 {
currentPoint := findPointForTime(currentTime)
cumulativeValue += complex(float64(currentPoint.X), float64(currentPoint.Y)) * cmplx.Exp(complex(0.0, -2.0*math.Pi*float64(n)*currentTime))
currentTime += deltaTime
}
cumulativeValue *= deltaTime
This algorithm gives back an element of a the fourier serie. But when I try to get the function back from the serie, it is nowhere close the original input.
I tried to implement the same algorithm in Python, without the conversions, and it works flawlessly.
Investigation
I first thought that the issue had to do with the findPointForTime function, but I have already comfirmed it has not.
Then, while debugging, I saw that the first few values are quite equivalent in Python, but not so much after the 500th addition (mid-algorithm).
The issue may then be that either the precision of go's complex numbers isn't sufficient, or that cmplx.Exp is not correct (which seems improbable).
So, is there a way to improve the precision of the complex128 in go ?
TLDR: The issue may be go's floating point precision. Is there a way to improve it ?
- Note 1: Weirdly, the code works for one input and for none other so far.
- Note 2: My code is (largely) inspired from someone else, and it worked in their case, which leads me to think that there isn't any need for other libraries such as "math/big" (though it might be worth the try).
Edits
- Edit 1: The integration does not depends on deltaTime, because it is the interval on which i'm integrating (thus, it is a multipication factor, and, as a constant, it can be either inside ou outside the loop), however it depends on the currentTime variable.
As per how complex fourier transform works, the integration is
So I'm first getting the value f(t) then I compute the exponential part, multiply them together with deltaTime (which I left outside -- at the end of the loop) and add them to the accumulator. finally, I repeat this while currentTime is lower than 1second. (which, I believe, is the method of integration with stairs => maybe trapezoids are better?) - Edit 2: I am using python's default complex system, so I doubt it's 128 bits. The python code is as follow:
currentTime = 0
deltaTime = 0.001
cumulativeValue = complex(0)
while currentTime < 1.0:
point = getPointforTime(currentTime)
cumulativeValue += point * cmath.exp(-2.0j*cmath.pi*n*currentTime)*deltaTime
currentTime += deltatime