Forum Discussion
PeterBartholomew1
Jan 28, 2023Silver Contributor
Would you recommend the use of Excel complex numbers where performance is required?
Excel is now meant to be Turing complete so it appears to be possible to write serious computing functionality. As an experiment, I have implemented a Discrete Fourier Transformation algorithm using recursive FFT. I avoided the built-in text-based functionality to process complex numbers and instead wrote a Lambda function to replace complex multiplication
Multiplyλ
= LET(
u, TAKE(w, , 1),
v, TAKE(w, , -1),
x, TAKE(z, , 1),
y, TAKE(z, , -1),
HSTACK(u * x - v * y, u * y + v * x)
)
I allowed each complex number of the array to spill across two columns, but was it necessary?
For anyone who might be interested, the solution I presented uses a double recursion to navigate a tree of calculations (typically this is used to reduce 10 000 000 multiplications to a mere 50 000, but I am not planning to try that with Excel)
DFTλ(z, N, s)
= IF( N = 1, z,
LET(
z₀, DFTλ(Splitλ(z, 2, 0), N / 2, 2 * s),
z₁, DFTλ(Splitλ(z, 2, 1), N / 2, 2 * s),
W, TAKE(Splitλ(W₀, N₀ / N), N / 2),
p, z₀,
q, Multiplyλ(W, z₁),
VSTACK(p + q, p - q)
)
)
The key element of the function DFTλ is that it calls itself twice, first following a branch of the calculation until it goes full depth; it evaluates that and then backs up a level and calculates the other branch. The final part of the routine combines two results before moving back up a further level.
I agree I haven't exactly followed the spreadsheet mantra for formula of 'keep it simple', but someone has to try it!
# Lambda functions
# Recursion
# Complex Numbers
- aaltomaniCopper ContributorI implemented FFT as a lambda (radix-2 and Bluestein, source here: https://github.com/altomani/XL-FFT) and I used the same representation of complex numbers as two adjacent cells. I also tested the "native" representation of complex numbers as strings and for me it was much slower.
- PeterBartholomew1Silver Contributor
That is some impressive coding for Excel formulas. Sorry I missed your original post. Do you actually work with FFTs or was it just a case of experimentation with modern Excel?
I found the theoretical basis of the FFT algorithm somewhat heavy-going and finished up by implementing version with a double recursion. I am now looking at following
Nonrecursive Fast Fourier Transform - YouTube
to see what a non-recursive form might look like.
As for the original question on the in-built complex function calculation, your answer is very much in line with my expectations. Thanks for the confirmation.
- aaltomaniCopper Contributor
I needed the FFT for a fast convolution of probability distributions. I had previously used a VBA implementation, and recently migrated to pure Excel formulas. It is at least as fast as the VBA implementation, except for some edge case when copying formulas to a different sheet (relevant thread here: https://techcommunity.microsoft.com/t5/excel/puzzling-performance-issues-with-lambda-array-formulas/m-p/3720783).
How do you plan to make a non-recursive version? Implementations in "fast" languages such as C use arrays that are mutated in place. Have you found a way to emulate that in Excel?
- lori_mSteel Contributor
Impressive FFT recursion! Interesting topic but unsurprisingly not a huge amount of feedback so far, perhaps tboulden might have further insight? I'd never used complex numbers in coding before and it didn't help that in the Rosetta Code link, the outputs from python as well as a number of other scripts were erroneous.
After a few false starts I ended up with the following representation for a complex matrix X+iY:=LAMBDA(i,IF(i,X,Y))
I chose 'i' to indicate a complex number, though the 'i' is not imaginary here but a lambda parameter that may be input as (1), (0) or (({1,0}) for real, imaginary or both parts respectively.
I didn't manage to do the recursion but working through the referenced Wikipedia article was able to reduce the large DFT matrix multiplication into smaller matrix products. Even so, 4096 = 64x64 elements took just 0.1s compared to over 10s using the built-in Fourier analysis tool.- tbouldenIron Contributor
lori_m PeterBartholomew1 Apologies for my long absence! I'll have to dive-in on this over the weekend, but it looks pretty thrilling! Back once I've wrapped my head around it, or when I hit a brick wall and have a question!
- lori_mSteel Contributor
Good to hear from you tboulden!
I found this considerably mentally taxing too and that was without even attempting the recursion that Peter managed. Translating the equations into array operations was enough of an uphill climb in itself!
I was pleased to be able to find the complex number representation above but found care was needed to maintain efficiency, particularly short-circuit evaluation of arguments via IF. I also wanted to add the python code did run successfully when I changed the output, I had just missed initially that the inconsistency was due to reporting amplitudes instead.