累积求和并设定上限和下限?

10

我希望找到一种向量化方法来计算一个向量的累积和,但加上了上下限。

在我的情况下,输入仅包含1和-1。您可以在答案中使用此假设。当然,更通用的解决方案也是欢迎的。

例如:

x     = [1 1 1 1 -1 -1 -1 -1 -1 -1];
upper = 3;
lower = 0;
s     = cumsum(x)                    %// Ordinary cumsum.
s =
     1     2     3     4     3     2     1     0    -1    -2

y     = cumsumlim(x, upper, lower)   %// Cumsum with limits.
y =
     1     2     3     3     2     1     0     0     0     0
                 ^                       ^
                 |                       |
            upper limit             lower limit

当累加总和达到上限(在第三个元素处)时,它不会再增加。同样,当累加总和达到下限(在第七个元素处)时,它不会再减少。一个for循环版本如下:

function y = cumsumlim(x, upper, lower)

y = zeros(size(x));
y(1) = x(1);

for i = 2 : numel(x)
    y(i) = y(i-1) + x(i);
    y(i) = min(y(i), upper);
    y(i) = max(y(i), lower);
end

end

你有什么想法吗?


1
x 是否仅包含 1-1 - Divakar
@BenW 要么限制 x 可以包含的内容,要么选择更具代表性的 x。首先让它超出限制的范围 1 以上和/或以下,让它多次违反同一限制,并且最重要的是,如Divakar所提到的,如果 x 可以包含其他数字,请包含一些。 - Dan
@rayryeng,我添加了更多的解释。希望这会有所帮助。 - Ben.W
1
@Divakar,在我的情况下,输入只包含1和-1。此外,我已经添加了一个for循环版本的代码,以说明我想要做什么。希望这能帮助解释。 - Ben.W
@Ben.W,我建议你接受Luis的答案(当有人回答你的问题时这是一个很好的姿态)。它在答案左侧有一个勾号。如果你不喜欢他的解决方案,你也可以接受我的。 - Stewie Griffin
显示剩余5条评论
2个回答

5

这是一种有点“hackish”的解决方案,但或许值得一提。

您可以使用带符号整数数据类型进行求和,并利用该数据类型的固有限制。 要使其起作用,需要将输入转换为该整数类型并乘以适当的系数,然后应用初始偏移量。 系数和偏移量是根据 “lower” 和 “upper” 的函数选择的。 在 cumsum 后,撤销乘法和偏移量即可获得所需结果。

在您的示例中,数据类型为int8就足够了;所需的系数和偏移量分别为85-128

x = [1 1 1 1 -1 -1 -1 -1 -1 -1];
result = cumsum([-128 int8(x)*85]); %// integer sum, with factor and initial offset
result = (double(result(2:end))+128)/85; %// undo factor and offset

这提供了

result =
     1     2     3     3     2     1     0     0     0     0

4

我不会为您提供一个魔法向量化的方法来完成这个任务,但我可以提供一些数据,这些数据可能会帮助您继续工作。

您的cumsumlim函数非常快速!

tic
for ii = 1:100
    y = cumsumlim(x,3,0);
end
t = toc;
disp(['Length of vector: ' num2str(numel(x))])
disp(['Total time for one execution: ' num2str(t*10), ' ms.'])
Length of vector: 65000
Total time for one execution: 1.7965 ms.

我真的怀疑这是你的瓶颈。你尝试过对代码进行分析吗?


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接