假设我有跳跃大小的矢量J和初始起点X_0。 另外我有边界0,B(假设0 <X_0 <B)。 我想要做随机游走其中X -1 = [分钟(X_ {I-1} + J_i,B)] ^ +。 (阳性部件)。 基本上,如果它越过边界,它是由等于边界。 任何人都知道一个量化的方式来做到这一点? 我做它目前的方式包括做cumsums,然后发现它违反条件的地方,然后从那里开始,重复计算cumsum等,直到我发现我停止侵犯边界。 它的工作原理,当边界很少打,但如果他们打所有的时间,就基本成为一个循环。
在下面的代码,我在许多样品做这个。 要“修复”里出来的边界的,我通过取样检测有环......(不要以为有一个量化的“查找”)
% X_init is a row vector describing initial resource values to use for
% each sample
% J is matrix where each col is a sequence of Jumps (columns = sample #)
% In this code the jumps are subtracted, but same thing
X_intvl = repmat(X_init,NumJumps,1) - cumsum(J);
X = [X_init; X_intvl];
for sample = 1:NumSamples
k = find(or(X_intvl(:,sample) > B, X_intvl(:,sample) < 0),1);
while(~isempty(k))
change = X_intvl(k-1,sample) - X_intvl(k,sample);
X_intvl(k:end,sample) = X_intvl(k:end,sample)+change;
k = find(or(X_intvl(:,sample) > B, X_intvl(:,sample) < 0),1);
end
end
有趣的问题(+1)。
我遇到了类似的问题而回,虽然略显复杂,因为我的下限和上限对T依赖。 我从来没有制定出一个完全量化的解决方案。 最后,我发现了最快的解决方案是一个单回路,该回路在每个步骤结合的约束。 适应代码到您的情况产生如下:
%# Set the parameters
LB = 0; %# Lower bound
UB = 5; %# Upper bound
T = 100; %# Number of observations
N = 3; %# Number of samples
X0 = (1/2) * (LB + UB); %# Arbitrary start point halfway between LB and UB
%# Generate the jumps
Jump = randn(N, T-1);
%# Build the constrained random walk
X = X0 * ones(N, T);
for t = 2:T
X(:, t) = max(min(X(:, t-1) + Jump(:, t-1), UB), 0);
end
X = X';
如果这种方法被证明比目前你在做什么更快的我会有兴趣听。 我怀疑这将是其中的约束在多于一个或两个地方结合情况。 我无法测试它自己,你所提供的代码是不是“工作”的例子,即我不能只是复制并粘贴到Matlab和运行它,因为它取决于几个变量,其示例(或模拟)值不提供。 我试图适应它自己,但不能让它正常工作?
更新:我刚换周围的代码,以便观测索引的列和样本索引的行,然后我转X
中的最后一步。 这将使程序更有效,因为matlab进行数字阵列逐列分配内存 - 因此它执行时向下一个阵列的列的操作(作为横跨行相对)更快。 请注意,你只会注意到加速大型N
。
最后的思考:这些天来,JIT加速器是在Matlab的效率使得单回路(双回路仍然相当缓慢)非常好。 因此,我个人是认为每一次尝试,并获得在Matlab完全矢量化的解决方案,即没有循环,可以权衡参与寻找一个聪明的解决方案的努力是否值得效率的小幅上扬,以进行在利用一个单一的环的更易于获得方法。 而且要记住,完全量化的解决方案有时比单涉及循环时慢的解决方案是非常重要的T
和N
小!
我想提出另一个矢量解决方案。
所以,首先要设置的参数并随机生成Jumpls
。 我用相同的参数集作为科林Ť鲍尔斯 :
% Set the parameters
LB = 0; % Lower bound
UB = 20; % Upper bound
T = 1000; % Number of observations
N = 3; % Number of samples
X0 = (1/2) * (UB + LB); % Arbitrary start point halfway between LB and UB
% Generate the jumps
Jump = randn(N, T-1);
但我改变了一代代码:
% Generate initial data without bounds
X = cumsum(Jump, 2);
% Apply bounds
Amplitude = UB - LB;
nsteps = ceil( max(abs(X(:))) / Amplitude - 0.5 );
for ii = 1:nsteps
ind = abs(X) > (1/2) * Amplitude;
X(ind) = Amplitude * sign(X(ind)) - X(ind);
end
% Shifting X
X = X0 + X;
因此,而不是for
循环我使用cumsum
功能的智能后处理。
NB此解决方案比科林Ť鲍尔斯的一个较小的范围(显著较慢Amplitude < 5
但是对于松散边界( Amplitude > 20
)它工作快得多。