Discover MakerZone

MATLAB and Simulink resources for Arduino, LEGO, and Raspberry Pi

Learn more

Discover what MATLAB® can do for your career.

Opportunities for recent engineering grads.

Apply Today

Improve performance in 'expansion of data' function

Asked by Stephen on 15 Jan 2013

Hi,

In my application i have a performance bottleneck in the following function. I have experimented a little and improved it a bit but im wondering if it can be made any faster. Its right on the edge of acceptable and too slow still.

I need a function to do the following:

if I = [1 2 3 4] then expanding it by 4 would give [1 1 1 1 2 2 2 2 3 3 3 3 4 4 4 4]

I am using the data generated from the code below to apply to another set of data

 %Expand I and Q Data to longer arrays
 %Expands the original data by copying each number a few times
 function [I_mod Q_mod] = expandIQ(I,Q,expandfactor)
 expandfactor = round(expandfactor);
 I_mod = [];
 Q_mod = [];
 for i=1:expandfactor:(length(I)*expandfactor)
   I_mod = [I_mod I((i-1)/expandfactor+1)*ones(1,expandfactor)];
   Q_mod = [Q_mod Q((i-1)/expandfactor+1)*ones(1,expandfactor)];
 end
 if(length(I_mod) ~= length(I)*expandfactor)
    error('Unexpected length of I_mod')
 end

I have tried 'pre-allocating for speed' as matlab suggested, however this reduced it drastically.

I have been testing the performance using:

 I = ones(1,length_of_I);
 Q = ones(1,length_of_I);
 tic
 expandIQ(I,Q,expandfactor);
 toc

where length_of_I << expandfactor

eg. length_of_I = 16, expandfactor = 500000 or length_of_I = 500, expandfactor = 50000

Im sure there is a faster way but i can't think of any. I am more comfortable in C than matlab so any suggestions/ideas before i try mex?

Thanks, Stephen

2 Comments

Stephen on 15 Jan 2013

Ahhh, this is much better :) Any improvements on this? Its still a bit slow :/

 %Expand I and Q Data to longer arrays
 %Expands the original data by copying each number a few times
 function [I_mod Q_mod] = expandIQ(I,Q,expandfactor)
 expandfactor = round(expandfactor);
 I_mod = ones(1,length(I)*expandfactor);
 Q_mod = ones(1,length(I)*expandfactor);
 for i=1:length(I)
    start = (i-1)*expandfactor+1;
    I_mod(start:(start+expandfactor-1)) = I(i).*I_mod(start:(start+expandfactor-1));
    Q_mod(start:(start+expandfactor-1)) = Q(i).*Q_mod(start:(start+expandfactor-1));
 end
 if(length(I_mod) ~= length(I)*expandfactor)
    error('Unexpected length of I_mod')
 end
Matt Kindig on 15 Jan 2013

I haven't tested your code, but I think this is what you are trying to achieve. It seems fairly fast for your length(I)=16, expandfactor = 500000 example:

tic; 
I=(1:16); 
Y = I'*ones(1,500e3); 
Y=reshape(Y',[],1)'; 
toc  %0.087 sec on my machine
% for your second example (length(I)=500, expandfactor = 50e3)
  tic; 
  I=(1:500); 
  Y = I'*ones(1,50e3); 
  Y=reshape(Y',[],1)'; 
  toc  %0.229 sec on my machine.
Stephen

Products

No products are associated with this question.

1 Answer

Answer by Cedric Wannaz on 16 Jan 2013
Accepted answer

Hi Stephen,

See if the following brings an improvement in your specific context:

 function [I_mod Q_mod] = expandIQ(I,Q,expandfactor)
    expandfactor = round(expandfactor) ;
    I_mod = reshape(repmat(I, expandfactor, 1), 1, []) ; 
    Q_mod = reshape(repmat(Q, expandfactor, 1), 1, []) ;
 end

It's not too relevant here, but there is a profiler in the Tools menu.

Cheers,

Cedric

1 Comment

Stephen on 16 Jan 2013

Thats fantastic!

Thanks

Cedric Wannaz

Contact us