avgn
avgn

Reputation: 992

What's the point of Matlab's "complex" function?

c=complex(a,b) in matlab is much slower than doing c=a+1i*b.

The following is in Matlab 2018a

a=rand(15000);
b=rand(15000);

%
clear c; 
tic; c=a+1i*b; toc
Elapsed time is 0.338525 seconds

%
clear c; 
tic; c=complex(a,b); toc
Elapsed time is 2.542403 seconds.

Is the complex actually useful in any situation? Why is it so slow?

Upvotes: 5

Views: 310

Answers (3)

Cris Luengo
Cris Luengo

Reputation: 60494

I wanted to add some historical perspective:

In versions of MATLAB prior to R2018a, complex numbers were stored in separate real and imaginary arrays internally. Thus, the result of complex could just point at the data for the two input arrays. complex(a,b) was thus very fast and memory-efficient compared to a+1i*b which actually needs to do arithmetic and create new memory storage.

In the current version of MATLAB, complex data is stored in “interleaved format”, meaning it’s a single array with real and complex values for each array element next to each other. This means data needs to be copied with either format, complex has lost its value.

Upvotes: 6

Robert Seifert
Robert Seifert

Reputation: 25232

Why is it so slow?

It isn't, really. But your "benchmark code" is not appropriate, as it does may behave differently for every run or by changing the order.

The timeit function is the dedicated function for benchmarks.

function [t] = bench()
    A = rand(10000);
    B = rand(10000);

    % functions to compare
    fcns = {
        @() compare1(A,B);
        @() compare2(A,B);
    };

    % timeit
    t = zeros(2,1);
    for ii = 1:10
        t = t + cellfun(@timeit, fcns);
    end
end

function c = compare1(a,b)  
    c = a + 1i*b;
end
function c = compare2(a,b) 
    c = complex(a,b);
end

for ten runs it leads to:

8.0663 % a + 1i*b
8.3191 % complex(a,b)

As you see, there is not much of a difference. The one there is, can be accounted for the function overhead of complex (type-check, cast) as mentioned by Luis Mendo.


Some more reasons in addition to Luis Mendo's answer, why this function may exist:

  • historical reasons, backwards compatibility
  • Nowadays you can just do [1,2,3]+1i*[1;2;3] which is the same as bsxfun(@(x,y) x+1i*y, [1,2,3], [1;2;3]), but this bsxfun(@complex, [1,2,3], [1;2;3]) is presumably faster than the second option (same applies for cellfun and arrayfun, though I can't test it.)
  • Maybe most importantly: Code generation. Matlab can automatically generate C-code from Matlab code, where complex is supported and a+1i*b isn't. There are various industrial applications, which heavily rely on this feature.

Upvotes: 2

Luis Mendo
Luis Mendo

Reputation: 112659

The documentation and the command-line help give some hints as to when it may be useful: when you want to force a complex-type result even if the imaginary part is zero, or when you have integer data types as inputs:

C = COMPLEX(A,B) returns the complex result A + Bi

In the event that B is all zeros, C is complex with all zero imaginary part, unlike the result of the addition A+0i, which returns a strictly real result.

The complex function provides a useful substitute for expressions such as A+1i*B or A+1j*B in cases when A and B are not single or double, or when B is all zero.

As for why it is slower: we can only guess, because it's a built-in function; but checking if the inputs are not floating point or if the second input is all zeros may account for some of the extra time.

Upvotes: 5

Related Questions