问题
There is an input vector with allowed set of values {-2,-1,0,1,2}, e.g.
input = [2 2 2 2 0 1 0 -1 0 -2 -2 -1 0 1]
Vector is scanned iteratively from start to end and at each point a certain transition table is realized, based on the current value of the vector, and a certain accumulated value determined by previous iterations. This value is incremented/decremented by a requested step (3 here) up to the top value (9 here) beyond which it cannot go. The output vector represents certain ongoing deltas derived out of the current input value and accumulation, according to the defined transitions.
The loop in Octave (3.8) performs very poorly and I cannot find a way to vectorize this. Is vectorization possible at all when such indirect memory of accumulation is used in between input and output?
input = [2 2 2 2 0 1 0 -1 0 -2 -2 -1 0 1]
step = 3;
top = 9;
acc = out = 0;
for i = 1 : length(input)
if (input(i) == +2)
if (acc < 0) out(i) = -acc+step;
elseif (acc > top-step) out(i) = 0;
elseif (acc >= 0) out(i) = step;
endif
elseif (input(i) == +1)
if (acc >= 0) out(i) = 0;
elseif (acc < 0) out(i) = -acc;
endif
elseif (input(i) == 0) out(i) = 0;
elseif (input(i) == -1)
if (acc <= 0) out(i) = 0;
elseif (acc > 0) out(i) = -acc;
endif
elseif (input(i) == -2)
if (acc > 0) out(i) = -acc-step;
elseif (acc < -top+step) out(i) = 0;
elseif (acc <= 0) out(i) = -step;
endif
endif
acc += out(i);
endfor
out
out =
3 3 3 0 0 0 0 -9 0 -3 -3 0 0 6
# e.g. the -9 resets the first three 3's buildup: 3+3+3-9=0
Performance bechmark:
Solution 1 (slow loop)
(EDITED)
input = repmat([2 2 2 2 0 1 0 -1 0 -2 -2 -1 0 1], 1,20000);
out = zeros(1, length(input));
tic; for i = 1 : length(input)
(...)
endfor; toc;
Elapsed time is 8.95053 seconds.
来源:https://stackoverflow.com/questions/34046161/trivial-impossible-algorithm-challenge-in-octave-matlab-iterations-memory