3

ジャンプサイズのベクトルJと初期開始点X_0があるとします。また、境界0、Bがあります(0 <X_0 <Bと仮定します)。X_i = [min(X_ {i-1} + J_i、B)]^+のランダムウォークを実行したい。(正の部分)。基本的に境界を越えると境界と等しくなります。誰もがこれを行うためのベクトル化された方法を知っていますか?現在のやり方は、cumsumを実行してから、条件に違反する場所を見つけ、そこから開始して、境界に違反しなくなるまでcumsumの計算を繰り返すことなどです。境界がめったにヒットしない場合に機能しますが、常にヒットすると、基本的にforループになります。

以下のコードでは、これを多くのサンプルで行っています。境界の外に出るものを「修正」するには、サンプルをループしてチェックする必要があります...(ベクトル化された「検索」があるとは思わないでください)

% 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
4

2 に答える 2

2

興味深い質問 (+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';

この方法が現在行っている方法よりも高速であることが証明されるかどうかを聞いてみたいと思います. 制約が 1 つまたは 2 つ以上の場所で拘束されている場合になると思います。あなたが提供したコードは「動作する」例ではないため、自分でテストすることはできません。つまり、サンプル(またはシミュレートされた)値のいくつかの変数に依存するため、コピーしてMatlabに貼り付けて実行することはできません提供されません。自分で調整してみましたが、うまく動作しませんでしたか?

更新:観察が列でインデックス付けされ、サンプルが行でインデックス付けされるようにコードを切り替えてからX、最後のステップで転置します。Matlab は数値配列に列単位でメモリを割り当てるため、これによりルーチンがより効率的になります。したがって、配列の列を下って操作を実行すると (行全体ではなく) 高速になります。大規模な の高速化のみに気付くことに注意してくださいN

最終的な考え:最近、JIT アクセラレータは、Matlab の単一ループを効率的にするのに非常に優れています (二重ループはまだかなり遅いです)。したがって、個人的には、Matlab で完全にベクトル化されたソリューション、つまりループのないソリューションを取得しようとするたびに、巧妙なソリューションを見つけるために必要な労力が、わずかな効率向上に見合うだけの価値があるかどうかを検討する必要があると思います。単一のループを利用するより簡単に入手できる方法よりも。また、とが小さい場合、完全にベクトル化されたソリューションは、単一ループを含むソリューションよりも遅くなる場合があることを覚えておくことが重要です。TN

于 2013-01-10T03:08:10.127 に答える