The Matlab documentation says that
For speed and improved robustness, you can replace complex i and j by 1i. For example, instead of using
a = i;
use
a = 1i;
The robustness part is clear, as there might be variables called i
or j
. However, as for speed, I have made a simple test in Matlab 2010b and I obtain results which seem to contradict the claim:
>>clear all
>> a=0; tic, for n=1:1e8, a=i; end, toc
Elapsed time is 3.056741 seconds.
>> a=0; tic, for n=1:1e8, a=1i; end, toc
Elapsed time is 3.205472 seconds.
Any ideas? Could it be a version-related issue?
After comments by @TryHard and @horchler, I have tried assigning other values to the variable a
, with these results:
Increasing order of elapsed time:
"i" < "1i" < "1*i" (trend "A")
"2i" < "2*1i" < "2*i" (trend "B")
"1+1i" < "1+i" < "1+1*i" (trend "A")
"2+2i" < "2+2*1i" < "2+2*i" (trend "B")
I think you are looking at a pathological example. Try something more complex (results shown for R2012b on OSX):
(repeated addition)
>> clear all
>> a=0; tic, for n=1:1e8, a = a + i; end, toc
Elapsed time is 2.217482 seconds. % <-- slower
>> clear all
>> a=0; tic, for n=1:1e8, a = a + 1i; end, toc
Elapsed time is 1.962985 seconds. % <-- faster
(repeated multiplication)
>> clear all
>> a=0; tic, for n=1:1e8, a = a * i; end, toc
Elapsed time is 2.239134 seconds. % <-- slower
>> clear all
>> a=0; tic, for n=1:1e8, a = a * 1i; end, toc
Elapsed time is 1.998718 seconds. % <-- faster
One thing to remember is that optimizations are applied differently whether you are running from the command line or a saved M-function.
Here is a test of my own:
function testComplex()
tic, test1(); toc
tic, test2(); toc
tic, test3(); toc
tic, test4(); toc
tic, test5(); toc
tic, test6(); toc
end
function a = test1
a = zeros(1e7,1);
for n=1:1e7
a(n) = 2 + 2i;
end
end
function a = test2
a = zeros(1e7,1);
for n=1:1e7
a(n) = 2 + 2j;
end
end
function a = test3
a = zeros(1e7,1);
for n=1:1e7
a(n) = 2 + 2*i;
end
end
function a = test4
a = zeros(1e7,1);
for n=1:1e7
a(n) = 2 + 2*j;
end
end
function a = test5
a = zeros(1e7,1);
for n=1:1e7
a(n) = complex(2,2);
end
end
function a = test6
a = zeros(1e7,1);
for n=1:1e7
a(n) = 2 + 2*sqrt(-1);
end
end
The results on my Windows machine running R2013a:
>> testComplex
Elapsed time is 0.946414 seconds. %// 2 + 2i
Elapsed time is 0.947957 seconds. %// 2 + 2j
Elapsed time is 0.811044 seconds. %// 2 + 2*i
Elapsed time is 0.685793 seconds. %// 2 + 2*j
Elapsed time is 0.767683 seconds. %// complex(2,2)
Elapsed time is 8.193529 seconds. %// 2 + 2*sqrt(-1)
Note that the results fluctuate a little bit with different runs where the order of calls is shuffled. So take the timings with a grain of salt.
My conclusion: doesn't matter in terms of speed if you use 1i
or 1*i
.
One interesting difference is that if you also have a variable in the function scope where you also use it as the imaginary unit, MATLAB throws an error:
Error: File: testComplex.m Line: 38 Column: 5
"i" previously appeared to be used as a function or command, conflicting with its
use here as the name of a variable.
A possible cause of this error is that you forgot to initialize the variable, or you
have initialized it implicitly using load or eval.
To see the error, change the above test3
function into:
function a = test3
a = zeros(1e7,1);
for n=1:1e7
a(n) = 2 + 2*i;
end
i = rand(); %// added this line!
end
i.e, the variable i
was used as both a function and a variable in the same local scope.