Is there a faster complex exponent?

7 次查看(过去 30 天)
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 个评论
Paul
Paul 2023-12-15
编辑:Paul 2023-12-16
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 2023-12-15
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

请先登录,再进行评论。

采纳的回答

Daniel Dolan
Daniel Dolan 2023-12-18
(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.

更多回答(1 个)

Sulaymon Eshkabilov
Sulaymon Eshkabilov 2023-12-15
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 个评论
Daniel Dolan
Daniel Dolan 2023-12-15
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.

请先登录,再进行评论。

类别

Help CenterFile Exchange 中查找有关 Symbolic Math Toolbox 的更多信息

产品


版本

R2023b

Community Treasure Hunt

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

Start Hunting!

Translated by