belgarion
belgarion

Reputation: 115

How do I create a dynamic average? (Don't know how else to call it)

I have a 10000x1 matrix. I need to find the percentage of information contained in each case. The method of doing so is to make another matrix that contains the sum of remaining cells.

Example:

% info is a 10000x1
% info_n contains percentages of information.


info_n = zeros([10000 1]);
info_n(1)= info(1)                 /sum(info);
info_n(2)=(info(1)+info(2))        /sum(info);
info_n(3)=(info(1)+info(2)+info(3))/sum(info);

I need to do this but all the way to info_n(10000).

So far, I tried this:

for i = 1:10000

info_n(i)=(info(i))/sum(info);   

end

but I can't think of a way to add previous information. Thank you for the help!

Upvotes: 0

Views: 58

Answers (1)

flawr
flawr

Reputation: 11638

You can use cumsum ("cumulative sum") for this task:

info_n = cumsum(info)/sum(info);

EDIT: @LuisMendo's comment sparked my curiosity. It seems that you actually gain something by using his method if the length N of the vector is below about 2^15 but the advantage after that drops. This is because cumsum probably needs O(N^2) but sum only needs O(N) time.

On the left you see the times as well as the ratio of the times of the two methods plotted against the logarithm of the size. On the right you see the actual absolute time differences, which varies a lot depending on what else is currently running:

enter image description here

Testing script:

N = 2.^(1:28);
y1 = zeros(size(N));
y2 = zeros(size(N));
vec = 1:numel(N);
for k=vec;
    disp(k)
    info = zeros(N(k),1);
    % flawr's suggestion
    tic
    info_n = cumsum(info);
    info_n = info_n / info_n(end);
    y1(k) = toc;
    % LuisMendo's suggestion
    tic
    info_m = cumsum(info)/sum(info);
    y2(k) = toc;
end
subplot(1,2,1)
semilogy(vec,y1,vec,y2,vec,y1./y2,vec,vec.^0);
legend('LuisMendo','flawr','LM/f','Location','SouthEast');
subplot(1,2,2)
plot(vec,y1-y2)

Upvotes: 7

Related Questions