Is there a faster complex exponent?

11 views (last 30 days)
Is there any way to more quickly evaluate complex exponentials, i.e:
where Q is a real array? Quick numerical tests show that complex input noticeably slows down MATLAB's exp function.
Several thoughts:
  • Some libraries, such as Julia Base, provide a cis/cisoid function that directly evaluates the Euler expansion.
  • The GNU C library has sincos function that simultaneously evaluate sine and cosine more quickly than separate calls.
  • The Fixed Point Designer has a cordicexp function that seems to be identical to cis, but I don't have this toolbox. No idea how this performs compared to the standard exp function.
  11 Comments
Paul
Paul on 15 Dec 2023
Edited: Paul on 16 Dec 2023
FWIW, Simulink offers a sincos and cos + jsin functions (Trigonometric Function), with options for how those functions are computed (Algorithm - Approximation Method). Don't know if the "under the hood" Simulink implementation would offer any performance benefits if brought into Matlab proper.
Bruno Luong
Bruno Luong on 15 Dec 2023
But again I'm not convice MATLAB is NOT already do specific acceleration for exp(1i*Q). It is faster than cos alone on my PC and Walter PC as well

Sign in to comment.

Accepted Answer

Daniel Dolan
Daniel Dolan on 18 Dec 2023
(It's a little tacky answering my own question, but I wanted to synthesize helpful comments from Walter and Bruno).
The MATLAB exp must be highly optimized for pure imaginary input. The following code:
function doit()
cis(0); % ensure tabulation runs before time testing
L=50;
N=logspace(3,8,L);
N=round(N);
t0=nan(L,1);
t=nan(L,3);
for k=1:L
Q = 20*pi*(rand(1,N(k))-0.5); % span multiple cycles, including negative values
start = tic;
[~] = exp(1i*Q);
t0(k) = toc(start);
%
start=tic;
[~]=cos(Q)+1i*sin(Q); % explicit cis(Q)
t(k,1)=toc(start);
start=tic;
[~] = cos(Q); % cosine only
t(k,2) = toc(start);
start=tic;
[~]=cis(Q);
t(k,3)=toc(start);
end
plot(N,t./t0);
set(gca,'XScale','log')
figure(gcf);
xlabel('Iterations');
ylabel('Time ratio');
legend('Explicit','Cosine only','Tabulation');
end
%%
function out=cis(in)
persistent lookup
if isempty(lookup)
phi=linspace(0,2*pi,1000);
z=cos(phi)+1i*sin(phi);
lookup=griddedInterpolant(phi,z);
end
in=rem(in,2*pi);
out=lookup(in);
end
generates this plot on an M1 Mac running 2023b.
Explicit construction of a real cosine and imaginary sine is slower than the builtin exp function, though not as much so as I would have expected. Not sure what the resonances between 1E3 and 1E4 evaluations come from.
A single trig evaluation is always faster than exp on my Mac. Maybe there are hardware-specific optimizations on the PC?
If Q is always real, periodicity makes it pretty easy to build an interpolation table. I thought this might be faster than exp, but that did not pan out. For many iterations, my tabulation nearly matches exp performance.
To conclude, there is no obvious way to beat MATLAB exp(i*Q) performance for real Q. Hypothetically, a compiled function invoking simultaneous sin/cos evaluation might squeeze out a factor of two, but that does not account for complex number management.

More Answers (1)

Sulaymon Eshkabilov
Sulaymon Eshkabilov on 15 Dec 2023
Let's compare two ways e.g.:
Q = linspace(-10, 10, 1e6);
tic;
CQ1 = exp(1i*Q);
T1 =toc
T1 = 0.0145
tic;
CQ2 = cos(Q)+1i*sin(Q);
T2 =toc
T2 = 0.0347
fprintf('Calc time of exp(1i*Q): %f; cos(Q)+i*sin(Q): %f; \n', [T1, T2])
Calc time of exp(1i*Q): 0.014515; cos(Q)+i*sin(Q): 0.034731;
  1 Comment
Daniel Dolan
Daniel Dolan on 15 Dec 2023
It's no surprise that two trig evaluations are slower than the complex exponent. The question is whether we can do better than the complex exponent.

Sign in to comment.

Categories

Find more on Loops and Conditional Statements in Help Center and File Exchange

Products


Release

R2023b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!